1use crate::datastructures::asset::Asset;
2use crate::datastructures::client::TradingClient;
3use crate::datastructures::config::Config;
4use crate::datastructures::order::Order;
5use async_trait::async_trait;
6use reqwest::{header::HeaderMap, Client as HttpClient};
7
8pub struct AlpacaClient {
9 http_client: HttpClient,
10 base_url: String,
11 api_key: String,
12 secret_key: String,
13}
14
15#[async_trait]
16impl TradingClient for AlpacaClient {
17 fn new(config: &Config) -> Self {
18 AlpacaClient {
19 http_client: HttpClient::new(),
20 base_url: config.alpaca_base_url.clone(),
21 api_key: config.alpaca_api_key.clone(),
22 secret_key: config.alpaca_secret_key.clone(),
23 }
24 }
25
26 async fn create_order(&self, order: &Order) -> Result<(), Box<dyn std::error::Error>> {
27 let url = format!("{}/v2/orders", self.base_url);
28 let mut headers = HeaderMap::new();
29 headers.insert("APCA-API-KEY-ID", self.api_key.parse()?);
30 headers.insert("APCA-API-SECRET-KEY", self.secret_key.parse()?);
31 headers.insert("accept", "application/json".parse()?);
32
33 let response = self
34 .http_client
35 .post(&url)
36 .headers(headers)
37 .json(&order)
38 .send()
39 .await?
40 .text()
41 .await?;
42
43 println!("Create Order Response: {}", response);
44 Ok(())
45 }
46
47 async fn get_asset(&self, symbol: &str) -> Result<Asset, Box<dyn std::error::Error>> {
48 let url = format!("{}/v2/assets/{}", self.base_url, symbol);
49 let mut headers = HeaderMap::new();
50 headers.insert("APCA-API-KEY-ID", self.api_key.parse()?);
51 headers.insert("APCA-API-SECRET-KEY", self.secret_key.parse()?);
52 headers.insert("accept", "application/json".parse()?);
53
54 let response = self
55 .http_client
56 .get(&url)
57 .headers(headers)
58 .send()
59 .await?
60 .text()
61 .await?;
62
63 println!("Get Asset Response: {}", response);
64
65 let asset: Asset = serde_json::from_str(&response)?;
66 Ok(asset)
67 }
68}