0

I'm reading data from a message queue, deserializing it with Serde and storing it into structs which I want to store that timeseries data into polars. Reading this my understanding is that polars is built arround storing the data in columns so as I work around I tried the following.

On start I call:

 async fn init_dataframe() -> HashMap<String, Equities> {
     let mut btc = Equities::new("BTCUSD".to_string());
     btc.dataframe = Equities::instantiate_data(&btc);

     let dataframes = HashMap::from([("BTCUSD".to_string(), btc)]);

     dataframes
 }

 pub fn instantiate_data(&self) -> DataFrame {
     let columns = vec![
         Series::new("broker_time", &self.data.broker_time),
         Series::new("timeframe", &self.data.timeframe),
         Series::new("open", &self.data.open),
         Series::new("high", &self.data.high),
         Series::new("low", &self.data.low),
         Series::new("close", &self.data.close),
         Series::new("tick_volume", &self.data.tick_volume),
         Series::new("spread", &self.data.spread),
     ];
  
     DataFrame::new(columns).unwrap()
 }

Equities and Candles:

#[derive(Debug)]
pub struct Equities {
    pub symbol: String,
    pub data: Candles,
    pub dataframe: DataFrame,
}

#[derive(Debug)]
pub struct Candles {
    pub broker_time: Vec<String>,
    pub timeframe: Vec<String>,
    pub open: Vec<f32>,
    high: Vec<f32>,
    low: Vec<f32>,
    close: Vec<f32>,
    tick_volume: Vec<f32>,
    spread: Vec<f64>,
}

As I retrieve data I find the symbol location in the hashmap, access the equities object and try appending the data to each vec series to be stored in polars:

match candle {
  candleEnum::CandleJson(candle) => {
     dataframes[candle.symbol()].data.broker_time.push(candle.broker_time().to_string());
  }
  candleEnum::TickJson(candle) => {
     dataframes[candle.symbol()].data.broker_time.push(candle.broker_time().to_string());
  }
}

Error: trait `IndexMut` is required to modify indexed content, but it is not implemented for 
`std::collections::HashMap<std::string::String, handlers::equities::Equities>`

This doesn't work as the HashMap requires IndexMut so I looked into using the .entry() method but am unable to select the dataframe object from the Equities struct to access data to insert the streamed data. Is there a better way to do this? How can I access and modify data from the Entries struct? I'm still very new to using rust coming from a python background so any pointers are much appreciated.

Edit I was able to fix the mut HashMap error thanks to @cdhowie. Now as I try and print the dataframe, it still shows an empty dataframe despite data being pushed to the Candles vecs.

match candle {
  candleEnum::CandleJson(candle) => {
     dataframes.get_mut(candle.symbol()).unwrap().data.broker_time.push(candle.broker_time().to_string());
  }
  candleEnum::TickJson(candle) => {
     dataframes.get_mut(candle.symbol()).unwrap().data.broker_time.push(candle.broker_time().to_string());
  }
}
Mass
  • 1
  • 2
  • Try replacing `[candle.symbol()]` with `.get_mut(candle.symbol()).unwrap()`. Note that the `.unwrap()` call will panic (crash the whole program) if the symbol isn't present in the map. – cdhowie May 05 '22 at 06:20
  • @cdhowie that seems to have fixed the HashMap error, and I am now able to insert into the vectors however if I call `dbg!("{:#?}", &dataframes[candle.symbol()].dataframe);` afterwards, it still shows an empty dataframe. I tried `Equities::instantiate_data(&dataframes[candle.symbol()]);` again to reload the series data however it still shows an empty dataframe. Doing `dbg!("{:#?}", &dataframes[candle.symbol()].data.close);` does show that the vecs are filling with data – Mass May 05 '22 at 06:48

0 Answers0