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,25 @@
1
+ """横截面算子的历史入池门禁;ContextVar 隔离并发计算。"""
2
+
3
+ from contextvars import ContextVar
4
+ from datetime import datetime
5
+
6
+ import polars as pl
7
+
8
+ from quant_core.app.factor.computation.panel_expression import PanelExpression
9
+
10
+ ELIGIBLE_KEYS: ContextVar[frozenset[tuple[datetime, str]] | None] = ContextVar(
11
+ "alpha_eligible_keys", default=None
12
+ )
13
+
14
+
15
+ def mask_cross_section(feature: PanelExpression) -> PanelExpression:
16
+ """仅横截面聚合前掩码,避免删除未入池证券的时序历史。"""
17
+ keys = ELIGIBLE_KEYS.get()
18
+ if keys is None:
19
+ return feature
20
+ mask = pl.Series(
21
+ [key in keys for key in feature.df.select("datetime", "vt_symbol").iter_rows()]
22
+ )
23
+ return PanelExpression(
24
+ feature.df.with_columns(pl.when(mask).then(pl.col("data")).otherwise(None).alias("data"))
25
+ )
@@ -0,0 +1,114 @@
1
+ """Factor Domain 常量与枚举(T1 Canonical Contract)"""
2
+
3
+ from enum import Enum
4
+
5
+ # dataset_revision 兜底值:契约侧未声明 dataset_revision 的行(遗留数据 /
6
+ # 逐次本地计算)入库时归一为该值——Store 列 NOT NULL,唯一键含 dataset_revision
7
+ # (R2-2:NULL 在 PG 唯一约束下互不冲突,必须归一才能保证修订行不串键)。
8
+ LEGACY_DATASET_REVISION = "0-legacy"
9
+
10
+ # 本地逐次计算的 dataset_revision(local-python 身份专用;与批量同步的
11
+ # 时间戳批次修订空间不重叠——同一身份内才比较修订序)
12
+ LOCAL_DATASET_REVISION = "local"
13
+ LOCAL_FACTOR_SOURCE = "local-python"
14
+
15
+ FACTOR_MOMENTUM_20D = "momentum_20d"
16
+ FACTOR_VOLUME_RATIO_5D = "volume_ratio_5d"
17
+ FACTOR_MA_CLOSE_10 = "ma_close_10"
18
+
19
+
20
+ class FactorDefinitionStatus(str, Enum):
21
+ """因子定义生命周期;与因子值可用性 FactorStatus 分离。"""
22
+
23
+ DRAFT = "draft"
24
+ VALIDATING = "validating"
25
+ VALIDATED = "validated"
26
+ APPROVED = "approved"
27
+ REJECTED = "rejected"
28
+ DEPRECATED = "deprecated"
29
+
30
+
31
+ class FactorSourceType(str, Enum):
32
+ """因子输入来源类别。"""
33
+
34
+ MARKET = "market"
35
+ FUNDAMENTAL = "fundamental"
36
+ FLOW = "flow"
37
+ ALTERNATIVE = "alternative"
38
+ DERIVED = "derived"
39
+
40
+
41
+ class FactorDataModality(str, Enum):
42
+ """因子输入模态。"""
43
+
44
+ STRUCTURED = "structured"
45
+ TEXT = "text"
46
+ IMAGE = "image"
47
+ MULTIMODAL = "multimodal"
48
+
49
+
50
+ class FactorAuthoringSource(str, Enum):
51
+ """因子规格的创建入口。"""
52
+
53
+ HUMAN = "human"
54
+ AGENT = "agent"
55
+ PYTHON = "python"
56
+
57
+
58
+ class FactorSourceKind(str, Enum):
59
+ """因子值的三类生产来源(AC-1:共享同一 Canonical Contract)"""
60
+
61
+ EXTERNAL_PROVIDER = "external_provider"
62
+ LOCAL_CALCULATOR = "local_calculator"
63
+ MODEL = "model"
64
+
65
+
66
+ class FactorStatus(str, Enum):
67
+ """因子值状态(缺失/不可用/未发布禁止用 0 表达——NULL ≠ 0)"""
68
+
69
+ AVAILABLE = "available"
70
+ MISSING = "missing"
71
+ UNAVAILABLE = "unavailable"
72
+ NOT_YET_PUBLISHED = "not_yet_published"
73
+
74
+
75
+ class FactorFrequency(str, Enum):
76
+ """因子结果的时间粒度;分钟计算流程尚未实现。"""
77
+
78
+ DAILY = "1d"
79
+ MINUTE_1 = "1m"
80
+ MINUTE_5 = "5m"
81
+
82
+
83
+ class FactorCoverageState(str, Enum):
84
+ """截面覆盖状态(R1-4:封闭枚举,逐 identity×instrument 格)
85
+
86
+ - PRESENT:decision_time 可见且存在可消费值行;
87
+ - MISSING:该格无可见值行(含 Provider 明示缺失)——不是 present,更不是 0;
88
+ - UNAVAILABLE:Provider 明示不可用(区别于未知缺失);
89
+ - NOT_YET_PUBLISHED:Store 中存在该格数据但 available_at > decision_time
90
+ (尚未到可见时间;区别于 MISSING)。
91
+
92
+ 「历史窗口不足(insufficient_history)」需要 lookback 输入才能判定,
93
+ 归 Selection/策略层语义(T5),不在本报告封闭枚举内预建空壳。
94
+ """
95
+
96
+ PRESENT = "present"
97
+ MISSING = "missing"
98
+ UNAVAILABLE = "unavailable"
99
+ NOT_YET_PUBLISHED = "not_yet_published"
100
+
101
+
102
+ class FactorFreshness(str, Enum):
103
+ """截面新鲜度策略(R2-5,T5 前裁定:默认精确、回退须显式)
104
+
105
+ - EXACT:只消费 target_as_of 当日的值;目标日无值 → MISSING/
106
+ NOT_YET_PUBLISHED,绝不因历史上存在旧值就冒充 PRESENT(默认,
107
+ 语义最诚实、无静默过期风险);
108
+ - LATEST_KNOWN:目标日无值时显式回退到目标日之前最近的可得历史值,
109
+ 覆盖报告中以 stale 标注 + value_as_of 暴露实际归属日——回退必须
110
+ 是策略作者的显式选择,不是 Runtime 默认行为。
111
+ """
112
+
113
+ EXACT = "exact"
114
+ LATEST_KNOWN = "latest_known"
@@ -0,0 +1,35 @@
1
+ """Factor 错误类型。"""
2
+
3
+ from quant_core.common.exceptions.base import AppException
4
+
5
+
6
+ class FactorPublicationError(AppException):
7
+ """因子发布内容或摘要不符合契约。"""
8
+
9
+ error_code = "FACTOR_PUBLICATION_ERROR"
10
+ http_status = 422
11
+
12
+
13
+ class PublishedFactorNotFound(AppException):
14
+ """指定发布版本不存在。"""
15
+
16
+ error_code = "PUBLISHED_FACTOR_NOT_FOUND"
17
+ http_status = 404
18
+
19
+
20
+ class FactorNotRegisteredException(AppException):
21
+ """引用未注册因子。"""
22
+
23
+ error_code = "FACTOR_NOT_REGISTERED"
24
+ http_status = 409
25
+
26
+ def __init__(self, factor_name: str):
27
+ super().__init__(f"factor 未注册: {factor_name}")
28
+
29
+
30
+ class InsufficientFactorHistoryError(ValueError):
31
+ """交易日历不足以解析 lookback/warmup 窗口"""
32
+
33
+
34
+ class InvalidFactorRangeError(ValueError):
35
+ """非法查询区间(如 start > end)"""
@@ -0,0 +1,65 @@
1
+ from __future__ import annotations
2
+
3
+ from functools import partial
4
+
5
+ """Factor 的框架无关依赖组装;入口不直接构造 Adapter/Repository。"""
6
+
7
+ from datetime import date
8
+
9
+ from quant_core.app.data.interface.market_data_query import IMarketDataQuery
10
+ from quant_core.app.factor.computation.python_factor_executor import (
11
+ execute_python_windows,
12
+ )
13
+ from quant_core.app.factor.interface.public.factor_diagnostics import IFactorDiagnostics
14
+ from quant_core.app.factor.interface.public.factor_exposure_query import IFactorExposureQuery
15
+ from quant_core.app.factor.interface.public.factor_selection import IFactorSelection
16
+ from quant_core.app.factor.schema.factor_computation_schema import FactorComputationSpec
17
+ from quant_core.app.factor.schema.factor_contract import FactorDefinition
18
+ from quant_core.app.factor.service.factor_compute_service import FactorComputeService
19
+ from quant_core.app.factor.service.selection_service import SelectionService
20
+
21
+
22
+ def build_factor_compute(
23
+ trading_days: list[date], definitions: list[FactorDefinition]
24
+ ) -> FactorComputeService:
25
+ """只按数据库读取的定义组装计算器,不注册代码内置因子。"""
26
+ return FactorComputeService(trading_days, definitions, execute_python_windows)
27
+
28
+
29
+ def build_factor_selection() -> IFactorSelection:
30
+ """向其他模块提供唯一的因子横截面评分实现。"""
31
+ return SelectionService()
32
+
33
+
34
+ def builtin_factor_specs(
35
+ family: str,
36
+ *,
37
+ universe_ref: str,
38
+ price_basis: str,
39
+ units: dict[str, str],
40
+ instrument_ids: tuple[str, ...] = (),
41
+ ) -> list[FactorComputationSpec]:
42
+ """读取内置候选配方,不产生数据库副作用。"""
43
+ from quant_core.app.factor.builtin.factor_recipe_catalog import recipe_specs
44
+
45
+ return recipe_specs(
46
+ family,
47
+ universe_ref=universe_ref,
48
+ price_basis=price_basis,
49
+ units=units,
50
+ instrument_ids=instrument_ids,
51
+ )
52
+
53
+
54
+ def build_factor_diagnostics() -> IFactorDiagnostics:
55
+ """诊断数学由 Factor 维护,研究仅通过公开能力调用。"""
56
+ from quant_core.app.factor.service.factor_diagnostics_service import FactorDiagnosticsService
57
+
58
+ return FactorDiagnosticsService()
59
+
60
+
61
+ def build_factor_exposure_query(market: IMarketDataQuery) -> IFactorExposureQuery:
62
+ """跨域绑定市场依赖,策略仅接收暴露查询协议。"""
63
+ from quant_core.app.factor.service.factor_exposure_service import query_exposures
64
+
65
+ return partial(query_exposures, market)
File without changes
@@ -0,0 +1,12 @@
1
+ """物化流程依赖的因子计算接口。"""
2
+
3
+ from typing import Protocol
4
+
5
+ from quant_core.app.factor.schema.factor_compute_request import FactorComputeRequest
6
+ from quant_core.app.factor.schema.factor_contract import FactorValue
7
+
8
+
9
+ class IFactorCompute(Protocol):
10
+ async def compute_many(
11
+ self, requests: list[FactorComputeRequest], *, dataset_revision: str
12
+ ) -> list[FactorValue]: ...
@@ -0,0 +1,15 @@
1
+ """可替换 Python 执行函数的类型契约。"""
2
+
3
+ from collections.abc import Callable
4
+ from decimal import Decimal
5
+ from typing import Any
6
+
7
+ from quant_core.app.data.schema.market_schema import BarResponse
8
+ from quant_core.app.factor.schema.factor_computation_schema import FactorComputationSpec
9
+ from quant_core.app.factor.schema.factor_panel import FactorPanel
10
+ from quant_core.app.factor.schema.factor_result_schema import PanelValues
11
+
12
+ WindowExecutor = Callable[
13
+ [list[tuple[str, list[BarResponse], dict[str, Any]]]], list[Decimal | None]
14
+ ]
15
+ PanelExecutor = Callable[[FactorComputationSpec, FactorPanel], PanelValues]
@@ -0,0 +1,42 @@
1
+ """因子输入准备消费的本地快照接口,不包含网络同步能力。"""
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.history_schema import DailyFactResponse
8
+ from quant_core.app.data.schema.market_schema import (
9
+ BarResponse,
10
+ InstrumentResponse,
11
+ TradingCalendarDayResponse,
12
+ )
13
+
14
+
15
+ class FactorLocalData(Protocol):
16
+ start: datetime
17
+ end: datetime
18
+ revision: str
19
+
20
+ async def list_daily_facts(
21
+ self, instrument_id: str, start: date, end: date
22
+ ) -> list[DailyFactResponse]: ...
23
+
24
+ async def get_instrument(self, instrument_id: str) -> InstrumentResponse: ...
25
+
26
+ async def list_calendar_days(
27
+ self, exchange: str, start: date, end: date, only_open: bool = False
28
+ ) -> list[TradingCalendarDayResponse]: ...
29
+
30
+ async def list_bars(
31
+ self, instrument_id: str, frequency: str, start: datetime, end: datetime, limit: int
32
+ ) -> list[BarResponse]: ...
33
+
34
+ async def get_adjusted_bars(
35
+ self,
36
+ instrument_id: str,
37
+ frequency: str,
38
+ view: BarViewRequest,
39
+ start: datetime,
40
+ end: datetime,
41
+ limit: int,
42
+ ) -> AdjustedBarSeries: ...
@@ -0,0 +1,18 @@
1
+ """面板物化对计算服务的依赖契约。"""
2
+
3
+ from datetime import datetime
4
+ from typing import Protocol
5
+
6
+ from quant_core.app.factor.schema.factor_contract import FactorDefinition, FactorValue
7
+ from quant_core.app.factor.schema.factor_panel import FactorPanel
8
+
9
+
10
+ class IFactorPanelCompute(Protocol):
11
+ async def compute(
12
+ self,
13
+ definitions: list[FactorDefinition],
14
+ panel: FactorPanel,
15
+ *,
16
+ as_of: datetime,
17
+ dataset_revision: str,
18
+ ) -> list[FactorValue]: ...
@@ -0,0 +1,12 @@
1
+ """计算核心所需的 PIT 面板准备接口;数据供应方可替换。"""
2
+
3
+ from datetime import date
4
+ from typing import Protocol
5
+
6
+ from quant_core.app.factor.schema.factor_panel import FactorPanel
7
+
8
+
9
+ class IFactorPanelInput(Protocol):
10
+ async def __call__(
11
+ self, instrument_ids: tuple[str, ...], day: date, next_day: date, lookback: int
12
+ ) -> FactorPanel: ...
@@ -0,0 +1,39 @@
1
+ """Factor 时点查询用例消费的最小存储能力。"""
2
+
3
+ from datetime import date, datetime
4
+ from typing import Protocol
5
+
6
+ from quant_core.app.factor.schema.factor_contract import FactorIdentity, FactorValue
7
+ from quant_core.app.factor.schema.factor_query_result_schema import ProbeCellStatus
8
+
9
+
10
+ class IFactorQueryStore(Protocol):
11
+ async def list_snapshot(
12
+ self,
13
+ identities: tuple[FactorIdentity, ...],
14
+ instrument_ids: tuple[str, ...],
15
+ decision_time: datetime,
16
+ *,
17
+ dataset_revision: str | None = None,
18
+ as_of_on: date | None = None,
19
+ ) -> list[FactorValue]: ...
20
+
21
+ async def list_series(
22
+ self,
23
+ identity: FactorIdentity,
24
+ instrument_id: str,
25
+ start: datetime,
26
+ end: datetime,
27
+ decision_time: datetime,
28
+ *,
29
+ dataset_revision: str | None = None,
30
+ ) -> tuple[FactorValue, ...]: ...
31
+
32
+ async def probe_status(
33
+ self,
34
+ identities: tuple[FactorIdentity, ...],
35
+ instrument_ids: tuple[str, ...],
36
+ *,
37
+ target_as_of: date,
38
+ dataset_revision: str | None = None,
39
+ ) -> dict[tuple[tuple, str], ProbeCellStatus]: ...
File without changes
@@ -0,0 +1,18 @@
1
+ """对研究公开的诊断数学接口。"""
2
+
3
+ from decimal import Decimal
4
+ from typing import Protocol
5
+
6
+ from quant_core.app.factor.schema.diagnostic_types import CrossSection, FactorDiagnostics
7
+
8
+
9
+ class IFactorDiagnostics(Protocol):
10
+ def analyze(
11
+ self,
12
+ sections: tuple[CrossSection, ...],
13
+ *,
14
+ quantiles: int = 5,
15
+ selections: tuple[tuple[str, ...], ...] = (),
16
+ comparison_values: dict[str, Decimal] | None = None,
17
+ horizon_sections: dict[int, tuple[CrossSection, ...]] | None = None,
18
+ ) -> FactorDiagnostics: ...
@@ -0,0 +1,12 @@
1
+ """研究和策略共享的 PIT 暴露读取契约。"""
2
+
3
+ from datetime import datetime
4
+ from typing import Protocol
5
+
6
+ from quant_core.app.factor.schema.selection_types import SelectionExposure
7
+
8
+
9
+ class IFactorExposureQuery(Protocol):
10
+ async def __call__(
11
+ self, instrument_ids: tuple[str, ...], decision_time: datetime
12
+ ) -> dict[str, SelectionExposure]: ...
@@ -0,0 +1,15 @@
1
+ """本地因子运行的跨域存取契约。"""
2
+
3
+ from typing import Protocol
4
+ from uuid import UUID
5
+
6
+ from quant_core.common.local_run import LocalRunRecord
7
+
8
+
9
+ class LocalFactorStore(Protocol):
10
+ def save(self, record: LocalRunRecord, values: dict | None = None) -> None: ...
11
+ def get(self, run_uuid: UUID) -> LocalRunRecord: ...
12
+ def list_runs(self, limit: int = 20, offset: int = 0) -> list[LocalRunRecord]: ...
13
+ def load_values(self, run_uuid: UUID) -> dict: ...
14
+
15
+ def list_values(self, run_uuid: UUID, limit: int = 100, offset: int = 0) -> list[dict]: ...
@@ -0,0 +1,57 @@
1
+ """Factor Query Protocol - 统一因子读取边界(T1 最小消费面,T4 实现)
2
+
3
+ R1-1 契约收口:本 Protocol 是全系统唯一的因子只读消费面,方法签名与
4
+ `FactorRuntimeService` 的公开实现逐字一致——`FactorRuntimeService` 必须
5
+ 真实结构满足本 Protocol(isinstance 守护测试),禁止再出现「Protocol 一套
6
+ 方法名、实现另一套」的假满足。
7
+
8
+ AC-4:本 Protocol 只引用 Canonical Factor Contract(app/factor/schema),
9
+ 不引用 Tushare SDK、不引用具体 Repository——消费方(Strategy/Selection/Agent)
10
+ 通过它读取因子,不感知 Provider 与存储实现(依赖方向:下游 → 本协议 → Store)。
11
+
12
+ 与 Strategy 域 StrategyFactorProviderProtocol(本地计算推模式)的关系见
13
+ TASK 文档 R1-1 Ownership 表:Strategy 域是生产端/消费端,因子身份与值的
14
+ SSOT 在本域。
15
+ """
16
+
17
+ from datetime import date, datetime
18
+ from typing import Protocol, runtime_checkable
19
+
20
+ from quant_core.app.factor.constants import FactorFreshness
21
+ from quant_core.app.factor.schema.factor_contract import FactorIdentity, FactorSnapshot, FactorValue
22
+
23
+
24
+ @runtime_checkable
25
+ class IFactorQuery(Protocol):
26
+ """Canonical Factor Store 的只读消费面(point-in-time 安全)
27
+
28
+ 签名与 FactorRuntimeService 公开实现逐字一致(R1-1 守护测试 +
29
+ inspect 签名一致性守护);R2-5 增补 target_as_of/freshness(截面
30
+ 新鲜度策略),R2-2 增补 dataset_revision(旧数据集复现)。
31
+ """
32
+
33
+ async def get_snapshot(
34
+ self,
35
+ identities: list[FactorIdentity],
36
+ instrument_ids: list[str],
37
+ decision_time: datetime,
38
+ *,
39
+ target_as_of: date | None = None,
40
+ freshness: FactorFreshness = FactorFreshness.EXACT,
41
+ dataset_revision: str | None = None,
42
+ ) -> FactorSnapshot:
43
+ """按因子身份×标的集合读取 decision_time 时点可读的目标业务日截面"""
44
+ ...
45
+
46
+ async def get_series(
47
+ self,
48
+ identity: FactorIdentity,
49
+ instrument_id: str,
50
+ start: datetime,
51
+ end: datetime,
52
+ decision_time: datetime,
53
+ *,
54
+ dataset_revision: str | None = None,
55
+ ) -> tuple[FactorValue, ...]:
56
+ """按单因子×单标的读取 [start, end] 历史序列(只含 decision_time 可见值)"""
57
+ ...
@@ -0,0 +1,20 @@
1
+ """策略与研究共享的因子选股能力契约。"""
2
+
3
+ from typing import Protocol
4
+
5
+ from quant_core.app.factor.schema.factor_contract import FactorSnapshot
6
+ from quant_core.app.factor.schema.selection_types import (
7
+ SelectionDefinition,
8
+ SelectionExposure,
9
+ SelectionResult,
10
+ )
11
+
12
+
13
+ class IFactorSelection(Protocol):
14
+ def select(
15
+ self,
16
+ definition: SelectionDefinition,
17
+ universe: tuple[str, ...] | list[str],
18
+ snapshot: FactorSnapshot,
19
+ exposures: dict[str, SelectionExposure] | None = None,
20
+ ) -> SelectionResult: ...
File without changes
File without changes
@@ -0,0 +1 @@
1
+ """Factor Domain Schema 层"""
@@ -0,0 +1,42 @@
1
+ """因子研究诊断的来源无关值类型。"""
2
+
3
+ from dataclasses import dataclass
4
+ from datetime import date
5
+ from decimal import Decimal
6
+
7
+
8
+ @dataclass(frozen=True)
9
+ class CrossSection:
10
+ as_of: date
11
+ factor_values: dict[str, Decimal]
12
+ forward_returns: dict[str, Decimal]
13
+
14
+
15
+ @dataclass(frozen=True)
16
+ class IcPoint:
17
+ as_of: date
18
+ ic: Decimal | None
19
+ rank_ic: Decimal | None
20
+ sample_size: int
21
+
22
+
23
+ @dataclass(frozen=True)
24
+ class QuantileReturn:
25
+ quantile: int
26
+ mean_return: Decimal | None
27
+ sample_size: int
28
+
29
+
30
+ @dataclass(frozen=True)
31
+ class DecayPoint:
32
+ lag: int
33
+ mean_rank_ic: Decimal | None
34
+
35
+
36
+ @dataclass(frozen=True)
37
+ class FactorDiagnostics:
38
+ ic_series: tuple[IcPoint, ...]
39
+ quantile_returns: tuple[QuantileReturn, ...]
40
+ decay: tuple[DecayPoint, ...]
41
+ selection_turnover: Decimal | None
42
+ factor_correlation: Decimal | None = None
@@ -0,0 +1,36 @@
1
+ """Worker 因子产物,可由单一归档进程导入本地库。"""
2
+
3
+ from datetime import datetime
4
+ from decimal import Decimal
5
+
6
+ from pydantic import BaseModel, ConfigDict, field_validator
7
+
8
+ from quant_core.common.local_run import LocalRunRecord
9
+
10
+
11
+ class FactorArtifactValue(BaseModel):
12
+ model_config = ConfigDict(extra="forbid")
13
+ name: str
14
+ as_of: datetime
15
+ instrument_id: str
16
+ value: Decimal | None
17
+
18
+ @field_validator("as_of")
19
+ @classmethod
20
+ def aware(cls, value: datetime) -> datetime:
21
+ if value.utcoffset() is None:
22
+ raise ValueError("因子时间需要时区")
23
+ return value
24
+
25
+ @field_validator("value")
26
+ @classmethod
27
+ def finite(cls, value: Decimal | None) -> Decimal | None:
28
+ if value is not None and not value.is_finite():
29
+ raise ValueError("因子值必须有限")
30
+ return value
31
+
32
+
33
+ class FactorArtifact(BaseModel):
34
+ model_config = ConfigDict(extra="forbid")
35
+ record: LocalRunRecord
36
+ values: tuple[FactorArtifactValue, ...]