From 61cd795cc2d6f7d39919411d7a4fb48be4613e2c Mon Sep 17 00:00:00 2001 From: Giulio De Pasquale Date: Sun, 24 Jan 2021 14:22:52 +0000 Subject: [PATCH] split closeposition message in closeposition and submitorder. now close positions retrieves open positions before closing --- rustybot/src/events.rs | 11 ++----- rustybot/src/managers.rs | 64 ++++++++++++++++++++-------------------- rustybot/src/strategy.rs | 15 ++-------- 3 files changed, 38 insertions(+), 52 deletions(-) diff --git a/rustybot/src/events.rs b/rustybot/src/events.rs index 2a23e0a..57c5968 100644 --- a/rustybot/src/events.rs +++ b/rustybot/src/events.rs @@ -15,14 +15,9 @@ pub struct ActorMessage { #[derive(Debug)] pub enum Message { - Update { - tick: u64, - }, - ClosePosition { - position: Position, - order_form: OrderForm, - }, - OpenPosition, + Update { tick: u64 }, + ClosePosition { position_id: u64 }, + SubmitOrder { order: OrderForm }, } #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] diff --git a/rustybot/src/managers.rs b/rustybot/src/managers.rs index f006646..c3998e7 100644 --- a/rustybot/src/managers.rs +++ b/rustybot/src/managers.rs @@ -356,19 +356,12 @@ impl OrderManagerHandle { Ok(recv.await?) } - pub async fn close_position( - &mut self, - position: Position, - order_form: OrderForm, - ) -> Result { + pub async fn close_position(&mut self, position_id: u64) -> Result { let (send, recv) = oneshot::channel(); self.sender .send(ActorMessage { - message: Message::ClosePosition { - position, - order_form, - }, + message: Message::ClosePosition { position_id }, respond_to: send, }) .await?; @@ -409,9 +402,8 @@ impl OrderManager { self.update().await?; } Message::ClosePosition { - position, - order_form, - } => self.close_position(&position, &order_form).await?, + position_id: position_id, + } => self.close_position(position_id).await?, _ => {} }; @@ -420,17 +412,14 @@ impl OrderManager { Ok(()) } - pub async fn close_position( - &mut self, - position: &Position, - order_form: &OrderForm, - ) -> Result<(), BoxError> { - info!("Closing position #{}", position.id()); + pub async fn close_position(&mut self, position_id: u64) -> Result<(), BoxError> { + info!("Closing position #{}", position_id); - debug!("Retrieving open orders and current prices..."); - let (open_orders, order_book) = tokio::join!( + debug!("Retrieving open orders, positions and current prices..."); + let (open_orders, order_book, open_positions) = tokio::join!( self.client.active_orders(&self.pair), - self.client.order_book(&self.pair) + self.client.order_book(&self.pair), + self.client.active_positions(&self.pair) ); let open_orders = match open_orders { @@ -449,6 +438,22 @@ impl OrderManager { } }; + let position = match open_positions { + Ok(opt_positions) => { + let positions = opt_positions.ok_or::("No open positions".into())?; + + positions + .into_iter() + .find(|x| x.id() == position_id) + .ok_or::("Position #{} not found in open positions".into())? + } + + Err(e) => { + error!("Could not retrieve open positions: {}", e); + return Err(e); + } + }; + let opt_position_order = open_orders .iter() .find(|x| x.current_form.amount().neg() == position.amount()); @@ -490,15 +495,15 @@ impl OrderManager { let (_, strat_messages) = self.strategy - .on_position_close(active_order, position, &order_book)?; + .on_position_close(active_order, &position, &order_book)?; if let Some(messages) = strat_messages { for m in messages { match m { - Message::ClosePosition { order_form, .. } => { - info!("Closing open order with a {} order", order_form.kind()); + Message::SubmitOrder { order } => { + info!("Closing open order with a {} order", order.kind()); - if let Ok(_) = self.client.submit_order(&order_form).await { + if let Ok(_) = self.client.submit_order(&order).await { info!("Cancelling open order #{}", active_order.id); self.client.cancel_order(active_order).await?; } @@ -591,13 +596,8 @@ impl PairManager { if let Some(messages) = opt_pos_messages { for m in messages { match m { - Message::ClosePosition { - position, - order_form, - } => { - self.order_manager - .close_position(position, order_form) - .await?; + Message::ClosePosition { position_id } => { + self.order_manager.close_position(position_id).await?; } _ => {} } diff --git a/rustybot/src/strategy.rs b/rustybot/src/strategy.rs index 9c5c759..538fcb1 100644 --- a/rustybot/src/strategy.rs +++ b/rustybot/src/strategy.rs @@ -112,15 +112,7 @@ impl PositionStrategy for TrailingStop { } else { debug!("Inserting close position message..."); messages.push(Message::ClosePosition { - position: position.clone(), - order_form: OrderForm::new( - position.pair().clone(), - OrderKind::Limit { - price: 0.0, - amount: position.amount(), - }, - TradingPlatform::Margin, - ), + position_id: position.id(), }); PositionProfitState::Critical } @@ -249,9 +241,8 @@ impl OrderStrategy for FastOrderStrategy { let delta = (1.0 - (offer_comparison / order_price)) * 100.0; if delta > self.threshold { - messages.push(Message::ClosePosition { - position: active_position.clone(), - order_form: OrderForm::new( + messages.push(Message::SubmitOrder { + order: OrderForm::new( order.symbol.clone(), OrderKind::Market { amount: order.current_form.amount(),