renamed strategies

This commit is contained in:
Giulio De Pasquale 2021-02-16 18:18:39 +00:00
parent 6e848c35e3
commit 7f848223b9
2 changed files with 36 additions and 69 deletions

View File

@ -16,7 +16,7 @@ use crate::events::{ActorMessage, Event, Message};
use crate::models::{ use crate::models::{
ActiveOrder, OrderBook, OrderForm, OrderKind, Position, PriceTicker, TradingPlatform, ActiveOrder, OrderBook, OrderForm, OrderKind, Position, PriceTicker, TradingPlatform,
}; };
use crate::strategy::{FastOrderStrategy, OrderStrategy, PositionStrategy, TrailingStop}; use crate::strategy::{HiddenTrailingStop, MarketEnforce, OrderStrategy, PositionStrategy};
use crate::BoxError; use crate::BoxError;
pub type OptionUpdate = (Option<Vec<Event>>, Option<Vec<Message>>); pub type OptionUpdate = (Option<Vec<Event>>, Option<Vec<Message>>);
@ -534,12 +534,12 @@ impl PairManager {
order_manager: OrderManagerHandle::new( order_manager: OrderManagerHandle::new(
pair.clone(), pair.clone(),
client.clone(), client.clone(),
Box::new(FastOrderStrategy::default()), Box::new(MarketEnforce::default()),
), ),
position_manager: PositionManagerHandle::new( position_manager: PositionManagerHandle::new(
pair, pair,
client, client,
Box::new(TrailingStop::new()), Box::new(HiddenTrailingStop::new()),
), ),
} }
} }

View File

