futu_core/qot_right_gate/
read.rs1use crate::diagnostic_text::jp_stock_quote_permission_hint;
2use crate::diagnostic_text::{DiagnosticTextKey, DiagnosticTextSpec, MessageArgs};
3
4use super::common::{
5 qot_permission_action, qot_right_denies_realtime, qot_right_is_none, us_future_right_for_mkt,
6};
7use super::constants::{QOT_RIGHT_BMP, QOT_RIGHT_LEVEL1, QOT_RIGHT_NO};
8use super::model::{QotRightSnapshot, SecurityRightClass};
9
10const QOT_MARKET_EVENT_CONTRACT: i32 = 101;
11const QOT_MARKET_JP_SECURITY: i32 = 41;
12const SECURITY_TYPE_EQTY: i32 = 3;
13const REPRESENTATIVE_JP_CASH_TSE_MKT_ID: u32 = 830;
14
15pub fn us_index_no_right_unsupported_diagnostic(
25 endpoint: &'static str,
26 market: i32,
27 code: &str,
28 security: SecurityRightClass,
29 rights: &QotRightSnapshot,
30) -> Option<DiagnosticTextSpec> {
31 (market == 11 && security.is_index() && rights.us_index_qot_right == QOT_RIGHT_NO).then(|| {
32 DiagnosticTextSpec::new(
33 DiagnosticTextKey::QotUsIndexUnsupported,
34 MessageArgs::new()
35 .with("endpoint", endpoint)
36 .with("code", code),
37 )
38 })
39}
40
41pub fn qot_read_right_reject_reason(
42 market: i32,
43 code: &str,
44 security: SecurityRightClass,
45 rights: &QotRightSnapshot,
46) -> Option<String> {
47 if market == QOT_MARKET_EVENT_CONTRACT && rights.event_contract_qot_right == QOT_RIGHT_NO {
56 return Some(format!(
57 "EventContract 行情权限不足,不能获取 {code};\
58 请检查 EventContract quote permissions。"
59 ));
60 }
61
62 if security.is_us_security(market) {
63 if security.is_index() && qot_right_denies_realtime(rights.us_index_qot_right) {
64 return Some(format!(
65 "US index 行情权限不足,不能获取 {code};{}",
66 qot_permission_action(Some("US"), code)
67 ));
68 }
69 if security.is_us_otc() && qot_right_denies_realtime(rights.us_otc_qot_right) {
70 return Some(format!(
71 "US OTC 行情权限不足,不能获取 {code};{}",
72 qot_permission_action(Some("US"), code)
73 ));
74 }
75 if qot_right_denies_realtime(rights.us_qot_right) {
76 return Some(format!(
77 "US 行情权限不足,不能获取 {code};{}",
78 qot_permission_action(Some("US"), code)
79 ));
80 }
81 } else if market == 11 && security.is_option() {
82 if rights.us_option_qot_right == QOT_RIGHT_BMP {
83 return Some(format!(
84 "US option 行情权限不足,不能获取 {code};{}",
85 qot_permission_action(Some("US"), code)
86 ));
87 }
88 } else if security.is_future(market) && (60..=109).contains(&security.mkt_id) {
89 if us_future_right_for_mkt(rights, security.mkt_id) == QOT_RIGHT_BMP {
90 return Some(format!(
91 "US future 行情权限不足,不能获取 {code};{}",
92 qot_permission_action(Some("US"), code)
93 ));
94 }
95 } else if security.is_sh_market(market) {
96 if rights.sh_qot_right == QOT_RIGHT_BMP {
97 return Some(format!(
98 "SH 行情权限不足,不能获取 {code};{}",
99 qot_permission_action(Some("SH"), code)
100 ));
101 }
102 } else if security.is_sz_market(market) {
103 if rights.sz_qot_right == QOT_RIGHT_BMP {
104 return Some(format!(
105 "SZ 行情权限不足,不能获取 {code};{}",
106 qot_permission_action(Some("SZ"), code)
107 ));
108 }
109 } else if security.is_sg_future() {
110 if rights.sg_future_qot_right == QOT_RIGHT_BMP {
111 return Some(format!(
112 "SG future 行情权限不足,不能获取 {code};{}",
113 qot_permission_action(Some("SG"), code)
114 ));
115 }
116 } else if security.is_jp_future() {
117 if rights.jp_future_qot_right == QOT_RIGHT_BMP {
118 return Some(format!(
119 "JP future 行情权限不足,不能获取 {code};{}",
120 qot_permission_action(Some("JP"), code)
121 ));
122 }
123 } else if security.is_sg_security_market(market) {
124 if qot_right_is_none(rights.sg_stock_qot_right) {
125 return Some(format!(
126 "SG stock 行情权限不足,不能获取 {code};{}",
127 qot_permission_action(Some("SG"), code)
128 ));
129 }
130 } else if security.is_my_security_market(market) {
131 if qot_right_is_none(rights.my_stock_qot_right) {
132 return Some(format!(
133 "MY stock 行情权限不足,不能获取 {code};{}",
134 qot_permission_action(Some("MY"), code)
135 ));
136 }
137 } else if security.is_jp_security_market(market) {
138 if qot_right_is_none(rights.jp_stock_qot_right) {
139 return Some(format!(
140 "JP stock / 日股行情权限不足,不能获取 {code};{}",
141 jp_stock_quote_permission_hint().text_with_code()
142 ));
143 }
144 } else if security.is_crypto(market) && rights.cc_qot_right != QOT_RIGHT_LEVEL1 {
145 return Some(format!(
146 "Crypto 行情权限不足,不能获取 {code};\
147 请检查 Crypto MarketCrypto quote permissions;{}。",
148 qot_permission_action(Some("Crypto"), code)
149 ));
150 }
151
152 None
153}
154
155pub fn qot_read_right_reject_reason_for_jp_stock_without_static(
156 market: i32,
157 code: &str,
158 rights: &QotRightSnapshot,
159) -> Option<String> {
160 if market != QOT_MARKET_JP_SECURITY {
161 return None;
162 }
163
164 qot_read_right_reject_reason(
171 market,
172 code,
173 SecurityRightClass {
174 sec_type: SECURITY_TYPE_EQTY,
175 mkt_id: REPRESENTATIVE_JP_CASH_TSE_MKT_ID,
176 option_code_like: false,
177 },
178 rights,
179 )
180}