use std::collections::HashMap; use std::future::Future; use bitfinex::positions::Position; use tokio::task::JoinHandle; use crate::BoxError; use crate::pairs::PairStatus; #[derive(Copy, Clone)] pub enum SignalKind { ClosePosition, OpenPosition, } #[derive(Copy, Clone)] pub struct EventMetadata { position_id: Option, order_id: Option, } #[derive(Copy, Clone, PartialEq, Eq, Hash)] pub enum EventKind { NewMinimum, NewMaximum, ReachedLoss, ReachedBreakEven, ReachedMinProfit, ReachedGoodProfit, ReachedMaxLoss, TrailingStopSet, TrailingStopMoved, OrderSubmitted, NewTick, } #[derive(Copy, Clone)] 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 EventDispatcher { event_handlers: HashMap JoinHandle<()>>>>, } impl EventDispatcher { pub fn new() -> Self { EventDispatcher { event_handlers: HashMap::new(), } } pub fn call_handler(&mut self, event: &Event, status: &PairStatus) { if let Some(callbacks) = self.event_handlers.get_mut(&event.kind()) { for f in callbacks { f(event.clone(), status); } } } pub fn register_event_handler(&mut self, event: EventKind, mut f: F) where F: FnMut(Event, &PairStatus) -> Fut, Fut: Future + Send, { self.event_handlers .entry(event) .or_default() .push(Box::new(move |e, s| tokio::spawn(f(e, s)))); } }