split closeposition message in closeposition and submitorder. now close positions retrieves open positions before closing

This commit is contained in:
Giulio De Pasquale 2021-01-24 14:22:52 +00:00
parent 394174a244
commit 61cd795cc2
3 changed files with 38 additions and 52 deletions

View File

@ -15,14 +15,9 @@ pub struct ActorMessage {
#[derive(Debug)] #[derive(Debug)]
pub enum Message { pub enum Message {
Update { Update { tick: u64 },
tick: u64, ClosePosition { position_id: u64 },
}, SubmitOrder { order: OrderForm },
ClosePosition {
position: Position,
order_form: OrderForm,
},
OpenPosition,
} }
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)] #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]

View File

@ -356,19 +356,12 @@ impl OrderManagerHandle {
Ok(recv.await?) Ok(recv.await?)
} }
pub async fn close_position( pub async fn close_position(&mut self, position_id: u64) -> Result<OptionUpdate, BoxError> {
&mut self,
position: Position,
order_form: OrderForm,
) -> Result<OptionUpdate, BoxError> {
let (send, recv) = oneshot::channel(); let (send, recv) = oneshot::channel();
self.sender self.sender
.send(ActorMessage { .send(ActorMessage {
message: Message::ClosePosition { message: Message::ClosePosition { position_id },
position,
order_form,
},
respond_to: send, respond_to: send,
}) })
.await?; .await?;
@ -409,9 +402,8 @@ impl OrderManager {
self.update().await?; self.update().await?;
} }
Message::ClosePosition { Message::ClosePosition {
position, position_id: position_id,
order_form, } => self.close_position(position_id).await?,
} => self.close_position(&position, &order_form).await?,
_ => {} _ => {}
}; };
@ -420,17 +412,14 @@ impl OrderManager {
Ok(()) Ok(())
} }
pub async fn close_position( pub async fn close_position(&mut self, position_id: u64) -> Result<(), BoxError> {
&mut self, info!("Closing position #{}", position_id);
position: &Position,
order_form: &OrderForm,
) -> Result<(), BoxError> {
info!("Closing position #{}", position.id());
debug!("Retrieving open orders and current prices..."); debug!("Retrieving open orders, positions and current prices...");
let (open_orders, order_book) = tokio::join!( let (open_orders, order_book, open_positions) = tokio::join!(
self.client.active_orders(&self.pair), 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 { 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::<BoxError>("No open positions".into())?;
positions
.into_iter()
.find(|x| x.id() == position_id)
.ok_or::<BoxError>("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 let opt_position_order = open_orders
.iter() .iter()
.find(|x| x.current_form.amount().neg() == position.amount()); .find(|x| x.current_form.amount().neg() == position.amount());
@ -490,15 +495,15 @@ impl OrderManager {
let (_, strat_messages) = let (_, strat_messages) =
self.strategy self.strategy
.on_position_close(active_order, position, &order_book)?; .on_position_close(active_order, &position, &order_book)?;
if let Some(messages) = strat_messages { if let Some(messages) = strat_messages {
for m in messages { for m in messages {
match m { match m {
Message::ClosePosition { order_form, .. } => { Message::SubmitOrder { order } => {
info!("Closing open order with a {} order", order_form.kind()); 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); info!("Cancelling open order #{}", active_order.id);
self.client.cancel_order(active_order).await?; self.client.cancel_order(active_order).await?;
} }
@ -591,13 +596,8 @@ impl PairManager {
if let Some(messages) = opt_pos_messages { if let Some(messages) = opt_pos_messages {
for m in messages { for m in messages {
match m { match m {
Message::ClosePosition { Message::ClosePosition { position_id } => {
position, self.order_manager.close_position(position_id).await?;
order_form,
} => {
self.order_manager
.close_position(position, order_form)
.await?;
} }
_ => {} _ => {}
} }

View File

@ -112,15 +112,7 @@ impl PositionStrategy for TrailingStop {
} else { } else {
debug!("Inserting close position message..."); debug!("Inserting close position message...");
messages.push(Message::ClosePosition { messages.push(Message::ClosePosition {
position: position.clone(), position_id: position.id(),
order_form: OrderForm::new(
position.pair().clone(),
OrderKind::Limit {
price: 0.0,
amount: position.amount(),
},
TradingPlatform::Margin,
),
}); });
PositionProfitState::Critical PositionProfitState::Critical
} }
@ -249,9 +241,8 @@ impl OrderStrategy for FastOrderStrategy {
let delta = (1.0 - (offer_comparison / order_price)) * 100.0; let delta = (1.0 - (offer_comparison / order_price)) * 100.0;
if delta > self.threshold { if delta > self.threshold {
messages.push(Message::ClosePosition { messages.push(Message::SubmitOrder {
position: active_position.clone(), order: OrderForm::new(
order_form: OrderForm::new(
order.symbol.clone(), order.symbol.clone(),
OrderKind::Market { OrderKind::Market {
amount: order.current_form.amount(), amount: order.current_form.amount(),