tokio_binance/client/
account.rs

1use reqwest::{Url, Client};
2use crate::param::{
3    Parameters, 
4    OrderType, 
5    Side, 
6    TimeInForce,
7    ID
8};
9use crate::builder::ParamBuilder;
10use crate::types::*;
11use crate::client::*;
12
13/// Client for dealing with orders
14#[derive(Clone)]
15pub struct AccountClient {
16    api_key: String,
17    secret_key: String,
18    url: Url,
19    client: Client
20}
21
22impl AccountClient {
23    /// Creates new client instance.
24    /// # Example
25    ///
26    /// ```no_run
27    /// use tokio_binance::{AccountClient, BINANCE_US_URL};
28    /// 
29    /// #[tokio::main]
30    /// async fn main() -> Result<(), Box<dyn std::error::Error>> {
31    ///     let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
32    ///     Ok(())
33    /// }
34    /// ```
35    pub fn connect<A, S, U>(api_key: A, secret_key: S, url: U) -> crate::error::Result<Self> 
36    where
37        A: Into<String>,
38        S: Into<String>,
39        U: Into<String>
40    {
41        Ok(Self {
42            api_key: api_key.into(), 
43            secret_key: secret_key.into(),
44            url: url.into().parse::<Url>()?,
45            client: Client::new()
46        })
47    }
48    /// Place a new limit order.
49    /// # Example
50    ///
51    /// ```no_run
52    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
53    /// use tokio_binance::{Side::Sell, TimeInForce::Fok, OrderRespType::Full};
54    /// use serde_json::Value;
55    /// 
56    /// # #[tokio::main]
57    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
58    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
59    /// let response = client
60    ///     // false will send as test, true will send as a real order.
61    ///     .place_limit_order("BNBUSDT", Sell, 20.00, 5.00, false)
62    ///     // optional: lifetime of order; default is Gtc.
63    ///     .with_time_in_force(Fok)
64    ///     // optional: unique id; auto generated by default.
65    ///     .with_new_client_order_id("<uuid>")
66    ///     // optional: splits quantity; sets time in force to Gtc.
67    ///     .with_iceberg_qty(1.00)
68    ///     // optional: output verbosity; default is Ack.
69    ///     .with_new_order_resp_type(Full)
70    ///     // optional: converts Limit to Stop-Limit; triggers when price hits below 21.00.
71    ///     .with_stop_loss_limit(21.00)
72    ///     // optional: converts Limit to Stop-Limit; triggers when price hits above 21.00.
73    ///     .with_take_profit_limit(21.00)
74    ///     // optional: processing time for request; default is 5000, can't be above 60000.
75    ///     .with_recv_window(8000)
76    ///     // optional: converts Limit to Limit-Maker; consumes builder and returns a different one.
77    ///     .into_limit_maker_order()
78    ///     //
79    ///     .json::<Value>()
80    ///     .await?;
81    /// # Ok(())
82    /// # }
83    /// ```
84    pub fn place_limit_order<'a>(
85        &self, symbol: &'a str, 
86        side: Side, 
87        price: f64, 
88        quantity: f64, 
89        execute: bool
90    ) -> ParamBuilder<'a, '_, LimitOrderParams>{
91        let Self { ref api_key, ref secret_key, url, client } = self;
92
93        let url = if execute {
94            url.join("/api/v3/order").unwrap()
95        } else {
96            url.join("/api/v3/order/test").unwrap()
97        };
98
99        ParamBuilder::new(
100            Parameters { 
101                symbol: Some(symbol),
102                side: Some(side),
103                order_type: Some(OrderType::Limit),
104                price: Some(price),
105                quantity: Some(quantity),
106                time_in_force: Some(TimeInForce::Gtc),
107                ..Parameters::default() 
108            },
109            client.post(url),
110            Some(api_key),
111            Some(secret_key)
112        )
113    }
114    /// Place a new market order.
115    /// # Example
116    ///
117    /// ```no_run
118    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
119    /// use tokio_binance::{Side::Sell, TimeInForce::Fok, OrderRespType::Full};
120    /// use serde_json::Value;
121    /// 
122    /// # #[tokio::main]
123    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
124    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
125    /// let response = client
126    ///     // false will send as test, true will send as a real order.
127    ///     .place_market_order("BNBUSDT", Sell, 5.00, false)
128    ///     // optional: unique id; auto generated by default.
129    ///     .with_new_client_order_id("<uuid>")
130    ///     // optional: output verbosity; default is Ack.
131    ///     .with_new_order_resp_type(Full)
132    ///     // optional: converts Market to Stop-Loss; triggers when price hits below 21.00.
133    ///     .with_stop_loss(21.00)
134    ///     // optional: converts Market to Stop-Loss; triggers when price hits above 21.00.
135    ///     .with_take_profit(21.00)
136    ///     // optional: processing time for request; default is 5000, can't be above 60000.
137    ///     .with_recv_window(8000)
138    ///     //
139    ///     .json::<Value>()
140    ///     .await?;
141    /// # Ok(())
142    /// # }
143    /// ```
144    pub fn place_market_order<'a>(
145        &self, symbol: &'a str, 
146        side: Side, 
147        quantity: f64, 
148        execute: bool
149    ) -> ParamBuilder<'a, '_, MarketOrderParams>{
150        let Self { ref api_key, ref secret_key, url, client } = self;
151
152        let url = if execute {
153            url.join("/api/v3/order").unwrap()
154        } else {
155            url.join("/api/v3/order/test").unwrap()
156        };
157
158        ParamBuilder::new(
159            Parameters { 
160                symbol: Some(symbol),
161                side: Some(side),
162                order_type: Some(OrderType::Market),
163                quantity: Some(quantity),
164                ..Parameters::default() 
165            },
166            client.post(url),
167            Some(api_key),
168            Some(secret_key)
169        )
170    }
171    /// Get order.
172    /// # Example
173    ///
174    /// ```no_run
175    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
176    /// use tokio_binance::ID;
177    /// use serde_json::Value;
178    /// 
179    /// # #[tokio::main]
180    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
181    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
182    /// let response = client
183    ///     .get_order("BNBUSDT", ID::ClientOId("<uuid>"))
184    ///     // optional: processing time for request; default is 5000, can't be above 60000.
185    ///     .with_recv_window(8000)
186    ///     //
187    ///     .json::<Value>()
188    ///     .await?;
189    /// # Ok(())
190    /// # }
191    /// ```
192    pub fn get_order<'a>(&self, symbol: &'a str, id: ID<'a>) -> ParamBuilder<'a, '_, OrderStatusParams>{
193        let Self { ref api_key, ref secret_key, url, client } = self;
194
195        let url = url.join("/api/v3/order").unwrap();
196
197        let order_id = if let ID::OrderId(id) = id {
198            Some(id)
199        } else {
200            None
201        };
202
203        let orig_client_order_id = if let ID::ClientOId(id) = id {
204            Some(id)
205        } else {
206            None
207        };
208
209        ParamBuilder::new(
210            Parameters { 
211                symbol: Some(symbol),
212                order_id,
213                orig_client_order_id,
214                ..Parameters::default() 
215            },
216            client.get(url),
217            Some(api_key),
218            Some(secret_key)
219        )
220    }
221    /// Cancel order.
222    /// # Example
223    ///
224    /// ```no_run
225    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
226    /// use tokio_binance::ID;
227    /// use serde_json::Value;
228    /// 
229    /// # #[tokio::main]
230    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
231    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
232    /// let response = client
233    ///     .cancel_order("BNBUSDT", ID::ClientOId("<uuid>"))
234    ///     // optional: unique id; auto generated by default.
235    ///     .with_new_client_order_id("<uuid>")
236    ///     // optional: processing time for request; default is 5000, can't be above 60000.
237    ///     .with_recv_window(8000)
238    ///     //
239    ///     .json::<Value>()
240    ///     .await?;
241    /// # Ok(())
242    /// # }
243    /// ```
244    pub fn cancel_order<'a>(&self, symbol: &'a str, id: ID<'a>) -> ParamBuilder<'a, '_, CancelOrderParams>{
245        let Self { ref api_key, ref secret_key, url, client } = self;
246
247        let url = url.join("/api/v3/order").unwrap();
248
249        let order_id = if let ID::OrderId(id) = id {
250            Some(id)
251        } else {
252            None
253        };
254
255        let orig_client_order_id = if let ID::ClientOId(id) = id {
256            Some(id)
257        } else {
258            None
259        };
260
261        ParamBuilder::new(
262            Parameters { 
263                symbol: Some(symbol),
264                order_id,
265                orig_client_order_id,
266                ..Parameters::default() 
267            },
268            client.delete(url),
269            Some(api_key),
270            Some(secret_key)
271        )
272    }
273    /// Get open orders.
274    /// # Example
275    ///
276    /// ```no_run
277    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
278    /// use serde_json::Value;
279    /// 
280    /// # #[tokio::main]
281    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
282    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
283    /// let response = client
284    ///     .get_open_orders()
285    ///     // optional: filter by symbol; gets all symbols by default.
286    ///     .with_symbol("BNBUSDT")
287    ///     // optional: processing time for request; default is 5000, can't be above 60000.
288    ///     .with_recv_window(8000)
289    ///     //
290    ///     .json::<Value>()
291    ///     .await?;
292    /// # Ok(())
293    /// # }
294    /// ```
295    pub fn get_open_orders(&self) -> ParamBuilder<'_, '_, OpenOrderParams>{
296        let Self { ref api_key, ref secret_key, url, client } = self;
297
298        let url = url.join("/api/v3/openOrders").unwrap();
299
300        ParamBuilder::new(
301            Parameters::default(),
302            client.get(url),
303            Some(api_key),
304            Some(secret_key)
305        )
306    }
307    /// Get all orders.
308    /// # Example
309    ///
310    /// ```no_run
311    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
312    /// use chrono::{Utc, Duration};
313    /// use serde_json::Value;
314    /// 
315    /// # #[tokio::main]
316    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
317    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
318    /// let end = Utc::now();
319    /// let start = end - Duration::hours(23);
320    /// 
321    /// let response = client
322    ///     .get_all_orders("BNBUSDT")
323    ///     // optional: filter by orders greater than or equal to the provided id.
324    ///     // If supplied, neither startTime or endTime can be provided
325    ///     .with_order_id(1230494)
326    ///     // optional: get orders from; pass 24 hours of orders is the default.
327    ///     .with_start_time(start)
328    ///     // optional: get orders until; default is now.
329    ///     .with_end_time(end)
330    ///     // optional: limit the amount of orders; default 500; max 1000.
331    ///     .with_limit(100)
332    ///     // optional: processing time for request; default is 5000, can't be above 60000.
333    ///     .with_recv_window(8000)
334    ///     //
335    ///     .json::<Value>()
336    ///     .await?;
337    /// # Ok(())
338    /// # }
339    /// ```
340    pub fn get_all_orders<'a>(&self, symbol: &'a str) -> ParamBuilder<'a, '_, AllOrdersParams>{
341        let Self { ref api_key, ref secret_key, url, client } = self;
342
343        let url = url.join("/api/v3/allOrders").unwrap();
344
345        ParamBuilder::new(
346            Parameters { symbol: Some(symbol), ..Parameters::default() },
347            client.get(url),
348            Some(api_key),
349            Some(secret_key)
350        )
351    }
352    /// Place a new oco order.
353    /// # Price Restrictions:                    
354    /// - SELL: Limit Price > Last Price > Stop Price             
355    /// - BUY: Limit Price < Last Price < Stop Price
356    /// # Example
357    ///
358    /// ```no_run
359    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
360    /// use tokio_binance::{Side::Sell, TimeInForce::Gtc, OrderRespType::Full};
361    /// use serde_json::Value;
362    /// 
363    /// # #[tokio::main]
364    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
365    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
366    /// let response = client
367    ///     // Limit to sell at 30.00 and Stop-Loss at 20.00; One cancels the other.
368    ///     .place_oco_order("BNBUSDT", Sell, 30.00, 20.00, 5.00)
369    ///     // optional: A unique Id for the entire orderList; auto generated by default.
370    ///     .with_list_client_order_id("<uuid>")
371    ///     // optional: A unique Id for the limit order; auto generated by default.
372    ///     .with_limit_client_order_id("<uuid>")
373    ///     // optional: splits quantity for the limit order leg;
374    ///     .with_limit_iceberg_qty(1.00)
375    ///     // optional: A unique Id for the stop loss/stop loss limit leg; auto generated by default.
376    ///     .with_stop_client_order_id("<uuid>")
377    ///     // optional: Converts Stop-Loss to Stop-Limit; triggers bellow 20.00.
378    ///     .with_stop_limit_price(19.00, Gtc)
379    ///     // optional: splits quantity for the stop order leg;
380    ///     .with_stop_iceberg_qty(1.00)
381    ///     // optional: output verbosity; default is Ack.
382    ///     .with_new_order_resp_type(Full)
383    ///     // optional: processing time for request; default is 5000, can't be above 60000.
384    ///     .with_recv_window(8000)
385    ///     //
386    ///     .json::<Value>()
387    ///     .await?;
388    /// # Ok(())
389    /// # }
390    /// ```
391    pub fn place_oco_order<'a>(
392        &self, symbol: &'a str, 
393        side: Side, 
394        price: f64,
395        stop_price: f64,
396        quantity: f64,
397    ) -> ParamBuilder<'a, '_, OcoParams>{
398        let Self { ref api_key, ref secret_key, url, client } = self;
399
400        let url = url.join("/api/v3/order/oco").unwrap();
401
402        ParamBuilder::new(
403            Parameters { 
404                symbol: Some(symbol),
405                side: Some(side),
406                price: Some(price),
407                stop_price: Some(stop_price),
408                quantity: Some(quantity),
409                ..Parameters::default() 
410            },
411            client.post(url),
412            Some(api_key),
413            Some(secret_key)
414        )
415    }
416    /// Cancel oco order.
417    /// # Example
418    ///
419    /// ```no_run
420    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
421    /// use tokio_binance::ID;
422    /// use serde_json::Value;
423    /// 
424    /// # #[tokio::main]
425    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
426    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
427    /// let response = client
428    ///     .cancel_oco_order("BNBUSDT", ID::ClientOId("<uuid>"))
429    ///     // optional: unique id; auto generated by default.
430    ///     .with_new_client_order_id("<uuid>")
431    ///     // optional: processing time for request; default is 5000, can't be above 60000.
432    ///     .with_recv_window(8000)
433    ///     //
434    ///     .json::<Value>()
435    ///     .await?;
436    /// # Ok(())
437    /// # }
438    /// ```
439    pub fn cancel_oco_order<'a>(&self, symbol: &'a str, id: ID<'a>) -> ParamBuilder<'a, '_, CancelOcoParams>{
440        let Self { ref api_key, ref secret_key, url, client } = self;
441
442        let url = url.join("/api/v3/orderList").unwrap();
443
444        let order_list_id = if let ID::OrderId(id) = id {
445            Some(id)
446        } else {
447            None
448        };
449
450        let list_client_order_id = if let ID::ClientOId(id) = id {
451            Some(id)
452        } else {
453            None
454        };
455
456        ParamBuilder::new(
457            Parameters { 
458                symbol: Some(symbol),
459                order_list_id,
460                list_client_order_id,
461                ..Parameters::default() 
462            },
463            client.delete(url),
464            Some(api_key),
465            Some(secret_key)
466        )
467    }
468    /// Get oco order.
469    /// # Example
470    ///
471    /// ```no_run
472    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
473    /// use tokio_binance::ID;
474    /// use serde_json::Value;
475    /// 
476    /// # #[tokio::main]
477    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
478    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
479    /// let response = client
480    ///     .get_oco_order(ID::ClientOId("<uuid>"))
481    ///     // optional: processing time for request; default is 5000, can't be above 60000.
482    ///     .with_recv_window(8000)
483    ///     //
484    ///     .json::<Value>()
485    ///     .await?;
486    /// # Ok(())
487    /// # }
488    /// ```
489    pub fn get_oco_order<'a>(&self, id: ID<'a>) -> ParamBuilder<'a, '_, OcoStatusParams>{
490        let Self { ref api_key, ref secret_key, url, client } = self;
491
492        let url = url.join("/api/v3/orderList").unwrap();
493
494        let order_list_id = if let ID::OrderId(id) = id {
495            Some(id)
496        } else {
497            None
498        };
499
500        let orig_client_order_id = if let ID::ClientOId(id) = id {
501            Some(id)
502        } else {
503            None
504        };
505
506        ParamBuilder::new(
507            Parameters { 
508                order_list_id,
509                orig_client_order_id,
510                ..Parameters::default() 
511            },
512            client.get(url),
513            Some(api_key),
514            Some(secret_key)
515        )
516    }
517    /// Get all oco orders.
518    /// # Example
519    ///
520    /// ```no_run
521    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
522    /// use chrono::{Utc, Duration};
523    /// use serde_json::Value;
524    /// 
525    /// # #[tokio::main]
526    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
527    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
528    /// let end = Utc::now();
529    /// let start = end - Duration::hours(23);
530    /// 
531    /// let response = client
532    ///     .get_all_oco_orders()
533    ///     // optional: filter by orders greater than or equal to the provided id.
534    ///     // If supplied, neither startTime or endTime can be provided
535    ///     .with_from_id(1230494)
536    ///     // optional: get orders from; pass 24 hours of orders is the default.
537    ///     .with_start_time(start)
538    ///     // optional: get orders until; default is now.
539    ///     .with_end_time(end)
540    ///     // optional: limit the amount of orders; default 500; max 1000.
541    ///     .with_limit(100)
542    ///     // optional: processing time for request; default is 5000, can't be above 60000.
543    ///     .with_recv_window(8000)
544    ///     //
545    ///     .json::<Value>()
546    ///     .await?;
547    /// # Ok(())
548    /// # }
549    /// ```
550    pub fn get_all_oco_orders(&self) -> ParamBuilder<'_, '_, AllOcoParams>{
551        let Self { ref api_key, ref secret_key, url, client } = self;
552
553        let url = url.join("/api/v3/allOrderList").unwrap();
554
555        ParamBuilder::new(
556            Parameters::default(),
557            client.get(url),
558            Some(api_key),
559            Some(secret_key)
560        )
561    }
562    /// Get open oco orders.
563    /// # Example
564    ///
565    /// ```no_run
566    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
567    /// use serde_json::Value;
568    /// 
569    /// # #[tokio::main]
570    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
571    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
572    /// let response = client
573    ///     .get_open_oco_orders()
574    ///     // optional: processing time for request; default is 5000, can't be above 60000.
575    ///     .with_recv_window(8000)
576    ///     //
577    ///     .json::<Value>()
578    ///     .await?;
579    /// # Ok(())
580    /// # }
581    /// ```
582    pub fn get_open_oco_orders(&self) -> ParamBuilder<'_, '_, OpenOcoParams>{
583        let Self { ref api_key, ref secret_key, url, client } = self;
584
585        let url = url.join("/api/v3/openOrderList").unwrap();
586
587        ParamBuilder::new(
588            Parameters::default(),
589            client.get(url),
590            Some(api_key),
591            Some(secret_key)
592        )
593    }
594    /// Get current account information.
595    /// # Example
596    ///
597    /// ```no_run
598    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
599    /// use serde_json::Value;
600    /// 
601    /// # #[tokio::main]
602    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
603    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
604    /// let response = client
605    ///     .get_account()
606    ///     // optional: processing time for request; default is 5000, can't be above 60000.
607    ///     .with_recv_window(8000)
608    ///     //
609    ///     .json::<Value>()
610    ///     .await?;
611    /// # Ok(())
612    /// # }
613    /// ```
614    pub fn get_account(&self) -> ParamBuilder<'_, '_, AccountParams>{
615        let Self { ref api_key, ref secret_key, url, client } = self;
616
617        let url = url.join("/api/v3/account").unwrap();
618
619        ParamBuilder::new(
620            Parameters::default(),
621            client.get(url),
622            Some(api_key),
623            Some(secret_key)
624        )
625    }
626    /// Get trades for a specific account and symbol.
627    /// # Example
628    ///
629    /// ```no_run
630    /// # use tokio_binance::{AccountClient, BINANCE_US_URL};
631    /// use chrono::{Utc, Duration};
632    /// use serde_json::Value;
633    /// 
634    /// # #[tokio::main]
635    /// # async fn main() -> Result<(), Box<dyn std::error::Error>> {
636    /// # let client = AccountClient::connect("<api-key>", "<secret-key>", BINANCE_US_URL)?;
637    /// let end = Utc::now();
638    /// let start = end - Duration::hours(23);
639    /// 
640    /// let response = client
641    ///     .get_account_trades("BNBUSDT")
642    ///     // optional: filter by orders greater than or equal to the provided id.
643    ///     // If supplied, neither startTime or endTime can be provided
644    ///     .with_from_id(1230494)
645    ///     // optional: get orders from; pass 24 hours of orders is the default.
646    ///     .with_start_time(start)
647    ///     // optional: get orders until; default is now.
648    ///     .with_end_time(end)
649    ///     // optional: limit the amount of orders; default 500; max 1000.
650    ///     .with_limit(100)
651    ///     // optional: processing time for request; default is 5000, can't be above 60000.
652    ///     .with_recv_window(8000)
653    ///     //
654    ///     .json::<Value>()
655    ///     .await?;
656    /// # Ok(())
657    /// # }
658    /// ```
659    pub fn get_account_trades<'a>(&self, symbol: &'a str) -> ParamBuilder<'a, '_, AccountTradesParams>{
660        let Self { ref api_key, ref secret_key, url, client } = self;
661
662        let url = url.join("/api/v3/myTrades").unwrap();
663
664        ParamBuilder::new(
665            Parameters { symbol: Some(symbol), ..Parameters::default() },
666            client.get(url),
667            Some(api_key),
668            Some(secret_key)
669        )
670    }
671    /// Helper method for getting a withdraw client instance.
672    pub fn to_withdraw_client(&self) -> WithdrawalClient {
673        WithdrawalClient { 
674            api_key: self.api_key.clone(),
675            secret_key: self.secret_key.clone(), 
676            url: self.url.clone(), 
677            client: self.client.clone() 
678        }
679    }
680    /// Helper method for getting a market client instance.
681    pub fn to_market_data_client(&self) -> MarketDataClient {
682        MarketDataClient { 
683            api_key: self.api_key.clone(), 
684            url: self.url.clone(), 
685            client: self.client.clone() 
686        }
687    }
688    /// Helper method for getting a general client instance.
689    pub fn to_general_client(&self) -> GeneralClient {
690        GeneralClient { url: self.url.clone(), client: self.client.clone() }
691    }
692
693}