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///
18pub fn calculate_pnl(position: &Position) -> Option<f64> {
19    let (bid, offer) = (position.market.bid, position.market.offer);
20
21    // Get the appropriate price based on direction
22    let current_price = match position.position.direction {
23        Direction::Buy => bid?,
24        Direction::Sell => offer?,
25    };
26
27    // Calculate price difference
28    let price_diff = match position.position.direction {
29        Direction::Buy => current_price - position.position.level,
30        Direction::Sell => position.position.level - current_price,
31    };
32
33    // Return P&L
34    Some(price_diff * position.position.size)
35}
36
37/// Calculate the percentage return for a position
38///
39/// # Arguments
40///
41/// * `position` - The position to calculate percentage return for
42///
43/// # Returns
44///
45/// * `Option<f64>` - The calculated percentage return if market prices are available, None otherwise
46pub fn calculate_percentage_return(position: &Position) -> Option<f64> {
47    let pnl = calculate_pnl(position)?;
48    let initial_value = position.position.level * position.position.size;
49
50    // Avoid division by zero
51    if initial_value == 0.0 {
52        return None;
53    }
54
55    Some((pnl / initial_value) * 100.0)
56}