1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
6pub enum Direction {
7 #[serde(rename = "BUY")]
8 Buy,
9 #[serde(rename = "SELL")]
10 Sell,
11}
12
13#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
14pub enum OrderType {
15 #[serde(rename = "MARKET")]
16 Market,
17 #[serde(rename = "LIMIT")]
18 Limit,
19 #[serde(rename = "QUOTE")]
20 Quote,
21}
22
23#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
24pub enum MarketStatus {
25 #[serde(rename = "TRADEABLE")]
26 Tradeable,
27 #[serde(rename = "CLOSED")]
28 Closed,
29 #[serde(rename = "EDITS_ONLY")]
30 EditsOnly,
31 #[serde(rename = "OFFLINE")]
32 Offline,
33 #[serde(other)]
34 Unknown,
35}
36
37#[derive(Debug, Deserialize)]
38#[serde(rename_all = "camelCase")]
39pub struct LoginResponse {
40 pub current_account_id: Option<String>,
41 pub lightstreamer_endpoint: String,
42 pub client_id: String,
43 pub currency_iso_code: Option<String>,
44 pub dealing_enabled: Option<bool>,
45}
46
47#[derive(Debug, Deserialize)]
48#[serde(rename_all = "camelCase")]
49pub(crate) struct V3LoginResponse {
50 pub account_id: Option<String>,
51 pub current_account_id: Option<String>,
52 pub lightstreamer_endpoint: String,
53 pub client_id: String,
54 pub currency_iso_code: Option<String>,
55 pub dealing_enabled: Option<bool>,
56 pub oauth_token: Option<OAuthToken>,
57}
58
59#[derive(Debug, Deserialize)]
60#[serde(rename_all = "camelCase")]
61pub(crate) struct OAuthToken {
62 pub access_token: String,
63 pub refresh_token: String,
64 pub expires_in: u64,
65}
66
67#[derive(Debug, Deserialize)]
68pub struct AccountsResponse {
69 pub accounts: Vec<Account>,
70}
71
72#[derive(Debug, Deserialize)]
73#[serde(rename_all = "camelCase")]
74pub struct Account {
75 pub account_id: String,
76 pub account_name: String,
77 pub preferred: bool,
78 pub balance: Option<AccountBalance>,
79 pub currency: Option<String>,
80}
81
82#[derive(Debug, Deserialize)]
83#[serde(rename_all = "camelCase")]
84pub struct AccountBalance {
85 pub balance: f64,
86 pub available: f64,
87 pub deposit: f64,
88 pub profit_loss: f64,
89}
90
91#[derive(Debug, Deserialize)]
92pub struct PositionsResponse {
93 pub positions: Vec<Position>,
94}
95
96#[derive(Debug, Deserialize)]
97pub struct Position {
98 pub position: PositionDetail,
99 pub market: PositionMarket,
100}
101
102#[derive(Debug, Deserialize)]
103#[serde(rename_all = "camelCase")]
104pub struct PositionDetail {
105 pub deal_id: String,
106 pub direction: Direction,
107 pub currency: String,
108 pub size: Option<f64>,
109 pub level: Option<f64>,
110}
111
112#[derive(Debug, Deserialize)]
113#[serde(rename_all = "camelCase")]
114pub struct PositionMarket {
115 pub epic: String,
116 pub instrument_name: String,
117 pub bid: Option<f64>,
118 pub offer: Option<f64>,
119 pub market_status: Option<MarketStatus>,
120}
121
122#[derive(Debug, Deserialize)]
123#[serde(rename_all = "camelCase")]
124pub struct MarketDetails {
125 pub instrument: Instrument,
126 pub snapshot: MarketSnapshot,
127}
128
129#[derive(Debug, Deserialize)]
130#[serde(rename_all = "camelCase")]
131pub struct Instrument {
132 pub name: String,
133 pub epic: String,
134 pub instrument_type: Option<String>,
135 pub expiry: Option<String>,
136}
137
138#[derive(Debug, Deserialize)]
139#[serde(rename_all = "camelCase")]
140pub struct MarketSnapshot {
141 pub market_status: MarketStatus,
142 pub bid: Option<f64>,
143 pub offer: Option<f64>,
144 pub high: Option<f64>,
145 pub low: Option<f64>,
146}
147
148#[derive(Debug, Deserialize)]
149pub struct MarketsResponse {
150 pub markets: Vec<MarketData>,
151}
152
153#[derive(Debug, Deserialize)]
154#[serde(rename_all = "camelCase")]
155pub struct MarketData {
156 pub epic: String,
157 pub instrument_name: String,
158 pub bid: Option<f64>,
159 pub offer: Option<f64>,
160}
161
162#[derive(Debug, Clone, Default)]
163pub struct HistoricalPricesQuery<'a> {
164 pub resolution: &'a str,
165 pub from: Option<&'a str>,
166 pub to: Option<&'a str>,
167 pub max: Option<u32>,
168}
169impl<'a> HistoricalPricesQuery<'a> {
170 pub fn new(resolution: &'a str) -> Self {
171 Self {
172 resolution,
173 ..Self::default()
174 }
175 }
176 pub fn from(mut self, value: &'a str) -> Self {
177 self.from = Some(value);
178 self
179 }
180 pub fn to(mut self, value: &'a str) -> Self {
181 self.to = Some(value);
182 self
183 }
184 pub fn max(mut self, value: u32) -> Self {
185 self.max = Some(value);
186 self
187 }
188}
189
190#[derive(Debug, Deserialize)]
191pub struct HistoricalPricesResponse {
192 pub prices: Vec<HistoricalPrice>,
193}
194
195#[derive(Debug, Deserialize)]
196#[serde(rename_all = "camelCase")]
197pub struct HistoricalPrice {
198 pub snapshot_time: Option<String>,
199 pub snapshot_time_utc: Option<String>,
200 pub open_price: PricePoint,
201 pub close_price: PricePoint,
202}
203
204#[derive(Debug, Default, Deserialize)]
205pub struct PricePoint {
206 pub bid: Option<f64>,
207 pub ask: Option<f64>,
208 pub last_traded: Option<f64>,
209}
210
211#[derive(Debug, Serialize)]
212#[serde(rename_all = "camelCase")]
213pub struct CreatePositionRequest {
214 pub currency_code: String,
215 pub direction: Direction,
216 pub epic: String,
217 pub expiry: String,
218 pub force_open: bool,
219 pub guaranteed_stop: bool,
220 pub order_type: OrderType,
221 pub size: f64,
222 #[serde(skip_serializing_if = "Option::is_none")]
223 pub level: Option<f64>,
224 #[serde(skip_serializing_if = "Option::is_none")]
225 pub limit_level: Option<f64>,
226 #[serde(skip_serializing_if = "Option::is_none")]
227 pub stop_level: Option<f64>,
228}
229
230#[derive(Debug, Deserialize)]
231#[serde(rename_all = "camelCase")]
232pub struct DealReferenceResponse {
233 pub deal_reference: String,
234}