From 7f848223b994b2d46163953313908ddf11aed95e Mon Sep 17 00:00:00 2001 From: Giulio De Pasquale Date: Tue, 16 Feb 2021 18:18:39 +0000 Subject: [PATCH] renamed strategies --- rustybot/src/managers.rs | 6 +-- rustybot/src/strategy.rs | 99 ++++++++++++++-------------------------- 2 files changed, 36 insertions(+), 69 deletions(-) diff --git a/rustybot/src/managers.rs b/rustybot/src/managers.rs index 77fe2c1..ed32db7 100644 --- a/rustybot/src/managers.rs +++ b/rustybot/src/managers.rs @@ -16,7 +16,7 @@ use crate::events::{ActorMessage, Event, Message}; use crate::models::{ ActiveOrder, OrderBook, OrderForm, OrderKind, Position, PriceTicker, TradingPlatform, }; -use crate::strategy::{FastOrderStrategy, OrderStrategy, PositionStrategy, TrailingStop}; +use crate::strategy::{HiddenTrailingStop, MarketEnforce, OrderStrategy, PositionStrategy}; use crate::BoxError; pub type OptionUpdate = (Option>, Option>); @@ -534,12 +534,12 @@ impl PairManager { order_manager: OrderManagerHandle::new( pair.clone(), client.clone(), - Box::new(FastOrderStrategy::default()), + Box::new(MarketEnforce::default()), ), position_manager: PositionManagerHandle::new( pair, client, - Box::new(TrailingStop::new()), + Box::new(HiddenTrailingStop::new()), ), } } diff --git a/rustybot/src/strategy.rs b/rustybot/src/strategy.rs index 374ad62..e4fe8da 100644 --- a/rustybot/src/strategy.rs +++ b/rustybot/src/strategy.rs @@ -67,15 +67,15 @@ impl Debug for dyn OrderStrategy { ***************/ #[derive(Clone, Debug)] -pub struct TrailingStop { +pub struct HiddenTrailingStop { stop_percentages: HashMap, } -impl TrailingStop { +impl HiddenTrailingStop { // in percentage - const CAPITAL_MAX_LOSS: f64 = 17.5; - const CAPITAL_MIN_PROFIT: f64 = 10.0; - const CAPITAL_GOOD_PROFIT: f64 = 20.0; + const CAPITAL_MAX_LOSS: f64 = 15.0; + const CAPITAL_MIN_PROFIT: f64 = 9.0; + const CAPITAL_GOOD_PROFIT: f64 = HiddenTrailingStop::CAPITAL_MIN_PROFIT * 2.0; // in percentage const MIN_PROFIT_TRAILING_DELTA: f64 = 0.2; @@ -83,14 +83,17 @@ impl TrailingStop { const LEVERAGE: f64 = 15.0; - const MIN_PROFIT_PERC: f64 = (TrailingStop::CAPITAL_MIN_PROFIT / TrailingStop::LEVERAGE) - + TrailingStop::MIN_PROFIT_TRAILING_DELTA; - const GOOD_PROFIT_PERC: f64 = (TrailingStop::CAPITAL_GOOD_PROFIT / TrailingStop::LEVERAGE) - + TrailingStop::GOOD_PROFIT_TRAILING_DELTA; - const MAX_LOSS_PERC: f64 = -(TrailingStop::CAPITAL_MAX_LOSS / TrailingStop::LEVERAGE); + const MIN_PROFIT_PERC: f64 = (HiddenTrailingStop::CAPITAL_MIN_PROFIT + / HiddenTrailingStop::LEVERAGE) + + HiddenTrailingStop::MIN_PROFIT_TRAILING_DELTA; + const GOOD_PROFIT_PERC: f64 = (HiddenTrailingStop::CAPITAL_GOOD_PROFIT + / HiddenTrailingStop::LEVERAGE) + + HiddenTrailingStop::GOOD_PROFIT_TRAILING_DELTA; + const MAX_LOSS_PERC: f64 = + -(HiddenTrailingStop::CAPITAL_MAX_LOSS / HiddenTrailingStop::LEVERAGE); pub fn new() -> Self { - TrailingStop { + HiddenTrailingStop { stop_percentages: HashMap::new(), } } @@ -98,8 +101,10 @@ impl TrailingStop { fn update_stop_percentage(&mut self, position: &Position) { if let Some(profit_state) = position.profit_state() { let profit_state_delta = match profit_state { - PositionProfitState::MinimumProfit => Some(TrailingStop::MIN_PROFIT_TRAILING_DELTA), - PositionProfitState::Profit => Some(TrailingStop::GOOD_PROFIT_TRAILING_DELTA), + PositionProfitState::MinimumProfit => { + Some(HiddenTrailingStop::MIN_PROFIT_TRAILING_DELTA) + } + PositionProfitState::Profit => Some(HiddenTrailingStop::GOOD_PROFIT_TRAILING_DELTA), _ => None, }; @@ -125,8 +130,10 @@ impl TrailingStop { } } info!( - "\tState: {:?} | PL%: {:0.2} | Stop: {:0.2}", + "\tState: {:?} | PL: {:0.2}{} ({:0.2}%) | Stop: {:0.2}", position.profit_state().unwrap(), + position.pl(), + position.pair().quote(), position.pl_perc(), self.stop_percentages.get(&position.id()).unwrap_or(&0.0) ); @@ -134,9 +141,9 @@ impl TrailingStop { } } -impl PositionStrategy for TrailingStop { +impl PositionStrategy for HiddenTrailingStop { fn name(&self) -> String { - "Trailing stop".into() + "Hidden Trailing Stop".into() } /// Sets the profit state of an open position @@ -149,15 +156,15 @@ impl PositionStrategy for TrailingStop { let pl_perc = position.pl_perc(); let state = { - if pl_perc > TrailingStop::GOOD_PROFIT_PERC { + if pl_perc > HiddenTrailingStop::GOOD_PROFIT_PERC { PositionProfitState::Profit - } else if TrailingStop::MIN_PROFIT_PERC <= pl_perc - && pl_perc < TrailingStop::GOOD_PROFIT_PERC + } else if HiddenTrailingStop::MIN_PROFIT_PERC <= pl_perc + && pl_perc < HiddenTrailingStop::GOOD_PROFIT_PERC { PositionProfitState::MinimumProfit - } else if (0.0..TrailingStop::MIN_PROFIT_PERC).contains(&pl_perc) { + } else if (0.0..HiddenTrailingStop::MIN_PROFIT_PERC).contains(&pl_perc) { PositionProfitState::BreakEven - } else if (TrailingStop::MAX_LOSS_PERC..0.0).contains(&pl_perc) { + } else if (HiddenTrailingStop::MAX_LOSS_PERC..0.0).contains(&pl_perc) { PositionProfitState::Loss } else { PositionProfitState::Critical @@ -249,21 +256,21 @@ impl PositionStrategy for TrailingStop { } #[derive(Clone, Debug)] -pub struct FastOrderStrategy { +pub struct MarketEnforce { // threshold (%) for which we trigger a market order // to close an open position threshold: f64, } -impl Default for FastOrderStrategy { +impl Default for MarketEnforce { fn default() -> Self { Self { threshold: 0.15 } } } -impl OrderStrategy for FastOrderStrategy { +impl OrderStrategy for MarketEnforce { fn name(&self) -> String { - "Fast order strategy".into() + "Market Enforce".into() } fn on_open_order( @@ -294,7 +301,7 @@ impl OrderStrategy for FastOrderStrategy { messages.push(Message::SubmitOrder { order: OrderForm::new( order.symbol.clone(), - OrderKind::Market {}, + OrderKind::Market, *order.details.platform(), order.details.amount(), ), @@ -303,44 +310,4 @@ impl OrderStrategy for FastOrderStrategy { Ok((None, (!messages.is_empty()).then_some(messages))) } - - // fn on_position_order( - // &self, - // order: &ActiveOrder, - // _: &Position, - // order_book: &OrderBook, - // ) -> Result { - // let mut messages = vec![]; - // - // // long - // let offer_comparison = { - // if order.current_form.amount() > 0.0 { - // order_book.highest_bid() - // } else { - // order_book.lowest_ask() - // } - // }; - // - // // if the best offer is higher than our threshold, - // // ask the manager to close the position with a market order - // let order_price = order - // .current_form - // .price() - // .ok_or("The active order does not have a price!")?; - // let delta = (1.0 - (offer_comparison / order_price)).abs() * 100.0; - // - // if delta > self.threshold { - // messages.push(Message::SubmitOrder { - // order: OrderForm::new( - // order.symbol.clone(), - // OrderKind::Market { - // amount: order.current_form.amount(), - // }, - // order.current_form.platform().clone(), - // ), - // }) - // } - // - // Ok((None, (!messages.is_empty()).then_some(messages))) - // } }