diff --git a/rustybot/src/connectors.rs b/rustybot/src/connectors.rs index 4757f7f..0a32b6c 100644 --- a/rustybot/src/connectors.rs +++ b/rustybot/src/connectors.rs @@ -57,21 +57,52 @@ impl Client { pair: &SymbolPair, ) -> Result>, BoxError> { // 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.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 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 - // TODO: change fee with account's taker fee 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() { - x.update_profit_loss(best_ask, 0.075); + x.update_profit_loss(best_ask, *fee); } 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, 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 for bitfinex::positions::Position { } }; + let platform = { + if self.symbol().to_ascii_lowercase().contains("f0") { + TradingPlatform::Derivative + } else { + TradingPlatform::Margin + } + }; + Ok(Position::new( SymbolPair::from_str(self.symbol())?, state, @@ -432,6 +510,7 @@ impl TryInto for bitfinex::positions::Position { self.pl_perc(), self.price_liq(), self.position_id(), + platform, ) .with_creation_date(self.mts_create()) .with_creation_update(self.mts_update())) @@ -648,23 +727,23 @@ impl From<&bitfinex::orders::ActiveOrder> for OrderDetails { // TODO: fields are hardcoded, to fix impl From<&bitfinex::responses::TradeResponse> for Trade { fn from(response: &TradeResponse) -> Self { - let pair = SymbolPair::from_str(&response.symbol).unwrap(); + let pair = SymbolPair::from_str(&response.symbol()).unwrap(); let fee = { - if response.is_maker { - OrderFee::Maker(response.fee) + if response.is_maker() { + OrderFee::Maker(response.fee()) } else { - OrderFee::Taker(response.fee) + OrderFee::Taker(response.fee()) } }; Self { - trade_id: response.trade_id, + trade_id: response.trade_id(), pair, - execution_timestamp: response.execution_timestamp, - price: response.execution_price, - amount: response.execution_amount, + execution_timestamp: response.execution_timestamp(), + price: response.execution_price(), + amount: response.execution_amount(), fee, - fee_currency: Symbol::new(response.symbol.clone()), + fee_currency: Symbol::new(response.symbol().to_owned().clone()), } } } diff --git a/rustybot/src/models.rs b/rustybot/src/models.rs index 32c8743..305d52b 100644 --- a/rustybot/src/models.rs +++ b/rustybot/src/models.rs @@ -186,7 +186,7 @@ impl PartialEq for ActiveOrder { impl Eq for ActiveOrder {} -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Eq, PartialEq)] pub enum TradingPlatform { Exchange, Derivative, @@ -396,6 +396,7 @@ pub struct Position { position_id: u64, creation_date: Option, creation_update: Option, + platform: TradingPlatform, } impl Position { @@ -408,6 +409,7 @@ impl Position { pl_perc: f64, price_liq: f64, position_id: u64, + platform: TradingPlatform, ) -> Self { Position { pair, @@ -421,6 +423,7 @@ impl Position { creation_date: None, creation_update: None, profit_state: None, + platform, } } @@ -505,6 +508,9 @@ impl Position { pub fn is_long(&self) -> bool { self.amount.is_sign_positive() } + pub fn platform(&self) -> TradingPlatform { + self.platform + } } impl Hash for Position {