ig_client/application/models/
market.rs

1pub(crate) use crate::presentation::InstrumentType;
2use serde::{Deserialize, Serialize};
3use std::fmt::Display;
4
5/// Model for a market instrument
6#[derive(Debug, Clone, Deserialize)]
7pub struct Instrument {
8    /// Unique identifier for the instrument
9    pub epic: String,
10    /// Human-readable name of the instrument
11    pub name: String,
12    /// Type of the instrument
13    #[serde(rename = "instrumentType")]
14    pub instrument_type: InstrumentType,
15    /// Expiry date of the instrument
16    pub expiry: String,
17    /// Size of one contract
18    #[serde(rename = "contractSize")]
19    pub contract_size: Option<f64>,
20    /// Size of one lot
21    #[serde(rename = "lotSize")]
22    pub lot_size: Option<f64>,
23    /// Upper price limit for the instrument
24    #[serde(rename = "highLimitPrice")]
25    pub high_limit_price: Option<f64>,
26    /// Lower price limit for the instrument
27    #[serde(rename = "lowLimitPrice")]
28    pub low_limit_price: Option<f64>,
29    /// Margin factor for the instrument
30    #[serde(rename = "marginFactor")]
31    pub margin_factor: Option<f64>,
32    /// Unit for the margin factor
33    #[serde(rename = "marginFactorUnit")]
34    pub margin_factor_unit: Option<String>,
35    /// Factor for price slippage
36    #[serde(rename = "slippageFactor")]
37    pub slippage_factor: Option<f64>,
38    /// Premium for limited risk trades
39    #[serde(rename = "limitedRiskPremium")]
40    pub limited_risk_premium: Option<f64>,
41    /// Code for news related to this instrument
42    #[serde(rename = "newsCode")]
43    pub news_code: Option<String>,
44    /// Code for chart data related to this instrument
45    #[serde(rename = "chartCode")]
46    pub chart_code: Option<String>,
47    /// Available currencies for trading this instrument
48    pub currencies: Option<Vec<Currency>>,
49}
50
51/// Model for an instrument's currency
52#[derive(Debug, Clone, Deserialize)]
53pub struct Currency {
54    /// Currency code (e.g., "USD", "EUR")
55    pub code: String,
56    /// Currency symbol (e.g., "$", "€")
57    pub symbol: Option<String>,
58    /// Base exchange rate for the currency
59    #[serde(rename = "baseExchangeRate")]
60    pub base_exchange_rate: Option<f64>,
61    /// Current exchange rate
62    #[serde(rename = "exchangeRate")]
63    pub exchange_rate: Option<f64>,
64    /// Whether this is the default currency for the instrument
65    #[serde(rename = "isDefault")]
66    pub is_default: Option<bool>,
67}
68
69/// Model for market data
70#[derive(Debug, Clone, Deserialize)]
71pub struct MarketDetails {
72    /// Detailed information about the instrument
73    pub instrument: Instrument,
74    /// Current market snapshot with prices
75    pub snapshot: MarketSnapshot,
76}
77
78/// Trading rules for a market
79#[derive(Debug, Clone, Deserialize)]
80pub struct DealingRules {
81    /// Minimum deal size allowed
82    #[serde(rename = "minDealSize")]
83    pub min_deal_size: Option<f64>,
84    /// Maximum deal size allowed
85    #[serde(rename = "maxDealSize")]
86    pub max_deal_size: Option<f64>,
87    /// Minimum distance for controlled risk stop
88    #[serde(rename = "minControlledRiskStopDistance")]
89    pub min_controlled_risk_stop_distance: Option<f64>,
90    /// Minimum distance for normal stop or limit orders
91    #[serde(rename = "minNormalStopOrLimitDistance")]
92    pub min_normal_stop_or_limit_distance: Option<f64>,
93    /// Maximum distance for stop or limit orders
94    #[serde(rename = "maxStopOrLimitDistance")]
95    pub max_stop_or_limit_distance: Option<f64>,
96    /// Market order preference setting
97    #[serde(rename = "marketOrderPreference")]
98    pub market_order_preference: String,
99    /// Trailing stops preference setting
100    #[serde(rename = "trailingStopsPreference")]
101    pub trailing_stops_preference: String,
102}
103
104/// Market snapshot
105#[derive(Debug, Clone, Deserialize)]
106pub struct MarketSnapshot {
107    /// Current status of the market (e.g., "OPEN", "CLOSED")
108    #[serde(rename = "marketStatus")]
109    pub market_status: String,
110    /// Net change in price since previous close
111    #[serde(rename = "netChange")]
112    pub net_change: Option<f64>,
113    /// Percentage change in price since previous close
114    #[serde(rename = "percentageChange")]
115    pub percentage_change: Option<f64>,
116    /// Time of the last price update
117    #[serde(rename = "updateTime")]
118    pub update_time: Option<String>,
119    /// Delay time in milliseconds for market data
120    #[serde(rename = "delayTime")]
121    pub delay_time: Option<i64>,
122    /// Current bid price
123    pub bid: Option<f64>,
124    /// Current offer/ask price
125    pub offer: Option<f64>,
126    /// Highest price of the current trading session
127    #[serde(rename = "high")]
128    pub high: Option<f64>,
129    /// Lowest price of the current trading session
130    #[serde(rename = "low")]
131    pub low: Option<f64>,
132    /// Odds for binary markets
133    #[serde(rename = "binaryOdds")]
134    pub binary_odds: Option<f64>,
135    /// Factor for decimal places in price display
136    #[serde(rename = "decimalPlacesFactor")]
137    pub decimal_places_factor: Option<i64>,
138    /// Factor for scaling prices
139    #[serde(rename = "scalingFactor")]
140    pub scaling_factor: Option<i64>,
141    /// Extra spread for controlled risk trades
142    #[serde(rename = "controlledRiskExtraSpread")]
143    pub controlled_risk_extra_spread: Option<f64>,
144}
145
146/// Model for market search results
147#[derive(Debug, Clone, Deserialize)]
148pub struct MarketSearchResult {
149    /// List of markets matching the search criteria
150    pub markets: Vec<MarketData>,
151}
152
153/// Basic market data
154#[derive(Debug, Clone, Deserialize, Serialize)]
155pub struct MarketData {
156    /// Unique identifier for the market
157    pub epic: String,
158    /// Human-readable name of the instrument
159    #[serde(rename = "instrumentName")]
160    pub instrument_name: String,
161    /// Type of the instrument
162    #[serde(rename = "instrumentType")]
163    pub instrument_type: InstrumentType,
164    /// Expiry date of the instrument
165    pub expiry: String,
166    /// Upper price limit for the market
167    #[serde(rename = "highLimitPrice")]
168    pub high_limit_price: Option<f64>,
169    /// Lower price limit for the market
170    #[serde(rename = "lowLimitPrice")]
171    pub low_limit_price: Option<f64>,
172    /// Current status of the market
173    #[serde(rename = "marketStatus")]
174    pub market_status: String,
175    /// Net change in price since previous close
176    #[serde(rename = "netChange")]
177    pub net_change: Option<f64>,
178    /// Percentage change in price since previous close
179    #[serde(rename = "percentageChange")]
180    pub percentage_change: Option<f64>,
181    /// Time of the last price update
182    #[serde(rename = "updateTime")]
183    pub update_time: Option<String>,
184    /// Current bid price
185    pub bid: Option<f64>,
186    /// Current offer/ask price
187    pub offer: Option<f64>,
188}
189
190impl Display for MarketData {
191    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
192        let json = serde_json::to_string(self).unwrap_or_else(|_| "Invalid JSON".to_string());
193        write!(f, "{}", json)
194    }
195}
196
197/// Model for historical prices
198#[derive(Debug, Clone, Deserialize)]
199pub struct HistoricalPricesResponse {
200    /// List of historical price points
201    pub prices: Vec<HistoricalPrice>,
202    /// Type of the instrument
203    #[serde(rename = "instrumentType")]
204    pub instrument_type: InstrumentType,
205    /// API usage allowance information
206    #[serde(rename = "allowance")]
207    pub allowance: PriceAllowance,
208}
209
210/// Historical price data point
211#[derive(Debug, Clone, Deserialize)]
212pub struct HistoricalPrice {
213    /// Timestamp of the price data point
214    #[serde(rename = "snapshotTime")]
215    pub snapshot_time: String,
216    /// Opening price for the period
217    #[serde(rename = "openPrice")]
218    pub open_price: PricePoint,
219    /// Highest price for the period
220    #[serde(rename = "highPrice")]
221    pub high_price: PricePoint,
222    /// Lowest price for the period
223    #[serde(rename = "lowPrice")]
224    pub low_price: PricePoint,
225    /// Closing price for the period
226    #[serde(rename = "closePrice")]
227    pub close_price: PricePoint,
228    /// Volume traded during the period
229    #[serde(rename = "lastTradedVolume")]
230    pub last_traded_volume: Option<i64>,
231}
232
233/// Price point with bid, ask and last traded prices
234#[derive(Debug, Clone, Deserialize)]
235pub struct PricePoint {
236    /// Bid price at this point
237    pub bid: Option<f64>,
238    /// Ask/offer price at this point
239    pub ask: Option<f64>,
240    /// Last traded price at this point
241    #[serde(rename = "lastTraded")]
242    pub last_traded: Option<f64>,
243}
244
245/// Information about API usage allowance for price data
246#[derive(Debug, Clone, Deserialize)]
247pub struct PriceAllowance {
248    /// Remaining API calls allowed in the current period
249    #[serde(rename = "remainingAllowance")]
250    pub remaining_allowance: i64,
251    /// Total API calls allowed per period
252    #[serde(rename = "totalAllowance")]
253    pub total_allowance: i64,
254    /// Time until the allowance resets
255    #[serde(rename = "allowanceExpiry")]
256    pub allowance_expiry: i64,
257}