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}