1use anyhow::Result;
2
3use super::super::commands::{
4 BrokerArgs, CapitalFlowArgs, CompanyExecutiveBackgroundArgs, CompanyExecutivesArgs,
5 CompanyOperationalEfficiencyArgs, CompanyProfileArgs, CorporateActionsBuybacksArgs,
6 CorporateActionsDividendsArgs, CorporateActionsStockSplitsArgs, DailyShortVolumeArgs,
7 DerivativeUnusualArgs, FinancialUnusualArgs, FinancialsEarningsPriceHistoryArgs,
8 FinancialsEarningsPriceMoveArgs, FinancialsRevenueBreakdownArgs, FinancialsStatementsArgs,
9 InsiderHolderListArgs, InsiderTradeListArgs, KlineArgs, OptionExerciseProbabilityArgs,
10 OptionScreenArgs, OptionVolatilityArgs, OrderbookArgs, PlateListArgs, PlateStocksArgs,
11 ProtoJsonArgs, QuoteArgs, ResearchAnalystConsensusArgs, ResearchMorningstarReportArgs,
12 ResearchRatingSummaryArgs, RtArgs, ShareholdersHolderDetailArgs,
13 ShareholdersHoldingChangesArgs, ShareholdersInstitutionalArgs, ShareholdersOverviewArgs,
14 ShortInterestArgs, SnapshotArgs, StaticArgs, StockScreenArgs, SubArgs, TechnicalUnusualArgs,
15 TickerArgs, TopTenBuySellBrokersArgs, ValuationDetailArgs, ValuationPlateStockListArgs,
16 WarrantScreenArgs,
17};
18use crate::cmd;
19use crate::output::OutputFormat;
20
21pub(super) async fn dispatch_quote(
22 gateway: &str,
23 output: OutputFormat,
24 args: QuoteArgs,
25) -> Result<()> {
26 cmd::quote::run(gateway, &args.symbols, output).await
27}
28
29pub(super) async fn dispatch_snapshot(
30 gateway: &str,
31 output: OutputFormat,
32 args: SnapshotArgs,
33) -> Result<()> {
34 cmd::snapshot::run(gateway, &args.symbols, output).await
35}
36
37pub(super) async fn dispatch_sub(gateway: &str, output: OutputFormat, args: SubArgs) -> Result<()> {
38 cmd::sub::run(gateway, &args.symbols, &args.r#type, output).await
39}
40
41pub(super) async fn dispatch_kline(
42 gateway: &str,
43 output: OutputFormat,
44 args: KlineArgs,
45) -> Result<()> {
46 let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
48 anyhow::anyhow!(
49 "kline: 需要 positional <SYMBOL> 或 --symbol/--code/--stock \
50 (如 `futucli kline US.AAPL` 或 `futucli kline --code US.AAPL`)"
51 )
52 })?;
53 cmd::kline::run_with_format(
54 gateway,
55 &symbol,
56 &args.r#type,
57 args.count,
58 args.begin.as_deref(),
59 args.end.as_deref(),
60 output,
61 )
62 .await
63}
64
65pub(super) async fn dispatch_orderbook(
66 gateway: &str,
67 output: OutputFormat,
68 args: OrderbookArgs,
69) -> Result<()> {
70 let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
71 anyhow::anyhow!("orderbook: 需要 positional <SYMBOL> 或 --symbol/--code/--stock")
72 })?;
73 cmd::orderbook::run(gateway, &symbol, args.depth, args.odd_lot, output).await
74}
75
76pub(super) async fn dispatch_ticker(
77 gateway: &str,
78 output: OutputFormat,
79 args: TickerArgs,
80) -> Result<()> {
81 let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
82 anyhow::anyhow!("ticker: 需要 positional <SYMBOL> 或 --symbol/--code/--stock")
83 })?;
84 cmd::ticker::run(gateway, &symbol, args.count, output).await
85}
86
87pub(super) async fn dispatch_rt(gateway: &str, output: OutputFormat, args: RtArgs) -> Result<()> {
88 let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
89 anyhow::anyhow!("rt: 需要 positional <SYMBOL> 或 --symbol/--code/--stock")
90 })?;
91 cmd::rt::run(gateway, &symbol, output).await
92}
93
94pub(super) async fn dispatch_static(
95 gateway: &str,
96 output: OutputFormat,
97 args: StaticArgs,
98) -> Result<()> {
99 cmd::static_info::run(gateway, &args.symbols, output).await
100}
101
102pub(super) async fn dispatch_broker(
103 gateway: &str,
104 output: OutputFormat,
105 args: BrokerArgs,
106) -> Result<()> {
107 let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
108 anyhow::anyhow!("broker: 需要 positional <SYMBOL> 或 --symbol/--code/--stock")
109 })?;
110 cmd::broker::run(gateway, &symbol, output).await
111}
112
113pub(super) async fn dispatch_plate_list(
114 gateway: &str,
115 output: OutputFormat,
116 args: PlateListArgs,
117) -> Result<()> {
118 cmd::plate::list(gateway, &args.market, &args.set, output).await
119}
120
121pub(super) async fn dispatch_plate_stocks(
122 gateway: &str,
123 output: OutputFormat,
124 args: PlateStocksArgs,
125) -> Result<()> {
126 let plate = args
127 .plate
128 .or(args.plate_arg)
129 .ok_or_else(|| anyhow::anyhow!("plate-stocks: 需要位置参数 <PLATE> 或 --plate"))?;
130 cmd::plate::stocks(gateway, &plate, output).await
131}
132
133pub(super) async fn dispatch_option_quote(
134 gateway: &str,
135 output: OutputFormat,
136 args: ProtoJsonArgs,
137) -> Result<()> {
138 cmd::proto_json::run_option_quote(gateway, &args.c2s_json, output).await
139}
140
141pub(super) async fn dispatch_option_strategy(
142 gateway: &str,
143 output: OutputFormat,
144 args: ProtoJsonArgs,
145) -> Result<()> {
146 cmd::proto_json::run_option_strategy(gateway, &args.c2s_json, output).await
147}
148
149pub(super) async fn dispatch_option_strategy_analysis(
150 gateway: &str,
151 output: OutputFormat,
152 args: ProtoJsonArgs,
153) -> Result<()> {
154 cmd::proto_json::run_option_strategy_analysis(gateway, &args.c2s_json, output).await
155}
156
157pub(super) async fn dispatch_option_strategy_spread(
158 gateway: &str,
159 output: OutputFormat,
160 args: ProtoJsonArgs,
161) -> Result<()> {
162 cmd::proto_json::run_option_strategy_spread(gateway, &args.c2s_json, output).await
163}
164
165pub(super) async fn dispatch_capital_flow(
166 gateway: &str,
167 output: OutputFormat,
168 args: CapitalFlowArgs,
169) -> Result<()> {
170 cmd::analysis::run_capital_flow(
171 gateway,
172 &args.symbol,
173 args.period_type,
174 args.begin.as_deref(),
175 args.end.as_deref(),
176 output,
177 )
178 .await
179}
180
181pub(super) async fn dispatch_company_profile(
182 gateway: &str,
183 output: OutputFormat,
184 args: CompanyProfileArgs,
185) -> Result<()> {
186 cmd::analysis::run_company_profile(gateway, &args.symbol, output).await
187}
188
189pub(super) async fn dispatch_company_executives(
190 gateway: &str,
191 output: OutputFormat,
192 args: CompanyExecutivesArgs,
193) -> Result<()> {
194 cmd::analysis::run_company_executives(gateway, &args.symbol, output).await
195}
196
197pub(super) async fn dispatch_company_executive_background(
198 gateway: &str,
199 output: OutputFormat,
200 args: CompanyExecutiveBackgroundArgs,
201) -> Result<()> {
202 cmd::analysis::run_company_executive_background(
203 gateway,
204 &args.symbol,
205 &args.leader_name,
206 output,
207 )
208 .await
209}
210
211pub(super) async fn dispatch_company_operational_efficiency(
212 gateway: &str,
213 output: OutputFormat,
214 args: CompanyOperationalEfficiencyArgs,
215) -> Result<()> {
216 cmd::analysis::run_company_operational_efficiency(
217 gateway,
218 &args.symbol,
219 args.next_key.as_deref(),
220 args.num,
221 args.currency_code.as_deref(),
222 args.financial_type,
223 output,
224 )
225 .await
226}
227
228pub(super) async fn dispatch_financials_earnings_price_move(
229 gateway: &str,
230 output: OutputFormat,
231 args: FinancialsEarningsPriceMoveArgs,
232) -> Result<()> {
233 cmd::analysis::run_financials_earnings_price_move(
234 gateway,
235 &args.symbol,
236 args.period_count,
237 output,
238 )
239 .await
240}
241
242pub(super) async fn dispatch_financials_earnings_price_history(
243 gateway: &str,
244 output: OutputFormat,
245 args: FinancialsEarningsPriceHistoryArgs,
246) -> Result<()> {
247 cmd::analysis::run_financials_earnings_price_history(gateway, &args.symbol, output).await
248}
249
250pub(super) async fn dispatch_financials_statements(
251 gateway: &str,
252 output: OutputFormat,
253 args: FinancialsStatementsArgs,
254) -> Result<()> {
255 cmd::analysis::run_financials_statements(
256 gateway,
257 &args.symbol,
258 args.statement_type,
259 args.financial_type,
260 args.currency_code.as_deref(),
261 args.next_key.as_deref(),
262 args.num,
263 output,
264 )
265 .await
266}
267
268pub(super) async fn dispatch_financials_revenue_breakdown(
269 gateway: &str,
270 output: OutputFormat,
271 args: FinancialsRevenueBreakdownArgs,
272) -> Result<()> {
273 cmd::analysis::run_financials_revenue_breakdown(
274 gateway,
275 &args.symbol,
276 args.date,
277 args.financial_type,
278 args.currency_code.as_deref(),
279 output,
280 )
281 .await
282}
283
284pub(super) async fn dispatch_research_analyst_consensus(
285 gateway: &str,
286 output: OutputFormat,
287 args: ResearchAnalystConsensusArgs,
288) -> Result<()> {
289 cmd::analysis::run_research_analyst_consensus(gateway, &args.symbol, output).await
290}
291
292pub(super) async fn dispatch_research_rating_summary(
293 gateway: &str,
294 output: OutputFormat,
295 args: ResearchRatingSummaryArgs,
296) -> Result<()> {
297 cmd::analysis::run_research_rating_summary(
298 gateway,
299 &args.symbol,
300 args.rating_dimension_type,
301 args.uid.as_deref(),
302 args.next_key.as_deref(),
303 args.num,
304 output,
305 )
306 .await
307}
308
309pub(super) async fn dispatch_research_morningstar_report(
310 gateway: &str,
311 output: OutputFormat,
312 args: ResearchMorningstarReportArgs,
313) -> Result<()> {
314 cmd::analysis::run_research_morningstar_report(gateway, &args.symbol, output).await
315}
316
317pub(super) async fn dispatch_valuation_detail(
318 gateway: &str,
319 output: OutputFormat,
320 args: ValuationDetailArgs,
321) -> Result<()> {
322 cmd::analysis::run_valuation_detail(
323 gateway,
324 &args.symbol,
325 args.valuation_type,
326 args.interval_type,
327 output,
328 )
329 .await
330}
331
332pub(super) async fn dispatch_valuation_plate_stock_list(
333 gateway: &str,
334 output: OutputFormat,
335 args: ValuationPlateStockListArgs,
336) -> Result<()> {
337 cmd::analysis::run_valuation_plate_stock_list(
338 gateway,
339 &args.symbol,
340 args.valuation_type,
341 args.next_key.as_deref(),
342 args.num,
343 args.sort_type,
344 args.sort_id,
345 args.filter_security.as_deref(),
346 output,
347 )
348 .await
349}
350
351pub(super) async fn dispatch_stock_screen(
352 gateway: &str,
353 output: OutputFormat,
354 args: StockScreenArgs,
355) -> Result<()> {
356 cmd::analysis::run_stock_screen(gateway, &args.c2s_json, output).await
357}
358
359pub(super) async fn dispatch_option_screen(
360 gateway: &str,
361 output: OutputFormat,
362 args: OptionScreenArgs,
363) -> Result<()> {
364 cmd::analysis::run_option_screen(gateway, &args.c2s_json, output).await
365}
366
367pub(super) async fn dispatch_warrant_screen(
368 gateway: &str,
369 output: OutputFormat,
370 args: WarrantScreenArgs,
371) -> Result<()> {
372 cmd::analysis::run_warrant_screen(gateway, &args.c2s_json, output).await
373}
374
375pub(super) async fn dispatch_technical_unusual(
376 gateway: &str,
377 output: OutputFormat,
378 args: TechnicalUnusualArgs,
379) -> Result<()> {
380 cmd::analysis::run_technical_unusual(
381 gateway,
382 &args.stock_symbol,
383 args.time_range,
384 args.indicator_filters,
385 args.language_id,
386 output,
387 )
388 .await
389}
390
391pub(super) async fn dispatch_financial_unusual(
392 gateway: &str,
393 output: OutputFormat,
394 args: FinancialUnusualArgs,
395) -> Result<()> {
396 cmd::analysis::run_financial_unusual(
397 gateway,
398 &args.stock_symbol,
399 args.time_range,
400 args.analysis_dimensions,
401 args.language_id,
402 output,
403 )
404 .await
405}
406
407pub(super) async fn dispatch_derivative_unusual(
408 gateway: &str,
409 output: OutputFormat,
410 args: DerivativeUnusualArgs,
411) -> Result<()> {
412 cmd::analysis::run_derivative_unusual(
413 gateway,
414 &args.stock_symbol,
415 args.time_range,
416 args.analysis_dimensions,
417 args.language_id,
418 output,
419 )
420 .await
421}
422
423pub(super) async fn dispatch_corporate_actions_buybacks(
424 gateway: &str,
425 output: OutputFormat,
426 args: CorporateActionsBuybacksArgs,
427) -> Result<()> {
428 cmd::analysis::run_corporate_actions_buybacks(
429 gateway,
430 &args.symbol,
431 args.next_key.as_deref(),
432 args.num,
433 output,
434 )
435 .await
436}
437
438pub(super) async fn dispatch_corporate_actions_dividends(
439 gateway: &str,
440 output: OutputFormat,
441 args: CorporateActionsDividendsArgs,
442) -> Result<()> {
443 cmd::analysis::run_corporate_actions_dividends(gateway, &args.symbol, output).await
444}
445
446pub(super) async fn dispatch_corporate_actions_stock_splits(
447 gateway: &str,
448 output: OutputFormat,
449 args: CorporateActionsStockSplitsArgs,
450) -> Result<()> {
451 cmd::analysis::run_corporate_actions_stock_splits(
452 gateway,
453 &args.symbol,
454 args.next_key.as_deref(),
455 args.num,
456 output,
457 )
458 .await
459}
460
461pub(super) async fn dispatch_daily_short_volume(
462 gateway: &str,
463 output: OutputFormat,
464 args: DailyShortVolumeArgs,
465) -> Result<()> {
466 cmd::analysis::run_daily_short_volume(
467 gateway,
468 &args.symbol,
469 args.next_key.as_deref(),
470 args.num,
471 output,
472 )
473 .await
474}
475
476pub(super) async fn dispatch_short_interest(
477 gateway: &str,
478 output: OutputFormat,
479 args: ShortInterestArgs,
480) -> Result<()> {
481 cmd::analysis::run_short_interest(
482 gateway,
483 &args.symbol,
484 args.next_key.as_deref(),
485 args.num,
486 output,
487 )
488 .await
489}
490
491pub(super) async fn dispatch_top_ten_buy_sell_brokers(
492 gateway: &str,
493 output: OutputFormat,
494 args: TopTenBuySellBrokersArgs,
495) -> Result<()> {
496 cmd::analysis::run_top_ten_buy_sell_brokers(gateway, &args.symbol, args.days_before, output)
497 .await
498}
499
500pub(super) async fn dispatch_shareholders_overview(
501 gateway: &str,
502 output: OutputFormat,
503 args: ShareholdersOverviewArgs,
504) -> Result<()> {
505 cmd::analysis::run_shareholders_overview(gateway, &args.symbol, args.period_id, output).await
506}
507
508pub(super) async fn dispatch_shareholders_holding_changes(
509 gateway: &str,
510 output: OutputFormat,
511 args: ShareholdersHoldingChangesArgs,
512) -> Result<()> {
513 cmd::analysis::run_shareholders_holding_changes(
514 cmd::analysis::ShareholdersHoldingChangesCommand {
515 gateway,
516 symbol: &args.symbol,
517 next_key: args.next_key,
518 num: args.num,
519 sort_type: args.sort_type,
520 sort_column: args.sort_column,
521 filter_type: args.filter_type,
522 format: output,
523 },
524 )
525 .await
526}
527
528pub(super) async fn dispatch_shareholders_holder_detail(
529 gateway: &str,
530 output: OutputFormat,
531 args: ShareholdersHolderDetailArgs,
532) -> Result<()> {
533 cmd::analysis::run_shareholders_holder_detail(cmd::analysis::ShareholdersHolderDetailCommand {
534 gateway,
535 symbol: &args.symbol,
536 request_type: args.request_type,
537 next_key: args.next_key,
538 num: args.num,
539 sort_column: args.sort_column,
540 sort_type: args.sort_type,
541 period_id: args.period_id,
542 holder_id: args.holder_id,
543 format: output,
544 })
545 .await
546}
547
548pub(super) async fn dispatch_shareholders_institutional(
549 gateway: &str,
550 output: OutputFormat,
551 args: ShareholdersInstitutionalArgs,
552) -> Result<()> {
553 cmd::analysis::run_shareholders_institutional(
554 gateway,
555 &args.symbol,
556 args.next_key,
557 args.num,
558 output,
559 )
560 .await
561}
562
563pub(super) async fn dispatch_insider_holder_list(
564 gateway: &str,
565 output: OutputFormat,
566 args: InsiderHolderListArgs,
567) -> Result<()> {
568 cmd::analysis::run_insider_holder_list(gateway, &args.symbol, args.next_key, args.num, output)
569 .await
570}
571
572pub(super) async fn dispatch_insider_trade_list(
573 gateway: &str,
574 output: OutputFormat,
575 args: InsiderTradeListArgs,
576) -> Result<()> {
577 cmd::analysis::run_insider_trade_list(
578 gateway,
579 &args.symbol,
580 args.holder_id,
581 args.next_key,
582 args.num,
583 output,
584 )
585 .await
586}
587
588pub(super) async fn dispatch_option_volatility(
589 gateway: &str,
590 output: OutputFormat,
591 args: OptionVolatilityArgs,
592) -> Result<()> {
593 cmd::analysis::run_option_volatility(
594 gateway,
595 &args.symbol,
596 args.query_time_period,
597 args.hv_time_period,
598 output,
599 )
600 .await
601}
602
603pub(super) async fn dispatch_option_exercise_probability(
604 gateway: &str,
605 output: OutputFormat,
606 args: OptionExerciseProbabilityArgs,
607) -> Result<()> {
608 cmd::analysis::run_option_exercise_probability(gateway, &args.symbol, output).await
609}