Skip to main content

ig_client/utils/
finance.rs

1// src/utils/finance.rs
2//
3// Financial calculation utilities for the IG client
4
5use crate::presentation::account::Position;
6use crate::presentation::order::Direction;
7
8/// Calculate the Profit and Loss (P&L) for a position based on current market prices
9///
10/// # Arguments
11///
12/// * `position` - The position to calculate P&L for
13///
14/// # Returns
15///
16/// * `Option<f64>` - The calculated P&L if market prices are available, None otherwise
17///
18#[must_use]
19pub fn calculate_pnl(position: &Position) -> Option<f64> {
20    let (bid, offer) = (position.market.bid, position.market.offer);
21
22    // Get the appropriate price based on direction
23    let current_price = match position.position.direction {
24        Direction::Buy => bid?,
25        Direction::Sell => offer?,
26    };
27
28    // Calculate price difference
29    let price_diff = match position.position.direction {
30        Direction::Buy => current_price - position.position.level,
31        Direction::Sell => position.position.level - current_price,
32    };
33
34    // Return P&L
35    Some(price_diff * position.position.size)
36}
37
38/// Calculate the percentage return for a position
39///
40/// # Arguments
41///
42/// * `position` - The position to calculate percentage return for
43///
44/// # Returns
45///
46/// * `Option<f64>` - The calculated percentage return if market prices are available, None otherwise
47#[must_use]
48pub fn calculate_percentage_return(position: &Position) -> Option<f64> {
49    let pnl = calculate_pnl(position)?;
50    let initial_value = position.position.level * position.position.size;
51
52    // Avoid division by zero
53    if initial_value == 0.0 {
54        return None;
55    }
56
57    Some((pnl / initial_value) * 100.0)
58}