moved amount out of OrderKind and into OrderForm. leverage detection for open positions

This commit is contained in:
Giulio De Pasquale 2021-02-13 15:29:00 +00:00
parent ce8eec71ff
commit 127ffaa1b9
4 changed files with 99 additions and 146 deletions

View File

@ -311,39 +311,46 @@ impl Connector for BitfinexConnector {
async fn submit_order(&self, order: &OrderForm) -> Result<ActiveOrder, BoxError> {
let symbol_name = format!("t{}", BitfinexConnector::format_trading_pair(order.pair()));
let amount = order.amount();
let order_form = match order.kind() {
OrderKind::Limit { price, amount } => {
bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
.with_leverage(15)
let order_form = {
let pre_leverage = {
match order.kind() {
OrderKind::Limit { price } => {
bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
}
OrderKind::Market => {
bitfinex::orders::OrderForm::new(symbol_name, 0.0, amount, order.into())
}
OrderKind::Stop { price } => {
bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
}
OrderKind::StopLimit { price, limit_price } => {
bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
.with_price_aux_limit(limit_price)?
}
OrderKind::TrailingStop { distance } => {
bitfinex::orders::OrderForm::new(symbol_name, 0.0, amount, order.into())
.with_price_trailing(distance)?
}
OrderKind::FillOrKill { price } => {
bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
}
OrderKind::ImmediateOrCancel { price } => {
bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
}
}
.with_meta(OrderMeta::new(
BitfinexConnector::AFFILIATE_CODE.to_string(),
))
};
// adding leverage, if any
match order.leverage() {
Some(leverage) => pre_leverage.with_leverage(leverage as u32),
None => pre_leverage,
}
OrderKind::Market { amount, .. } => {
bitfinex::orders::OrderForm::new(symbol_name, 0.0, amount, order.into())
.with_leverage(15)
}
OrderKind::Stop { price, amount } => {
bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
}
OrderKind::StopLimit {
price,
amount,
limit_price,
} => bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
.with_price_aux_limit(limit_price)?,
OrderKind::TrailingStop { distance, amount } => {
bitfinex::orders::OrderForm::new(symbol_name, 0.0, amount, order.into())
.with_price_trailing(distance)?
}
OrderKind::FillOrKill { price, amount } => {
bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
}
OrderKind::ImmediateOrCancel { price, amount } => {
bitfinex::orders::OrderForm::new(symbol_name, price, amount, order.into())
}
}
.with_meta(OrderMeta::new(
BitfinexConnector::AFFILIATE_CODE.to_string(),
));
};
let response =
BitfinexConnector::retry_nonce(|| self.bfx.orders.submit_order(&order_form)).await?;
@ -474,6 +481,7 @@ impl TryFrom<&bitfinex::responses::OrderResponse> for ActiveOrder {
SymbolPair::from_str(response.symbol())?,
response.into(),
response.into(),
response.amount(),
),
creation_timestamp: 0,
update_timestamp: 0,
@ -511,6 +519,7 @@ impl TryInto<Position> for bitfinex::positions::Position {
self.price_liq(),
self.position_id(),
platform,
self.leverage(),
)
.with_creation_date(self.mts_create())
.with_creation_update(self.mts_update()))
@ -579,41 +588,33 @@ impl From<&bitfinex::responses::OrderResponse> for OrderKind {
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(),
}
Self::Market
}
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(),
}
}
}
@ -626,41 +627,33 @@ impl From<&bitfinex::orders::ActiveOrder> for OrderKind {
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(),
}
Self::Market {}
}
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(),
}
}
}
@ -677,7 +670,7 @@ impl From<&bitfinex::orders::ActiveOrder> for ActiveOrder {
group_id: order.group_id().map(|x| x as u64),
client_id: Some(order.client_id()),
symbol: pair.clone(),
details: OrderForm::new(pair, order.into(), order.into()),
details: OrderForm::new(pair, order.into(), order.into(), order.amount()),
creation_timestamp: order.creation_timestamp(),
update_timestamp: order.update_timestamp(),
}

View File

