powerquant-cli 0.2.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. powerquant_cli-0.2.6.dist-info/METADATA +62 -0
  2. powerquant_cli-0.2.6.dist-info/RECORD +355 -0
  3. powerquant_cli-0.2.6.dist-info/WHEEL +4 -0
  4. powerquant_cli-0.2.6.dist-info/entry_points.txt +2 -0
  5. powerquant_cli-0.2.6.dist-info/licenses/LICENSE +36 -0
  6. powerquant_cli-0.2.6.dist-info/licenses/licenses/LICENSE.vnpy +21 -0
  7. pqdata/__init__.py +6 -0
  8. pqdata/client.py +389 -0
  9. pqdata/download.py +60 -0
  10. pqdata/exceptions.py +14 -0
  11. pqdata/schema/__init__.py +1 -0
  12. pqdata/schema/adjustment_schema.py +67 -0
  13. pqdata/schema/bar_content_schema.py +24 -0
  14. pqdata/schema/bar_schema.py +56 -0
  15. pqdata/schema/corporate_action_schema.py +46 -0
  16. pqdata/schema/history_schema.py +61 -0
  17. pqdata/schema/pit_daily_window.py +16 -0
  18. pqdata/schema/query_schema.py +53 -0
  19. pqdata/schema/quote_schema.py +73 -0
  20. pqdata/schema/reference_schema.py +48 -0
  21. pqdata/schema/reliability_schema.py +152 -0
  22. quant_cli/__init__.py +0 -0
  23. quant_cli/api.py +39 -0
  24. quant_cli/app/__init__.py +0 -0
  25. quant_cli/app/backtest/__init__.py +0 -0
  26. quant_cli/app/backtest/cli/__init__.py +0 -0
  27. quant_cli/app/backtest/cli/local_backtest_cli.py +72 -0
  28. quant_cli/app/backtest/local_backtest_dependency.py +10 -0
  29. quant_cli/app/backtest/local_backtest_schema.py +49 -0
  30. quant_cli/app/backtest/repository/__init__.py +0 -0
  31. quant_cli/app/backtest/repository/backtest_local_repository.py +67 -0
  32. quant_cli/app/backtest/service/__init__.py +0 -0
  33. quant_cli/app/backtest/service/local_backtest_service.py +271 -0
  34. quant_cli/app/data/__init__.py +0 -0
  35. quant_cli/app/data/cli/__init__.py +0 -0
  36. quant_cli/app/data/cli/data_cli.py +78 -0
  37. quant_cli/app/data/data_dependency.py +35 -0
  38. quant_cli/app/data/repository/__init__.py +0 -0
  39. quant_cli/app/data/repository/parquet_repository.py +124 -0
  40. quant_cli/app/data/schema/__init__.py +0 -0
  41. quant_cli/app/data/schema/dataset_audit_schema.py +37 -0
  42. quant_cli/app/data/schema/dataset_request_schema.py +28 -0
  43. quant_cli/app/data/schema/parquet_file_schema.py +17 -0
  44. quant_cli/app/data/service/__init__.py +0 -0
  45. quant_cli/app/data/service/bar_cache_service.py +287 -0
  46. quant_cli/app/data/service/dataset_audit_service.py +137 -0
  47. quant_cli/app/data/service/dataset_load_service.py +115 -0
  48. quant_cli/app/data/service/dataset_prepare_service.py +187 -0
  49. quant_cli/app/factor/__init__.py +0 -0
  50. quant_cli/app/factor/cli/__init__.py +0 -0
  51. quant_cli/app/factor/cli/factor_definition_cli.py +81 -0
  52. quant_cli/app/factor/cli/local_factor_cli.py +102 -0
  53. quant_cli/app/factor/cli/local_selection_cli.py +58 -0
  54. quant_cli/app/factor/interface/__init__.py +0 -0
  55. quant_cli/app/factor/interface/local_selection_store.py +12 -0
  56. quant_cli/app/factor/local_factor_dependency.py +38 -0
  57. quant_cli/app/factor/repository/__init__.py +0 -0
  58. quant_cli/app/factor/repository/factor_local_repository.py +154 -0
  59. quant_cli/app/factor/repository/selection_local_repository.py +67 -0
  60. quant_cli/app/factor/schema/local_selection_schema.py +56 -0
  61. quant_cli/app/factor/service/__init__.py +0 -0
  62. quant_cli/app/factor/service/factor_data_prepare_service.py +181 -0
  63. quant_cli/app/factor/service/local_factor_query_service.py +146 -0
  64. quant_cli/app/factor/service/local_factor_service.py +120 -0
  65. quant_cli/app/factor/service/local_selection_service.py +139 -0
  66. quant_cli/app/job/__init__.py +0 -0
  67. quant_cli/app/job/cli/__init__.py +0 -0
  68. quant_cli/app/job/cli/local_job_cli.py +69 -0
  69. quant_cli/app/job/schema/__init__.py +0 -0
  70. quant_cli/app/job/schema/local_job_schema.py +11 -0
  71. quant_cli/app/job/service/__init__.py +0 -0
  72. quant_cli/app/job/service/local_job_service.py +60 -0
  73. quant_cli/app/quant_cli.py +49 -0
  74. quant_cli/app/research/__init__.py +0 -0
  75. quant_cli/app/research/cli/__init__.py +0 -0
  76. quant_cli/app/research/cli/local_research_cli.py +93 -0
  77. quant_cli/app/research/local_research_dependency.py +10 -0
  78. quant_cli/app/research/repository/__init__.py +0 -0
  79. quant_cli/app/research/repository/research_local_repository.py +67 -0
  80. quant_cli/app/research/schema/__init__.py +0 -0
  81. quant_cli/app/research/schema/local_research_schema.py +26 -0
  82. quant_cli/app/research/service/__init__.py +0 -0
  83. quant_cli/app/research/service/local_research_execution_service.py +105 -0
  84. quant_cli/app/research/service/local_research_service.py +101 -0
  85. quant_cli/app/strategy/__init__.py +0 -0
  86. quant_cli/app/strategy/cli/__init__.py +0 -0
  87. quant_cli/app/strategy/cli/strategy_cli.py +104 -0
  88. quant_cli/common/__init__.py +0 -0
  89. quant_cli/common/constants.py +7 -0
  90. quant_cli/common/database/__init__.py +0 -0
  91. quant_cli/common/database/duckdb_connection.py +30 -0
  92. quant_cli/common/http/__init__.py +0 -0
  93. quant_cli/common/http/definition_client.py +54 -0
  94. quant_cli/common/utils/__init__.py +0 -0
  95. quant_cli/common/utils/cli_utils.py +37 -0
  96. quant_cli/common/utils/platform_utils.py +11 -0
  97. quant_cli/common/utils/runtime_environment.py +12 -0
  98. quant_cli/examples/cached_factor_screen.py +165 -0
  99. quant_cli/examples/factors/ma_close_10.py +10 -0
  100. quant_cli/examples/factors/max_drawdown_20d.py +18 -0
  101. quant_cli/examples/factors/momentum_20d.py +13 -0
  102. quant_cli/examples/factors/multi_intraday_screen.py +16 -0
  103. quant_cli/examples/factors/risk_adjusted_momentum_20d.py +18 -0
  104. quant_cli/examples/factors/volume_ratio_5d.py +14 -0
  105. quant_cli/examples/factors/volume_weighted_close_pressure.py +14 -0
  106. quant_cli/examples/full_market_screen.py +189 -0
  107. quant_cli/examples/local_quant_validation.py +196 -0
  108. quant_cli/examples/published_definition_validation.py +219 -0
  109. quant_cli/examples/research/factor_pit_coverage.py +87 -0
  110. quant_cli/examples/research/ipo_first_day.py +348 -0
  111. quant_cli/examples/selection/README.md +59 -0
  112. quant_cli/examples/selection/backtest.json +18 -0
  113. quant_cli/examples/selection/buy_hold.py +7 -0
  114. quant_cli/examples/selection/compute.json +15 -0
  115. quant_cli/examples/selection/prepare.json +13 -0
  116. quant_cli/examples/selection/select.json +44 -0
  117. quant_cli/examples/strategies/bar_roundtrip.py +12 -0
  118. quant_cli/examples/strategies/buy_and_hold.py +11 -0
  119. quant_cli/examples/strategies/contrarian_timing.py +14 -0
  120. quant_cli/examples/strategies/factor_gate_vwap.py +22 -0
  121. quant_cli/examples/strategies/ipo_next_day_vwap.py +31 -0
  122. quant_cli/examples/strategies/momentum_timing.py +14 -0
  123. quant_cli/examples/strategies/monthly_equal_weight.py +19 -0
  124. quant_cli/examples/strategies/session_roundtrip.py +16 -0
  125. quant_cli/examples/strategies/trend_drawdown_guard.py +22 -0
  126. quant_cli/examples/strategies/weekly_risk_adjusted_rotation.py +61 -0
  127. quant_cli/examples/unified_snapshot_validation.py +260 -0
  128. quant_core/__init__.py +0 -0
  129. quant_core/app/SPEC.md +18 -0
  130. quant_core/app/__init__.py +0 -0
  131. quant_core/app/backtest/SPEC.md +65 -0
  132. quant_core/app/backtest/__init__.py +1 -0
  133. quant_core/app/backtest/backtest_input_schema.py +20 -0
  134. quant_core/app/backtest/backtest_run.py +393 -0
  135. quant_core/app/backtest/data_guard.py +77 -0
  136. quant_core/app/backtest/historical_clock.py +26 -0
  137. quant_core/app/backtest/legacy_result_schema.py +34 -0
  138. quant_core/app/backtest/metrics.py +194 -0
  139. quant_core/app/backtest/performance_report.py +61 -0
  140. quant_core/app/backtest/report_schema.py +64 -0
  141. quant_core/app/backtest/schema.py +477 -0
  142. quant_core/app/backtest/service/__init__.py +0 -0
  143. quant_core/app/backtest/service/backtest_execution_service.py +114 -0
  144. quant_core/app/data/__init__.py +0 -0
  145. quant_core/app/data/constants.py +284 -0
  146. quant_core/app/data/domain/__init__.py +0 -0
  147. quant_core/app/data/domain/trading_quantity_value.py +57 -0
  148. quant_core/app/data/exceptions.py +95 -0
  149. quant_core/app/data/interface/__init__.py +0 -0
  150. quant_core/app/data/interface/adjustment_factor_query.py +21 -0
  151. quant_core/app/data/interface/market_data_query.py +71 -0
  152. quant_core/app/data/interface/market_data_verification.py +20 -0
  153. quant_core/app/data/interface/market_event_source.py +11 -0
  154. quant_core/app/data/interface/market_revision_query.py +8 -0
  155. quant_core/app/data/interface/market_runtime_repository.py +44 -0
  156. quant_core/app/data/interface/market_time_slice_source.py +11 -0
  157. quant_core/app/data/repository/__init__.py +0 -0
  158. quant_core/app/data/schema/__init__.py +1 -0
  159. quant_core/app/data/schema/adjustment_schema.py +67 -0
  160. quant_core/app/data/schema/corporate_action_schema.py +46 -0
  161. quant_core/app/data/schema/event_schema.py +506 -0
  162. quant_core/app/data/schema/exchange_operating_state.py +37 -0
  163. quant_core/app/data/schema/exchange_state_schema.py +106 -0
  164. quant_core/app/data/schema/history_schema.py +48 -0
  165. quant_core/app/data/schema/instrument_identity.py +69 -0
  166. quant_core/app/data/schema/market_schema.py +128 -0
  167. quant_core/app/data/schema/pit_daily_window.py +16 -0
  168. quant_core/app/data/schema/quote_schema.py +73 -0
  169. quant_core/app/data/schema/reliability_schema.py +152 -0
  170. quant_core/app/data/schema/snapshot_schema.py +82 -0
  171. quant_core/app/data/schema/trading_state_schema.py +211 -0
  172. quant_core/app/data/service/__init__.py +0 -0
  173. quant_core/app/data/service/calendar_coverage_service.py +63 -0
  174. quant_core/app/data/service/prepared_data_verification_service.py +40 -0
  175. quant_core/app/data/service/prepared_market_service.py +189 -0
  176. quant_core/app/data/service/price_adjustment_service.py +235 -0
  177. quant_core/app/factor/LICENSE.vnpy +21 -0
  178. quant_core/app/factor/__init__.py +13 -0
  179. quant_core/app/factor/builtin/__init__.py +0 -0
  180. quant_core/app/factor/builtin/alpha101_recipe.py +1095 -0
  181. quant_core/app/factor/builtin/alpha158_recipe.py +1284 -0
  182. quant_core/app/factor/builtin/factor_recipe_catalog.py +100 -0
  183. quant_core/app/factor/computation/__init__.py +0 -0
  184. quant_core/app/factor/computation/factor_batch_evaluator.py +141 -0
  185. quant_core/app/factor/computation/factor_expression.py +106 -0
  186. quant_core/app/factor/computation/factor_source_loader.py +24 -0
  187. quant_core/app/factor/computation/operators/__init__.py +0 -0
  188. quant_core/app/factor/computation/operators/arithmetic_operator.py +182 -0
  189. quant_core/app/factor/computation/operators/cross_section_operator.py +66 -0
  190. quant_core/app/factor/computation/operators/time_series_operator.py +342 -0
  191. quant_core/app/factor/computation/panel_evaluator.py +59 -0
  192. quant_core/app/factor/computation/panel_expression.py +193 -0
  193. quant_core/app/factor/computation/python_factor_executor.py +87 -0
  194. quant_core/app/factor/computation/universe_filter.py +25 -0
  195. quant_core/app/factor/constants.py +114 -0
  196. quant_core/app/factor/exceptions.py +35 -0
  197. quant_core/app/factor/factor_dependency.py +65 -0
  198. quant_core/app/factor/interface/__init__.py +0 -0
  199. quant_core/app/factor/interface/factor_compute.py +12 -0
  200. quant_core/app/factor/interface/factor_execution.py +15 -0
  201. quant_core/app/factor/interface/factor_local_data.py +42 -0
  202. quant_core/app/factor/interface/factor_panel_compute.py +18 -0
  203. quant_core/app/factor/interface/factor_panel_input.py +12 -0
  204. quant_core/app/factor/interface/factor_query_store.py +39 -0
  205. quant_core/app/factor/interface/public/__init__.py +0 -0
  206. quant_core/app/factor/interface/public/factor_diagnostics.py +18 -0
  207. quant_core/app/factor/interface/public/factor_exposure_query.py +12 -0
  208. quant_core/app/factor/interface/public/factor_local.py +15 -0
  209. quant_core/app/factor/interface/public/factor_query.py +57 -0
  210. quant_core/app/factor/interface/public/factor_selection.py +20 -0
  211. quant_core/app/factor/model/__init__.py +0 -0
  212. quant_core/app/factor/repository/__init__.py +0 -0
  213. quant_core/app/factor/schema/__init__.py +1 -0
  214. quant_core/app/factor/schema/diagnostic_types.py +42 -0
  215. quant_core/app/factor/schema/factor_artifact_schema.py +36 -0
  216. quant_core/app/factor/schema/factor_computation_schema.py +102 -0
  217. quant_core/app/factor/schema/factor_compute_request.py +24 -0
  218. quant_core/app/factor/schema/factor_contract.py +257 -0
  219. quant_core/app/factor/schema/factor_input_schema.py +32 -0
  220. quant_core/app/factor/schema/factor_panel.py +65 -0
  221. quant_core/app/factor/schema/factor_publication_schema.py +41 -0
  222. quant_core/app/factor/schema/factor_query_result_schema.py +12 -0
  223. quant_core/app/factor/schema/factor_result_schema.py +6 -0
  224. quant_core/app/factor/schema/local_factor_schema.py +42 -0
  225. quant_core/app/factor/schema/panel_policy.py +13 -0
  226. quant_core/app/factor/schema/selection_report.py +116 -0
  227. quant_core/app/factor/schema/selection_types.py +135 -0
  228. quant_core/app/factor/service/__init__.py +1 -0
  229. quant_core/app/factor/service/factor_compute_service.py +140 -0
  230. quant_core/app/factor/service/factor_diagnostic_runner.py +134 -0
  231. quant_core/app/factor/service/factor_diagnostics_service.py +140 -0
  232. quant_core/app/factor/service/factor_exposure_service.py +24 -0
  233. quant_core/app/factor/service/factor_input_service.py +258 -0
  234. quant_core/app/factor/service/factor_local_execution_service.py +51 -0
  235. quant_core/app/factor/service/factor_panel_service.py +86 -0
  236. quant_core/app/factor/service/factor_runtime_service.py +306 -0
  237. quant_core/app/factor/service/factor_selection_runner.py +88 -0
  238. quant_core/app/factor/service/published_factor_execution_service.py +160 -0
  239. quant_core/app/factor/service/selection_service.py +234 -0
  240. quant_core/app/factor/visibility.py +22 -0
  241. quant_core/app/opportunity/SPEC.md +45 -0
  242. quant_core/app/opportunity/__init__.py +1 -0
  243. quant_core/app/order_execution/SPEC.md +64 -0
  244. quant_core/app/order_execution/__init__.py +1 -0
  245. quant_core/app/order_execution/bar_matcher.py +55 -0
  246. quant_core/app/order_execution/constants.py +142 -0
  247. quant_core/app/order_execution/domain/__init__.py +45 -0
  248. quant_core/app/order_execution/domain/execution_batch.py +108 -0
  249. quant_core/app/order_execution/domain/order_entity.py +197 -0
  250. quant_core/app/order_execution/domain/order_event.py +87 -0
  251. quant_core/app/order_execution/domain/order_policy.py +29 -0
  252. quant_core/app/order_execution/domain/order_value.py +142 -0
  253. quant_core/app/order_execution/fee_model.py +60 -0
  254. quant_core/app/order_execution/interface/__init__.py +0 -0
  255. quant_core/app/order_execution/interface/order_account.py +10 -0
  256. quant_core/app/order_execution/interface/order_trading_rules.py +10 -0
  257. quant_core/app/order_execution/interface/public/__init__.py +0 -0
  258. quant_core/app/order_execution/interface/public/execution_account.py +53 -0
  259. quant_core/app/order_execution/interface/public/order_events.py +19 -0
  260. quant_core/app/order_execution/interface/public/order_execution.py +107 -0
  261. quant_core/app/order_execution/interface/public/order_runtime.py +30 -0
  262. quant_core/app/order_execution/interface/public/order_submission.py +17 -0
  263. quant_core/app/order_execution/order_event_bus.py +28 -0
  264. quant_core/app/order_execution/order_execution_dependency.py +48 -0
  265. quant_core/app/order_execution/order_submission_service.py +301 -0
  266. quant_core/app/order_execution/schema/__init__.py +0 -0
  267. quant_core/app/order_execution/schema/order_request_schema.py +88 -0
  268. quant_core/app/order_execution/simulation_broker.py +883 -0
  269. quant_core/app/order_execution/slippage_model.py +40 -0
  270. quant_core/app/order_execution/tradability_policy.py +174 -0
  271. quant_core/app/order_execution/validators.py +40 -0
  272. quant_core/app/portfolio/SPEC.md +69 -0
  273. quant_core/app/portfolio/__init__.py +0 -0
  274. quant_core/app/portfolio/domain/__init__.py +32 -0
  275. quant_core/app/portfolio/domain/entitlement_entity.py +45 -0
  276. quant_core/app/portfolio/domain/portfolio_entity.py +511 -0
  277. quant_core/app/portfolio/domain/portfolio_event.py +59 -0
  278. quant_core/app/portfolio/domain/portfolio_value.py +21 -0
  279. quant_core/app/portfolio/domain/position_entity.py +165 -0
  280. quant_core/app/portfolio/domain/reservation_entity.py +69 -0
  281. quant_core/app/portfolio/interface/__init__.py +0 -0
  282. quant_core/app/portfolio/interface/public/__init__.py +0 -0
  283. quant_core/app/portfolio/interface/public/portfolio.py +77 -0
  284. quant_core/app/portfolio/interface/public/simulation_account.py +16 -0
  285. quant_core/app/portfolio/ledger_schema.py +130 -0
  286. quant_core/app/portfolio/order_account_listener.py +36 -0
  287. quant_core/app/portfolio/portfolio_dependency.py +21 -0
  288. quant_core/app/portfolio/portfolio_schema.py +204 -0
  289. quant_core/app/portfolio/simulated_portfolio.py +427 -0
  290. quant_core/app/research/SPEC.md +57 -0
  291. quant_core/app/research/__init__.py +0 -0
  292. quant_core/app/research/adapter/__init__.py +0 -0
  293. quant_core/app/research/adapter/market_label_query.py +84 -0
  294. quant_core/app/research/interface/__init__.py +0 -0
  295. quant_core/app/research/interface/research_dataset.py +47 -0
  296. quant_core/app/research/interface/research_evaluation.py +19 -0
  297. quant_core/app/research/schema/__init__.py +0 -0
  298. quant_core/app/research/schema/comparison_schema.py +12 -0
  299. quant_core/app/research/schema/dataset_schema.py +112 -0
  300. quant_core/app/research/schema/research_schema.py +120 -0
  301. quant_core/app/research/service/__init__.py +0 -0
  302. quant_core/app/research/service/research_dataset_service.py +80 -0
  303. quant_core/app/research/service/research_evaluation_service.py +56 -0
  304. quant_core/app/research/service/research_service.py +171 -0
  305. quant_core/app/strategy/SPEC.md +215 -0
  306. quant_core/app/strategy/__init__.py +1 -0
  307. quant_core/app/strategy/constants.py +87 -0
  308. quant_core/app/strategy/exceptions.py +32 -0
  309. quant_core/app/strategy/interface/__init__.py +0 -0
  310. quant_core/app/strategy/interface/public/__init__.py +0 -0
  311. quant_core/app/strategy/interface/public/portfolio_construction.py +19 -0
  312. quant_core/app/strategy/interface/public/strategy.py +30 -0
  313. quant_core/app/strategy/interface/public/strategy_market_query.py +53 -0
  314. quant_core/app/strategy/interface/public/strategy_portfolio_reader.py +33 -0
  315. quant_core/app/strategy/interface/strategy_factor_reader.py +19 -0
  316. quant_core/app/strategy/interface/strategy_order_reader.py +14 -0
  317. quant_core/app/strategy/schema/__init__.py +0 -0
  318. quant_core/app/strategy/schema/portfolio_schema.py +28 -0
  319. quant_core/app/strategy/schema/portfolio_target.py +70 -0
  320. quant_core/app/strategy/schema/python_strategy_schema.py +94 -0
  321. quant_core/app/strategy/schema/screener_schema.py +51 -0
  322. quant_core/app/strategy/schema/signal_schema.py +33 -0
  323. quant_core/app/strategy/schema/strategy_publication_schema.py +32 -0
  324. quant_core/app/strategy/schema/strategy_schema.py +96 -0
  325. quant_core/app/strategy/service/__init__.py +0 -0
  326. quant_core/app/strategy/service/factor_top_n_strategy.py +103 -0
  327. quant_core/app/strategy/service/portfolio_construction_service.py +142 -0
  328. quant_core/app/strategy/service/python_strategy_service.py +65 -0
  329. quant_core/app/strategy/service/screener_service.py +77 -0
  330. quant_core/app/strategy/service/store_factor_reader.py +120 -0
  331. quant_core/app/strategy/service/strategy_market_view.py +120 -0
  332. quant_core/app/strategy/service/strategy_runtime_service.py +319 -0
  333. quant_core/app/strategy/service/strategy_scheduler.py +50 -0
  334. quant_core/app/strategy/strategies/__init__.py +7 -0
  335. quant_core/app/strategy/strategies/momentum_volume_breakout.py +157 -0
  336. quant_core/app/strategy/strategy_context.py +316 -0
  337. quant_core/app/strategy/strategy_dependency.py +101 -0
  338. quant_core/app/trading_runtime/SPEC.md +70 -0
  339. quant_core/app/trading_runtime/__init__.py +1 -0
  340. quant_core/app/trading_runtime/domain/__init__.py +0 -0
  341. quant_core/app/trading_runtime/replay/__init__.py +0 -0
  342. quant_core/app/trading_runtime/replay/daily_state_expand.py +49 -0
  343. quant_core/app/trading_runtime/replay/exchange_state_resolver.py +90 -0
  344. quant_core/app/trading_runtime/replay/market_runtime_service.py +573 -0
  345. quant_core/app/trading_runtime/replay/market_state_resolver.py +150 -0
  346. quant_core/app/trading_runtime/runtime_ports.py +64 -0
  347. quant_core/app/trading_runtime/runtime_schema.py +129 -0
  348. quant_core/app/trading_runtime/runtime_session.py +361 -0
  349. quant_core/app/trading_runtime/strategy_portfolio_adapter.py +58 -0
  350. quant_core/app/trading_runtime/trading_rule_book.py +37 -0
  351. quant_core/app/trading_runtime/trading_rule_query.py +12 -0
  352. quant_core/common/__init__.py +0 -0
  353. quant_core/common/exceptions/__init__.py +0 -0
  354. quant_core/common/exceptions/base.py +89 -0
  355. quant_core/common/local_run.py +45 -0
