futu_backend/trade_query/
crypto_account.rs1use futu_core::error::{FutuError, Result};
2use futu_domain_trade_account::crypto_account_currency_label_like_cpp;
3
4use super::*;
5
6use crate::crypto_trade::{
7 CryptoAccountContext, lookup_crypto_account_context, lookup_crypto_read_account_context,
8};
9
10mod cache;
11mod command;
12mod status;
13use cache::cache_cmd20631_crypto_account_info;
14use command::request_cmd20631_crypto_account_info;
15use status::ensure_cmd20631_crypto_account_info_status;
16
17const FTAPI_CURRENCY_HKD: i32 = 1;
18
19pub async fn query_crypto_account_info(
26 backend: &BackendConn,
27 acc_id: u64,
28 trd_cache: &TrdCache,
29 requested_currency: Option<i32>,
30) -> Result<()> {
31 ensure_crypto_currency_supported(requested_currency)?;
32 let ctx = lookup_crypto_account_context(trd_cache, acc_id)?;
33 query_crypto_account_info_with_context(backend, acc_id, trd_cache, requested_currency, &ctx)
34 .await
35}
36
37pub async fn query_crypto_account_info_for_startup(
40 backend: &BackendConn,
41 acc_id: u64,
42 trd_cache: &TrdCache,
43 currency: i32,
44) -> Result<()> {
45 ensure_crypto_currency_supported(Some(currency))?;
46 let ctx = lookup_crypto_read_account_context(trd_cache, acc_id)?;
47 query_crypto_account_info_with_context(backend, acc_id, trd_cache, Some(currency), &ctx).await
48}
49
50pub async fn query_crypto_position_account_info(
56 backend: &BackendConn,
57 acc_id: u64,
58 trd_cache: &TrdCache,
59 requested_currency: Option<i32>,
60) -> Result<()> {
61 ensure_crypto_currency_supported(requested_currency)?;
62 let ctx = lookup_crypto_account_context(trd_cache, acc_id)?;
63 query_crypto_account_info_with_context(backend, acc_id, trd_cache, requested_currency, &ctx)
64 .await
65}
66
67async fn query_crypto_account_info_with_context(
68 backend: &BackendConn,
69 acc_id: u64,
70 trd_cache: &TrdCache,
71 requested_currency: Option<i32>,
72 ctx: &CryptoAccountContext,
73) -> Result<()> {
74 let effective_currency = requested_currency.unwrap_or(FTAPI_CURRENCY_HKD);
75 let Some(currency_label) = crypto_account_currency_label_like_cpp(effective_currency) else {
76 return Err(FutuError::ServerError {
77 ret_type: -1,
78 msg: format!("Crypto account info: unsupported currency id {effective_currency}"),
79 });
80 };
81 let req = asset_pl::AccountInfoReq {
82 msg_header: Some(ctx.build_asset_msg_header("account_info")),
83 union_currency: Some(currency_label.to_string()),
84 without_zero_quantity_pstn: None,
85 };
86 let parsed = request_cmd20631_crypto_account_info(backend, acc_id, req).await?;
87 ensure_cmd20631_crypto_account_info_status(&parsed, acc_id)?;
88
89 cache_cmd20631_crypto_account_info(
90 trd_cache,
91 acc_id,
92 requested_currency,
93 currency_label,
94 &parsed,
95 );
96 Ok(())
97}
98
99fn ensure_crypto_currency_supported(requested_currency: Option<i32>) -> Result<()> {
100 let effective_currency = requested_currency.unwrap_or(FTAPI_CURRENCY_HKD);
101 if crypto_account_currency_label_like_cpp(effective_currency).is_some() {
102 return Ok(());
103 }
104 Err(FutuError::ServerError {
105 ret_type: -1,
106 msg: format!("Crypto account info: unsupported currency id {effective_currency}"),
107 })
108}
109
110#[cfg(test)]
111mod tests;