Skip to main content

binance/futures/
account.rs

1use std::collections::BTreeMap;
2use std::fmt::Display;
3use crate::util::build_signed_request;
4use crate::errors::Result;
5use crate::client::Client;
6use crate::api::{API, Futures};
7use crate::model::Empty;
8use crate::account::OrderSide;
9use crate::futures::model::{Order, TradeHistory};
10
11use super::model::{
12    ChangeLeverageResponse, Transaction, CanceledOrder, PositionRisk, AccountBalance,
13    AccountInformation,
14};
15
16#[derive(Clone)]
17pub struct FuturesAccount {
18    pub client: Client,
19    pub recv_window: u64,
20}
21
22pub enum ContractType {
23    Perpetual,
24    CurrentMonth,
25    NextMonth,
26    CurrentQuarter,
27    NextQuarter,
28}
29
30impl From<ContractType> for String {
31    fn from(item: ContractType) -> Self {
32        match item {
33            ContractType::Perpetual => String::from("PERPETUAL"),
34            ContractType::CurrentMonth => String::from("CURRENT_MONTH"),
35            ContractType::NextMonth => String::from("NEXT_MONTH"),
36            ContractType::CurrentQuarter => String::from("CURRENT_QUARTER"),
37            ContractType::NextQuarter => String::from("NEXT_QUARTER"),
38        }
39    }
40}
41
42pub enum PositionSide {
43    Both,
44    Long,
45    Short,
46}
47
48impl Display for PositionSide {
49    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
50        match self {
51            Self::Both => write!(f, "BOTH"),
52            Self::Long => write!(f, "LONG"),
53            Self::Short => write!(f, "SHORT"),
54        }
55    }
56}
57
58pub enum OrderType {
59    Limit,
60    Market,
61    Stop,
62    StopMarket,
63    TakeProfit,
64    TakeProfitMarket,
65    TrailingStopMarket,
66}
67
68impl Display for OrderType {
69    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
70        match self {
71            Self::Limit => write!(f, "LIMIT"),
72            Self::Market => write!(f, "MARKET"),
73            Self::Stop => write!(f, "STOP"),
74            Self::StopMarket => write!(f, "STOP_MARKET"),
75            Self::TakeProfit => write!(f, "TAKE_PROFIT"),
76            Self::TakeProfitMarket => write!(f, "TAKE_PROFIT_MARKET"),
77            Self::TrailingStopMarket => write!(f, "TRAILING_STOP_MARKET"),
78        }
79    }
80}
81
82pub enum WorkingType {
83    MarkPrice,
84    ContractPrice,
85}
86
87impl Display for WorkingType {
88    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89        match self {
90            Self::MarkPrice => write!(f, "MARK_PRICE"),
91            Self::ContractPrice => write!(f, "CONTRACT_PRICE"),
92        }
93    }
94}
95
96#[allow(clippy::all)]
97pub enum TimeInForce {
98    GTC,
99    IOC,
100    FOK,
101    GTX,
102}
103
104impl Display for TimeInForce {
105    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
106        match self {
107            Self::GTC => write!(f, "GTC"),
108            Self::IOC => write!(f, "IOC"),
109            Self::FOK => write!(f, "FOK"),
110            Self::GTX => write!(f, "GTX"),
111        }
112    }
113}
114
115struct OrderRequest {
116    pub symbol: String,
117    pub side: OrderSide,
118    pub position_side: Option<PositionSide>,
119    pub order_type: OrderType,
120    pub time_in_force: Option<TimeInForce>,
121    pub qty: Option<f64>,
122    pub reduce_only: Option<bool>,
123    pub price: Option<f64>,
124    pub stop_price: Option<f64>,
125    pub close_position: Option<bool>,
126    pub activation_price: Option<f64>,
127    pub callback_rate: Option<f64>,
128    pub working_type: Option<WorkingType>,
129    pub price_protect: Option<f64>,
130}
131
132pub struct CustomOrderRequest {
133    pub symbol: String,
134    pub side: OrderSide,
135    pub position_side: Option<PositionSide>,
136    pub order_type: OrderType,
137    pub time_in_force: Option<TimeInForce>,
138    pub qty: Option<f64>,
139    pub reduce_only: Option<bool>,
140    pub price: Option<f64>,
141    pub stop_price: Option<f64>,
142    pub close_position: Option<bool>,
143    pub activation_price: Option<f64>,
144    pub callback_rate: Option<f64>,
145    pub working_type: Option<WorkingType>,
146    pub price_protect: Option<f64>,
147}
148
149pub struct IncomeRequest {
150    pub symbol: Option<String>,
151    pub income_type: Option<IncomeType>,
152    pub start_time: Option<u64>,
153    pub end_time: Option<u64>,
154    pub limit: Option<u32>,
155}
156
157#[allow(non_camel_case_types)]
158pub enum IncomeType {
159    TRANSFER,
160    WELCOME_BONUS,
161    REALIZED_PNL,
162    FUNDING_FEE,
163    COMMISSION,
164    INSURANCE_CLEAR,
165    REFERRAL_KICKBACK,
166    COMMISSION_REBATE,
167    API_REBATE,
168    CONTEST_REWARD,
169    CROSS_COLLATERAL_TRANSFER,
170    OPTIONS_PREMIUM_FEE,
171    OPTIONS_SETTLE_PROFIT,
172    INTERNAL_TRANSFER,
173    AUTO_EXCHANGE,
174    DELIVERED_SETTELMENT,
175    COIN_SWAP_DEPOSIT,
176    COIN_SWAP_WITHDRAW,
177    POSITION_LIMIT_INCREASE_FEE,
178}
179
180impl Display for IncomeType {
181    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
182        match self {
183            Self::TRANSFER => write!(f, "TRANSFER"),
184            Self::WELCOME_BONUS => write!(f, "WELCOME_BONUS"),
185            Self::REALIZED_PNL => write!(f, "REALIZED_PNL"),
186            Self::FUNDING_FEE => write!(f, "FUNDING_FEE"),
187            Self::COMMISSION => write!(f, "COMMISSION"),
188            Self::INSURANCE_CLEAR => write!(f, "INSURANCE_CLEAR"),
189            Self::REFERRAL_KICKBACK => write!(f, "REFERRAL_KICKBACK"),
190            Self::COMMISSION_REBATE => write!(f, "COMMISSION_REBATE"),
191            Self::API_REBATE => write!(f, "API_REBATE"),
192            Self::CONTEST_REWARD => write!(f, "CONTEST_REWARD"),
193            Self::CROSS_COLLATERAL_TRANSFER => write!(f, "CROSS_COLLATERAL_TRANSFER"),
194            Self::OPTIONS_PREMIUM_FEE => write!(f, "OPTIONS_PREMIUM_FEE"),
195            Self::OPTIONS_SETTLE_PROFIT => write!(f, "OPTIONS_SETTLE_PROFIT"),
196            Self::INTERNAL_TRANSFER => write!(f, "INTERNAL_TRANSFER"),
197            Self::AUTO_EXCHANGE => write!(f, "AUTO_EXCHANGE"),
198            Self::DELIVERED_SETTELMENT => write!(f, "DELIVERED_SETTELMENT"),
199            Self::COIN_SWAP_DEPOSIT => write!(f, "COIN_SWAP_DEPOSIT"),
200            Self::COIN_SWAP_WITHDRAW => write!(f, "COIN_SWAP_WITHDRAW"),
201            Self::POSITION_LIMIT_INCREASE_FEE => write!(f, "POSITION_LIMIT_INCREASE_FEE"),
202        }
203    }
204}
205
206impl FuturesAccount {
207    pub fn limit_buy(
208        &self, symbol: impl Into<String>, qty: impl Into<f64>, price: f64,
209        time_in_force: TimeInForce,
210    ) -> Result<Transaction> {
211        let buy = OrderRequest {
212            symbol: symbol.into(),
213            side: OrderSide::Buy,
214            position_side: None,
215            order_type: OrderType::Limit,
216            time_in_force: Some(time_in_force),
217            qty: Some(qty.into()),
218            reduce_only: None,
219            price: Some(price),
220            stop_price: None,
221            close_position: None,
222            activation_price: None,
223            callback_rate: None,
224            working_type: None,
225            price_protect: None,
226        };
227        let order = self.build_order(buy);
228        let request = build_signed_request(order, self.recv_window)?;
229        self.client
230            .post_signed(API::Futures(Futures::Order), request)
231    }
232
233    pub fn limit_sell(
234        &self, symbol: impl Into<String>, qty: impl Into<f64>, price: f64,
235        time_in_force: TimeInForce,
236    ) -> Result<Transaction> {
237        let sell = OrderRequest {
238            symbol: symbol.into(),
239            side: OrderSide::Sell,
240            position_side: None,
241            order_type: OrderType::Limit,
242            time_in_force: Some(time_in_force),
243            qty: Some(qty.into()),
244            reduce_only: None,
245            price: Some(price),
246            stop_price: None,
247            close_position: None,
248            activation_price: None,
249            callback_rate: None,
250            working_type: None,
251            price_protect: None,
252        };
253        let order = self.build_order(sell);
254        let request = build_signed_request(order, self.recv_window)?;
255        self.client
256            .post_signed(API::Futures(Futures::Order), request)
257    }
258
259    // Place a MARKET order - BUY
260    pub fn market_buy<S, F>(&self, symbol: S, qty: F) -> Result<Transaction>
261    where
262        S: Into<String>,
263        F: Into<f64>,
264    {
265        let buy = OrderRequest {
266            symbol: symbol.into(),
267            side: OrderSide::Buy,
268            position_side: None,
269            order_type: OrderType::Market,
270            time_in_force: None,
271            qty: Some(qty.into()),
272            reduce_only: None,
273            price: None,
274            stop_price: None,
275            close_position: None,
276            activation_price: None,
277            callback_rate: None,
278            working_type: None,
279            price_protect: None,
280        };
281        let order = self.build_order(buy);
282        let request = build_signed_request(order, self.recv_window)?;
283        self.client
284            .post_signed(API::Futures(Futures::Order), request)
285    }
286
287    // Place a MARKET order - SELL
288    pub fn market_sell<S, F>(&self, symbol: S, qty: F) -> Result<Transaction>
289    where
290        S: Into<String>,
291        F: Into<f64>,
292    {
293        let sell = OrderRequest {
294            symbol: symbol.into(),
295            side: OrderSide::Sell,
296            position_side: None,
297            order_type: OrderType::Market,
298            time_in_force: None,
299            qty: Some(qty.into()),
300            reduce_only: None,
301            price: None,
302            stop_price: None,
303            close_position: None,
304            activation_price: None,
305            callback_rate: None,
306            working_type: None,
307            price_protect: None,
308        };
309        let order = self.build_order(sell);
310        let request = build_signed_request(order, self.recv_window)?;
311        self.client
312            .post_signed(API::Futures(Futures::Order), request)
313    }
314
315    pub fn cancel_order<S>(&self, symbol: S, order_id: u64) -> Result<CanceledOrder>
316    where
317        S: Into<String>,
318    {
319        let mut parameters = BTreeMap::new();
320        parameters.insert("symbol".into(), symbol.into());
321        parameters.insert("orderId".into(), order_id.to_string());
322
323        let request = build_signed_request(parameters, self.recv_window)?;
324        self.client
325            .delete_signed(API::Futures(Futures::Order), Some(request))
326    }
327
328    pub fn cancel_order_with_client_id<S>(
329        &self, symbol: S, orig_client_order_id: String,
330    ) -> Result<CanceledOrder>
331    where
332        S: Into<String>,
333    {
334        let mut parameters = BTreeMap::new();
335        parameters.insert("symbol".into(), symbol.into());
336        parameters.insert("origClientOrderId".into(), orig_client_order_id);
337
338        let request = build_signed_request(parameters, self.recv_window)?;
339        self.client
340            .delete_signed(API::Futures(Futures::Order), Some(request))
341    }
342
343    // Place a STOP_MARKET close - BUY
344    pub fn stop_market_close_buy<S, F>(&self, symbol: S, stop_price: F) -> Result<Transaction>
345    where
346        S: Into<String>,
347        F: Into<f64>,
348    {
349        let sell = OrderRequest {
350            symbol: symbol.into(),
351            side: OrderSide::Buy,
352            position_side: None,
353            order_type: OrderType::StopMarket,
354            time_in_force: None,
355            qty: None,
356            reduce_only: None,
357            price: None,
358            stop_price: Some(stop_price.into()),
359            close_position: Some(true),
360            activation_price: None,
361            callback_rate: None,
362            working_type: None,
363            price_protect: None,
364        };
365        let order = self.build_order(sell);
366        let request = build_signed_request(order, self.recv_window)?;
367        self.client
368            .post_signed(API::Futures(Futures::Order), request)
369    }
370
371    // Place a STOP_MARKET close - SELL
372    pub fn stop_market_close_sell<S, F>(&self, symbol: S, stop_price: F) -> Result<Transaction>
373    where
374        S: Into<String>,
375        F: Into<f64>,
376    {
377        let sell = OrderRequest {
378            symbol: symbol.into(),
379            side: OrderSide::Sell,
380            position_side: None,
381            order_type: OrderType::StopMarket,
382            time_in_force: None,
383            qty: None,
384            reduce_only: None,
385            price: None,
386            stop_price: Some(stop_price.into()),
387            close_position: Some(true),
388            activation_price: None,
389            callback_rate: None,
390            working_type: None,
391            price_protect: None,
392        };
393        let order = self.build_order(sell);
394        let request = build_signed_request(order, self.recv_window)?;
395        self.client
396            .post_signed(API::Futures(Futures::Order), request)
397    }
398
399    // Custom order for for professional traders
400    pub fn custom_order(&self, order_request: CustomOrderRequest) -> Result<Transaction> {
401        let order = OrderRequest {
402            symbol: order_request.symbol,
403            side: order_request.side,
404            position_side: order_request.position_side,
405            order_type: order_request.order_type,
406            time_in_force: order_request.time_in_force,
407            qty: order_request.qty,
408            reduce_only: order_request.reduce_only,
409            price: order_request.price,
410            stop_price: order_request.stop_price,
411            close_position: order_request.close_position,
412            activation_price: order_request.activation_price,
413            callback_rate: order_request.callback_rate,
414            working_type: order_request.working_type,
415            price_protect: order_request.price_protect,
416        };
417        let order = self.build_order(order);
418        let request = build_signed_request(order, self.recv_window)?;
419        self.client
420            .post_signed(API::Futures(Futures::Order), request)
421    }
422
423    // Custom order for for professional traders
424    pub fn custom_batch_orders(
425        &self, _order_count: u64, order_requests: Vec<CustomOrderRequest>,
426    ) -> Result<Transaction> {
427        let request = String::new();
428        for order_request in order_requests {
429            let order = OrderRequest {
430                symbol: order_request.symbol,
431                side: order_request.side,
432                position_side: order_request.position_side,
433                order_type: order_request.order_type,
434                time_in_force: order_request.time_in_force,
435                qty: order_request.qty,
436                reduce_only: order_request.reduce_only,
437                price: order_request.price,
438                stop_price: order_request.stop_price,
439                close_position: order_request.close_position,
440                activation_price: order_request.activation_price,
441                callback_rate: order_request.callback_rate,
442                working_type: order_request.working_type,
443                price_protect: order_request.price_protect,
444            };
445            let _order = self.build_order(order);
446            // TODO : make a request string for batch orders api
447            // let request = build_signed_request(order, self.recv_window)?;
448        }
449        self.client
450            .post_signed(API::Futures(Futures::Order), request)
451    }
452
453    pub fn get_all_orders<S, F, N>(
454        &self, symbol: S, order_id: F, start_time: F, end_time: F, limit: N,
455    ) -> Result<Vec<Order>>
456    where
457        S: Into<String>,
458        F: Into<Option<u64>>,
459        N: Into<Option<u16>>,
460    {
461        let mut parameters = BTreeMap::new();
462        parameters.insert("symbol".into(), symbol.into());
463        if let Some(order_id) = order_id.into() {
464            parameters.insert("orderId".into(), order_id.to_string());
465        }
466        if let Some(start_time) = start_time.into() {
467            parameters.insert("startTime".into(), start_time.to_string());
468        }
469        if let Some(end_time) = end_time.into() {
470            parameters.insert("endTime".into(), end_time.to_string());
471        }
472        if let Some(limit) = limit.into() {
473            parameters.insert("limit".into(), limit.to_string());
474        }
475
476        let request = build_signed_request(parameters, self.recv_window)?;
477        self.client
478            .get_signed(API::Futures(Futures::AllOrders), Some(request))
479    }
480
481    pub fn get_user_trades<S, F, N>(
482        &self, symbol: S, from_id: F, start_time: F, end_time: F, limit: N,
483    ) -> Result<Vec<TradeHistory>>
484    where
485        S: Into<String>,
486        F: Into<Option<u64>>,
487        N: Into<Option<u16>>,
488    {
489        let mut parameters = BTreeMap::new();
490        parameters.insert("symbol".into(), symbol.into());
491        if let Some(order_id) = from_id.into() {
492            parameters.insert("fromId".into(), order_id.to_string());
493        }
494        if let Some(start_time) = start_time.into() {
495            parameters.insert("startTime".into(), start_time.to_string());
496        }
497        if let Some(end_time) = end_time.into() {
498            parameters.insert("endTime".into(), end_time.to_string());
499        }
500        if let Some(limit) = limit.into() {
501            parameters.insert("limit".into(), limit.to_string());
502        }
503
504        let request = build_signed_request(parameters, self.recv_window)?;
505        self.client
506            .get_signed(API::Futures(Futures::UserTrades), Some(request))
507    }
508    fn build_order(&self, order: OrderRequest) -> BTreeMap<String, String> {
509        let mut parameters = BTreeMap::new();
510        parameters.insert("symbol".into(), order.symbol);
511        parameters.insert("side".into(), order.side.to_string());
512        parameters.insert("type".into(), order.order_type.to_string());
513
514        if let Some(position_side) = order.position_side {
515            parameters.insert("positionSide".into(), position_side.to_string());
516        }
517        if let Some(time_in_force) = order.time_in_force {
518            parameters.insert("timeInForce".into(), time_in_force.to_string());
519        }
520        if let Some(qty) = order.qty {
521            parameters.insert("quantity".into(), qty.to_string());
522        }
523        if let Some(reduce_only) = order.reduce_only {
524            parameters.insert("reduceOnly".into(), reduce_only.to_string().to_uppercase());
525        }
526        if let Some(price) = order.price {
527            parameters.insert("price".into(), price.to_string());
528        }
529        if let Some(stop_price) = order.stop_price {
530            parameters.insert("stopPrice".into(), stop_price.to_string());
531        }
532        if let Some(close_position) = order.close_position {
533            parameters.insert(
534                "closePosition".into(),
535                close_position.to_string().to_uppercase(),
536            );
537        }
538        if let Some(activation_price) = order.activation_price {
539            parameters.insert("activationPrice".into(), activation_price.to_string());
540        }
541        if let Some(callback_rate) = order.callback_rate {
542            parameters.insert("callbackRate".into(), callback_rate.to_string());
543        }
544        if let Some(working_type) = order.working_type {
545            parameters.insert("workingType".into(), working_type.to_string());
546        }
547        if let Some(price_protect) = order.price_protect {
548            parameters.insert(
549                "priceProtect".into(),
550                price_protect.to_string().to_uppercase(),
551            );
552        }
553
554        parameters
555    }
556
557    pub fn position_information<S>(&self, symbol: S) -> Result<Vec<PositionRisk>>
558    where
559        S: Into<String>,
560    {
561        let mut parameters = BTreeMap::new();
562        parameters.insert("symbol".into(), symbol.into());
563
564        let request = build_signed_request(parameters, self.recv_window)?;
565        self.client
566            .get_signed(API::Futures(Futures::PositionRisk), Some(request))
567    }
568
569    pub fn account_information(&self) -> Result<AccountInformation> {
570        let parameters = BTreeMap::new();
571
572        let request = build_signed_request(parameters, self.recv_window)?;
573        self.client
574            .get_signed(API::Futures(Futures::Account), Some(request))
575    }
576
577    pub fn account_balance(&self) -> Result<Vec<AccountBalance>> {
578        let parameters = BTreeMap::new();
579
580        let request = build_signed_request(parameters, self.recv_window)?;
581        self.client
582            .get_signed(API::Futures(Futures::Balance), Some(request))
583    }
584
585    pub fn change_initial_leverage<S>(
586        &self, symbol: S, leverage: u8,
587    ) -> Result<ChangeLeverageResponse>
588    where
589        S: Into<String>,
590    {
591        let mut parameters: BTreeMap<String, String> = BTreeMap::new();
592        parameters.insert("symbol".into(), symbol.into());
593        parameters.insert("leverage".into(), leverage.to_string());
594
595        let request = build_signed_request(parameters, self.recv_window)?;
596        self.client
597            .post_signed(API::Futures(Futures::ChangeInitialLeverage), request)
598    }
599
600    pub fn change_margin_type<S>(&self, symbol: S, isolated: bool) -> Result<()>
601    where
602        S: Into<String>,
603    {
604        let mut parameters: BTreeMap<String, String> = BTreeMap::new();
605        let margin_type = if isolated { "ISOLATED" } else { "CROSSED" };
606        parameters.insert("symbol".into(), symbol.into());
607        parameters.insert("marginType".into(), margin_type.into());
608
609        let request = build_signed_request(parameters, self.recv_window)?;
610        self.client
611            .post_signed::<Empty>(API::Futures(Futures::MarginType), request)
612            .map(|_| ())
613    }
614
615    pub fn change_position_margin<S>(
616        &self, symbol: S, amount: f64, is_adding_margin: bool,
617    ) -> Result<()>
618    where
619        S: Into<String>,
620    {
621        let mut parameters: BTreeMap<String, String> = BTreeMap::new();
622        let margin = if is_adding_margin { "1" } else { "2" };
623        parameters.insert("symbol".into(), symbol.into());
624        parameters.insert("amount".into(), amount.to_string());
625        parameters.insert("type".into(), margin.into());
626
627        let request = build_signed_request(parameters, self.recv_window)?;
628        self.client
629            .post_signed::<Empty>(API::Futures(Futures::PositionMargin), request)
630            .map(|_| ())
631    }
632
633    pub fn change_position_mode(&self, dual_side_position: bool) -> Result<()> {
634        let mut parameters: BTreeMap<String, String> = BTreeMap::new();
635        let dual_side = if dual_side_position { "true" } else { "false" };
636        parameters.insert("dualSidePosition".into(), dual_side.into());
637
638        let request = build_signed_request(parameters, self.recv_window)?;
639        self.client
640            .post_signed::<Empty>(API::Futures(Futures::PositionSide), request)
641            .map(|_| ())
642    }
643
644    pub fn cancel_all_open_orders<S>(&self, symbol: S) -> Result<()>
645    where
646        S: Into<String>,
647    {
648        let mut parameters: BTreeMap<String, String> = BTreeMap::new();
649        parameters.insert("symbol".into(), symbol.into());
650        let request = build_signed_request(parameters, self.recv_window)?;
651        self.client
652            .delete_signed::<Empty>(API::Futures(Futures::AllOpenOrders), Some(request))
653            .map(|_| ())
654    }
655
656    pub fn get_all_open_orders<S>(&self, symbol: S) -> Result<Vec<crate::futures::model::Order>>
657    where
658        S: Into<String>,
659    {
660        let mut parameters: BTreeMap<String, String> = BTreeMap::new();
661        parameters.insert("symbol".into(), symbol.into());
662        let request = build_signed_request(parameters, self.recv_window)?;
663        self.client
664            .get_signed(API::Futures(Futures::OpenOrders), Some(request))
665    }
666
667    pub fn get_income(
668        &self, income_request: IncomeRequest,
669    ) -> Result<Vec<crate::futures::model::Income>> {
670        let mut parameters: BTreeMap<String, String> = BTreeMap::new();
671        if let Some(symbol) = income_request.symbol {
672            parameters.insert("symbol".into(), symbol);
673        }
674        if let Some(income_type) = income_request.income_type {
675            parameters.insert("incomeType".into(), income_type.to_string());
676        }
677        if let Some(start_time) = income_request.start_time {
678            parameters.insert("startTime".into(), start_time.to_string());
679        }
680        if let Some(end_time) = income_request.end_time {
681            parameters.insert("endTime".into(), end_time.to_string());
682        }
683        if let Some(limit) = income_request.limit {
684            parameters.insert("limit".into(), limit.to_string());
685        }
686
687        let request = build_signed_request(parameters, self.recv_window)?;
688        println!("{}", request);
689        self.client
690            .get_signed(API::Futures(Futures::Income), Some(request))
691    }
692}