use std::collections::HashMap; use crate::connectors::Client; use crate::currency::SymbolPair; use crate::events::{Event, SignalKind}; use crate::models::{Order, Position, PriceTicker}; use crate::strategy::PositionStrategy; use crate::BoxError; pub struct EventManager { events: Vec, } #[derive(Clone, Debug)] pub struct PriceManager { pair: SymbolPair, prices: Vec, client: Client, } impl PriceManager { pub fn new(pair: SymbolPair, client: Client) -> Self { PriceManager { pair, prices: Vec::new(), client, } } pub fn add_entry(&mut self, entry: PriceEntry) { self.prices.push(entry); } pub async fn update(&mut self, tick: u64) -> Result { let current_prices = self.client.current_prices(&self.pair).await?.into(); Ok(PriceEntry::new( tick, current_prices, self.pair.clone(), None, None, )) } // pub fn add_position(&mut self, position: Position) { // let (new_position, events, signals) = { // match &self.strategy { // Some(strategy) => strategy.on_new_tick(&position, &self), // None => (position, vec![], vec![]), // } // }; // // self.positions // .entry(self.current_tick) // .or_default() // .push(new_position.clone()); // // // calling position state callbacks // self.dispatcher // .call_position_state_handlers(&new_position, &self); // // // adding events and calling callbacks // for e in events { // self.add_event(e); // } // // // adding signals to current tick vector // for s in signals { // self.add_signal(s); // } // } // fn add_event(&mut self, event: Event) { // self.events.push(event); // // self.dispatcher.call_event_handlers(&event, &self); // } // // fn add_signal(&mut self, signal: SignalKind) { // self.signals.insert(self.current_tick(), signal); // } pub fn pair(&self) -> &SymbolPair { &self.pair } // pub fn position_previous_tick(&self, id: u64, tick: Option) -> Option<&Position> { // let tick = match tick { // Some(tick) => { // if tick < 1 { // 1 // } else { // tick // } // } // None => self.current_tick() - 1, // }; // // self.positions // .get(&tick) // .and_then(|x| x.iter().find(|x| x.position_id() == id)) // } } #[derive(Clone, Debug)] pub struct PriceEntry { tick: u64, pair: SymbolPair, price: PriceTicker, events: Option>, signals: Option>, } impl PriceEntry { pub fn new( tick: u64, price: PriceTicker, pair: SymbolPair, events: Option>, signals: Option>, ) -> Self { PriceEntry { tick, pair, price, events, signals, } } pub fn tick(&self) -> u64 { self.tick } pub fn pair(&self) -> &SymbolPair { &self.pair } pub fn price(&self) -> PriceTicker { self.price } pub fn events(&self) -> &Option> { &self.events } pub fn signals(&self) -> &Option> { &self.signals } } #[derive(Debug)] pub struct PositionManager { pair: SymbolPair, positions_history: HashMap, active_position: Option, client: Client, strategy: Option>, } impl PositionManager { pub fn new(pair: SymbolPair, client: Client) -> Self { PositionManager { pair, positions_history: HashMap::new(), active_position: None, client, strategy: None, } } pub fn with_strategy(mut self, strategy: Box) -> Self { self.strategy = Some(strategy); self } pub async fn update(&mut self, tick: u64) -> Result>, BoxError> { let opt_active_positions = self.client.active_positions(&self.pair).await?; let mut events = vec![]; if opt_active_positions.is_none() { return Ok(None); } // we assume there is only ONE active position per pair match opt_active_positions .unwrap() .into_iter() .filter(|x| x.pair() == &self.pair) .next() { Some(position) => { // applying strategy to position let active_position = { match &self.strategy { Some(strategy) => { let (pos, strategy_events, _) = strategy.on_new_tick(&position, &self); events.extend(strategy_events); pos } None => position, } }; self.positions_history.insert(tick, active_position.clone()); self.active_position = Some(active_position); } None => { self.active_position = None; } } if events.is_empty() { Ok(None) } else { Ok(Some(events)) } } } pub struct OrderManager { pair: SymbolPair, open_orders: Vec, client: Client, } impl OrderManager { pub fn new(pair: SymbolPair, client: Client) -> Self { OrderManager { pair, open_orders: Vec::new(), client, } } pub fn update(&self) -> Option> { unimplemented!() } }