ig_client/application/models/
market.rs

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