ig_client/application/services/
account_service.rs1use crate::application::services::AccountService;
2use crate::{
3 application::models::account::{
4 AccountActivity, AccountInfo, Positions, TransactionHistory, WorkingOrders,
5 },
6 config::Config,
7 error::AppError,
8 session::interface::IgSession,
9 transport::http_client::IgHttpClient,
10};
11use async_trait::async_trait;
12use reqwest::Method;
13use std::sync::Arc;
14use tracing::{debug, info};
15
16pub struct AccountServiceImpl<T: IgHttpClient> {
18 config: Arc<Config>,
19 client: Arc<T>,
20}
21
22impl<T: IgHttpClient> AccountServiceImpl<T> {
23 pub fn new(config: Arc<Config>, client: Arc<T>) -> Self {
25 Self { config, client }
26 }
27
28 pub fn get_config(&self) -> Arc<Config> {
33 self.config.clone()
34 }
35
36 pub fn set_config(&mut self, config: Arc<Config>) {
41 self.config = config;
42 }
43}
44
45#[async_trait]
46impl<T: IgHttpClient + 'static> AccountService for AccountServiceImpl<T> {
47 async fn get_accounts(&self, session: &IgSession) -> Result<AccountInfo, AppError> {
48 info!("Getting account information");
49
50 let result = self
51 .client
52 .request::<(), AccountInfo>(Method::GET, "accounts", session, None, "1")
53 .await?;
54
55 debug!(
56 "Account information obtained: {} accounts",
57 result.accounts.len()
58 );
59 Ok(result)
60 }
61
62 async fn get_positions(&self, session: &IgSession) -> Result<Positions, AppError> {
63 info!("Getting open positions");
64
65 let result = self
66 .client
67 .request::<(), Positions>(Method::GET, "positions", session, None, "2")
68 .await?;
69
70 debug!("Positions obtained: {} positions", result.positions.len());
71 Ok(result)
72 }
73
74 async fn get_working_orders(&self, session: &IgSession) -> Result<WorkingOrders, AppError> {
75 info!("Getting working orders");
76
77 let result = self
78 .client
79 .request::<(), WorkingOrders>(Method::GET, "workingorders", session, None, "2")
80 .await?;
81
82 debug!(
83 "Working orders obtained: {} orders",
84 result.working_orders.len()
85 );
86 Ok(result)
87 }
88
89 async fn get_activity(
90 &self,
91 session: &IgSession,
92 from: &str,
93 to: &str,
94 ) -> Result<AccountActivity, AppError> {
95 let path = format!("history/activity?from={}&to={}&pageSize=500", from, to);
96 info!("Getting account activity");
97
98 let result = self
99 .client
100 .request::<(), AccountActivity>(Method::GET, &path, session, None, "3")
101 .await?;
102
103 debug!(
104 "Account activity obtained: {} activities",
105 result.activities.len()
106 );
107 Ok(result)
108 }
109
110 async fn get_activity_with_details(
111 &self,
112 session: &IgSession,
113 from: &str,
114 to: &str,
115 ) -> Result<AccountActivity, AppError> {
116 let path = format!(
117 "history/activity?from={}&to={}&detailed=true&pageSize=500",
118 from, to
119 );
120 info!("Getting detailed account activity");
121
122 let result = self
123 .client
124 .request::<(), AccountActivity>(Method::GET, &path, session, None, "3")
125 .await?;
126
127 debug!(
128 "Detailed account activity obtained: {} activities",
129 result.activities.len()
130 );
131 Ok(result)
132 }
133
134 async fn get_transactions(
135 &self,
136 session: &IgSession,
137 from: &str,
138 to: &str,
139 page_size: u32,
140 page_number: u32,
141 ) -> Result<TransactionHistory, AppError> {
142 let path = format!(
143 "history/transactions?from={}&to={}&pageSize={}&pageNumber={}",
144 from, to, page_size, page_number
145 );
146 info!("Getting transaction history");
147
148 let result = self
149 .client
150 .request::<(), TransactionHistory>(Method::GET, &path, session, None, "2")
151 .await?;
152
153 debug!(
154 "Transaction history obtained: {} transactions",
155 result.transactions.len()
156 );
157 Ok(result)
158 }
159}
160
161#[cfg(test)]
162mod tests {
163 use super::*;
164 use crate::config::Config;
165 use crate::transport::http_client::IgHttpClientImpl;
166 use crate::utils::rate_limiter::RateLimitType;
167 use std::sync::Arc;
168
169 #[test]
170 fn test_get_and_set_config() {
171 let config = Arc::new(Config::with_rate_limit_type(
172 RateLimitType::TradingAccount,
173 0.7,
174 ));
175 let client = Arc::new(IgHttpClientImpl::new(config.clone()));
176 let mut service = AccountServiceImpl::new(config.clone(), client.clone());
177
178 let cfg1 = service.get_config();
179 assert!(Arc::ptr_eq(&cfg1, &config));
180
181 let new_cfg = Arc::new(Config::default());
182 service.set_config(new_cfg.clone());
183 assert!(Arc::ptr_eq(&service.get_config(), &new_cfg));
184 }
185}