rust #10
@ -1,11 +1,14 @@
|
||||
use std::convert::{TryFrom, TryInto};
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use bitfinex::api::Bitfinex;
|
||||
use bitfinex::orders::OrderMeta;
|
||||
use bitfinex::orders::{OrderMeta, OrderResponse};
|
||||
use bitfinex::ticker::TradingPairTicker;
|
||||
use chrono::{DateTime, NaiveDate, NaiveDateTime, Utc};
|
||||
use log::debug;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::{Debug, Formatter};
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::currency::SymbolPair;
|
||||
use crate::models::{
|
||||
@ -13,7 +16,6 @@ use crate::models::{
|
||||
PriceTicker,
|
||||
};
|
||||
use crate::BoxError;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Clone, Debug)]
|
||||
pub enum ExchangeKind {
|
||||
@ -65,6 +67,10 @@ impl Client {
|
||||
pub async fn order_book(&self, pair: &SymbolPair) -> Result<OrderBook, BoxError> {
|
||||
self.inner.order_book(pair).await
|
||||
}
|
||||
|
||||
pub async fn cancel_order(&self, order: &ActiveOrder) -> Result<ActiveOrder, BoxError> {
|
||||
self.inner.cancel_order(order).await
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@ -75,6 +81,7 @@ pub trait Connector: Send + Sync {
|
||||
async fn order_book(&self, pair: &SymbolPair) -> Result<OrderBook, BoxError>;
|
||||
async fn active_orders(&self, pair: &SymbolPair) -> Result<Vec<ActiveOrder>, BoxError>;
|
||||
async fn submit_order(&self, order: OrderForm) -> Result<ActiveOrder, BoxError>;
|
||||
async fn cancel_order(&self, order: &ActiveOrder) -> Result<ActiveOrder, BoxError>;
|
||||
}
|
||||
|
||||
impl Debug for dyn Connector {
|
||||
@ -169,21 +176,7 @@ impl Connector for BitfinexConnector {
|
||||
|
||||
let response = self.bfx.orders.submit_order(&order_form).await?;
|
||||
|
||||
Ok(ActiveOrder {
|
||||
id: response.id(),
|
||||
group_id: response.gid(),
|
||||
client_id: response.cid(),
|
||||
symbol: SymbolPair::from_str(response.symbol())?,
|
||||
creation_timestamp: response.mts_create(),
|
||||
update_timestamp: response.mts_update(),
|
||||
amount: response.amount(),
|
||||
amount_original: response.amount_orig(),
|
||||
order_type: (&response.order_type()).into(),
|
||||
previous_order_type: response.prev_order_type().map(|x| (&x).into()),
|
||||
price: response.price(),
|
||||
price_avg: response.price_avg(),
|
||||
hidden: response.hidden(),
|
||||
})
|
||||
Ok(response.try_into()?)
|
||||
}
|
||||
|
||||
async fn order_book(&self, pair: &SymbolPair) -> Result<OrderBook, BoxError> {
|
||||
@ -207,6 +200,43 @@ impl Connector for BitfinexConnector {
|
||||
|
||||
Ok(OrderBook::new(pair.clone()).with_entries(entries))
|
||||
}
|
||||
|
||||
async fn cancel_order(&self, order: &ActiveOrder) -> Result<ActiveOrder, BoxError> {
|
||||
let date = DateTime::<Utc>::from_utc(
|
||||
NaiveDateTime::from_timestamp(order.update_timestamp as i64, 0),
|
||||
Utc,
|
||||
);
|
||||
let cancel_form = bitfinex::orders::CancelOrderForm::new(order.id, order.client_id, date);
|
||||
|
||||
Ok(self
|
||||
.bfx
|
||||
.orders
|
||||
.cancel_order(&cancel_form)
|
||||
.await?
|
||||
.try_into()?)
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<bitfinex::orders::OrderResponse> for ActiveOrder {
|
||||
type Error = BoxError;
|
||||
|
||||
fn try_from(response: OrderResponse) -> Result<Self, Self::Error> {
|
||||
Ok(Self {
|
||||
id: response.id(),
|
||||
group_id: response.gid(),
|
||||
client_id: response.cid(),
|
||||
symbol: SymbolPair::from_str(response.symbol())?,
|
||||
creation_timestamp: response.mts_create(),
|
||||
update_timestamp: response.mts_update(),
|
||||
amount: response.amount(),
|
||||
amount_original: response.amount_orig(),
|
||||
order_type: (&response.order_type()).into(),
|
||||
previous_order_type: response.prev_order_type().map(|x| (&x).into()),
|
||||
price: response.price(),
|
||||
price_avg: response.price_avg(),
|
||||
hidden: response.hidden(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl TryInto<Position> for bitfinex::positions::Position {
|
||||
|
@ -449,8 +449,15 @@ impl OrderManager {
|
||||
// TODO FIXME
|
||||
match order_kind {
|
||||
OrderKind::Market => {
|
||||
self.submit_market_order(1.0, position.amount().neg())
|
||||
.await?;
|
||||
info!("Closing open order with a market order.");
|
||||
if let Ok(_) = self
|
||||
.submit_market_order(1.0, position.amount().neg())
|
||||
.await
|
||||
{
|
||||
// cancel active order
|
||||
info!("Cancelling open order #{}", open_order.id);
|
||||
self.client.cancel_order(open_order).await?;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
@ -495,7 +502,7 @@ impl OrderManager {
|
||||
}
|
||||
|
||||
pub async fn submit_limit_order(
|
||||
&mut self,
|
||||
&self,
|
||||
closing_price: f64,
|
||||
amount: f64,
|
||||
) -> Result<ActiveOrder, BoxError> {
|
||||
@ -510,7 +517,7 @@ impl OrderManager {
|
||||
}
|
||||
|
||||
pub async fn submit_exchange_limit_order(
|
||||
&mut self,
|
||||
&self,
|
||||
closing_price: f64,
|
||||
amount: f64,
|
||||
) -> Result<ActiveOrder, BoxError> {
|
||||
@ -526,7 +533,7 @@ impl OrderManager {
|
||||
}
|
||||
|
||||
pub async fn submit_market_order(
|
||||
&mut self,
|
||||
&self,
|
||||
closing_price: f64,
|
||||
amount: f64,
|
||||
) -> Result<ActiveOrder, BoxError> {
|
||||
@ -541,7 +548,7 @@ impl OrderManager {
|
||||
}
|
||||
|
||||
pub async fn submit_exchange_market_order(
|
||||
&mut self,
|
||||
&self,
|
||||
closing_price: f64,
|
||||
amount: f64,
|
||||
) -> Result<ActiveOrder, BoxError> {
|
||||
|
@ -16,7 +16,7 @@ use crate::BoxError;
|
||||
* DEFINITIONS
|
||||
***************/
|
||||
|
||||
pub trait PositionStrategy: DynClone + Send {
|
||||
pub trait PositionStrategy: DynClone + Send + Sync {
|
||||
fn name(&self) -> String;
|
||||
fn on_new_tick(
|
||||
&self,
|
||||
@ -31,7 +31,7 @@ impl Debug for dyn PositionStrategy {
|
||||
}
|
||||
}
|
||||
|
||||
pub trait OrderStrategy: DynClone + Send {
|
||||
pub trait OrderStrategy: DynClone + Send + Sync {
|
||||
/// The name of the strategy, used for debugging purposes
|
||||
fn name(&self) -> String;
|
||||
/// This method is called when the OrderManager checks the open orders on a new tick.
|
||||
@ -235,11 +235,6 @@ impl OrderStrategy for FastOrderStrategy {
|
||||
// ask the manager to close the position with a market order
|
||||
let delta = (1.0 - (offer_comparison / order.price)) * 100.0;
|
||||
|
||||
debug!(
|
||||
"Offer comp: {} | Our offer: {} | Current delta: {}",
|
||||
offer_comparison, order.price, delta
|
||||
);
|
||||
|
||||
if delta > self.threshold {
|
||||
messages.push(Message::ClosePosition {
|
||||
position: active_position.clone(),
|
||||
|
Loading…
Reference in New Issue
Block a user