rs_backtester/
utilities.rs1use csv::Writer;
2use std::error::Error;
3use std::fs::File;
4use crate::datas::Data;
5use crate::strategies::Strategy;
6
7pub trait SerializeAsCsv {
9 fn to_csv(&self, writer: &mut Writer<std::fs::File>) -> Result<(), Box<dyn Error>>;
10}
11
12
13pub fn serialize_to_csv<T: SerializeAsCsv>(data: &T, file_path: &str) -> Result<(), Box<dyn Error>> {
15 let mut wtr = Writer::from_path(file_path)?;
16 data.to_csv(&mut wtr)?;
17 wtr.flush()?;
18 Ok(())
19}
20
21impl SerializeAsCsv for Data {
22 fn to_csv(&self, writer: &mut Writer<File>) -> Result<(), Box<dyn Error>> {
23 writer.serialize(("ticker","date","open","high","low","close")).expect("couldn't write csv");
24 for i in 0..self.datetime.len() {
25 writer.write_record(&[
26 self.ticker.clone(),
27 self.datetime[i].to_string(),
28 self.open[i].to_string(),
29 self.high[i].to_string(),
30 self.low[i].to_string(),
31 self.close[i].to_string(),
32 ])?;
33 }
34 Ok(())
35 }
36}
37
38impl SerializeAsCsv for Strategy {
39 fn to_csv(&self, writer: &mut Writer<File>) -> Result<(), Box<dyn Error>> {
40 if let Some(indicators) = self.indicator.clone() {
41 let mut header: Vec<String> = Vec::new();
42 header.push("Name".to_string());
43 header.push("Choice".to_string());
44 for (index,_) in indicators.iter().enumerate(){
45 header.push(format!("Indicator {}", index+1));
46 }
47 writer.write_record(&header)?;
48 for i in 0..self.choices.len() {
49 let mut row: Vec<String> = vec![self.name.to_string(),self.choices[i].to_string().into()];
50 row.extend(indicators.iter().map(|indicator|indicator[i].to_string()));
51 writer.write_record(&row)?;
52 }
53 }
54 Ok(())
55 }
56}