Skip to main content

futucli/cli/dispatch/
qot.rs

1use anyhow::Result;
2
3use super::super::commands::{
4    BrokerArgs, CapitalFlowArgs, CompanyExecutiveBackgroundArgs, CompanyExecutivesArgs,
5    CompanyOperationalEfficiencyArgs, CompanyProfileArgs, CorporateActionsBuybacksArgs,
6    CorporateActionsDividendsArgs, CorporateActionsStockSplitsArgs, DailyShortVolumeArgs,
7    DerivativeUnusualArgs, FinancialCalendarArgs, FinancialCalendarTargetArgs,
8    FinancialUnusualArgs, FinancialsEarningsPriceHistoryArgs, FinancialsEarningsPriceMoveArgs,
9    FinancialsRevenueBreakdownArgs, FinancialsStatementsArgs, IndicatorListArgs,
10    InsiderHolderListArgs, InsiderTradeListArgs, IpoCalendarArgs, KlineArgs,
11    OptionExerciseProbabilityArgs, OptionScreenArgs, OptionVolatilityArgs, OrderbookArgs,
12    PlateListArgs, PlateStocksArgs, ProtoJsonArgs, QuoteArgs, ReferenceArgs,
13    ResearchAnalystConsensusArgs, ResearchMorningstarReportArgs, ResearchRatingSummaryArgs, RtArgs,
14    ShareholdersHolderDetailArgs, ShareholdersHoldingChangesArgs, ShareholdersInstitutionalArgs,
15    ShareholdersOverviewArgs, ShortInterestArgs, SnapshotArgs, StaticArgs, StockScreenArgs,
16    SubArgs, TechnicalUnusualArgs, TickerArgs, TopTenBuySellBrokersArgs, ValuationDetailArgs,
17    ValuationPlateStockListArgs, WarrantScreenArgs,
18};
19use crate::cmd;
20use crate::output::OutputFormat;
21
22pub(super) async fn dispatch_quote(
23    gateway: &str,
24    output: OutputFormat,
25    args: QuoteArgs,
26) -> Result<()> {
27    cmd::quote::run(gateway, &args.symbols, output).await
28}
29
30pub(super) async fn dispatch_snapshot(
31    gateway: &str,
32    output: OutputFormat,
33    args: SnapshotArgs,
34) -> Result<()> {
35    cmd::snapshot::run(gateway, &args.symbols, output).await
36}
37
38pub(super) async fn dispatch_sub(gateway: &str, output: OutputFormat, args: SubArgs) -> Result<()> {
39    cmd::sub::run(
40        gateway,
41        &args.symbols,
42        &args.r#type,
43        args.extended_time,
44        args.session.as_deref(),
45        args.orderbook_detail,
46        output,
47    )
48    .await
49}
50
51pub(super) async fn dispatch_kline(
52    gateway: &str,
53    output: OutputFormat,
54    args: KlineArgs,
55) -> Result<()> {
56    // v1.4.83 §10: positional 或 --symbol/--code/--stock flag 二选一
57    let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
58        anyhow::anyhow!(
59            "kline: 需要 positional <SYMBOL> 或 --symbol/--code/--stock \
60             (如 `futucli kline US.AAPL` 或 `futucli kline --code US.AAPL`)"
61        )
62    })?;
63    cmd::kline::run_with_format(
64        gateway,
65        &symbol,
66        &args.r#type,
67        args.count,
68        &args.rehab_type,
69        args.page_size,
70        args.next_req_key.as_deref(),
71        args.need_kl_fields_flag,
72        args.extended_time,
73        args.session.as_deref(),
74        args.begin.as_deref(),
75        args.end.as_deref(),
76        output,
77    )
78    .await
79}
80
81pub(super) async fn dispatch_orderbook(
82    gateway: &str,
83    output: OutputFormat,
84    args: OrderbookArgs,
85) -> Result<()> {
86    let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
87        anyhow::anyhow!("orderbook: 需要 positional <SYMBOL> 或 --symbol/--code/--stock")
88    })?;
89    cmd::orderbook::run(gateway, &symbol, args.depth, args.odd_lot, output).await
90}
91
92pub(super) async fn dispatch_ticker(
93    gateway: &str,
94    output: OutputFormat,
95    args: TickerArgs,
96) -> Result<()> {
97    let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
98        anyhow::anyhow!("ticker: 需要 positional <SYMBOL> 或 --symbol/--code/--stock")
99    })?;
100    cmd::ticker::run(gateway, &symbol, args.count, output).await
101}
102
103pub(super) async fn dispatch_rt(gateway: &str, output: OutputFormat, args: RtArgs) -> Result<()> {
104    let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
105        anyhow::anyhow!("rt: 需要 positional <SYMBOL> 或 --symbol/--code/--stock")
106    })?;
107    cmd::rt::run(gateway, &symbol, output).await
108}
109
110pub(super) async fn dispatch_static(
111    gateway: &str,
112    output: OutputFormat,
113    args: StaticArgs,
114) -> Result<()> {
115    cmd::static_info::run(gateway, &args.symbols, output).await
116}
117
118pub(super) async fn dispatch_broker(
119    gateway: &str,
120    output: OutputFormat,
121    args: BrokerArgs,
122) -> Result<()> {
123    let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
124        anyhow::anyhow!("broker: 需要 positional <SYMBOL> 或 --symbol/--code/--stock")
125    })?;
126    cmd::broker::run(gateway, &symbol, output).await
127}
128
129pub(super) async fn dispatch_plate_list(
130    gateway: &str,
131    output: OutputFormat,
132    args: PlateListArgs,
133) -> Result<()> {
134    cmd::plate::list(gateway, &args.market, &args.set, output).await
135}
136
137pub(super) async fn dispatch_plate_stocks(
138    gateway: &str,
139    output: OutputFormat,
140    args: PlateStocksArgs,
141) -> Result<()> {
142    let plate = args
143        .plate
144        .or(args.plate_arg)
145        .ok_or_else(|| anyhow::anyhow!("plate-stocks: 需要位置参数 <PLATE> 或 --plate"))?;
146    cmd::plate::stocks(gateway, &plate, output).await
147}
148
149pub(super) async fn dispatch_reference(
150    gateway: &str,
151    output: OutputFormat,
152    args: ReferenceArgs,
153) -> Result<()> {
154    let symbol = args.symbol_positional.or(args.symbol_arg).ok_or_else(|| {
155        anyhow::anyhow!("reference: 需要位置参数 <SYMBOL> 或 --symbol/--code/--stock")
156    })?;
157    cmd::analysis::run_reference(gateway, &symbol, &args.reference_type, output).await
158}
159
160pub(super) async fn dispatch_option_quote(
161    gateway: &str,
162    output: OutputFormat,
163    args: ProtoJsonArgs,
164) -> Result<()> {
165    cmd::proto_json::run_option_quote(gateway, &args.c2s_json, output).await
166}
167
168pub(super) async fn dispatch_option_strategy(
169    gateway: &str,
170    output: OutputFormat,
171    args: ProtoJsonArgs,
172) -> Result<()> {
173    cmd::proto_json::run_option_strategy(gateway, &args.c2s_json, output).await
174}
175
176pub(super) async fn dispatch_option_strategy_analysis(
177    gateway: &str,
178    output: OutputFormat,
179    args: ProtoJsonArgs,
180) -> Result<()> {
181    cmd::proto_json::run_option_strategy_analysis(gateway, &args.c2s_json, output).await
182}
183
184pub(super) async fn dispatch_option_strategy_spread(
185    gateway: &str,
186    output: OutputFormat,
187    args: ProtoJsonArgs,
188) -> Result<()> {
189    cmd::proto_json::run_option_strategy_spread(gateway, &args.c2s_json, output).await
190}
191
192macro_rules! qot_proto_json_dispatch {
193    ($fn_name:ident, $runner:ident) => {
194        pub(super) async fn $fn_name(
195            gateway: &str,
196            output: OutputFormat,
197            args: ProtoJsonArgs,
198        ) -> Result<()> {
199            cmd::proto_json::$runner(gateway, &args.c2s_json, output).await
200        }
201    };
202}
203
204qot_proto_json_dispatch!(dispatch_earnings_calendar, run_earnings_calendar);
205qot_proto_json_dispatch!(dispatch_macro_indicator_list, run_macro_indicator_list);
206
207pub(super) async fn dispatch_indicator_list(
208    gateway: &str,
209    output: OutputFormat,
210    args: IndicatorListArgs,
211) -> Result<()> {
212    cmd::proto_json::run_indicator_list(gateway, &args.c2s_json, output).await
213}
214
215qot_proto_json_dispatch!(
216    dispatch_macro_indicator_history,
217    run_macro_indicator_history
218);
219qot_proto_json_dispatch!(dispatch_fed_watch_target_rate, run_fed_watch_target_rate);
220qot_proto_json_dispatch!(dispatch_fed_watch_dot_plot, run_fed_watch_dot_plot);
221qot_proto_json_dispatch!(dispatch_earnings_beat_rank, run_earnings_beat_rank);
222qot_proto_json_dispatch!(dispatch_dividend_rank, run_dividend_rank);
223qot_proto_json_dispatch!(dispatch_dividend_calendar, run_dividend_calendar);
224qot_proto_json_dispatch!(dispatch_economic_calendar, run_economic_calendar);
225qot_proto_json_dispatch!(dispatch_us_pre_market_rank, run_us_pre_market_rank);
226qot_proto_json_dispatch!(dispatch_us_after_hours_rank, run_us_after_hours_rank);
227qot_proto_json_dispatch!(dispatch_us_overnight_rank, run_us_overnight_rank);
228qot_proto_json_dispatch!(dispatch_top_movers_rank, run_top_movers_rank);
229qot_proto_json_dispatch!(dispatch_hot_list, run_hot_list);
230qot_proto_json_dispatch!(dispatch_short_selling_rank, run_short_selling_rank);
231qot_proto_json_dispatch!(dispatch_period_change_rank, run_period_change_rank);
232qot_proto_json_dispatch!(dispatch_high_dividend_soe_rank, run_high_dividend_soe_rank);
233qot_proto_json_dispatch!(dispatch_institution_list, run_institution_list);
234qot_proto_json_dispatch!(dispatch_institution_profile, run_institution_profile);
235qot_proto_json_dispatch!(
236    dispatch_institution_distribution,
237    run_institution_distribution
238);
239qot_proto_json_dispatch!(
240    dispatch_institution_holding_change,
241    run_institution_holding_change
242);
243qot_proto_json_dispatch!(
244    dispatch_institution_holding_list,
245    run_institution_holding_list
246);
247qot_proto_json_dispatch!(dispatch_ark_fund_holding, run_ark_fund_holding);
248qot_proto_json_dispatch!(dispatch_ark_stock_dynamic, run_ark_stock_dynamic);
249qot_proto_json_dispatch!(dispatch_ark_active_transaction, run_ark_active_transaction);
250qot_proto_json_dispatch!(dispatch_rating_change, run_rating_change);
251qot_proto_json_dispatch!(dispatch_search_quote, run_search_quote);
252qot_proto_json_dispatch!(dispatch_search_news, run_search_news);
253qot_proto_json_dispatch!(
254    dispatch_option_market_statistic,
255    run_option_market_statistic
256);
257qot_proto_json_dispatch!(
258    dispatch_option_underlying_his_statistic,
259    run_option_underlying_his_statistic
260);
261qot_proto_json_dispatch!(
262    dispatch_option_underlying_overview,
263    run_option_underlying_overview
264);
265qot_proto_json_dispatch!(
266    dispatch_option_underlying_his_volatility,
267    run_option_underlying_his_volatility
268);
269qot_proto_json_dispatch!(dispatch_option_underlying_rank, run_option_underlying_rank);
270qot_proto_json_dispatch!(dispatch_option_rank, run_option_rank);
271qot_proto_json_dispatch!(dispatch_option_event, run_option_event);
272qot_proto_json_dispatch!(dispatch_option_event_alert, run_option_event_alert);
273qot_proto_json_dispatch!(dispatch_set_option_event_alert, run_set_option_event_alert);
274qot_proto_json_dispatch!(
275    dispatch_option_zero_dte_screener,
276    run_option_zero_dte_screener
277);
278qot_proto_json_dispatch!(
279    dispatch_option_zero_dte_contract,
280    run_option_zero_dte_contract
281);
282qot_proto_json_dispatch!(
283    dispatch_option_earnings_screener,
284    run_option_earnings_screener
285);
286qot_proto_json_dispatch!(dispatch_option_seller_screener, run_option_seller_screener);
287qot_proto_json_dispatch!(dispatch_industrial_chain_list, run_industrial_chain_list);
288qot_proto_json_dispatch!(
289    dispatch_industrial_chain_detail,
290    run_industrial_chain_detail
291);
292qot_proto_json_dispatch!(
293    dispatch_industrial_chain_by_plate,
294    run_industrial_chain_by_plate
295);
296qot_proto_json_dispatch!(dispatch_industrial_plate_info, run_industrial_plate_info);
297qot_proto_json_dispatch!(dispatch_industrial_plate_stock, run_industrial_plate_stock);
298qot_proto_json_dispatch!(dispatch_heat_map_data, run_heat_map_data);
299qot_proto_json_dispatch!(dispatch_rise_fall_distribution, run_rise_fall_distribution);
300
301pub(super) async fn dispatch_capital_flow(
302    gateway: &str,
303    output: OutputFormat,
304    args: CapitalFlowArgs,
305) -> Result<()> {
306    cmd::analysis::run_capital_flow(
307        gateway,
308        &args.symbol,
309        args.period_type,
310        args.begin.as_deref(),
311        args.end.as_deref(),
312        output,
313    )
314    .await
315}
316
317pub(super) async fn dispatch_company_profile(
318    gateway: &str,
319    output: OutputFormat,
320    args: CompanyProfileArgs,
321) -> Result<()> {
322    cmd::analysis::run_company_profile(gateway, &args.symbol, output).await
323}
324
325pub(super) async fn dispatch_company_executives(
326    gateway: &str,
327    output: OutputFormat,
328    args: CompanyExecutivesArgs,
329) -> Result<()> {
330    cmd::analysis::run_company_executives(gateway, &args.symbol, output).await
331}
332
333pub(super) async fn dispatch_company_executive_background(
334    gateway: &str,
335    output: OutputFormat,
336    args: CompanyExecutiveBackgroundArgs,
337) -> Result<()> {
338    cmd::analysis::run_company_executive_background(
339        gateway,
340        &args.symbol,
341        &args.leader_name,
342        output,
343    )
344    .await
345}
346
347pub(super) async fn dispatch_company_operational_efficiency(
348    gateway: &str,
349    output: OutputFormat,
350    args: CompanyOperationalEfficiencyArgs,
351) -> Result<()> {
352    cmd::analysis::run_company_operational_efficiency(
353        gateway,
354        &args.symbol,
355        args.next_key.as_deref(),
356        args.num,
357        args.currency_code.as_deref(),
358        args.financial_type,
359        output,
360    )
361    .await
362}
363
364pub(super) async fn dispatch_financials_earnings_price_move(
365    gateway: &str,
366    output: OutputFormat,
367    args: FinancialsEarningsPriceMoveArgs,
368) -> Result<()> {
369    cmd::analysis::run_financials_earnings_price_move(
370        gateway,
371        &args.symbol,
372        args.period_count,
373        output,
374    )
375    .await
376}
377
378pub(super) async fn dispatch_financials_earnings_price_history(
379    gateway: &str,
380    output: OutputFormat,
381    args: FinancialsEarningsPriceHistoryArgs,
382) -> Result<()> {
383    cmd::analysis::run_financials_earnings_price_history(gateway, &args.symbol, output).await
384}
385
386pub(super) async fn dispatch_financial_calendar(
387    gateway: &str,
388    output: OutputFormat,
389    args: FinancialCalendarArgs,
390) -> Result<()> {
391    cmd::analysis::run_financial_calendar(
392        gateway,
393        cmd::analysis::FinancialCalendarCommand {
394            begin_date: &args.begin_date,
395            end_date: &args.end_date,
396            markets: &args.markets,
397            pub_types: &args.pub_types,
398            stock_types: &args.stock_types,
399            count: Some(args.count),
400            ranking_type: args.ranking_type,
401            estimate_types: &args.estimate_types,
402            custom_filters: &args.custom_filters,
403            watchlist_only: args.watchlist_only,
404            positions_only: args.positions_only,
405            watchlist_stock_ids: &args.watchlist_stock_ids,
406            holding_stock_ids: &args.holding_stock_ids,
407        },
408        output,
409    )
410    .await
411}
412
413pub(super) async fn dispatch_financial_calendar_target(
414    gateway: &str,
415    output: OutputFormat,
416    args: FinancialCalendarTargetArgs,
417) -> Result<()> {
418    cmd::analysis::run_financial_calendar_target(
419        gateway,
420        cmd::analysis::FinancialCalendarTargetCommand {
421            stock_ids: &args.stock_ids,
422            markets: &args.markets,
423            size: args.size,
424            start: args.start,
425        },
426        output,
427    )
428    .await
429}
430
431pub(super) async fn dispatch_ipo_calendar(
432    gateway: &str,
433    output: OutputFormat,
434    args: IpoCalendarArgs,
435) -> Result<()> {
436    cmd::analysis::run_ipo_calendar(
437        gateway,
438        &args.market,
439        &args.events,
440        args.begin_date.as_deref(),
441        args.end_date.as_deref(),
442        output,
443    )
444    .await
445}
446
447pub(super) async fn dispatch_financials_statements(
448    gateway: &str,
449    output: OutputFormat,
450    args: FinancialsStatementsArgs,
451) -> Result<()> {
452    cmd::analysis::run_financials_statements(
453        gateway,
454        &args.symbol,
455        args.statement_type,
456        args.financial_type,
457        args.currency_code.as_deref(),
458        args.next_key.as_deref(),
459        args.num,
460        output,
461    )
462    .await
463}
464
465pub(super) async fn dispatch_financials_revenue_breakdown(
466    gateway: &str,
467    output: OutputFormat,
468    args: FinancialsRevenueBreakdownArgs,
469) -> Result<()> {
470    cmd::analysis::run_financials_revenue_breakdown(
471        gateway,
472        &args.symbol,
473        args.date,
474        args.financial_type,
475        args.currency_code.as_deref(),
476        output,
477    )
478    .await
479}
480
481pub(super) async fn dispatch_research_analyst_consensus(
482    gateway: &str,
483    output: OutputFormat,
484    args: ResearchAnalystConsensusArgs,
485) -> Result<()> {
486    cmd::analysis::run_research_analyst_consensus(gateway, &args.symbol, output).await
487}
488
489pub(super) async fn dispatch_research_rating_summary(
490    gateway: &str,
491    output: OutputFormat,
492    args: ResearchRatingSummaryArgs,
493) -> Result<()> {
494    cmd::analysis::run_research_rating_summary(
495        gateway,
496        &args.symbol,
497        args.rating_dimension_type,
498        args.uid.as_deref(),
499        args.next_key.as_deref(),
500        args.num,
501        output,
502    )
503    .await
504}
505
506pub(super) async fn dispatch_research_morningstar_report(
507    gateway: &str,
508    output: OutputFormat,
509    args: ResearchMorningstarReportArgs,
510) -> Result<()> {
511    cmd::analysis::run_research_morningstar_report(gateway, &args.symbol, output).await
512}
513
514pub(super) async fn dispatch_valuation_detail(
515    gateway: &str,
516    output: OutputFormat,
517    args: ValuationDetailArgs,
518) -> Result<()> {
519    cmd::analysis::run_valuation_detail(
520        gateway,
521        &args.symbol,
522        args.valuation_type,
523        args.interval_type,
524        output,
525    )
526    .await
527}
528
529pub(super) async fn dispatch_valuation_plate_stock_list(
530    gateway: &str,
531    output: OutputFormat,
532    args: ValuationPlateStockListArgs,
533) -> Result<()> {
534    cmd::analysis::run_valuation_plate_stock_list(
535        gateway,
536        &args.symbol,
537        args.valuation_type,
538        args.next_key.as_deref(),
539        args.num,
540        args.sort_type,
541        args.sort_id,
542        args.filter_security.as_deref(),
543        output,
544    )
545    .await
546}
547
548pub(super) async fn dispatch_stock_screen(
549    gateway: &str,
550    output: OutputFormat,
551    args: StockScreenArgs,
552) -> Result<()> {
553    cmd::analysis::run_stock_screen(gateway, &args.c2s_json, output).await
554}
555
556pub(super) async fn dispatch_option_screen(
557    gateway: &str,
558    output: OutputFormat,
559    args: OptionScreenArgs,
560) -> Result<()> {
561    cmd::analysis::run_option_screen(gateway, &args.c2s_json, output).await
562}
563
564pub(super) async fn dispatch_warrant_screen(
565    gateway: &str,
566    output: OutputFormat,
567    args: WarrantScreenArgs,
568) -> Result<()> {
569    cmd::analysis::run_warrant_screen(gateway, &args.c2s_json, output).await
570}
571
572pub(super) async fn dispatch_technical_unusual(
573    gateway: &str,
574    output: OutputFormat,
575    args: TechnicalUnusualArgs,
576) -> Result<()> {
577    cmd::analysis::run_technical_unusual(
578        gateway,
579        &args.stock_symbol,
580        args.time_range,
581        args.indicator_filters,
582        args.language_id,
583        output,
584    )
585    .await
586}
587
588pub(super) async fn dispatch_financial_unusual(
589    gateway: &str,
590    output: OutputFormat,
591    args: FinancialUnusualArgs,
592) -> Result<()> {
593    cmd::analysis::run_financial_unusual(
594        gateway,
595        &args.stock_symbol,
596        args.time_range,
597        args.analysis_dimensions,
598        args.language_id,
599        output,
600    )
601    .await
602}
603
604pub(super) async fn dispatch_derivative_unusual(
605    gateway: &str,
606    output: OutputFormat,
607    args: DerivativeUnusualArgs,
608) -> Result<()> {
609    cmd::analysis::run_derivative_unusual(
610        gateway,
611        &args.stock_symbol,
612        args.time_range,
613        args.analysis_dimensions,
614        args.language_id,
615        output,
616    )
617    .await
618}
619
620pub(super) async fn dispatch_corporate_actions_buybacks(
621    gateway: &str,
622    output: OutputFormat,
623    args: CorporateActionsBuybacksArgs,
624) -> Result<()> {
625    cmd::analysis::run_corporate_actions_buybacks(
626        gateway,
627        &args.symbol,
628        args.next_key.as_deref(),
629        args.num,
630        output,
631    )
632    .await
633}
634
635pub(super) async fn dispatch_corporate_actions_dividends(
636    gateway: &str,
637    output: OutputFormat,
638    args: CorporateActionsDividendsArgs,
639) -> Result<()> {
640    cmd::analysis::run_corporate_actions_dividends(gateway, &args.symbol, output).await
641}
642
643pub(super) async fn dispatch_corporate_actions_stock_splits(
644    gateway: &str,
645    output: OutputFormat,
646    args: CorporateActionsStockSplitsArgs,
647) -> Result<()> {
648    cmd::analysis::run_corporate_actions_stock_splits(
649        gateway,
650        &args.symbol,
651        args.next_key.as_deref(),
652        args.num,
653        output,
654    )
655    .await
656}
657
658pub(super) async fn dispatch_daily_short_volume(
659    gateway: &str,
660    output: OutputFormat,
661    args: DailyShortVolumeArgs,
662) -> Result<()> {
663    cmd::analysis::run_daily_short_volume(
664        gateway,
665        &args.symbol,
666        args.next_key.as_deref(),
667        args.num,
668        output,
669    )
670    .await
671}
672
673pub(super) async fn dispatch_short_interest(
674    gateway: &str,
675    output: OutputFormat,
676    args: ShortInterestArgs,
677) -> Result<()> {
678    cmd::analysis::run_short_interest(
679        gateway,
680        &args.symbol,
681        args.next_key.as_deref(),
682        args.num,
683        output,
684    )
685    .await
686}
687
688pub(super) async fn dispatch_top_ten_buy_sell_brokers(
689    gateway: &str,
690    output: OutputFormat,
691    args: TopTenBuySellBrokersArgs,
692) -> Result<()> {
693    cmd::analysis::run_top_ten_buy_sell_brokers(gateway, &args.symbol, args.days_before, output)
694        .await
695}
696
697pub(super) async fn dispatch_shareholders_overview(
698    gateway: &str,
699    output: OutputFormat,
700    args: ShareholdersOverviewArgs,
701) -> Result<()> {
702    cmd::analysis::run_shareholders_overview(gateway, &args.symbol, args.period_id, output).await
703}
704
705pub(super) async fn dispatch_shareholders_holding_changes(
706    gateway: &str,
707    output: OutputFormat,
708    args: ShareholdersHoldingChangesArgs,
709) -> Result<()> {
710    cmd::analysis::run_shareholders_holding_changes(
711        cmd::analysis::ShareholdersHoldingChangesCommand {
712            gateway,
713            symbol: &args.symbol,
714            next_key: args.next_key,
715            num: args.num,
716            sort_type: args.sort_type,
717            sort_column: args.sort_column,
718            filter_type: args.filter_type,
719            format: output,
720        },
721    )
722    .await
723}
724
725pub(super) async fn dispatch_shareholders_holder_detail(
726    gateway: &str,
727    output: OutputFormat,
728    args: ShareholdersHolderDetailArgs,
729) -> Result<()> {
730    cmd::analysis::run_shareholders_holder_detail(cmd::analysis::ShareholdersHolderDetailCommand {
731        gateway,
732        symbol: &args.symbol,
733        request_type: args.request_type,
734        next_key: args.next_key,
735        num: args.num,
736        sort_column: args.sort_column,
737        sort_type: args.sort_type,
738        period_id: args.period_id,
739        holder_id: args.holder_id,
740        format: output,
741    })
742    .await
743}
744
745pub(super) async fn dispatch_shareholders_institutional(
746    gateway: &str,
747    output: OutputFormat,
748    args: ShareholdersInstitutionalArgs,
749) -> Result<()> {
750    cmd::analysis::run_shareholders_institutional(
751        gateway,
752        &args.symbol,
753        args.next_key,
754        args.num,
755        output,
756    )
757    .await
758}
759
760pub(super) async fn dispatch_insider_holder_list(
761    gateway: &str,
762    output: OutputFormat,
763    args: InsiderHolderListArgs,
764) -> Result<()> {
765    cmd::analysis::run_insider_holder_list(gateway, &args.symbol, args.next_key, args.num, output)
766        .await
767}
768
769pub(super) async fn dispatch_insider_trade_list(
770    gateway: &str,
771    output: OutputFormat,
772    args: InsiderTradeListArgs,
773) -> Result<()> {
774    cmd::analysis::run_insider_trade_list(
775        gateway,
776        &args.symbol,
777        args.holder_id,
778        args.next_key,
779        args.num,
780        output,
781    )
782    .await
783}
784
785pub(super) async fn dispatch_option_volatility(
786    gateway: &str,
787    output: OutputFormat,
788    args: OptionVolatilityArgs,
789) -> Result<()> {
790    cmd::analysis::run_option_volatility(
791        gateway,
792        &args.symbol,
793        args.query_time_period,
794        args.hv_time_period,
795        output,
796    )
797    .await
798}
799
800pub(super) async fn dispatch_option_exercise_probability(
801    gateway: &str,
802    output: OutputFormat,
803    args: OptionExerciseProbabilityArgs,
804) -> Result<()> {
805    cmd::analysis::run_option_exercise_probability(gateway, &args.symbol, output).await
806}