removed extra function for orderstrategy (for now). order manager update is now working
This commit is contained in:
		
							parent
							
								
									ef618ad754
								
							
						
					
					
						commit
						ac1fd3669f
					
				| @ -404,57 +404,34 @@ impl OrderManager { | |||||||
|         info!("Closing position #{}", position_id); |         info!("Closing position #{}", position_id); | ||||||
| 
 | 
 | ||||||
|         debug!("Retrieving open orders, positions and current prices..."); |         debug!("Retrieving open orders, positions and current prices..."); | ||||||
|         let (open_orders, order_book, open_positions) = tokio::join!( |         let (res_open_orders, res_order_book, res_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) |             self.client.active_positions(&self.pair) | ||||||
|         ); |         ); | ||||||
| 
 | 
 | ||||||
|         let open_orders = match open_orders { |         let (open_orders, order_book, open_positions) = | ||||||
|             Ok(open_orders) => open_orders, |             (res_open_orders?, res_order_book?, res_open_positions?); | ||||||
|             Err(e) => { |  | ||||||
|                 error!("Could not retrieve open orders: {}", e); |  | ||||||
|                 return Err(e); |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
| 
 | 
 | ||||||
|         let order_book = match order_book { |         let position = open_positions | ||||||
|             Ok(order_book) => order_book, |             .ok_or("No open positions!")? | ||||||
|             Err(e) => { |  | ||||||
|                 error!("Could not retrieve order book: {}", e); |  | ||||||
|                 return Err(e); |  | ||||||
|             } |  | ||||||
|         }; |  | ||||||
| 
 |  | ||||||
|         let position = match open_positions { |  | ||||||
|             Ok(opt_positions) => { |  | ||||||
|                 let positions = opt_positions.ok_or::<BoxError>("No open positions".into())?; |  | ||||||
| 
 |  | ||||||
|                 positions |  | ||||||
|             .into_iter() |             .into_iter() | ||||||
|             .find(|x| x.id() == position_id) |             .find(|x| x.id() == position_id) | ||||||
|                     .ok_or::<BoxError>("Position #{} not found in open positions".into())? |             .ok_or("Position #{} not found in open positions.")?; | ||||||
|             } |  | ||||||
| 
 |  | ||||||
|             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()); | ||||||
| 
 | 
 | ||||||
|         // checking if the position has an open order.
 |         // checking if the position has an open order.
 | ||||||
|         // If so, the strategy method is called, otherwise we open
 |         // If so, don't do anything since the order is taken care of
 | ||||||
|         // an undercut limit order at the best current price.
 |         // in the update phase.
 | ||||||
|         match opt_position_order { |         // If no order is open, send an undercut limit order at the best current price.
 | ||||||
|  |         if let None = opt_position_order { | ||||||
|             // No open order, undercutting best price with limit order
 |             // No open order, undercutting best price with limit order
 | ||||||
|             None => { |  | ||||||
|             let closing_price = self.best_closing_price(&position, &order_book); |             let closing_price = self.best_closing_price(&position, &order_book); | ||||||
| 
 | 
 | ||||||
|                 // TODO: hardocoded platform to Margin!
 |             // TODO: hardcoded platform to Margin!
 | ||||||
|             let order_form = OrderForm::new( |             let order_form = OrderForm::new( | ||||||
|                 self.pair.clone(), |                 self.pair.clone(), | ||||||
|                 OrderKind::Limit { |                 OrderKind::Limit { | ||||||
| @ -475,35 +452,6 @@ impl OrderManager { | |||||||
|                 return Err(e); |                 return Err(e); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|             Some(active_order) => { |  | ||||||
|                 debug!( |  | ||||||
|                     "Found open order, calling \"{}\" strategy.", |  | ||||||
|                     self.strategy.name() |  | ||||||
|                 ); |  | ||||||
| 
 |  | ||||||
|                 let (_, strat_messages) = |  | ||||||
|                     self.strategy |  | ||||||
|                         .on_position_order(active_order, &position, &order_book)?; |  | ||||||
| 
 |  | ||||||
|                 if let Some(messages) = strat_messages { |  | ||||||
|                     for m in messages { |  | ||||||
|                         match m { |  | ||||||
|                             Message::SubmitOrder { order } => { |  | ||||||
|                                 info!("Closing open order."); |  | ||||||
|                                 info!("Cancelling open order #{}", active_order.id); |  | ||||||
|                                 self.client.cancel_order(active_order).await?; |  | ||||||
| 
 |  | ||||||
|                                 info!("Submitting {}...", order.kind()); |  | ||||||
|                                 self.client.submit_order(&order).await?; |  | ||||||
|                             } |  | ||||||
|                             _ => { |  | ||||||
|                                 debug!("Received unsupported message from order strategy. Unimplemented.") |  | ||||||
|                             } |  | ||||||
|                         } |  | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         Ok((None, None)) |         Ok((None, None)) | ||||||
|     } |     } | ||||||
| @ -512,11 +460,42 @@ impl OrderManager { | |||||||
|     pub async fn update(&self) -> Result<OptionUpdate, BoxError> { |     pub async fn update(&self) -> Result<OptionUpdate, BoxError> { | ||||||
|         trace!("\t[OrderManager] Updating {}", self.pair); |         trace!("\t[OrderManager] Updating {}", self.pair); | ||||||
| 
 | 
 | ||||||
|         let (open_orders, opt_open_positions) = tokio::join!( |         let (res_open_orders, res_order_book) = tokio::join!( | ||||||
|             self.client.active_orders(&self.pair), |             self.client.active_orders(&self.pair), | ||||||
|             self.client.active_positions(&self.pair) |             self.client.order_book(&self.pair) | ||||||
|         ); |         ); | ||||||
|         let (_open_orders, _opt_open_positions) = (open_orders?, opt_open_positions?); | 
 | ||||||
|  |         let (open_orders, order_book) = (res_open_orders?, res_order_book?); | ||||||
|  | 
 | ||||||
|  |         for active_order in open_orders { | ||||||
|  |             debug!( | ||||||
|  |                 "Found open order, calling \"{}\" strategy.", | ||||||
|  |                 self.strategy.name() | ||||||
|  |             ); | ||||||
|  | 
 | ||||||
|  |             let (_, strat_messages) = self.strategy.on_open_order(&active_order, &order_book)?; | ||||||
|  | 
 | ||||||
|  |             if let Some(messages) = strat_messages { | ||||||
|  |                 for m in messages { | ||||||
|  |                     match m { | ||||||
|  |                         Message::SubmitOrder { order: order_form } => { | ||||||
|  |                             info!("Closing open order..."); | ||||||
|  |                             info!("\tCancelling open order #{}", &active_order.id); | ||||||
|  |                             self.client.cancel_order(&active_order).await?; | ||||||
|  | 
 | ||||||
|  |                             info!("\tSubmitting {}...", order_form.kind()); | ||||||
|  |                             self.client.submit_order(&order_form).await?; | ||||||
|  |                             info!("Done!"); | ||||||
|  |                         } | ||||||
|  |                         _ => { | ||||||
|  |                             debug!( | ||||||
|  |                                 "Received unsupported message from order strategy. Unimplemented." | ||||||
|  |                             ) | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
| 
 | 
 | ||||||
|         Ok((None, None)) |         Ok((None, None)) | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ use dyn_clone::DynClone; | |||||||
| use log::info; | use log::info; | ||||||
| 
 | 
 | ||||||
| use crate::events::{Event, EventKind, EventMetadata, Message}; | use crate::events::{Event, EventKind, EventMetadata, Message}; | ||||||
|  | use crate::managers::OptionUpdate; | ||||||
| use crate::models::{ | use crate::models::{ | ||||||
|     ActiveOrder, OrderBook, OrderBookEntry, OrderForm, OrderKind, Position, PositionProfitState, |     ActiveOrder, OrderBook, OrderBookEntry, OrderForm, OrderKind, Position, PositionProfitState, | ||||||
|     PositionState, TradingPlatform, |     PositionState, TradingPlatform, | ||||||
| @ -42,15 +43,19 @@ pub trait OrderStrategy: DynClone + Send + Sync { | |||||||
|     fn name(&self) -> String; |     fn name(&self) -> String; | ||||||
|     /// This method is called when the OrderManager checks the open orders on a new tick.
 |     /// This method is called when the OrderManager checks the open orders on a new tick.
 | ||||||
|     /// It should manage if some orders have to be closed or keep open.
 |     /// It should manage if some orders have to be closed or keep open.
 | ||||||
|     fn on_open_order(&self); |     fn on_open_order( | ||||||
|     /// This method is called when the OrderManager is requested to close
 |  | ||||||
|     /// a position that has an open order associated to it.
 |  | ||||||
|     fn on_position_order( |  | ||||||
|         &self, |         &self, | ||||||
|         order: &ActiveOrder, |         order: &ActiveOrder, | ||||||
|         open_position: &Position, |  | ||||||
|         order_book: &OrderBook, |         order_book: &OrderBook, | ||||||
|     ) -> Result<(Option<Vec<Event>>, Option<Vec<Message>>), BoxError>; |     ) -> Result<OptionUpdate, BoxError>; | ||||||
|  |     // /// This method is called when the OrderManager is requested to close
 | ||||||
|  |     // /// a position that has an open order associated to it.
 | ||||||
|  |     // fn on_position_order(
 | ||||||
|  |     //     &self,
 | ||||||
|  |     //     order: &ActiveOrder,
 | ||||||
|  |     //     open_position: &Position,
 | ||||||
|  |     //     order_book: &OrderBook,
 | ||||||
|  |     // ) -> Result<OptionUpdate, BoxError>;
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| impl Debug for dyn OrderStrategy { | impl Debug for dyn OrderStrategy { | ||||||
| @ -81,12 +86,6 @@ impl TrailingStop { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn update_stop_percentage(&mut self, position: &Position) { |     fn update_stop_percentage(&mut self, position: &Position) { | ||||||
|         info!( |  | ||||||
|             "\tState: {:?} | PL%: {:0.2}", |  | ||||||
|             position.profit_state().unwrap(), |  | ||||||
|             position.pl_perc() |  | ||||||
|         ); |  | ||||||
| 
 |  | ||||||
|         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(0.2), |                 PositionProfitState::MinimumProfit => Some(0.2), | ||||||
| @ -95,12 +94,6 @@ impl TrailingStop { | |||||||
|             }; |             }; | ||||||
| 
 | 
 | ||||||
|             if let Some(profit_state_delta) = profit_state_delta { |             if let Some(profit_state_delta) = profit_state_delta { | ||||||
|                 println!( |  | ||||||
|                     "PL%: {:0.2} | Delta: {}", |  | ||||||
|                     position.pl_perc(), |  | ||||||
|                     profit_state_delta |  | ||||||
|                 ); |  | ||||||
| 
 |  | ||||||
|                 let current_stop_percentage = position.pl_perc() - profit_state_delta; |                 let current_stop_percentage = position.pl_perc() - profit_state_delta; | ||||||
| 
 | 
 | ||||||
|                 match profit_state { |                 match profit_state { | ||||||
| @ -121,6 +114,12 @@ impl TrailingStop { | |||||||
|                     _ => {} |                     _ => {} | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |             info!( | ||||||
|  |                 "\tState: {:?} | PL%: {:0.2} | Stop: {:0.2}", | ||||||
|  |                 position.profit_state().unwrap(), | ||||||
|  |                 position.pl_perc(), | ||||||
|  |                 self.stop_percentages.get(&position.id()).unwrap_or(&0.0) | ||||||
|  |             ); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @ -223,6 +222,7 @@ impl PositionStrategy for TrailingStop { | |||||||
|         if let Some(profit_state) = position.profit_state() { |         if let Some(profit_state) = position.profit_state() { | ||||||
|             match profit_state { |             match profit_state { | ||||||
|                 PositionProfitState::Critical => { |                 PositionProfitState::Critical => { | ||||||
|  |                     info!("Maximum loss reached. Closing position."); | ||||||
|                     return (position, None, Some(vec![close_message])); |                     return (position, None, Some(vec![close_message])); | ||||||
|                 } |                 } | ||||||
|                 _ => {} |                 _ => {} | ||||||
| @ -267,16 +267,11 @@ impl OrderStrategy for FastOrderStrategy { | |||||||
|         "Fast order strategy".into() |         "Fast order strategy".into() | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     fn on_open_order(&self) { |     fn on_open_order( | ||||||
|         unimplemented!() |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     fn on_position_order( |  | ||||||
|         &self, |         &self, | ||||||
|         order: &ActiveOrder, |         order: &ActiveOrder, | ||||||
|         _: &Position, |  | ||||||
|         order_book: &OrderBook, |         order_book: &OrderBook, | ||||||
|     ) -> Result<(Option<Vec<Event>>, Option<Vec<Message>>), BoxError> { |     ) -> Result<OptionUpdate, BoxError> { | ||||||
|         let mut messages = vec![]; |         let mut messages = vec![]; | ||||||
| 
 | 
 | ||||||
|         // long
 |         // long
 | ||||||
| @ -310,4 +305,44 @@ 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)))
 | ||||||
|  |     // }
 | ||||||
| } | } | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user