Skip to content

Commit

Permalink
Extract closing_price into a function
Browse files Browse the repository at this point in the history
We use the same logic in three different places already, better extract it into a function to make this clearer.
  • Loading branch information
da-kami committed Jul 24, 2023
1 parent e2e4275 commit 3ec9b25
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 12 deletions.
6 changes: 2 additions & 4 deletions coordinator/src/node/expired_positions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use hex::FromHex;
use lightning::ln::PaymentHash;
use time::OffsetDateTime;
use trade::bitmex_client::BitmexClient;
use trade::cfd::closing_price;

pub async fn close(node: Node) {
let mut conn = match node.pool.get() {
Expand Down Expand Up @@ -57,10 +58,7 @@ pub async fn close(node: Node) {
};

let closing_price = match BitmexClient::get_quote(&position.expiry_timestamp).await {
Ok(quote) => match position.direction {
trade::Direction::Long => quote.bid_price,
trade::Direction::Short => quote.ask_price,
},
Ok(quote) => closing_price(position.direction, quote),
Err(e) => {
tracing::warn!(
"Failed to get quote from bitmex for {} at {}. Error: {e:?}",
Expand Down
6 changes: 2 additions & 4 deletions coordinator/src/node/unrealized_pnl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use time::OffsetDateTime;
use trade::bitmex_client::BitmexClient;
use trade::bitmex_client::Quote;
use trade::cfd::calculate_pnl;
use trade::cfd::closing_price;
use trade::Direction;

pub async fn sync(node: Node) -> Result<()> {
Expand All @@ -36,10 +37,7 @@ fn sync_position(
quote: Quote,
) -> Result<()> {
let closing_price = match position.closing_price {
None => match position.direction {
trade::Direction::Long => quote.bid_price,
trade::Direction::Short => quote.ask_price,
},
None => closing_price(position.direction, quote),
Some(closing_price) => {
Decimal::try_from(closing_price).expect("f32 closing price to fit into decimal")
}
Expand Down
46 changes: 46 additions & 0 deletions crates/trade/src/cfd.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::bitmex_client::Quote;
use crate::Direction;
use anyhow::Context;
use anyhow::Result;
Expand Down Expand Up @@ -104,9 +105,24 @@ pub fn calculate_pnl(
Ok(pnl)
}

/// The closing price that the trader gets based on bid and ask price
///
/// The closing price is always for the trade because the trader requests to close a position.
/// If the trader closes a long position then the trader gets the best bid price because the trader
/// is effectively going short to close a long order.
/// If the trader closes a short position then the trader gets the best ask price because the trader
/// is effectively going long to close a short order.
pub fn closing_price(trader_direction: Direction, quote: Quote) -> Decimal {
match trader_direction {
Direction::Long => quote.bid_price,
Direction::Short => quote.ask_price,
}
}

#[cfg(test)]
pub mod tests {
use super::*;
use time::OffsetDateTime;

#[test]
fn given_position_when_price_same_then_zero_pnl() {
Expand Down Expand Up @@ -224,4 +240,34 @@ pub mod tests {
// This is a liquidation, our margin is consumed by the loss
assert_eq!(pnl_long, 500000);
}

#[test]
fn given_long_position_then_traders_closing_price_is_bid_price() {
let quote = Quote {
bid_size: 0,
ask_size: 0,
bid_price: Decimal::from(20000),
ask_price: Decimal::from(20100),
symbol: "".to_string(),
timestamp: OffsetDateTime::now_utc(),
};

let closing_price = closing_price(Direction::Long, quote.clone());
assert_eq!(closing_price, quote.bid_price)
}

#[test]
fn given_short_position_then_traders_closing_price_is_ask_price() {
let quote = Quote {
bid_size: 0,
ask_size: 0,
bid_price: Decimal::from(20000),
ask_price: Decimal::from(20100),
symbol: "".to_string(),
timestamp: OffsetDateTime::now_utc(),
};

let closing_price = closing_price(Direction::Short, quote.clone());
assert_eq!(closing_price, quote.ask_price)
}
}
6 changes: 2 additions & 4 deletions mobile/native/src/trade/position/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use rust_decimal::prelude::ToPrimitive;
use time::Duration;
use time::OffsetDateTime;
use trade::bitmex_client::BitmexClient;
use trade::cfd::closing_price;
use trade::ContractSymbol;
use uuid::Uuid;

Expand Down Expand Up @@ -186,10 +187,7 @@ pub async fn close_position() -> Result<()> {
tracing::debug!("Adding order for the expired closed position");

let quote = BitmexClient::get_quote(&position.expiry).await?;
let closing_price = match position.direction {
trade::Direction::Long => quote.bid_price,
trade::Direction::Short => quote.ask_price,
};
let closing_price = closing_price(position.direction, quote);

let order = Order {
id: Uuid::new_v4(),
Expand Down

0 comments on commit 3ec9b25

Please sign in to comment.