1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
use std::fmt;
use chrono::prelude::*;
use serde::{Deserialize, Serialize};
use serde_variant::to_variant_name;
use crate::api::Requests;
use crate::client::TradingClient;
use crate::error::Error;
mod documents;
/// Module for interacting with the withdrawal related endpoints
pub mod withdrawals;
///
#[derive(Deserialize, Debug)]
pub struct AccountInformation<T> {
/// Timestamp of your API request
pub time: String,
/// Environment the request was placed in: "paper" or "money"
// TODO: Make this an enum
pub mode: String,
/// API returns "ok" when account was successfully retrieved.
pub status: String,
/// The actual results of the query. Depends upon the given generics
pub results: T,
}
/// Struct for account information.
// TODO: Make periods into chrono types
#[derive(Serialize, Deserialize, Debug)]
pub struct AccountResults {
/// Timestamp for when you created your account
pub created_at: DateTime<Utc>,
/// Unique Identification number for your account
pub account_id: String,
/// Your first name
pub firstname: String,
/// Your last name
pub lastname: Option<String>,
/// Your specified email address
pub email: String,
/// Your specified phone number
pub phone: Option<String>,
/// Your specified address
pub address: Option<String>,
/// The billing address you provided for your account
pub billing_address: Option<String>,
/// The billing email adress you provided for your account
pub billing_email: Option<String>,
/// The billing name you provided for your account
pub billing_name: Option<String>,
/// The billing VAT number you provided for your account
pub billing_vat: Option<String>,
/// The mode your account is currently on - "paper" or "money"
// TODO: Make this an enum
pub mode: String,
/// Identification Number of your securities account
pub deposit_id: Option<String>,
/// The internal client identification number related to your account
pub client_id: Option<String>,
/// The account reference number
pub account_number: Option<String>,
/// The account reference number
pub iban_brokerage: Option<String>,
/// IBAN of the brokerage account at our partner bank.
/// This is the IBAN you can transfer money from your referrence account to.
pub iban_origin: Option<String>,
/// Bank name your reference account is located a
pub bank_name_origin: Option<String>,
/// This is your account balance - the amount of money you have available in your brokerage account.
/// The balance calculates as follows:
/// (End-of-day balance from the day before) + (amount_sold_intraday)
/// - (amount_bought_intraday) - (amount_open_withdrawals).
pub balance: i64,
/// This number shows you how much cash you have left to invest.
///
/// The cash_to_invest calculates as follows:
///
/// (balance) - (amount_open_orders)
pub cash_to_invest: i64,
/// This number shows you how much cash you have in your account to withdraw to your reference account.
///
/// cash_to_withdraw is calculated as follows:
///
/// (Your end-of-day balance from the day before) - (amount_bought_intraday)
/// - (amount_open_withdrawals) - (amount_open_orders).
pub cash_to_withdraw: i64,
/// This is the intraday buy order amount.
/// For example, if you bought 2 shares for 100€ each that day, the amount_bought_intraday
/// would be 200€ (the API would return 2000000 in that case,
/// see the [numbers page](https://docs.lemon.markets/numbers) for more information).
pub amount_bought_intraday: i64,
/// This is the intraday sell order amount.
/// For example, if you sold 3 shares for 50€ each that day,
/// the amount_sold_intraday would be 150€ (the API would return 1500000 in that case,
/// see the [numbers page](https://docs.lemon.markets/numbers) for more information).
pub amount_sold_intraday: i64,
/// This is the intraday amount of open orders.
// If you place an order that has amount X and its status is open,
// the amount_open_orders would be the order amount
// (+ the sum of all other open intraday orders).
pub amount_open_orders: i64,
/// For example, if you withdraw 500€ to your reference account,
/// amount_open_withdrawals would return 5000000
/// (see the [numbers page](https://docs.lemon.markets/numbers) for more information
/// on the numbers format in the Trading API).
pub amount_open_withdrawals: i64,
/// This is the amount of estimated taxes (25%) for your intraday sell orders.
/// For example, if you made a profit of 100€ from your intraday sell orders,
/// the API would return 250000
/// (see the [numbers page](https://docs.lemon.markets/numbers
/// for more information in the Trading API
pub amount_estimate_taxes: i64,
/// Timestamp of live trading account approval
pub approved_at: Option<DateTime<Utc>>,
/// We offer different subscription plans for trading with lemon.markets.
/// This endpoint tells you which plan you are currently on - go, investor, trader, or b2b.
// TODO: Make this an enum
pub trading_plan: String,
/// We offer different subscription plans for trading with lemon.markets.
/// This endpoint tells you which plan you are currently on - go, investor, trader, or b2b.
// TODO: Make this an enum
pub data_plan: String,
/// Your tax tax allowance - between 0 and 801 €, as specified in your onboarding process
pub tax_allowance: Option<i64>,
/// Relevant start date for your tax allowance (usually 01/01/ of respective year)
pub tax_allowance_start: Option<DateTime<Utc>>,
/// Relevant end date for your tax allowance (usually 31/12/ of respective year)
pub tax_allowance_end: Option<DateTime<Utc>>,
}
/// Enum for the different ways of sorting the results
#[derive(Deserialize, Serialize, Debug)]
pub enum Sorting {
/// Use asc_ to sort your bank statements in ascending order (oldest ones first),
#[serde(rename = "asc_")]
Asc,
/// Desc to sort your bank statements in descending order (newest ones first).
#[serde(rename = "desc")]
Desc,
}
impl fmt::Display for Sorting {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match to_variant_name(self) {
Ok(name) => write!(f, "{}", name),
_ => write!(f, ""),
}
}
}
impl TradingClient {
/// Get account information
pub fn get_account_information(&self) -> Result<AccountInformation<AccountResults>, Error> {
const PATH: &str = "account";
let resp = self.get::<AccountInformation<AccountResults>>(PATH);
match resp {
Ok(r) => Ok(r),
Err(e) => Err(e),
}
}
}
#[cfg(test)]
mod test {
use std::env;
use crate::client::TradingClient;
#[test]
fn test_get_account_information() {
dotenv::dotenv().unwrap();
let api_key = env::var("LEMON_MARKET_TRADING_API_KEY").unwrap();
let client = TradingClient::paper_client(&api_key);
let resp = client.get_account_information().unwrap();
assert_eq!(resp.status, "ok");
}
}