@ -67,15 +67,15 @@ impl Debug for dyn OrderStrategy {
***************/ ***************/
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct TrailingStop { pub struct HiddenTrailingStop {
stop_percentages: HashMap<u64, f64>, stop_percentages: HashMap<u64, f64>,
} }
impl TrailingStop { impl HiddenTrailingStop {
// in percentage // in percentage
const CAPITAL_MAX_LOSS: f64 = 17.5; const CAPITAL_MAX_LOSS: f64 = 15.0;
const CAPITAL_MIN_PROFIT: f64 = 10.0; const CAPITAL_MIN_PROFIT: f64 = 9.0;
const CAPITAL_GOOD_PROFIT: f64 = 20.0; const CAPITAL_GOOD_PROFIT: f64 = HiddenTrailingStop::CAPITAL_MIN_PROFIT * 2.0;
// in percentage // in percentage
const MIN_PROFIT_TRAILING_DELTA: f64 = 0.2; const MIN_PROFIT_TRAILING_DELTA: f64 = 0.2;
@ -83,14 +83,17 @@ impl TrailingStop {
const LEVERAGE: f64 = 15.0; const LEVERAGE: f64 = 15.0;
const MIN_PROFIT_PERC: f64 = (TrailingStop::CAPITAL_MIN_PROFIT / TrailingStop::LEVERAGE) const MIN_PROFIT_PERC: f64 = (HiddenTrailingStop::CAPITAL_MIN_PROFIT
+ TrailingStop::MIN_PROFIT_TRAILING_DELTA; / HiddenTrailingStop::LEVERAGE)
const GOOD_PROFIT_PERC: f64 = (TrailingStop::CAPITAL_GOOD_PROFIT / TrailingStop::LEVERAGE) + HiddenTrailingStop::MIN_PROFIT_TRAILING_DELTA;
+ TrailingStop::GOOD_PROFIT_TRAILING_DELTA; const GOOD_PROFIT_PERC: f64 = (HiddenTrailingStop::CAPITAL_GOOD_PROFIT
const MAX_LOSS_PERC: f64 = -(TrailingStop::CAPITAL_MAX_LOSS / TrailingStop::LEVERAGE); / HiddenTrailingStop::LEVERAGE)
+ HiddenTrailingStop::GOOD_PROFIT_TRAILING_DELTA;
const MAX_LOSS_PERC: f64 =
-(HiddenTrailingStop::CAPITAL_MAX_LOSS / HiddenTrailingStop::LEVERAGE);
pub fn new() -> Self { pub fn new() -> Self {
TrailingStop { HiddenTrailingStop {
stop_percentages: HashMap::new(), stop_percentages: HashMap::new(),
} }
} }
@ -98,8 +101,10 @@ impl TrailingStop {
fn update_stop_percentage(&mut self, position: &Position) { fn update_stop_percentage(&mut self, position: &Position) {
if let Some(profit_state) = position.profit_state() { if let Some(profit_state) = position.profit_state() {
let profit_state_delta = match profit_state { let profit_state_delta = match profit_state {
PositionProfitState::MinimumProfit => Some(TrailingStop::MIN_PROFIT_TRAILING_DELTA), PositionProfitState::MinimumProfit => {
PositionProfitState::Profit => Some(TrailingStop::GOOD_PROFIT_TRAILING_DELTA), Some(HiddenTrailingStop::MIN_PROFIT_TRAILING_DELTA)
}
PositionProfitState::Profit => Some(HiddenTrailingStop::GOOD_PROFIT_TRAILING_DELTA),
_ => None, _ => None,
}; };
@ -125,8 +130,10 @@ impl TrailingStop {
} }
} }
info!( info!(
"\tState: {:?} | PL%: {:0.2} | Stop: {:0.2}", "\tState: {:?} | PL: {:0.2}{} ({:0.2}%) | Stop: {:0.2}",
position.profit_state().unwrap(), position.profit_state().unwrap(),
position.pl(),
position.pair().quote(),
position.pl_perc(), position.pl_perc(),
self.stop_percentages.get(&position.id()).unwrap_or(&0.0) 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 { fn name(&self) -> String {
"Trailing stop".into() "Hidden Trailing Stop".into()
} }
/// Sets the profit state of an open position /// Sets the profit state of an open position
@ -149,15 +156,15 @@ impl PositionStrategy for TrailingStop {
let pl_perc = position.pl_perc(); let pl_perc = position.pl_perc();
let state = { let state = {
if pl_perc > TrailingStop::GOOD_PROFIT_PERC { if pl_perc > HiddenTrailingStop::GOOD_PROFIT_PERC {
PositionProfitState::Profit PositionProfitState::Profit
} else if TrailingStop::MIN_PROFIT_PERC <= pl_perc } else if HiddenTrailingStop::MIN_PROFIT_PERC <= pl_perc
&& pl_perc < TrailingStop::GOOD_PROFIT_PERC && pl_perc < HiddenTrailingStop::GOOD_PROFIT_PERC
{ {
PositionProfitState::MinimumProfit 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 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 PositionProfitState::Loss
} else { } else {
PositionProfitState::Critical PositionProfitState::Critical
@ -249,21 +256,21 @@ impl PositionStrategy for TrailingStop {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct FastOrderStrategy { pub struct MarketEnforce {
// threshold (%) for which we trigger a market order // threshold (%) for which we trigger a market order
// to close an open position // to close an open position
threshold: f64, threshold: f64,
} }
impl Default for FastOrderStrategy { impl Default for MarketEnforce {
fn default() -> Self { fn default() -> Self {
Self { threshold: 0.15 } Self { threshold: 0.15 }
} }
} }
impl OrderStrategy for FastOrderStrategy { impl OrderStrategy for MarketEnforce {
fn name(&self) -> String { fn name(&self) -> String {
"Fast order strategy".into() "Market Enforce".into()
} }
fn on_open_order( fn on_open_order(
@ -294,7 +301,7 @@ impl OrderStrategy for FastOrderStrategy {
messages.push(Message::SubmitOrder { messages.push(Message::SubmitOrder {
order: OrderForm::new( order: OrderForm::new(
order.symbol.clone(), order.symbol.clone(),
OrderKind::Market {}, OrderKind::Market,
*order.details.platform(), *order.details.platform(),
order.details.amount(), order.details.amount(),
), ),
@ -303,44 +310,4 @@ impl OrderStrategy for FastOrderStrategy {
Ok((None, (!messages.is_empty()).then_some(messages))) Ok((None, (!messages.is_empty()).then_some(messages)))
} }
// fn on_position_order(
// &self,
// order: &ActiveOrder,
// _: &Position,
// order_book: &OrderBook,
// ) -> Result<OptionUpdate, BoxError> {
// 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)))
// }
} }