use std::collections::HashMap; use std::future::Future; use tokio::task::JoinHandle; use crate::managers::{OrderManager, PositionManager, PriceManager}; use crate::models::{Position, PositionProfitState}; #[derive(Clone, Debug, Hash, PartialEq, Eq)] pub enum SignalKind { ClosePosition(Position), OpenPosition, } #[derive(Copy, Clone, Debug)] pub struct EventMetadata { position_id: Option, order_id: Option, } impl EventMetadata { pub fn new(position_id: Option, order_id: Option) -> Self { EventMetadata { position_id, order_id, } } } #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub enum EventKind { NewMinimum, NewMaximum, ReachedLoss, ReachedBreakEven, ReachedMinProfit, ReachedGoodProfit, ReachedMaxLoss, TrailingStopSet, TrailingStopMoved, OrderSubmitted, NewTick, Any, } #[derive(Copy, Clone, Debug)] pub struct Event { kind: EventKind, tick: u64, metadata: Option, } impl Event { pub fn new(kind: EventKind, tick: u64, metadata: Option) -> Self { Event { kind, tick, metadata, } } fn has_metadata(&self) -> bool { self.metadata.is_some() } pub fn kind(&self) -> EventKind { self.kind } pub fn tick(&self) -> u64 { self.tick } pub fn metadata(&self) -> Option { self.metadata } } pub struct Dispatcher { event_handlers: HashMap JoinHandle<()>>>>, profit_state_handlers: HashMap JoinHandle<()>>>>, signal_handlers: HashMap JoinHandle<()>>>>, on_any_event_handlers: Vec JoinHandle<()>>>, on_any_profit_state_handlers: Vec JoinHandle<()>>>, } impl Dispatcher { pub fn new() -> Self { Dispatcher { event_handlers: HashMap::new(), profit_state_handlers: HashMap::new(), signal_handlers: HashMap::new(), on_any_event_handlers: Vec::new(), on_any_profit_state_handlers: Vec::new(), } } pub fn call_signal_handlers(&self, signal: &SignalKind) { if let Some(functions) = self.signal_handlers.get(&signal) { for f in functions { f(signal); } } } pub fn call_event_handlers(&self, event: &Event, status: &PriceManager) { if let Some(functions) = self.event_handlers.get(&event.kind()) { for f in functions { f(event, status); } } for f in &self.on_any_event_handlers { f(event, status); } } pub fn call_position_state_handlers(&self, position: &Position, status: &PriceManager) { if let Some(profit_state) = &position.profit_state() { if let Some(functions) = self.profit_state_handlers.get(profit_state) { for f in functions { f(position, status); } } } for f in &self.on_any_profit_state_handlers { f(position, status); } } pub fn register_event_handler(&mut self, event: EventKind, f: F) where F: Fn(&Event, &PriceManager) -> Fut, Fut: Future + Send, { match event { EventKind::Any => self .on_any_event_handlers .push(Box::new(move |e, s| tokio::spawn(f(&e, s)))), _ => self .event_handlers .entry(event) .or_default() .push(Box::new(move |e, s| tokio::spawn(f(&e, s)))), } } pub fn register_positionstate_handler( &mut self, state: PositionProfitState, f: F, ) where F: Fn(&Position, &PriceManager) -> Fut, Fut: Future + Send, { match state { // PositionProfitState::Any => self // .on_any_position_state_handlers // .push(Box::new(move |p, s| tokio::spawn(f(&p, s)))), _ => self .profit_state_handlers .entry(state) .or_default() .push(Box::new(move |p, s| tokio::spawn(f(&p, s)))), } } pub fn register_signal_handler(&mut self, signal: SignalKind, f: F) where F: Fn(&SignalKind) -> Fut, Fut: Future + Send, { match signal { // PositionProfitState::Any => self // .on_any_position_state_handlers // .push(Box::new(move |p, s| tokio::spawn(f(&p, s)))), _ => self .signal_handlers .entry(signal) .or_default() .push(Box::new(move |s| tokio::spawn(f(s)))), } } }