core/rustybot/src/managers.rs

248 lines
6.1 KiB
Rust
Raw Normal View History

2021-01-14 18:56:31 +00:00
use std::collections::HashMap;
2021-01-14 12:42:23 +00:00
2021-01-14 18:56:31 +00:00
use crate::connectors::Client;
use crate::currency::SymbolPair;
2021-01-14 18:56:31 +00:00
use crate::events::{Event, SignalKind};
use crate::models::{Order, Position, PriceTicker};
2021-01-14 12:42:23 +00:00
use crate::strategy::PositionStrategy;
use crate::BoxError;
2021-01-13 09:24:59 +00:00
2021-01-14 12:42:23 +00:00
pub struct EventManager {
2021-01-13 09:26:29 +00:00
events: Vec<Event>,
}
2021-01-13 09:03:24 +00:00
#[derive(Clone, Debug)]
pub struct PriceManager {
pair: SymbolPair,
prices: Vec<PriceEntry>,
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<PriceEntry, BoxError> {
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
}
}
#[derive(Clone, Debug)]
pub struct PriceEntry {
tick: u64,
pair: SymbolPair,
price: PriceTicker,
events: Option<Vec<Event>>,
signals: Option<Vec<SignalKind>>,
}
impl PriceEntry {
pub fn new(
tick: u64,
price: PriceTicker,
pair: SymbolPair,
events: Option<Vec<Event>>,
signals: Option<Vec<SignalKind>>,
) -> 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<Vec<Event>> {
&self.events
}
pub fn signals(&self) -> &Option<Vec<SignalKind>> {
&self.signals
}
}
2021-01-14 18:36:56 +00:00
#[derive(Debug)]
2021-01-14 12:42:23 +00:00
pub struct PositionManager {
2021-01-14 19:20:58 +00:00
current_tick: u64,
2021-01-14 18:36:56 +00:00
pair: SymbolPair,
positions_history: HashMap<u64, Position>,
active_position: Option<Position>,
2021-01-13 09:24:59 +00:00
client: Client,
2021-01-14 12:42:23 +00:00
strategy: Option<Box<dyn PositionStrategy>>,
}
impl PositionManager {
2021-01-14 18:36:56 +00:00
pub fn new(pair: SymbolPair, client: Client) -> Self {
2021-01-14 12:42:23 +00:00
PositionManager {
2021-01-14 19:20:58 +00:00
current_tick: 0,
2021-01-14 18:36:56 +00:00
pair,
positions_history: HashMap::new(),
active_position: None,
2021-01-14 12:42:23 +00:00
client,
strategy: None,
}
}
pub fn with_strategy(mut self, strategy: Box<dyn PositionStrategy>) -> Self {
self.strategy = Some(strategy);
self
}
2021-01-14 19:20:58 +00:00
pub fn current_tick(&self) -> u64 {
self.current_tick
}
2021-01-14 18:36:56 +00:00
pub async fn update(&mut self, tick: u64) -> Result<Option<Vec<Event>>, BoxError> {
2021-01-14 18:56:31 +00:00
let opt_active_positions = self.client.active_positions(&self.pair).await?;
2021-01-14 18:36:56 +00:00
let mut events = vec![];
2021-01-14 19:20:58 +00:00
self.current_tick = tick;
2021-01-14 18:36:56 +00:00
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,
}
};
2021-01-14 19:20:58 +00:00
self.positions_history
.insert(self.current_tick(), active_position.clone());
2021-01-14 18:36:56 +00:00
self.active_position = Some(active_position);
}
None => {
self.active_position = None;
}
}
if events.is_empty() {
Ok(None)
} else {
Ok(Some(events))
}
2021-01-14 12:42:23 +00:00
}
2021-01-14 19:20:58 +00:00
pub fn position_previous_tick(&self, id: u64, tick: Option<u64>) -> Option<&Position> {
let tick = match tick {
Some(tick) => {
if tick < 1 {
1
} else {
tick
}
}
None => self.current_tick() - 1,
};
self.positions_history
.get(&tick)
.filter(|x| x.position_id() == id)
.and_then(|x| Some(x))
}
2021-01-13 09:24:59 +00:00
}
2021-01-13 09:03:24 +00:00
2021-01-14 12:42:23 +00:00
pub struct OrderManager {
2021-01-14 18:36:56 +00:00
pair: SymbolPair,
2021-01-13 09:24:59 +00:00
open_orders: Vec<Order>,
client: Client,
}
2021-01-14 12:42:23 +00:00
impl OrderManager {
2021-01-14 18:36:56 +00:00
pub fn new(pair: SymbolPair, client: Client) -> Self {
2021-01-14 12:42:23 +00:00
OrderManager {
2021-01-14 18:36:56 +00:00
pair,
2021-01-14 12:42:23 +00:00
open_orders: Vec::new(),
client,
}
}
pub fn update(&self) -> Option<Vec<Event>> {
unimplemented!()
}
}