fetch account fees on-demand and apply them to position p/l
This commit is contained in:
parent
b46aec3395
commit
ce8eec71ff
@ -57,21 +57,52 @@ impl Client {
|
|||||||
pair: &SymbolPair,
|
pair: &SymbolPair,
|
||||||
) -> Result<Option<Vec<Position>>, BoxError> {
|
) -> Result<Option<Vec<Position>>, BoxError> {
|
||||||
// retrieving open positions and order book to calculate effective profit/loss
|
// retrieving open positions and order book to calculate effective profit/loss
|
||||||
let (positions, order_book) = tokio::join!(
|
let (positions, order_book, fees) = tokio::join!(
|
||||||
self.inner.active_positions(pair),
|
self.inner.active_positions(pair),
|
||||||
self.inner.order_book(pair)
|
self.inner.order_book(pair),
|
||||||
|
self.inner.trading_fees()
|
||||||
);
|
);
|
||||||
|
|
||||||
let (mut positions, order_book) = (positions?, order_book?);
|
let (mut positions, order_book, fees) = (positions?, order_book?, fees?);
|
||||||
let (best_ask, best_bid) = (order_book.lowest_ask(), order_book.highest_bid());
|
let (best_ask, best_bid) = (order_book.lowest_ask(), order_book.highest_bid());
|
||||||
|
|
||||||
|
let derivative_taker = fees
|
||||||
|
.iter()
|
||||||
|
.filter_map(|x| match x {
|
||||||
|
TradingFees::Taker {
|
||||||
|
platform,
|
||||||
|
percentage,
|
||||||
|
} if platform == &TradingPlatform::Derivative => Some(percentage),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.next()
|
||||||
|
.ok_or("Could not retrieve derivative taker fee!")?;
|
||||||
|
let margin_taker = fees
|
||||||
|
.iter()
|
||||||
|
.filter_map(|x| match x {
|
||||||
|
TradingFees::Taker {
|
||||||
|
platform,
|
||||||
|
percentage,
|
||||||
|
} if platform == &TradingPlatform::Margin => Some(percentage),
|
||||||
|
_ => None,
|
||||||
|
})
|
||||||
|
.next()
|
||||||
|
.ok_or("Could not retrieve margin taker fee!")?;
|
||||||
|
|
||||||
// updating positions with effective profit/loss
|
// updating positions with effective profit/loss
|
||||||
// TODO: change fee with account's taker fee
|
|
||||||
positions.iter_mut().flatten().for_each(|x| {
|
positions.iter_mut().flatten().for_each(|x| {
|
||||||
|
let fee = match x.platform() {
|
||||||
|
TradingPlatform::Funding | TradingPlatform::Exchange => {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
TradingPlatform::Margin => margin_taker,
|
||||||
|
TradingPlatform::Derivative => derivative_taker,
|
||||||
|
};
|
||||||
|
|
||||||
if x.is_short() {
|
if x.is_short() {
|
||||||
x.update_profit_loss(best_ask, 0.075);
|
x.update_profit_loss(best_ask, *fee);
|
||||||
} else {
|
} else {
|
||||||
x.update_profit_loss(best_bid, 0.075);
|
x.update_profit_loss(best_bid, *fee);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -380,7 +411,46 @@ impl Connector for BitfinexConnector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn trading_fees(&self) -> Result<Vec<TradingFees>, BoxError> {
|
async fn trading_fees(&self) -> Result<Vec<TradingFees>, BoxError> {
|
||||||
unimplemented!()
|
let mut fees = vec![];
|
||||||
|
let accountfees = self.bfx.account.account_summary().await?;
|
||||||
|
|
||||||
|
// Derivatives
|
||||||
|
let derivative_taker = TradingFees::Taker {
|
||||||
|
platform: TradingPlatform::Derivative,
|
||||||
|
percentage: accountfees.derivative_taker() * 100.0,
|
||||||
|
};
|
||||||
|
let derivative_maker = TradingFees::Maker {
|
||||||
|
platform: TradingPlatform::Derivative,
|
||||||
|
percentage: accountfees.derivative_rebate() * 100.0,
|
||||||
|
};
|
||||||
|
fees.push(derivative_taker);
|
||||||
|
fees.push(derivative_maker);
|
||||||
|
|
||||||
|
// Exchange
|
||||||
|
let exchange_taker = TradingFees::Taker {
|
||||||
|
platform: TradingPlatform::Exchange,
|
||||||
|
percentage: accountfees.taker_to_fiat() * 100.0,
|
||||||
|
};
|
||||||
|
let exchange_maker = TradingFees::Maker {
|
||||||
|
platform: TradingPlatform::Exchange,
|
||||||
|
percentage: accountfees.maker_fee() * 100.0,
|
||||||
|
};
|
||||||
|
fees.push(exchange_taker);
|
||||||
|
fees.push(exchange_maker);
|
||||||
|
|
||||||
|
// Margin
|
||||||
|
let margin_taker = TradingFees::Taker {
|
||||||
|
platform: TradingPlatform::Margin,
|
||||||
|
percentage: accountfees.taker_to_fiat() * 100.0,
|
||||||
|
};
|
||||||
|
let margin_maker = TradingFees::Maker {
|
||||||
|
platform: TradingPlatform::Margin,
|
||||||
|
percentage: accountfees.maker_fee() * 100.0,
|
||||||
|
};
|
||||||
|
fees.push(margin_taker);
|
||||||
|
fees.push(margin_maker);
|
||||||
|
|
||||||
|
Ok(fees)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,6 +493,14 @@ impl TryInto<Position> for bitfinex::positions::Position {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let platform = {
|
||||||
|
if self.symbol().to_ascii_lowercase().contains("f0") {
|
||||||
|
TradingPlatform::Derivative
|
||||||
|
} else {
|
||||||
|
TradingPlatform::Margin
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
Ok(Position::new(
|
Ok(Position::new(
|
||||||
SymbolPair::from_str(self.symbol())?,
|
SymbolPair::from_str(self.symbol())?,
|
||||||
state,
|
state,
|
||||||
@ -432,6 +510,7 @@ impl TryInto<Position> for bitfinex::positions::Position {
|
|||||||
self.pl_perc(),
|
self.pl_perc(),
|
||||||
self.price_liq(),
|
self.price_liq(),
|
||||||
self.position_id(),
|
self.position_id(),
|
||||||
|
platform,
|
||||||
)
|
)
|
||||||
.with_creation_date(self.mts_create())
|
.with_creation_date(self.mts_create())
|
||||||
.with_creation_update(self.mts_update()))
|
.with_creation_update(self.mts_update()))
|
||||||
@ -648,23 +727,23 @@ impl From<&bitfinex::orders::ActiveOrder> for OrderDetails {
|
|||||||
// TODO: fields are hardcoded, to fix
|
// TODO: fields are hardcoded, to fix
|
||||||
impl From<&bitfinex::responses::TradeResponse> for Trade {
|
impl From<&bitfinex::responses::TradeResponse> for Trade {
|
||||||
fn from(response: &TradeResponse) -> Self {
|
fn from(response: &TradeResponse) -> Self {
|
||||||
let pair = SymbolPair::from_str(&response.symbol).unwrap();
|
let pair = SymbolPair::from_str(&response.symbol()).unwrap();
|
||||||
let fee = {
|
let fee = {
|
||||||
if response.is_maker {
|
if response.is_maker() {
|
||||||
OrderFee::Maker(response.fee)
|
OrderFee::Maker(response.fee())
|
||||||
} else {
|
} else {
|
||||||
OrderFee::Taker(response.fee)
|
OrderFee::Taker(response.fee())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
trade_id: response.trade_id,
|
trade_id: response.trade_id(),
|
||||||
pair,
|
pair,
|
||||||
execution_timestamp: response.execution_timestamp,
|
execution_timestamp: response.execution_timestamp(),
|
||||||
price: response.execution_price,
|
price: response.execution_price(),
|
||||||
amount: response.execution_amount,
|
amount: response.execution_amount(),
|
||||||
fee,
|
fee,
|
||||||
fee_currency: Symbol::new(response.symbol.clone()),
|
fee_currency: Symbol::new(response.symbol().to_owned().clone()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,7 +186,7 @@ impl PartialEq for ActiveOrder {
|
|||||||
|
|
||||||
impl Eq for ActiveOrder {}
|
impl Eq for ActiveOrder {}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
|
||||||
pub enum TradingPlatform {
|
pub enum TradingPlatform {
|
||||||
Exchange,
|
Exchange,
|
||||||
Derivative,
|
Derivative,
|
||||||
@ -396,6 +396,7 @@ pub struct Position {
|
|||||||
position_id: u64,
|
position_id: u64,
|
||||||
creation_date: Option<u64>,
|
creation_date: Option<u64>,
|
||||||
creation_update: Option<u64>,
|
creation_update: Option<u64>,
|
||||||
|
platform: TradingPlatform,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Position {
|
impl Position {
|
||||||
@ -408,6 +409,7 @@ impl Position {
|
|||||||
pl_perc: f64,
|
pl_perc: f64,
|
||||||
price_liq: f64,
|
price_liq: f64,
|
||||||
position_id: u64,
|
position_id: u64,
|
||||||
|
platform: TradingPlatform,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Position {
|
Position {
|
||||||
pair,
|
pair,
|
||||||
@ -421,6 +423,7 @@ impl Position {
|
|||||||
creation_date: None,
|
creation_date: None,
|
||||||
creation_update: None,
|
creation_update: None,
|
||||||
profit_state: None,
|
profit_state: None,
|
||||||
|
platform,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,6 +508,9 @@ impl Position {
|
|||||||
pub fn is_long(&self) -> bool {
|
pub fn is_long(&self) -> bool {
|
||||||
self.amount.is_sign_positive()
|
self.amount.is_sign_positive()
|
||||||
}
|
}
|
||||||
|
pub fn platform(&self) -> TradingPlatform {
|
||||||
|
self.platform
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Hash for Position {
|
impl Hash for Position {
|
||||||
|
Loading…
Reference in New Issue
Block a user