@ -436,10 +436,11 @@ impl OrderManager {
self.pair.clone(),
OrderKind::Limit {
price: closing_price,
amount: position.amount().neg(),
},
TradingPlatform::Derivative,
);
position.amount().neg(),
)
.with_leverage(position.leverage());
info!("Submitting {} order", order_form.kind());
if let Err(e) = self.client.submit_order(&order_form).await {

View File

@ -213,34 +213,13 @@ impl Display for TradingPlatform {
#[derive(Copy, Clone, Debug)]
pub enum OrderKind {
Limit {
price: f64,
amount: f64,
},
Market {
amount: f64,
},
Stop {
price: f64,
amount: f64,
},
StopLimit {
price: f64,
amount: f64,
limit_price: f64,
},
TrailingStop {
distance: f64,
amount: f64,
},
FillOrKill {
price: f64,
amount: f64,
},
ImmediateOrCancel {
price: f64,
amount: f64,
},
Limit { price: f64 },
Market,
Stop { price: f64 },
StopLimit { price: f64, limit_price: f64 },
TrailingStop { distance: f64 },
FillOrKill { price: f64 },
ImmediateOrCancel { price: f64 },
}
impl OrderKind {
@ -260,67 +239,32 @@ impl OrderKind {
impl Display for OrderKind {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
match self {
OrderKind::Limit { price, amount } => {
OrderKind::Limit { price } => {
write!(f, "[{} | Price: {:0.5}]", self.as_str(), price,)
}
OrderKind::Market => {
write!(f, "[{}]", self.as_str())
}
OrderKind::Stop { price } => {
write!(f, "[{} | Price: {:0.5}", self.as_str(), price,)
}
OrderKind::StopLimit { price, limit_price } => {
write!(
f,
"[{} | Price: {:0.5}, Amount: {:0.5}]",
"[{} | Price: {:0.5}, Limit Price: {:0.5}]",
self.as_str(),
price,
amount
)
}
OrderKind::Market { amount } => {
write!(f, "[{} | Amount: {:0.5}]", self.as_str(), amount)
}
OrderKind::Stop { price, amount } => {
write!(
f,
"[{} | Price: {:0.5}, Amount: {:0.5}]",
self.as_str(),
price,
amount
)
}
OrderKind::StopLimit {
price,
amount,
limit_price,
} => {
write!(
f,
"[{} | Price: {:0.5}, Amount: {:0.5}, Limit Price: {:0.5}]",
self.as_str(),
price,
amount,
limit_price
)
}
OrderKind::TrailingStop { distance, amount } => {
write!(
f,
"[{} | Distance: {:0.5}, Amount: {:0.5}]",
self.as_str(),
distance,
amount
)
OrderKind::TrailingStop { distance } => {
write!(f, "[{} | Distance: {:0.5}]", self.as_str(), distance,)
}
OrderKind::FillOrKill { price, amount } => {
write!(
f,
"[{} | Price: {:0.5}, Amount: {:0.5}]",
self.as_str(),
price,
amount
)
OrderKind::FillOrKill { price } => {
write!(f, "[{} | Price: {:0.5}]", self.as_str(), price,)
}
OrderKind::ImmediateOrCancel { price, amount } => {
write!(
f,
"[{} | Price: {:0.5}, Amount: {:0.5}]",
self.as_str(),
price,
amount
)
OrderKind::ImmediateOrCancel { price } => {
write!(f, "[{} | Price: {:0.5}]", self.as_str(), price,)
}
}
}
@ -331,17 +275,31 @@ pub struct OrderForm {
pair: SymbolPair,
kind: OrderKind,
platform: TradingPlatform,
amount: f64,
leverage: Option<f64>,
}
impl OrderForm {
pub fn new(pair: SymbolPair, order_kind: OrderKind, platform: TradingPlatform) -> Self {
pub fn new(
pair: SymbolPair,
order_kind: OrderKind,
platform: TradingPlatform,
amount: f64,
) -> Self {
Self {
pair,
kind: order_kind,
platform,
amount,
leverage: None,
}
}
pub fn with_leverage(mut self, leverage: f64) -> Self {
self.leverage = Some(leverage);
self
}
pub fn pair(&self) -> &SymbolPair {
&self.pair
}
@ -355,15 +313,7 @@ impl OrderForm {
}
pub fn amount(&self) -> f64 {
match self.kind {
OrderKind::Limit { amount, .. } => amount,
OrderKind::Market { amount } => amount,
OrderKind::Stop { amount, .. } => amount,
OrderKind::StopLimit { amount, .. } => amount,
OrderKind::TrailingStop { amount, .. } => amount,
OrderKind::FillOrKill { amount, .. } => amount,
OrderKind::ImmediateOrCancel { amount, .. } => amount,
}
self.amount
}
pub fn price(&self) -> Option<f64> {
@ -377,6 +327,10 @@ impl OrderForm {
OrderKind::ImmediateOrCancel { price, .. } => Some(price),
}
}
pub fn leverage(&self) -> Option<f64> {
self.leverage
}
}
/***************
@ -397,6 +351,7 @@ pub struct Position {
creation_date: Option<u64>,
creation_update: Option<u64>,
platform: TradingPlatform,
leverage: f64,
}
impl Position {
@ -410,6 +365,7 @@ impl Position {
price_liq: f64,
position_id: u64,
platform: TradingPlatform,
leverage: f64,
) -> Self {
Position {
pair,
@ -424,6 +380,7 @@ impl Position {
creation_update: None,
profit_state: None,
platform,
leverage,
}
}
@ -511,6 +468,9 @@ impl Position {
pub fn platform(&self) -> TradingPlatform {
self.platform
}
pub fn leverage(&self) -> f64 {
self.leverage
}
}
impl Hash for Position {

View File

@ -10,7 +10,7 @@ use crate::managers::OptionUpdate;
use crate::models::OrderBookEntry::Trading;
use crate::models::{
ActiveOrder, OrderBook, OrderBookEntry, OrderForm, OrderKind, Position, PositionProfitState,
PositionState, TradingPlatform,
PositionState, TradingFees, TradingPlatform,
};
use crate::BoxError;
@ -309,10 +309,9 @@ impl OrderStrategy for FastOrderStrategy {
messages.push(Message::SubmitOrder {
order: OrderForm::new(
order.symbol.clone(),
OrderKind::Market {
amount: order.details.amount(),
},
OrderKind::Market {},
order.details.platform().clone(),
order.details.amount(),
),
})
}