pub mod strict_buy;
pub mod trend_tunnel;
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::{Notify, watch::Receiver};
use crate::{
clock::Clock,
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 ErrorInStrat {
error: String,
time: DateTime<Utc>,
}
impl fmt::Display for ErrorInStrat {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Error in stat (at internal time {}): {}",
self.time, self.error
)
}
}
impl Error for ErrorInStrat {}
impl ErrorInStrat {
pub fn new(error: String, time: DateTime<Utc>) -> Self {
Self { error, time }
}
}
#[atomic_enum(AtomicState)]
#[derive(PartialEq, Display)]
pub enum State {
Starting,
Running,
Stats,
Paused,
Stopped,
Terminated,
Killed,
}
pub trait Strategy: Send + Sync + 'static {
type _Clock: Clock;
type _Market: Market<_Clock = Self::_Clock>;
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, ErrorInStrat>>;
}
pub trait StrategyFactory: Send {
type _Strategy: Strategy;
fn with_core(
self,
core: Core<<Self::_Strategy as Strategy>::_Clock, <Self::_Strategy as Strategy>::_Market>,
) -> Self;
fn build(self) -> Self::_Strategy;
}