pub mod strict_buy;
use std::{error::Error, fmt, future::Future, pin::Pin, sync::Arc};
use atomic_enum::atomic_enum;
use chrono::{DateTime, Utc};
use strum_macros::Display;
use tokio::sync::{watch::Receiver, Notify};
use super::{
core::Core,
market::{Balance, Market},
};
#[derive(Debug, Clone)]
pub struct StratStat {
pub asset: Balance,
pub quote: Balance,
pub time: DateTime<Utc>,
}
impl StratStat {
pub fn new(asset: Balance, quote: Balance, time: DateTime<Utc>) -> Self {
Self { asset, quote, time }
}
}
#[derive(Debug, Clone)]
pub struct ErrorInStat {
error: String,
time: DateTime<Utc>,
}
impl fmt::Display for ErrorInStat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Error in stat (at internal time {}): {}",
self.time, self.error
)
}
}
impl Error for ErrorInStat {}
impl ErrorInStat {
pub fn new(error: String, time: DateTime<Utc>) -> Self {
Self { error, time }
}
}
#[atomic_enum(AtomicState)]
#[derive(PartialEq, Display)]
pub enum State {
Running,
Stats,
Paused,
Terminated,
Killed,
}
pub trait Strategy: Send + Sync {
fn run(&mut self) -> Pin<Box<dyn Future<Output = ()> + Send + '_>>;
fn state(&self) -> &Arc<AtomicState>;
fn notify(&self) -> &Arc<Notify>;
fn stat_channel(&self) -> Receiver<Result<StratStat, ErrorInStat>>;
}
pub trait StrategyFactory<M: Market> {
fn set_core(&mut self, core: Core<M>);
fn instanciate(&mut self) -> Box<dyn Strategy>;
}