ig_client/application/models/
account.rs

1/******************************************************************************
2   Author: Joaquín Béjar García
3   Email: jb@taunais.com
4   Date: 13/5/25
5******************************************************************************/
6use super::order::{Direction, OrderType, Status, TimeInForce};
7use crate::application::models::market::InstrumentType;
8use crate::impl_json_display;
9use crate::presentation::MarketState;
10use serde::{Deserialize, Serialize};
11
12/// Account information
13#[derive(Debug, Clone, Deserialize)]
14pub struct AccountInfo {
15    /// List of accounts owned by the user
16    pub accounts: Vec<Account>,
17}
18
19/// Details of a specific account
20#[derive(Debug, Clone, Deserialize)]
21pub struct Account {
22    /// Unique identifier for the account
23    #[serde(rename = "accountId")]
24    pub account_id: String,
25    /// Name of the account
26    #[serde(rename = "accountName")]
27    pub account_name: String,
28    /// Type of the account (e.g., CFD, Spread bet)
29    #[serde(rename = "accountType")]
30    pub account_type: String,
31    /// Balance information for the account
32    pub balance: AccountBalance,
33    /// Base currency of the account
34    pub currency: String,
35    /// Current status of the account
36    pub status: String,
37    /// Whether this is the preferred account
38    pub preferred: bool,
39}
40
41/// Account balance information
42#[derive(Debug, Clone, Deserialize)]
43pub struct AccountBalance {
44    /// Total balance of the account
45    pub balance: f64,
46    /// Deposit amount
47    pub deposit: f64,
48    /// Current profit or loss
49    #[serde(rename = "profitLoss")]
50    pub profit_loss: f64,
51    /// Available funds for trading
52    pub available: f64,
53}
54
55/// Account activity
56#[derive(Debug, Clone, Deserialize)]
57pub struct AccountActivity {
58    /// List of activities on the account
59    pub activities: Vec<Activity>,
60    /// Metadata about pagination
61    pub metadata: Option<ActivityMetadata>,
62}
63
64/// Metadata for activity pagination
65#[derive(Debug, Clone, Deserialize)]
66pub struct ActivityMetadata {
67    /// Paging information
68    pub paging: Option<ActivityPaging>,
69}
70
71/// Paging information for activities
72#[derive(Debug, Clone, Deserialize)]
73pub struct ActivityPaging {
74    /// Number of items per page
75    pub size: Option<i32>,
76    /// URL for the next page of results
77    pub next: Option<String>,
78}
79
80#[derive(Debug, Copy, Clone, Deserialize, Serialize)]
81/// Type of account activity
82pub enum ActivityType {
83    /// Activity related to editing stop and limit orders
84    #[serde(rename = "EDIT_STOP_AND_LIMIT")]
85    EditStopAndLimit,
86    /// Activity related to positions
87    #[serde(rename = "POSITION")]
88    Position,
89    /// System-generated activity
90    #[serde(rename = "SYSTEM")]
91    System,
92    /// Activity related to working orders
93    #[serde(rename = "WORKING_ORDER")]
94    WorkingOrder,
95}
96
97/// Individual activity record
98#[derive(Debug, Clone, Deserialize, Serialize)]
99pub struct Activity {
100    /// Date and time of the activity
101    pub date: String,
102    /// Unique identifier for the deal
103    #[serde(rename = "dealId", default)]
104    pub deal_id: Option<String>,
105    /// Instrument EPIC identifier
106    #[serde(default)]
107    pub epic: Option<String>,
108    /// Time period of the activity
109    #[serde(default)]
110    pub period: Option<String>,
111    /// Client-generated reference for the deal
112    #[serde(rename = "dealReference", default)]
113    pub deal_reference: Option<String>,
114    /// Type of activity
115    #[serde(rename = "type")]
116    pub activity_type: ActivityType,
117    /// Status of the activity
118    #[serde(default)]
119    pub status: Option<Status>,
120    /// Description of the activity
121    #[serde(default)]
122    pub description: Option<String>,
123    /// Additional details about the activity
124    /// This is a string when detailed=false, and an object when detailed=true
125    #[serde(default)]
126    pub details: Option<ActivityDetails>,
127    /// Channel the activity occurred on (e.g., "WEB" or "Mobile")
128    #[serde(default)]
129    pub channel: Option<String>,
130    /// The currency, e.g., a pound symbol
131    #[serde(default)]
132    pub currency: Option<String>,
133    /// Price level
134    #[serde(default)]
135    pub level: Option<String>,
136}
137
138/// Detailed information about an activity
139/// Only available when using the detailed=true parameter
140#[derive(Debug, Clone, Deserialize, Serialize)]
141pub struct ActivityDetails {
142    /// Client-generated reference for the deal
143    #[serde(rename = "dealReference", default)]
144    pub deal_reference: Option<String>,
145    /// List of actions associated with this activity
146    #[serde(default)]
147    pub actions: Vec<ActivityAction>,
148    /// Name of the market
149    #[serde(rename = "marketName", default)]
150    pub market_name: Option<String>,
151    /// Date until which the order is valid
152    #[serde(rename = "goodTillDate", default)]
153    pub good_till_date: Option<String>,
154    /// Currency of the transaction
155    #[serde(default)]
156    pub currency: Option<String>,
157    /// Size/quantity of the transaction
158    #[serde(default)]
159    pub size: Option<f64>,
160    /// Direction of the transaction (BUY or SELL)
161    #[serde(default)]
162    pub direction: Option<Direction>,
163    /// Price level
164    #[serde(default)]
165    pub level: Option<f64>,
166    /// Stop level price
167    #[serde(rename = "stopLevel", default)]
168    pub stop_level: Option<f64>,
169    /// Distance for the stop
170    #[serde(rename = "stopDistance", default)]
171    pub stop_distance: Option<f64>,
172    /// Whether the stop is guaranteed
173    #[serde(rename = "guaranteedStop", default)]
174    pub guaranteed_stop: Option<bool>,
175    /// Distance for the trailing stop
176    #[serde(rename = "trailingStopDistance", default)]
177    pub trailing_stop_distance: Option<f64>,
178    /// Step size for the trailing stop
179    #[serde(rename = "trailingStep", default)]
180    pub trailing_step: Option<f64>,
181    /// Limit level price
182    #[serde(rename = "limitLevel", default)]
183    pub limit_level: Option<f64>,
184    /// Distance for the limit
185    #[serde(rename = "limitDistance", default)]
186    pub limit_distance: Option<f64>,
187}
188
189/// Types of actions that can be performed on an activity
190#[derive(Debug, Copy, Clone, Deserialize, Serialize)]
191pub enum ActionType {
192    /// A limit order was deleted
193    #[serde(rename = "LIMIT_ORDER_DELETED")]
194    LimitOrderDeleted,
195    /// A limit order was filled
196    #[serde(rename = "LIMIT_ORDER_FILLED")]
197    LimitOrderFilled,
198    /// A limit order was opened
199    #[serde(rename = "LIMIT_ORDER_OPENED")]
200    LimitOrderOpened,
201    /// A limit order was rolled
202    #[serde(rename = "LIMIT_ORDER_ROLLED")]
203    LimitOrderRolled,
204    /// A position was closed
205    #[serde(rename = "POSITION_CLOSED")]
206    PositionClosed,
207    /// A position was deleted
208    #[serde(rename = "POSITION_DELETED")]
209    PositionDeleted,
210    /// A position was opened
211    #[serde(rename = "POSITION_OPENED")]
212    PositionOpened,
213    /// A position was partially closed
214    #[serde(rename = "POSITION_PARTIALLY_CLOSED")]
215    PositionPartiallyClosed,
216    /// A position was rolled
217    #[serde(rename = "POSITION_ROLLED")]
218    PositionRolled,
219    /// A stop/limit was amended
220    #[serde(rename = "STOP_LIMIT_AMENDED")]
221    StopLimitAmended,
222    /// A stop order was amended
223    #[serde(rename = "STOP_ORDER_AMENDED")]
224    StopOrderAmended,
225    /// A stop order was deleted
226    #[serde(rename = "STOP_ORDER_DELETED")]
227    StopOrderDeleted,
228    /// A stop order was filled
229    #[serde(rename = "STOP_ORDER_FILLED")]
230    StopOrderFilled,
231    /// A stop order was opened
232    #[serde(rename = "STOP_ORDER_OPENED")]
233    StopOrderOpened,
234    /// A stop order was rolled
235    #[serde(rename = "STOP_ORDER_ROLLED")]
236    StopOrderRolled,
237    /// Unknown action type
238    #[serde(rename = "UNKNOWN")]
239    Unknown,
240    /// A working order was deleted
241    #[serde(rename = "WORKING_ORDER_DELETED")]
242    WorkingOrderDeleted,
243}
244
245impl_json_display!(ActionType);
246
247/// Action associated with an activity
248#[derive(Debug, Clone, Deserialize, Serialize)]
249pub struct ActivityAction {
250    /// Type of action
251    #[serde(rename = "actionType")]
252    pub action_type: ActionType,
253    /// Deal ID affected by this action
254    #[serde(rename = "affectedDealId", default)]
255    pub affected_deal_id: Option<String>,
256}
257
258/// Open positions
259#[derive(Debug, Clone, Deserialize, Serialize)]
260pub struct Positions {
261    /// List of open positions
262    pub positions: Vec<Position>,
263}
264
265/// Individual position
266#[derive(Debug, Clone, Serialize, Deserialize)]
267pub struct Position {
268    /// Details of the position
269    pub position: PositionDetails,
270    /// Market information for the position
271    pub market: PositionMarket,
272    /// Profit and loss for the position
273    pub pnl: Option<f64>,
274}
275
276/// Details of a position
277#[derive(Debug, Clone, Deserialize, Serialize)]
278pub struct PositionDetails {
279    /// Size of one contract
280    #[serde(rename = "contractSize")]
281    pub contract_size: f64,
282    /// Date and time when the position was created
283    #[serde(rename = "createdDate")]
284    pub created_date: String,
285    /// UTC date and time when the position was created
286    #[serde(rename = "createdDateUTC")]
287    pub created_date_utc: String,
288    /// Unique identifier for the deal
289    #[serde(rename = "dealId")]
290    pub deal_id: String,
291    /// Client-generated reference for the deal
292    #[serde(rename = "dealReference")]
293    pub deal_reference: String,
294    /// Direction of the position (buy or sell)
295    pub direction: Direction,
296    /// Price level for take profit
297    #[serde(rename = "limitLevel")]
298    pub limit_level: Option<f64>,
299    /// Opening price level of the position
300    pub level: f64,
301    /// Size/quantity of the position
302    pub size: f64,
303    /// Price level for stop loss
304    #[serde(rename = "stopLevel")]
305    pub stop_level: Option<f64>,
306    /// Step size for trailing stop
307    #[serde(rename = "trailingStep")]
308    pub trailing_step: Option<f64>,
309    /// Distance for trailing stop
310    #[serde(rename = "trailingStopDistance")]
311    pub trailing_stop_distance: Option<f64>,
312    /// Currency of the position
313    pub currency: String,
314    /// Whether the position has controlled risk
315    #[serde(rename = "controlledRisk")]
316    pub controlled_risk: bool,
317    /// Premium paid for limited risk
318    #[serde(rename = "limitedRiskPremium")]
319    pub limited_risk_premium: Option<f64>,
320}
321
322/// Market information for a position
323#[derive(Debug, Clone, Deserialize, Serialize)]
324pub struct PositionMarket {
325    /// Human-readable name of the instrument
326    #[serde(rename = "instrumentName")]
327    pub instrument_name: String,
328    /// Expiry date of the instrument
329    pub expiry: String,
330    /// Unique identifier for the market
331    pub epic: String,
332    /// Type of the instrument
333    #[serde(rename = "instrumentType")]
334    pub instrument_type: String,
335    /// Size of one lot
336    #[serde(rename = "lotSize")]
337    pub lot_size: f64,
338    /// Highest price of the current trading session
339    pub high: f64,
340    /// Lowest price of the current trading session
341    pub low: f64,
342    /// Percentage change in price since previous close
343    #[serde(rename = "percentageChange")]
344    pub percentage_change: f64,
345    /// Net change in price since previous close
346    #[serde(rename = "netChange")]
347    pub net_change: f64,
348    /// Current bid price
349    pub bid: f64,
350    /// Current offer/ask price
351    pub offer: f64,
352    /// Time of the last price update
353    #[serde(rename = "updateTime")]
354    pub update_time: String,
355    /// UTC time of the last price update
356    #[serde(rename = "updateTimeUTC")]
357    pub update_time_utc: String,
358    /// Delay time in milliseconds for market data
359    #[serde(rename = "delayTime")]
360    pub delay_time: i64,
361    /// Whether streaming prices are available for this market
362    #[serde(rename = "streamingPricesAvailable")]
363    pub streaming_prices_available: bool,
364    /// Current status of the market (e.g., "OPEN", "CLOSED")
365    #[serde(rename = "marketStatus")]
366    pub market_status: String,
367    /// Factor for scaling prices
368    #[serde(rename = "scalingFactor")]
369    pub scaling_factor: i64,
370}
371
372/// Working orders
373#[derive(Debug, Clone, Deserialize, Serialize)]
374pub struct WorkingOrders {
375    /// List of pending working orders
376    #[serde(rename = "workingOrders")]
377    pub working_orders: Vec<WorkingOrder>,
378}
379
380/// Working order
381#[derive(Debug, Clone, Deserialize, Serialize)]
382pub struct WorkingOrder {
383    /// Details of the working order
384    #[serde(rename = "workingOrderData")]
385    pub working_order_data: WorkingOrderData,
386    /// Market information for the working order
387    #[serde(rename = "marketData")]
388    pub market_data: MarketData,
389}
390
391/// Details of a working order
392#[derive(Debug, Clone, Deserialize, Serialize)]
393pub struct WorkingOrderData {
394    /// Unique identifier for the deal
395    #[serde(rename = "dealId")]
396    pub deal_id: String,
397    /// Direction of the order (buy or sell)
398    pub direction: Direction,
399    /// Instrument EPIC identifier
400    pub epic: String,
401    /// Size/quantity of the order
402    #[serde(rename = "orderSize")]
403    pub order_size: f64,
404    /// Price level for the order
405    #[serde(rename = "orderLevel")]
406    pub order_level: f64,
407    /// Time in force for the order
408    #[serde(rename = "timeInForce")]
409    pub time_in_force: TimeInForce,
410    /// Expiry date for GTD orders
411    #[serde(rename = "goodTillDate")]
412    pub good_till_date: Option<String>,
413    /// ISO formatted expiry date for GTD orders
414    #[serde(rename = "goodTillDateISO")]
415    pub good_till_date_iso: Option<String>,
416    /// Date and time when the order was created
417    #[serde(rename = "createdDate")]
418    pub created_date: String,
419    /// UTC date and time when the order was created
420    #[serde(rename = "createdDateUTC")]
421    pub created_date_utc: String,
422    /// Whether the order has a guaranteed stop
423    #[serde(rename = "guaranteedStop")]
424    pub guaranteed_stop: bool,
425    /// Type of the order
426    #[serde(rename = "orderType")]
427    pub order_type: OrderType,
428    /// Distance for stop loss
429    #[serde(rename = "stopDistance")]
430    pub stop_distance: Option<f64>,
431    /// Distance for take profit
432    #[serde(rename = "limitDistance")]
433    pub limit_distance: Option<f64>,
434    /// Currency code for the order
435    #[serde(rename = "currencyCode")]
436    pub currency_code: String,
437    /// Whether direct market access is enabled
438    pub dma: bool,
439    /// Premium for limited risk
440    #[serde(rename = "limitedRiskPremium")]
441    pub limited_risk_premium: Option<f64>,
442    /// Price level for take profit
443    #[serde(rename = "limitLevel", default)]
444    pub limit_level: Option<f64>,
445    /// Price level for stop loss
446    #[serde(rename = "stopLevel", default)]
447    pub stop_level: Option<f64>,
448    /// Client-generated reference for the deal
449    #[serde(rename = "dealReference", default)]
450    pub deal_reference: Option<String>,
451}
452
453/// Market data for a working order
454#[derive(Debug, Clone, Deserialize, Serialize)]
455pub struct MarketData {
456    /// Human-readable name of the instrument
457    #[serde(rename = "instrumentName")]
458    pub instrument_name: String,
459    /// Exchange identifier
460    #[serde(rename = "exchangeId")]
461    pub exchange_id: String,
462    /// Expiry date of the instrument
463    pub expiry: String,
464    /// Current status of the market
465    #[serde(rename = "marketStatus")]
466    pub market_status: MarketState,
467    /// Unique identifier for the market
468    pub epic: String,
469    /// Type of the instrument
470    #[serde(rename = "instrumentType")]
471    pub instrument_type: InstrumentType,
472    /// Size of one lot
473    #[serde(rename = "lotSize")]
474    pub lot_size: f64,
475    /// Highest price of the current trading session
476    pub high: f64,
477    /// Lowest price of the current trading session
478    pub low: f64,
479    /// Percentage change in price since previous close
480    #[serde(rename = "percentageChange")]
481    pub percentage_change: f64,
482    /// Net change in price since previous close
483    #[serde(rename = "netChange")]
484    pub net_change: f64,
485    /// Current bid price
486    pub bid: f64,
487    /// Current offer/ask price
488    pub offer: f64,
489    /// Time of the last price update
490    #[serde(rename = "updateTime")]
491    pub update_time: String,
492    /// UTC time of the last price update
493    #[serde(rename = "updateTimeUTC")]
494    pub update_time_utc: String,
495    /// Delay time in milliseconds for market data
496    #[serde(rename = "delayTime")]
497    pub delay_time: i64,
498    /// Whether streaming prices are available for this market
499    #[serde(rename = "streamingPricesAvailable")]
500    pub streaming_prices_available: bool,
501    /// Factor for scaling prices
502    #[serde(rename = "scalingFactor")]
503    pub scaling_factor: i64,
504}
505
506/// Transaction history
507#[derive(Debug, Clone, Deserialize, Serialize)]
508pub struct TransactionHistory {
509    /// List of account transactions
510    pub transactions: Vec<AccountTransaction>,
511    /// Metadata about the transaction list
512    pub metadata: TransactionMetadata,
513}
514
515/// Transaction metadata
516#[derive(Debug, Clone, Deserialize, Serialize)]
517pub struct TransactionMetadata {
518    /// Pagination information
519    #[serde(rename = "pageData")]
520    pub page_data: PageData,
521    /// Total number of transactions
522    pub size: i32,
523}
524
525/// Pagination information
526#[derive(Debug, Clone, Deserialize, Serialize)]
527pub struct PageData {
528    /// Current page number
529    #[serde(rename = "pageNumber")]
530    pub page_number: i32,
531    /// Number of items per page
532    #[serde(rename = "pageSize")]
533    pub page_size: i32,
534    /// Total number of pages
535    #[serde(rename = "totalPages")]
536    pub total_pages: i32,
537}
538
539/// Individual transaction
540#[derive(Debug, Clone, Deserialize, Serialize)]
541pub struct AccountTransaction {
542    /// Date and time of the transaction
543    pub date: String,
544    /// UTC date and time of the transaction
545    #[serde(rename = "dateUtc")]
546    pub date_utc: String,
547    /// Represents the date and time in UTC when an event or entity was opened or initiated.
548    #[serde(rename = "openDateUtc")]
549    pub open_date_utc: String,
550    /// Name of the instrument
551    #[serde(rename = "instrumentName")]
552    pub instrument_name: String,
553    /// Time period of the transaction
554    pub period: String,
555    /// Profit or loss amount
556    #[serde(rename = "profitAndLoss")]
557    pub profit_and_loss: String,
558    /// Type of transaction
559    #[serde(rename = "transactionType")]
560    pub transaction_type: String,
561    /// Reference identifier for the transaction
562    pub reference: String,
563    /// Opening price level
564    #[serde(rename = "openLevel")]
565    pub open_level: String,
566    /// Closing price level
567    #[serde(rename = "closeLevel")]
568    pub close_level: String,
569    /// Size/quantity of the transaction
570    pub size: String,
571    /// Currency of the transaction
572    pub currency: String,
573    /// Whether this is a cash transaction
574    #[serde(rename = "cashTransaction")]
575    pub cash_transaction: bool,
576}
577
578impl_json_display!(AccountTransaction);