use std::collections::HashMap;
use std::path::PathBuf;
use bitcode::{Decode, Encode};
use polars::frame::DataFrame;
use avin_utils::{AvinError, CFG};
#[derive(Debug, PartialEq, Eq, Encode, Decode, Clone)]
pub struct Iid {
info: HashMap<String, String>,
}
impl Iid {
pub fn new(info: HashMap<String, String>) -> Iid {
debug_assert_ne!(info.get("exchange"), None);
debug_assert_ne!(info.get("category"), None);
debug_assert_ne!(info.get("ticker"), None);
debug_assert_ne!(info.get("figi"), None);
debug_assert_ne!(info.get("name"), None);
debug_assert_ne!(info.get("lot"), None);
debug_assert_ne!(info.get("step"), None);
Iid { info }
}
pub fn from_df(df: &DataFrame) -> Result<Iid, AvinError> {
debug_assert_eq!(df.height(), 1);
let columns = [
"exchange",
"exchange_specific",
"category",
"ticker",
"figi",
"country",
"currency",
"sector",
"class_code",
"isin",
"uid",
"name",
"lot",
"step",
"long",
"short",
"long_qual",
"short_qual",
"first_1m",
"first_d",
];
let mut info = HashMap::new();
for i in columns {
info.insert(i.to_string(), df.get_as_str(i));
}
Ok(Iid::new(info))
}
pub fn info(&self) -> &HashMap<String, String> {
&self.info
}
pub fn exchange(&self) -> &String {
self.info.get("exchange").unwrap()
}
pub fn category(&self) -> &String {
self.info.get("category").unwrap()
}
pub fn ticker(&self) -> &String {
self.info.get("ticker").unwrap()
}
pub fn figi(&self) -> &String {
self.info.get("figi").unwrap()
}
pub fn name(&self) -> &String {
self.info.get("name").unwrap()
}
pub fn lot(&self) -> u32 {
self.info.get("lot").unwrap().parse().unwrap()
}
pub fn step(&self) -> f64 {
self.info.get("step").unwrap().parse().unwrap()
}
pub fn path(&self) -> PathBuf {
let mut p = CFG.dir.data();
p.push(self.exchange());
p.push(self.category());
p.push(self.ticker());
p
}
}
impl std::fmt::Display for Iid {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
write!(
f,
"{}_{}_{}",
self.exchange(),
self.category(),
self.ticker()
)
}
}
impl std::hash::Hash for Iid {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.figi().hash(state);
}
}
trait Getter {
fn get_as_str(&self, col: &str) -> String;
}
impl Getter for DataFrame {
fn get_as_str(&self, column_name: &str) -> String {
self.column(column_name)
.unwrap()
.str()
.unwrap()
.first()
.unwrap()
.to_string()
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::path::Path;
#[test]
fn new() {
let mut info = HashMap::new();
info.insert("exchange".to_string(), "MOEX".to_string());
info.insert("category".to_string(), "SHARE".to_string());
info.insert("ticker".to_string(), "SBER".to_string());
info.insert("figi".to_string(), "BBG004730N88".to_string());
info.insert("name".to_string(), "Сбер Банк".to_string());
info.insert("lot".to_string(), "10".to_string());
info.insert("step".to_string(), "0.01".to_string());
let iid = Iid::new(info);
assert_eq!(iid.exchange(), "MOEX");
assert_eq!(iid.category(), "SHARE");
assert_eq!(iid.ticker(), "SBER");
assert_eq!(iid.figi(), "BBG004730N88");
assert_eq!(iid.name(), "Сбер Банк");
assert_eq!(iid.lot(), 10);
assert_eq!(iid.step(), 0.01);
}
#[test]
fn to_string() {
let mut info = HashMap::new();
info.insert("exchange".to_string(), "MOEX".to_string());
info.insert("category".to_string(), "SHARE".to_string());
info.insert("ticker".to_string(), "SBER".to_string());
info.insert("figi".to_string(), "BBG004730N88".to_string());
info.insert("name".to_string(), "Сбер Банк".to_string());
info.insert("lot".to_string(), "10".to_string());
info.insert("step".to_string(), "0.01".to_string());
let iid = Iid::new(info);
let s = iid.to_string();
assert_eq!("MOEX_SHARE_SBER", s);
}
#[test]
fn path() {
let mut info = HashMap::new();
info.insert("exchange".to_string(), "MOEX".to_string());
info.insert("category".to_string(), "SHARE".to_string());
info.insert("ticker".to_string(), "SBER".to_string());
info.insert("figi".to_string(), "BBG004730N88".to_string());
info.insert("name".to_string(), "Сбер Банк".to_string());
info.insert("lot".to_string(), "10".to_string());
info.insert("step".to_string(), "0.01".to_string());
let iid = Iid::new(info);
let path = Path::new("/home/alex/trading/data/MOEX/SHARE/SBER");
assert_eq!(iid.path(), path);
}
}