rust #10
@ -155,8 +155,10 @@ impl Connector for BitfinexConnector {
|
||||
Ok(ticker)
|
||||
}
|
||||
|
||||
async fn active_orders(&self, pair: &SymbolPair) -> Result<Vec<ActiveOrder>, BoxError> {
|
||||
unimplemented!()
|
||||
async fn active_orders(&self, _: &SymbolPair) -> Result<Vec<ActiveOrder>, BoxError> {
|
||||
let response = self.bfx.orders.active_orders().await?;
|
||||
|
||||
Ok(response.iter().map(Into::into).collect())
|
||||
}
|
||||
|
||||
async fn submit_order(&self, order: &OrderForm) -> Result<ActiveOrder, BoxError> {
|
||||
@ -321,6 +323,21 @@ impl From<&bitfinex::orders::OrderResponse> for TradingPlatform {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&bitfinex::orders::ActiveOrder> for TradingPlatform {
|
||||
fn from(response: &bitfinex::orders::ActiveOrder) -> Self {
|
||||
match response.order_type() {
|
||||
bitfinex::orders::OrderKind::Limit
|
||||
| bitfinex::orders::OrderKind::Market
|
||||
| bitfinex::orders::OrderKind::StopLimit
|
||||
| bitfinex::orders::OrderKind::Stop
|
||||
| bitfinex::orders::OrderKind::TrailingStop
|
||||
| bitfinex::orders::OrderKind::Fok
|
||||
| bitfinex::orders::OrderKind::Ioc => Self::Margin,
|
||||
_ => Self::Exchange,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&bitfinex::orders::OrderResponse> for OrderKind {
|
||||
fn from(response: &OrderResponse) -> Self {
|
||||
match response.order_type() {
|
||||
@ -345,11 +362,11 @@ impl From<&bitfinex::orders::OrderResponse> for OrderKind {
|
||||
| bitfinex::orders::OrderKind::ExchangeStopLimit => Self::StopLimit {
|
||||
price: response.price(),
|
||||
amount: response.amount(),
|
||||
limit_price: response.price_aux_limit(),
|
||||
limit_price: response.price_aux_limit().expect("Limit price not found!"),
|
||||
},
|
||||
bitfinex::orders::OrderKind::TrailingStop
|
||||
| bitfinex::orders::OrderKind::ExchangeTrailingStop => Self::TrailingStop {
|
||||
distance: response.price_trailing(),
|
||||
distance: response.price_trailing().expect("Distance not found!"),
|
||||
amount: response.amount(),
|
||||
},
|
||||
bitfinex::orders::OrderKind::Fok | bitfinex::orders::OrderKind::ExchangeFok => {
|
||||
@ -368,6 +385,70 @@ impl From<&bitfinex::orders::OrderResponse> for OrderKind {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&bitfinex::orders::ActiveOrder> for OrderKind {
|
||||
fn from(response: &bitfinex::orders::ActiveOrder) -> Self {
|
||||
match response.order_type() {
|
||||
bitfinex::orders::OrderKind::Limit | bitfinex::orders::OrderKind::ExchangeLimit => {
|
||||
Self::Limit {
|
||||
price: response.price(),
|
||||
amount: response.amount(),
|
||||
}
|
||||
}
|
||||
bitfinex::orders::OrderKind::Market | bitfinex::orders::OrderKind::ExchangeMarket => {
|
||||
Self::Market {
|
||||
amount: response.amount(),
|
||||
}
|
||||
}
|
||||
bitfinex::orders::OrderKind::Stop | bitfinex::orders::OrderKind::ExchangeStop => {
|
||||
Self::Stop {
|
||||
price: response.price(),
|
||||
amount: response.amount(),
|
||||
}
|
||||
}
|
||||
bitfinex::orders::OrderKind::StopLimit
|
||||
| bitfinex::orders::OrderKind::ExchangeStopLimit => Self::StopLimit {
|
||||
price: response.price(),
|
||||
amount: response.amount(),
|
||||
limit_price: response.price_aux_limit().expect("Limit price not found!"),
|
||||
},
|
||||
bitfinex::orders::OrderKind::TrailingStop
|
||||
| bitfinex::orders::OrderKind::ExchangeTrailingStop => Self::TrailingStop {
|
||||
distance: response.price_trailing().expect("Distance not found!"),
|
||||
amount: response.amount(),
|
||||
},
|
||||
bitfinex::orders::OrderKind::Fok | bitfinex::orders::OrderKind::ExchangeFok => {
|
||||
Self::FillOrKill {
|
||||
price: response.price(),
|
||||
amount: response.amount(),
|
||||
}
|
||||
}
|
||||
bitfinex::orders::OrderKind::Ioc | bitfinex::orders::OrderKind::ExchangeIoc => {
|
||||
Self::ImmediateOrCancel {
|
||||
price: response.price(),
|
||||
amount: response.amount(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&bitfinex::orders::ActiveOrder> for ActiveOrder {
|
||||
fn from(order: &bitfinex::orders::ActiveOrder) -> Self {
|
||||
let pair = SymbolPair::from_str(&order.symbol()).expect("Invalid symbol!");
|
||||
|
||||
Self {
|
||||
exchange: Exchange::Bitfinex,
|
||||
id: order.id(),
|
||||
group_id: order.group_id().map(|x| x as u64),
|
||||
client_id: Some(order.client_id()),
|
||||
symbol: pair.clone(),
|
||||
current_form: OrderForm::new(pair, order.into(), order.into()),
|
||||
creation_timestamp: order.creation_timestamp(),
|
||||
update_timestamp: order.update_timestamp(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<TradingPairTicker> for PriceTicker {
|
||||
fn from(t: TradingPairTicker) -> Self {
|
||||
Self {
|
||||
|
@ -319,7 +319,8 @@ impl PositionManager {
|
||||
* ORDERS
|
||||
******************/
|
||||
|
||||
pub type TrackedPositionsMap = HashMap<u64, ActiveOrder>;
|
||||
// Position ID: Order ID
|
||||
pub type TrackedPositionsMap = HashMap<u64, u64>;
|
||||
|
||||
pub struct OrderManagerHandle {
|
||||
sender: Sender<ActorMessage>,
|
||||
@ -405,7 +406,7 @@ impl OrderManager {
|
||||
pub async fn handle_message(&mut self, msg: ActorMessage) -> Result<(), BoxError> {
|
||||
match msg.message {
|
||||
Message::Update { .. } => {
|
||||
self.update();
|
||||
self.update().await?;
|
||||
}
|
||||
Message::ClosePosition {
|
||||
position,
|
||||
@ -424,39 +425,23 @@ impl OrderManager {
|
||||
position: &Position,
|
||||
order_form: &OrderForm,
|
||||
) -> Result<(), BoxError> {
|
||||
let open_order = self.tracked_positions.get(&position.id());
|
||||
info!("Closing position #{}", position.id());
|
||||
|
||||
debug!("Retrieving open orders...");
|
||||
let open_orders = self.client.active_orders(&self.pair).await?;
|
||||
|
||||
let opt_position_order = open_orders
|
||||
.iter()
|
||||
.find(|x| x.current_form.amount().neg() == position.amount());
|
||||
|
||||
debug!("Closing position #{}", position.id());
|
||||
debug!("Getting current prices...");
|
||||
let order_book = self.client.order_book(&self.pair).await?;
|
||||
|
||||
// checking if the position has an open order.
|
||||
// If so, the strategy method is called, otherwise we open
|
||||
// an undercut limit order at the best current price.
|
||||
match open_order {
|
||||
Some(open_order) => {
|
||||
debug!("There is an open order. Calling strategy.");
|
||||
let (_, messages) =
|
||||
self.strategy
|
||||
.on_position_close(open_order, position, &order_book)?;
|
||||
|
||||
if let Some(messages) = messages {
|
||||
for m in messages {
|
||||
match m {
|
||||
Message::ClosePosition { order_form, .. } => {
|
||||
info!("Closing open order with a {} order", order_form.kind());
|
||||
if let Ok(_) = self.client.submit_order(&order_form).await {
|
||||
info!("Cancelling open order #{}", open_order.id);
|
||||
self.client.cancel_order(open_order).await?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
debug!("Received unsupported message from order strategy. Unimplemented.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
match opt_position_order {
|
||||
// No open order, undercutting best price with limit order
|
||||
None => {
|
||||
let closing_price = self.best_closing_price(&position, &order_book);
|
||||
|
||||
@ -471,16 +456,50 @@ impl OrderManager {
|
||||
);
|
||||
|
||||
info!("Submitting {} order", order_form.kind());
|
||||
let active_order = self.client.submit_order(&order_form).await?;
|
||||
if let Err(e) = self.client.submit_order(&order_form).await {
|
||||
error!(
|
||||
"Could not submit {} to close position #{}: {}",
|
||||
order_form.kind(),
|
||||
position.id(),
|
||||
e
|
||||
);
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
Some(active_order) => {
|
||||
debug!(
|
||||
"Found open order, calling \"{}\" strategy.",
|
||||
self.strategy.name()
|
||||
);
|
||||
|
||||
self.tracked_positions.insert(position.id(), active_order);
|
||||
let (_, strat_messages) =
|
||||
self.strategy
|
||||
.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());
|
||||
|
||||
if let Ok(_) = self.client.submit_order(&order_form).await {
|
||||
info!("Cancelling open order #{}", active_order.id);
|
||||
self.client.cancel_order(active_order).await?;
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
debug!("Received unsupported message from order strategy. Unimplemented.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn update(&self) -> Result<OptionUpdate, BoxError> {
|
||||
pub async fn update(&self) -> Result<OptionUpdate, BoxError> {
|
||||
// TODO: implement me
|
||||
Ok((None, None))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user