@@ -0,0 +1,284 @@
1
+ """
2
+ Market Domain 常量 - Canonical 枚举
3
+
4
+ 本模块是 Market Domain 全部稳定业务值的唯一定义点。
5
+ 所有枚举只描述「数据是什么」,不描述「怎么存、从谁取、怎么算」。
6
+
7
+ 规则:
8
+ - 枚举存在不代表能力已实现;实现状态见 DATA-DICTIONARY.md 的 Dataset Catalog。
9
+ - 第三方字段、单位、代码格式一律不允许进入本模块,只能在 adapter/mapper 转换。
10
+ """
11
+
12
+ import re
13
+ from enum import Enum
14
+ from typing import Final
15
+
16
+ # ========== 身份与格式 ==========
17
+
18
+ MARKET_CN: Final[str] = "CN"
19
+ """中国市场的 Canonical market 前缀。"""
20
+
21
+ INSTRUMENT_ID_SEPARATOR: Final[str] = "."
22
+ """Canonical Instrument ID 分隔符:{market}.{exchange}.{symbol},如 CN.XSHE.000001。"""
23
+
24
+ CANONICAL_INSTRUMENT_ID_PATTERN: Final[re.Pattern[str]] = re.compile(
25
+ r"^[A-Z]{2}\.[A-Z0-9]+\.[A-Z0-9]+$"
26
+ )
27
+ """Canonical Instrument ID 格式({market}.{exchange}.{symbol})的唯一校验规则。
28
+
29
+ 域内所有需要校验 Canonical 标识的模块统一复用本模式,不允许各自复制正则。
30
+ """
31
+
32
+ CANONICAL_PROVIDER: Final[str] = "powerquant"
33
+ """Canonical 数据自身的来源标识(非第三方同步的数据)。"""
34
+
35
+ PROVIDER_AKSHARE: Final[str] = "akshare"
36
+ """AKShare 的 Provider 标识(Canonical 身份值,非 SDK 概念)。"""
37
+
38
+ PROVIDER_TUSHARE: Final[str] = "tushare"
39
+ """Tushare Pro 的 Provider 标识(Canonical 身份值,非 SDK 概念)。"""
40
+
41
+
42
+ class Exchange(str, Enum):
43
+ """Canonical 交易所枚举(第三方写法 SH/SZ/SSE/SZSE 由 mapper 转换)"""
44
+
45
+ XSHG = "XSHG"
46
+ XSHE = "XSHE"
47
+ BJSE = "BJSE"
48
+
49
+
50
+ class BoardType(str, Enum):
51
+ """A股板块"""
52
+
53
+ MAIN = "main"
54
+ STAR = "star"
55
+ CHINEXT = "chinext"
56
+ BSE = "bse"
57
+
58
+
59
+ class InstrumentType(str, Enum):
60
+ """标的类型。
61
+
62
+ 注意:enum 存在不代表支持对应的交易/研究能力,实现状态见 DATA-DICTIONARY.md。
63
+ """
64
+
65
+ STOCK = "stock"
66
+ ETF = "etf"
67
+ INDEX = "index"
68
+ # reserved:仅为未来扩展保留
69
+ BOND = "bond"
70
+ FUTURE = "future"
71
+ OPTION = "option"
72
+
73
+
74
+ class InstrumentStatus(str, Enum):
75
+ """标的状态"""
76
+
77
+ ACTIVE = "active"
78
+ DELISTED = "delisted"
79
+ SUSPENDED = "suspended"
80
+
81
+
82
+ # ========== 数据集分类 ==========
83
+
84
+
85
+ class MarketDataCategory(str, Enum):
86
+ """数据一级分类(稳定,不绑定供应商习惯)"""
87
+
88
+ REFERENCE = "reference"
89
+ MARKET_DATA = "market_data"
90
+ FUNDAMENTAL = "fundamental"
91
+ CORPORATE_ACTION = "corporate_action"
92
+ CLASSIFICATION = "classification"
93
+ MARKET_STATISTICS = "market_statistics"
94
+ FLOW = "flow"
95
+ ALTERNATIVE = "alternative"
96
+
97
+
98
+ class MarketDatasetType(str, Enum):
99
+ """数据集类型(枚举表示 PowerQuant 认可的数据类别,不代表全部实现)"""
100
+
101
+ INSTRUMENT = "instrument"
102
+ TRADING_CALENDAR = "trading_calendar"
103
+ BAR = "bar"
104
+ ADJUSTMENT_FACTOR = "adjustment_factor"
105
+ QUOTE = "quote"
106
+ DAILY_BASIC = "daily_basic"
107
+ INSTRUMENT_DAILY_FACT = "instrument_daily_fact"
108
+ SECTOR = "sector"
109
+ SECTOR_MEMBERSHIP = "sector_membership"
110
+ MARKET_SNAPSHOT = "market_snapshot"
111
+ # reserved:仅为未来扩展保留
112
+ TICK = "tick"
113
+ CORPORATE_ACTION = "corporate_action"
114
+ INDEX_MEMBERSHIP = "index_membership"
115
+ MONEY_FLOW = "money_flow"
116
+ MARGIN = "margin"
117
+ NEWS = "news"
118
+ ANNOUNCEMENT = "announcement"
119
+
120
+
121
+ class DatasetStatus(str, Enum):
122
+ """数据集实现状态"""
123
+
124
+ IMPLEMENTED = "implemented"
125
+ PLANNED = "planned"
126
+ RESERVED = "reserved"
127
+
128
+
129
+ class MarketDataJobMode(str, Enum):
130
+ """L1 数据作业的用户意图。"""
131
+
132
+ BOOTSTRAP = "bootstrap"
133
+ UPDATE = "update"
134
+ REPAIR = "repair"
135
+
136
+
137
+ class DatasetCheckpointStatus(str, Enum):
138
+ """单个同步分片的持久化状态。"""
139
+
140
+ PENDING = "pending"
141
+ SUCCEEDED = "succeeded"
142
+ FAILED = "failed"
143
+
144
+
145
+ class DatasetScopeType(str, Enum):
146
+ """Checkpoint 作用域类型;粒度由 Provider 接口形态决定。"""
147
+
148
+ MARKET_DATE = "market_date"
149
+ INSTRUMENT = "instrument"
150
+
151
+
152
+ class TemporalType(str, Enum):
153
+ """时间语义"""
154
+
155
+ STATIC = "static"
156
+ SNAPSHOT = "snapshot"
157
+ TIME_SERIES = "time_series"
158
+ INTERVAL = "interval"
159
+ EVENT = "event"
160
+
161
+
162
+ class EntityScope(str, Enum):
163
+ """数据挂载的实体范围"""
164
+
165
+ MARKET = "market"
166
+ EXCHANGE = "exchange"
167
+ INSTRUMENT = "instrument"
168
+ INDEX = "index"
169
+ SECTOR = "sector"
170
+
171
+
172
+ # ========== 行情语义 ==========
173
+
174
+
175
+ class BarFrequency(str, Enum):
176
+ """Canonical Bar 频率(第三方 1min/D/day 等由 mapper 转换)
177
+
178
+ timestamp 语义统一为 Bar 结束时间。
179
+ """
180
+
181
+ M1 = "1m"
182
+ M5 = "5m"
183
+ M15 = "15m"
184
+ M30 = "30m"
185
+ H1 = "1h"
186
+ D1 = "1d"
187
+ W1 = "1w"
188
+
189
+
190
+ class AdjustmentType(str, Enum):
191
+ """复权类型。
192
+
193
+ Bar 只存 Raw OHLCV,不内嵌复权因子;复权因子是独立数据集
194
+ AdjustmentFactor(见 DATA-DICTIONARY,Planned)。
195
+ V1 唯一支持 NONE;FORWARD / BACKWARD 仅为 Catalog/未来扩展保留,
196
+ AdjustmentFactor 数据集实现前不得假装支持。
197
+ """
198
+
199
+ NONE = "none"
200
+ # reserved:仅为未来扩展保留
201
+ FORWARD = "forward"
202
+ BACKWARD = "backward"
203
+
204
+
205
+ class SectorType(str, Enum):
206
+ """板块/行业分类类型"""
207
+
208
+ INDUSTRY = "industry"
209
+ CONCEPT = "concept"
210
+ REGION = "region"
211
+ CUSTOM = "custom"
212
+
213
+
214
+ # ========== 单位 ==========
215
+
216
+
217
+ class Unit(str, Enum):
218
+ """Canonical 计量单位。
219
+
220
+ percent 语义固定为:1.23 表示 1.23%(ratio 型 provider 数据由 mapper *100)。
221
+ """
222
+
223
+ CNY = "cny"
224
+ CNY_PER_SHARE = "cny_per_share"
225
+ SHARE = "share"
226
+ PERCENT = "percent"
227
+ RATIO = "ratio"
228
+ COUNT = "count"
229
+
230
+
231
+ # ========== Runtime / 事件(契约定义,Stream/Replay 归 market runtime)==========
232
+
233
+
234
+ class MarketEventType(str, Enum):
235
+ """市场事件类型。
236
+
237
+ 定义(见 SPEC「MarketEvent 契约」):具有市场时间语义、会改变市场参与者
238
+ 可观察信息集的市场事实事件。分两大类:
239
+
240
+ - Structured:Bar / Quote / Tick / Session / CorporateAction / MarketSnapshot
241
+ - Unstructured:News / Announcement / Policy(payload 是文本,事件协议结构化)
242
+
243
+ Live Stream 与 Historical Replay 产出同一套事件(Live/Replay 同构)。
244
+ 枚举存在不代表已实现;实现状态见 SPEC「事件实现范围」。
245
+ """
246
+
247
+ # ========== Structured ==========
248
+ BAR = "bar"
249
+ QUOTE = "quote" # planned
250
+ TICK = "tick" # reserved
251
+ SESSION_PRE_OPEN = "session_pre_open"
252
+ SESSION_OPEN = "session_open"
253
+ SESSION_BREAK_START = "session_break_start"
254
+ SESSION_BREAK_END = "session_break_end"
255
+ SESSION_CLOSE = "session_close"
256
+ EXCHANGE_STATE_SNAPSHOT = "exchange_state_snapshot" # T4R:交易所状态基线(事实)
257
+ EXCHANGE_STATE_EVENT = "exchange_state_event" # T4R:交易所状态推进(transition)
258
+ TRADING_STATE = "trading_state"
259
+ PRICE_LIMIT = "price_limit"
260
+ DAILY_STATE_SNAPSHOT = "daily_state_snapshot"
261
+ CORPORATE_ACTION = "corporate_action" # reserved
262
+ MARKET_SNAPSHOT = "market_snapshot" # reserved
263
+ # ========== Unstructured ==========
264
+ NEWS = "news" # planned
265
+ ANNOUNCEMENT = "announcement" # planned
266
+ POLICY = "policy" # reserved
267
+ # ========== Runtime 辅助 ==========
268
+ TIMER = "timer"
269
+
270
+
271
+ class MarketStreamMode(str, Enum):
272
+ """市场事件流模式:实时流 或 历史重放"""
273
+
274
+ LIVE = "live"
275
+ REPLAY = "replay"
276
+
277
+
278
+ # A股交易时段(本地时间 Asia/Shanghai)
279
+ SESSION_PRE_OPEN_TIME: Final[str] = "09:15"
280
+ SESSION_OPEN_TIME: Final[str] = "09:30"
281
+ SESSION_BREAK_START_TIME: Final[str] = "11:30"
282
+ SESSION_BREAK_END_TIME: Final[str] = "13:00"
283
+ SESSION_CLOSE_TIME: Final[str] = "15:00"
284
+ MARKET_TIMEZONE: Final[str] = "Asia/Shanghai"
File without changes
@@ -0,0 +1,57 @@
1
+ """交易数量的纯领域值,不依赖持久化或运行框架。"""
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass(frozen=True)
7
+ class TradingQuantityRule:
8
+ min_buy_quantity: int
9
+ buy_quantity_step: int
10
+ min_sell_quantity: int
11
+ sell_quantity_step: int
12
+
13
+ def __post_init__(self) -> None:
14
+ if (
15
+ min(
16
+ self.min_buy_quantity,
17
+ self.buy_quantity_step,
18
+ self.min_sell_quantity,
19
+ self.sell_quantity_step,
20
+ )
21
+ <= 0
22
+ ):
23
+ raise ValueError("交易数量规则必须为正数")
24
+
25
+ def buy_quantity(self, requested: int) -> int:
26
+ if requested < self.min_buy_quantity:
27
+ return 0
28
+ return (
29
+ self.min_buy_quantity
30
+ + ((requested - self.min_buy_quantity) // self.buy_quantity_step)
31
+ * self.buy_quantity_step
32
+ )
33
+
34
+ def sell_quantity(self, requested: int, held: int) -> int:
35
+ if requested <= 0 or held <= 0:
36
+ return 0
37
+ if requested >= held:
38
+ return held
39
+ regular = 0
40
+ if requested >= self.min_sell_quantity:
41
+ regular = (
42
+ self.min_sell_quantity
43
+ + ((requested - self.min_sell_quantity) // self.sell_quantity_step)
44
+ * self.sell_quantity_step
45
+ )
46
+ # 整百市场持有零股时,可单次卖出零股部分并留下整手余额。
47
+ odd_lot = 0
48
+ if self.sell_quantity_step > 1 and self.min_sell_quantity == self.sell_quantity_step:
49
+ remainder = held % self.sell_quantity_step
50
+ if remainder and requested >= remainder:
51
+ candidate = (
52
+ remainder
53
+ + ((requested - remainder) // self.sell_quantity_step) * self.sell_quantity_step
54
+ )
55
+ if held - candidate >= self.min_sell_quantity:
56
+ odd_lot = candidate
57
+ return max(regular, odd_lot)
@@ -0,0 +1,95 @@
1
+ """
2
+ Market Domain 业务异常 - Domain owns semantics
3
+
4
+ 具体业务错误由本 Domain 自定义并继承 common 的通用异常机制(common/exceptions/base.py)。
5
+ """
6
+
7
+ from quant_core.common.exceptions.base import AppException, NotFoundException
8
+
9
+
10
+ class MarketDataNotSyncedException(AppException):
11
+ """请求数据未同步到本地。
12
+
13
+ 语义:Market 域本地优先,数据缺口显式报错并提示 sync,
14
+ 禁止隐式调用外部 Provider fallback(保证回测可复现)。
15
+ """
16
+
17
+ error_code = "MARKET_DATA_NOT_SYNCED"
18
+ http_status = 409
19
+
20
+ def __init__(self, message: str = "市场数据未同步,请先执行数据同步"):
21
+ super().__init__(message)
22
+
23
+
24
+ class InstrumentNotFoundException(NotFoundException):
25
+ """标的不存在"""
26
+
27
+ error_code = "MARKET_INSTRUMENT_NOT_FOUND"
28
+ http_status = 404
29
+
30
+ def __init__(self, instrument_id: str | None = None):
31
+ message = f"标的不存在: {instrument_id}" if instrument_id else "标的不存在"
32
+ super().__init__(message)
33
+
34
+
35
+ class MarketDataValidationError(AppException):
36
+ """数据校验失败(脏数据不静默入库)"""
37
+
38
+ error_code = "MARKET_DATA_VALIDATION_ERROR"
39
+ http_status = 422
40
+
41
+ def __init__(self, message: str = "市场数据校验失败"):
42
+ super().__init__(message)
43
+
44
+
45
+ class MarketProviderException(AppException):
46
+ """外部 Provider 调用失败"""
47
+
48
+ error_code = "MARKET_PROVIDER_ERROR"
49
+ http_status = 502
50
+
51
+ def __init__(self, message: str = "外部数据源调用失败"):
52
+ super().__init__(message)
53
+
54
+
55
+ class _MarketDataQualityException(AppException):
56
+ """数据质量类异常的公共基类:错误信息携带 dataset/instrument/range/reason"""
57
+
58
+ def __init__(
59
+ self,
60
+ dataset: str,
61
+ instrument_id: str | None = None,
62
+ start: str | None = None,
63
+ end: str | None = None,
64
+ reason: str = "",
65
+ ):
66
+ self.dataset = dataset
67
+ self.instrument_id = instrument_id
68
+ self.range = (start, end)
69
+ self.reason = reason
70
+ parts = [f"dataset={dataset}"]
71
+ if instrument_id:
72
+ parts.append(f"instrument={instrument_id}")
73
+ if start or end:
74
+ parts.append(f"range=[{start or '*'} ~ {end or '*'}]")
75
+ if reason:
76
+ parts.append(f"reason={reason}")
77
+ super().__init__(";".join(parts))
78
+
79
+
80
+ class MarketDataIncompleteException(_MarketDataQualityException):
81
+ """数据不完整(存在无法解释的缺口),不可信可用
82
+
83
+ 由 Verify / Backtest 前置检查抛出;缺口原因(停牌/零成交等)
84
+ V1 不推断,统一按 unexplained missing 处理。
85
+ """
86
+
87
+ error_code = "MARKET_DATA_INCOMPLETE"
88
+ http_status = 409
89
+
90
+
91
+ class MarketDataInvalidException(_MarketDataQualityException):
92
+ """存在违反 Canonical 数据规则的数据,不可信可用"""
93
+
94
+ error_code = "MARKET_DATA_INVALID"
95
+ http_status = 409
File without changes
@@ -0,0 +1,21 @@
1
+ """价格视图服务消费的复权因子查询能力。"""
2
+
3
+ from datetime import date, datetime
4
+ from typing import Protocol
5
+
6
+ from quant_core.app.data.schema.adjustment_schema import (
7
+ AdjustmentFactorResponse as AdjustmentFactor,
8
+ )
9
+
10
+
11
+ class IAdjustmentFactorQuery(Protocol):
12
+ async def list_adjustment_factors(
13
+ self, instrument_id: str, start: date, end: date, known_at: datetime | None = None
14
+ ) -> list[AdjustmentFactor]: ...
15
+
16
+ async def get_adjustment_factor_on_or_before(
17
+ self,
18
+ instrument_id: str,
19
+ on_or_before: date | None = None,
20
+ known_at: datetime | None = None,
21
+ ) -> AdjustmentFactor | None: ...
@@ -0,0 +1,71 @@
1
+ """Market 的公开行情查询能力。"""
2
+
3
+ from datetime import date, datetime
4
+ from typing import Protocol
5
+
6
+ from quant_core.app.data.schema.adjustment_schema import AdjustedBarSeries, BarViewRequest
7
+ from quant_core.app.data.schema.market_schema import (
8
+ BarResponse,
9
+ InstrumentResponse,
10
+ TradingCalendarDayResponse,
11
+ TradingRuleResponse,
12
+ )
13
+ from quant_core.app.data.schema.pit_daily_window import PITDailyWindow
14
+ from quant_core.app.data.schema.quote_schema import DailyBasicResponse
15
+
16
+
17
+ class IMarketDataQuery(Protocol):
18
+ async def get_pit_daily_windows(
19
+ self,
20
+ instrument_id: str,
21
+ days: list[date],
22
+ next_days: list[date],
23
+ lookback: int,
24
+ ) -> tuple[PITDailyWindow, ...]: ...
25
+
26
+ async def get_instrument(self, instrument_id: str) -> InstrumentResponse: ...
27
+
28
+ async def search_instruments(
29
+ self,
30
+ keyword: str | None = None,
31
+ instrument_type: str | None = None,
32
+ exchange: str | None = None,
33
+ limit: int = 100,
34
+ ) -> list[InstrumentResponse]: ...
35
+
36
+ async def list_instruments_on(
37
+ self, on_date: date, limit: int = 10000
38
+ ) -> list[InstrumentResponse]: ...
39
+
40
+ async def list_daily_basic_at(
41
+ self, decision_time: datetime, limit: int = 10000
42
+ ) -> list[DailyBasicResponse]: ...
43
+
44
+ async def list_trading_rules(
45
+ self, instrument_ids: list[str], start: date, end: date
46
+ ) -> list[TradingRuleResponse]: ...
47
+
48
+ async def get_bars(
49
+ self,
50
+ instrument_id: str,
51
+ frequency: str,
52
+ start: datetime | None = None,
53
+ end: datetime | None = None,
54
+ limit: int = 1000,
55
+ ) -> list[BarResponse]: ...
56
+
57
+ async def get_adjusted_bars(
58
+ self,
59
+ instrument_id: str,
60
+ frequency: str,
61
+ view: BarViewRequest,
62
+ start: datetime | None = None,
63
+ end: datetime | None = None,
64
+ limit: int = 1000,
65
+ ) -> AdjustedBarSeries: ...
66
+
67
+ async def is_trading_day(self, exchange: str, trade_date: date) -> bool: ...
68
+
69
+ async def list_trading_days(
70
+ self, exchange: str, start: date, end: date
71
+ ) -> list[TradingCalendarDayResponse]: ...
@@ -0,0 +1,20 @@
1
+ """Market 的公开数据覆盖校验能力:只读,不同步。"""
2
+
3
+ from datetime import datetime
4
+ from typing import Protocol
5
+
6
+ from quant_core.app.data.schema.reliability_schema import DatasetHealthResult
7
+
8
+
9
+ class IMarketDataVerification(Protocol):
10
+ async def verify_bars(
11
+ self, instrument_id: str, frequency: str, start: datetime, end: datetime
12
+ ) -> DatasetHealthResult: ...
13
+
14
+ async def verify_adjustment_factors(
15
+ self, instrument_id: str, frequency: str, start: datetime, end: datetime
16
+ ) -> DatasetHealthResult: ...
17
+
18
+ async def verify_corporate_actions(
19
+ self, instrument_id: str, start: datetime, end: datetime
20
+ ) -> DatasetHealthResult: ...
@@ -0,0 +1,11 @@
1
+ """Market 的公开原子事件流能力。"""
2
+
3
+ from collections.abc import AsyncIterator
4
+ from typing import Protocol, runtime_checkable
5
+
6
+ from quant_core.app.data.schema.event_schema import MarketEvent, MarketStreamRequest
7
+
8
+
9
+ @runtime_checkable
10
+ class IMarketEventSource(Protocol):
11
+ def stream(self, request: MarketStreamRequest) -> AsyncIterator[MarketEvent]: ...
@@ -0,0 +1,8 @@
1
+ """研究等下游读取 Market 当前同步版本的公开能力。"""
2
+
3
+ from datetime import date
4
+ from typing import Protocol
5
+
6
+
7
+ class IMarketRevisionQuery(Protocol):
8
+ async def snapshot(self, start: date, end: date) -> dict[str, str]: ...
@@ -0,0 +1,44 @@
1
+ """Market Runtime 所需的内部持久化能力。"""
2
+
3
+ from datetime import date, datetime
4
+ from typing import Protocol
5
+
6
+ from quant_core.app.data.schema.corporate_action_schema import (
7
+ CorporateActionResponse as CorporateAction,
8
+ )
9
+ from quant_core.app.data.schema.history_schema import DailyFactResponse as InstrumentDailyFact
10
+ from quant_core.app.data.schema.market_schema import BarResponse as Bar
11
+ from quant_core.app.data.schema.market_schema import (
12
+ TradingCalendarDayResponse as TradingCalendarDay,
13
+ )
14
+
15
+
16
+ class IMarketRuntimeRepository(Protocol):
17
+ """Runtime 需要的持久化能力(只读历史数据)"""
18
+
19
+ async def list_bars(
20
+ self,
21
+ instrument_id: str,
22
+ frequency: str,
23
+ start: datetime | None = None,
24
+ end: datetime | None = None,
25
+ limit: int = 1000,
26
+ ) -> list[Bar]: ...
27
+
28
+ async def list_calendar_days(
29
+ self, exchange: str, start: date, end: date, only_open: bool = False
30
+ ) -> list[TradingCalendarDay]: ...
31
+
32
+ async def list_daily_facts(
33
+ self, instrument_id: str, start: date, end: date
34
+ ) -> list[InstrumentDailyFact]:
35
+ """日级官方交易事实(Q2 定案:回放状态来自日级事实的确定性展开)"""
36
+ ...
37
+
38
+ async def list_corporate_actions(
39
+ self,
40
+ instrument_ids: list[str],
41
+ start: date,
42
+ end: date,
43
+ known_at: datetime | None = None,
44
+ ) -> list[CorporateAction]: ...
@@ -0,0 +1,11 @@
1
+ """Market 的公开历史时间片流能力。"""
2
+
3
+ from collections.abc import AsyncIterator
4
+ from typing import Protocol, runtime_checkable
5
+
6
+ from quant_core.app.data.schema.event_schema import MarketStreamRequest, MarketTimeSlice
7
+
8
+
9
+ @runtime_checkable
10
+ class IMarketTimeSliceSource(Protocol):
11
+ def stream_slices(self, request: MarketStreamRequest) -> AsyncIterator[MarketTimeSlice]: ...
File without changes
@@ -0,0 +1 @@
1
+ """Market Domain 请求/响应 Schema"""