quantnodes 3.0.0__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 (399) hide show
  1. QuantNodes/__init__.py +15 -0
  2. QuantNodes/__main__.py +14 -0
  3. QuantNodes/agent/__init__.py +158 -0
  4. QuantNodes/agent/agents/__init__.py +13 -0
  5. QuantNodes/agent/agents/definition.py +180 -0
  6. QuantNodes/agent/agents/manager.py +73 -0
  7. QuantNodes/agent/config/__init__.py +34 -0
  8. QuantNodes/agent/config/executor.py +958 -0
  9. QuantNodes/agent/config/loader.py +427 -0
  10. QuantNodes/agent/config/templates/bollinger_bands.yaml +84 -0
  11. QuantNodes/agent/config/templates/dual_ma.yaml +72 -0
  12. QuantNodes/agent/config/templates/empty.yaml +56 -0
  13. QuantNodes/agent/config/templates/mean_reversion.yaml +47 -0
  14. QuantNodes/agent/config/templates/mean_reversion_zscore.yaml +90 -0
  15. QuantNodes/agent/config/templates/momentum.yaml +81 -0
  16. QuantNodes/agent/config/templates/momentum_breakout.yaml +84 -0
  17. QuantNodes/agent/config/templates/rsi_strategy.yaml +72 -0
  18. QuantNodes/agent/config/templates/volume_price.yaml +86 -0
  19. QuantNodes/agent/config/types.py +156 -0
  20. QuantNodes/agent/config_mapper.py +293 -0
  21. QuantNodes/agent/core/__init__.py +19 -0
  22. QuantNodes/agent/core/dream.py +47 -0
  23. QuantNodes/agent/core/quant_dream.py +274 -0
  24. QuantNodes/agent/cron_jobs.py +314 -0
  25. QuantNodes/agent/nanobot_bridge.py +242 -0
  26. QuantNodes/agent/permission/__init__.py +30 -0
  27. QuantNodes/agent/permission/defaults.py +36 -0
  28. QuantNodes/agent/permission/evaluate.py +41 -0
  29. QuantNodes/agent/permission/models.py +59 -0
  30. QuantNodes/agent/permission/service.py +133 -0
  31. QuantNodes/agent/providers/__init__.py +11 -0
  32. QuantNodes/agent/providers/base.py +102 -0
  33. QuantNodes/agent/providers/quantnodes.py +610 -0
  34. QuantNodes/agent/providers/rate_limiter.py +326 -0
  35. QuantNodes/agent/providers/registry.py +163 -0
  36. QuantNodes/agent/skills/__init__.py +20 -0
  37. QuantNodes/agent/skills/base.py +118 -0
  38. QuantNodes/agent/skills/bridge.py +73 -0
  39. QuantNodes/agent/skills/factor/__init__.py +14 -0
  40. QuantNodes/agent/skills/factor/correlation.py +99 -0
  41. QuantNodes/agent/skills/factor/group_backtest.py +114 -0
  42. QuantNodes/agent/skills/factor/ic_analysis.py +106 -0
  43. QuantNodes/agent/skills/loader.py +107 -0
  44. QuantNodes/agent/skills/registry.py +105 -0
  45. QuantNodes/agent/skills/strategy/__init__.py +16 -0
  46. QuantNodes/agent/skills/strategy/bollinger.py +86 -0
  47. QuantNodes/agent/skills/strategy/dual_ma.py +82 -0
  48. QuantNodes/agent/skills/strategy/momentum.py +74 -0
  49. QuantNodes/agent/skills/strategy/rsi_reversal.py +99 -0
  50. QuantNodes/agent/skills_quant/__init__.py +14 -0
  51. QuantNodes/agent/skills_quant/backtest-analyze/SKILL.md +42 -0
  52. QuantNodes/agent/skills_quant/config-driven/SKILL.md +72 -0
  53. QuantNodes/agent/skills_quant/factor-research/SKILL.md +40 -0
  54. QuantNodes/agent/skills_quant/quant-dream/SKILL.md +55 -0
  55. QuantNodes/agent/skills_quant/risk-management/SKILL.md +45 -0
  56. QuantNodes/agent/skills_quant/strategy-design/SKILL.md +43 -0
  57. QuantNodes/agent/templates/__init__.py +4 -0
  58. QuantNodes/agent/tools/__init__.py +173 -0
  59. QuantNodes/agent/tools/_workspace.py +51 -0
  60. QuantNodes/agent/tools/alpha_backtest.py +328 -0
  61. QuantNodes/agent/tools/alpha_evaluate.py +493 -0
  62. QuantNodes/agent/tools/backtest.py +226 -0
  63. QuantNodes/agent/tools/base.py +133 -0
  64. QuantNodes/agent/tools/code_search.py +207 -0
  65. QuantNodes/agent/tools/config_backtest.py +401 -0
  66. QuantNodes/agent/tools/context.py +97 -0
  67. QuantNodes/agent/tools/dream_skill.py +77 -0
  68. QuantNodes/agent/tools/echo.py +38 -0
  69. QuantNodes/agent/tools/factor.py +231 -0
  70. QuantNodes/agent/tools/file_ops.py +201 -0
  71. QuantNodes/agent/tools/git_ops.py +190 -0
  72. QuantNodes/agent/tools/operator_lookup.py +218 -0
  73. QuantNodes/agent/tools/output_truncation.py +77 -0
  74. QuantNodes/agent/tools/path_check.py +43 -0
  75. QuantNodes/agent/tools/pipeline.py +62 -0
  76. QuantNodes/agent/tools/registry.py +150 -0
  77. QuantNodes/agent/tools/sandbox.py +62 -0
  78. QuantNodes/agent/tools/shell_safety.py +63 -0
  79. QuantNodes/agent/tools/strategy.py +106 -0
  80. QuantNodes/agent/tools/task.py +171 -0
  81. QuantNodes/agent/tools/web_fetch.py +142 -0
  82. QuantNodes/agent/tools/web_search.py +114 -0
  83. QuantNodes/agent/tools/wiki.py +370 -0
  84. QuantNodes/agent/utils/__init__.py +11 -0
  85. QuantNodes/agent/utils/helpers.py +43 -0
  86. QuantNodes/agent/utils/prompt_templates.py +30 -0
  87. QuantNodes/agent/workflows/__init__.py +20 -0
  88. QuantNodes/agent/workflows/implementations/__init__.py +8 -0
  89. QuantNodes/agent/workflows/implementations/alpha_gpt.py +508 -0
  90. QuantNodes/agent/workflows/implementations/mcts.py +442 -0
  91. QuantNodes/agent/workflows/parsers.py +44 -0
  92. QuantNodes/agent/workflows/registry.py +119 -0
  93. QuantNodes/agent/workflows/step_agent.py +219 -0
  94. QuantNodes/agent/workflows/tool.py +198 -0
  95. QuantNodes/ai/__init__.py +93 -0
  96. QuantNodes/ai/llm/__init__.py +75 -0
  97. QuantNodes/ai/llm/base.py +233 -0
  98. QuantNodes/ai/llm/decorators.py +281 -0
  99. QuantNodes/ai/llm/gateway.py +571 -0
  100. QuantNodes/ai/llm/null.py +76 -0
  101. QuantNodes/ai/llm/openai.py +435 -0
  102. QuantNodes/ai/optimizer.py +405 -0
  103. QuantNodes/ai/prompts/__init__.py +229 -0
  104. QuantNodes/ai/sandbox.py +371 -0
  105. QuantNodes/ai/sandbox_pandas_bridge.py +150 -0
  106. QuantNodes/ai/strategy_gen.py +396 -0
  107. QuantNodes/backtest/__init__.py +64 -0
  108. QuantNodes/backtest/backtest_node.py +188 -0
  109. QuantNodes/backtest/broker_node.py +378 -0
  110. QuantNodes/backtest/config_runner.py +397 -0
  111. QuantNodes/backtest/config_strategy.py +64 -0
  112. QuantNodes/backtest/risk_node.py +360 -0
  113. QuantNodes/backtest/strategy_node.py +268 -0
  114. QuantNodes/cache_node/__init__.py +19 -0
  115. QuantNodes/cache_node/base.py +244 -0
  116. QuantNodes/cache_node/cache_store.py +99 -0
  117. QuantNodes/cache_node/metadata.py +100 -0
  118. QuantNodes/cli/__init__.py +109 -0
  119. QuantNodes/cli/_helpers.py +511 -0
  120. QuantNodes/cli/command.py +110 -0
  121. QuantNodes/cli/commands/__init__.py +69 -0
  122. QuantNodes/cli/commands/agent.py +158 -0
  123. QuantNodes/cli/commands/alpha.py +951 -0
  124. QuantNodes/cli/commands/chat.py +38 -0
  125. QuantNodes/cli/commands/evolve.py +120 -0
  126. QuantNodes/cli/commands/factor.py +569 -0
  127. QuantNodes/cli/commands/init.py +190 -0
  128. QuantNodes/cli/commands/run.py +259 -0
  129. QuantNodes/cli/commands/serve.py +398 -0
  130. QuantNodes/cli/commands/version.py +120 -0
  131. QuantNodes/cli/enhanced.py +146 -0
  132. QuantNodes/conf_node/__init__.py +37 -0
  133. QuantNodes/conf_node/base.py +120 -0
  134. QuantNodes/conf_node/env_config.py +132 -0
  135. QuantNodes/conf_node/ini_config.py +70 -0
  136. QuantNodes/conf_node/json_config.py +69 -0
  137. QuantNodes/conf_node/yaml_config.py +78 -0
  138. QuantNodes/constants.py +17 -0
  139. QuantNodes/core/__init__.py +196 -0
  140. QuantNodes/core/_lookback_helpers.py +49 -0
  141. QuantNodes/core/ast_parser.py +198 -0
  142. QuantNodes/core/base.py +61 -0
  143. QuantNodes/core/cache_manager.py +344 -0
  144. QuantNodes/core/cache_utils.py +150 -0
  145. QuantNodes/core/cond_builder.py +53 -0
  146. QuantNodes/core/config.py +170 -0
  147. QuantNodes/core/constants.py +48 -0
  148. QuantNodes/core/control.py +412 -0
  149. QuantNodes/core/data_preprocessing.py +453 -0
  150. QuantNodes/core/data_source.py +46 -0
  151. QuantNodes/core/events.py +178 -0
  152. QuantNodes/core/evolution/__init__.py +22 -0
  153. QuantNodes/core/evolution/loop.py +583 -0
  154. QuantNodes/core/evolution/operators.py +289 -0
  155. QuantNodes/core/evolution/settings.py +44 -0
  156. QuantNodes/core/expression.py +841 -0
  157. QuantNodes/core/feedback/__init__.py +38 -0
  158. QuantNodes/core/feedback/channels.py +182 -0
  159. QuantNodes/core/feedback/collector.py +91 -0
  160. QuantNodes/core/feedback/dataclass.py +239 -0
  161. QuantNodes/core/feedback/llm_judge.py +138 -0
  162. QuantNodes/core/knowledge/__init__.py +69 -0
  163. QuantNodes/core/knowledge/knowledge_base.py +217 -0
  164. QuantNodes/core/knowledge/lineage_compress.py +196 -0
  165. QuantNodes/core/knowledge/lineage_expand.py +123 -0
  166. QuantNodes/core/knowledge/metrics/__init__.py +43 -0
  167. QuantNodes/core/knowledge/metrics/evaluator.py +176 -0
  168. QuantNodes/core/knowledge/metrics/metrics.py +220 -0
  169. QuantNodes/core/knowledge/rag_prompt.py +196 -0
  170. QuantNodes/core/knowledge/retriever.py +209 -0
  171. QuantNodes/core/lambda_node.py +81 -0
  172. QuantNodes/core/monitoring/__init__.py +22 -0
  173. QuantNodes/core/monitoring/collector.py +292 -0
  174. QuantNodes/core/monitoring/dashboard.py +365 -0
  175. QuantNodes/core/node.py +375 -0
  176. QuantNodes/core/pandas_utils.py +504 -0
  177. QuantNodes/core/parallel/__init__.py +15 -0
  178. QuantNodes/core/parallel/worker.py +140 -0
  179. QuantNodes/core/parallel/worker_process.py +265 -0
  180. QuantNodes/core/path_utils.py +73 -0
  181. QuantNodes/core/pipeline.py +328 -0
  182. QuantNodes/core/plugin.py +135 -0
  183. QuantNodes/core/quality_gate/__init__.py +32 -0
  184. QuantNodes/core/quality_gate/complexity.py +94 -0
  185. QuantNodes/core/quality_gate/consistency.py +26 -0
  186. QuantNodes/core/quality_gate/node.py +97 -0
  187. QuantNodes/core/quality_gate/redundancy.py +51 -0
  188. QuantNodes/core/quality_gate/settings.py +43 -0
  189. QuantNodes/core/quality_gate/zoo.py +98 -0
  190. QuantNodes/core/serializable.py +116 -0
  191. QuantNodes/core/serialization.py +673 -0
  192. QuantNodes/core/tools.py +333 -0
  193. QuantNodes/core/trajectory/__init__.py +25 -0
  194. QuantNodes/core/trajectory/entry.py +116 -0
  195. QuantNodes/core/trajectory/lineage.py +67 -0
  196. QuantNodes/core/trajectory/pool.py +211 -0
  197. QuantNodes/core/trajectory/selector.py +140 -0
  198. QuantNodes/core/visualization/__init__.py +33 -0
  199. QuantNodes/core/visualization/builder.py +233 -0
  200. QuantNodes/core/visualization/gate_breakdown.py +140 -0
  201. QuantNodes/core/visualization/lineage_dag.py +203 -0
  202. QuantNodes/core/visualization/metric_distribution.py +125 -0
  203. QuantNodes/core/visualization/report.py +68 -0
  204. QuantNodes/database_node/__init__.py +69 -0
  205. QuantNodes/database_node/base.py +135 -0
  206. QuantNodes/database_node/clickhouse_node.py +272 -0
  207. QuantNodes/database_node/csv_node.py +83 -0
  208. QuantNodes/database_node/duckdb_node.py +86 -0
  209. QuantNodes/database_node/factory.py +83 -0
  210. QuantNodes/database_node/mysql_node.py +100 -0
  211. QuantNodes/database_node/parquet_node.py +75 -0
  212. QuantNodes/database_node/sqlite_node.py +67 -0
  213. QuantNodes/factor_node/__init__.py +50 -0
  214. QuantNodes/factor_node/factor.py +563 -0
  215. QuantNodes/factor_node/factor_db.py +421 -0
  216. QuantNodes/factor_node/factor_functions/__init__.py +252 -0
  217. QuantNodes/factor_node/factor_functions/_helpers.py +358 -0
  218. QuantNodes/factor_node/factor_functions/_helpers_debug.py +317 -0
  219. QuantNodes/factor_node/factor_functions/composite_ops.py +136 -0
  220. QuantNodes/factor_node/factor_functions/math_ops.py +433 -0
  221. QuantNodes/factor_node/factor_functions/section_ops.py +290 -0
  222. QuantNodes/factor_node/factor_functions/talib_ops.py +1293 -0
  223. QuantNodes/factor_node/factor_functions/time_ops.py +535 -0
  224. QuantNodes/factor_node/factor_operation.py +1115 -0
  225. QuantNodes/factor_node/factor_table.py +1073 -0
  226. QuantNodes/factor_node/quant_nodes_object.py +60 -0
  227. QuantNodes/mcp_server/__init__.py +27 -0
  228. QuantNodes/mcp_server/__main__.py +4 -0
  229. QuantNodes/mcp_server/server.py +272 -0
  230. QuantNodes/methods/__init__.py +28 -0
  231. QuantNodes/methods/pipeline.py +100 -0
  232. QuantNodes/methods/sandbox.py +102 -0
  233. QuantNodes/monitor/__init__.py +27 -0
  234. QuantNodes/monitor/agent_tools/__init__.py +5 -0
  235. QuantNodes/monitor/agent_tools/monitor_tool.py +98 -0
  236. QuantNodes/monitor/agent_tools/schedule_tool.py +98 -0
  237. QuantNodes/monitor/agent_tools/version_tool.py +133 -0
  238. QuantNodes/monitor/monitor/__init__.py +6 -0
  239. QuantNodes/monitor/monitor/alerter.py +60 -0
  240. QuantNodes/monitor/monitor/collector.py +164 -0
  241. QuantNodes/monitor/monitor/dashboard.py +115 -0
  242. QuantNodes/monitor/monitor/drift.py +190 -0
  243. QuantNodes/monitor/scheduler/__init__.py +4 -0
  244. QuantNodes/monitor/scheduler/runner.py +133 -0
  245. QuantNodes/monitor/scheduler/scheduler.py +184 -0
  246. QuantNodes/monitor/storage/__init__.py +16 -0
  247. QuantNodes/monitor/storage/models.py +70 -0
  248. QuantNodes/monitor/storage/repository.py +407 -0
  249. QuantNodes/monitor/version/__init__.py +4 -0
  250. QuantNodes/monitor/version/diff.py +81 -0
  251. QuantNodes/monitor/version/version_manager.py +182 -0
  252. QuantNodes/operator_node/__init__.py +28 -0
  253. QuantNodes/operator_node/base.py +97 -0
  254. QuantNodes/operator_node/query_node.py +129 -0
  255. QuantNodes/operator_node/sql_builder.py +125 -0
  256. QuantNodes/operator_node/sql_utils.py +172 -0
  257. QuantNodes/operator_node/transform.py +130 -0
  258. QuantNodes/operators/__init__.py +90 -0
  259. QuantNodes/operators/_engine.py +108 -0
  260. QuantNodes/operators/composite.py +161 -0
  261. QuantNodes/operators/composite_dag.py +667 -0
  262. QuantNodes/operators/composite_dag_ops.py +343 -0
  263. QuantNodes/operators/composite_dag_pandas_ops.py +382 -0
  264. QuantNodes/operators/custom.py +408 -0
  265. QuantNodes/operators/facade.py +164 -0
  266. QuantNodes/operators/math.py +163 -0
  267. QuantNodes/operators/proxy.py +29 -0
  268. QuantNodes/operators/registry.py +144 -0
  269. QuantNodes/operators/section.py +99 -0
  270. QuantNodes/operators/talib.py +757 -0
  271. QuantNodes/operators/templates.py +95 -0
  272. QuantNodes/operators/time_series.py +136 -0
  273. QuantNodes/prompts/__init__.py +20 -0
  274. QuantNodes/prompts/backtest/__init__.py +12 -0
  275. QuantNodes/prompts/backtest/factor_based.py +86 -0
  276. QuantNodes/prompts/backtest/standard.py +73 -0
  277. QuantNodes/prompts/factor/__init__.py +14 -0
  278. QuantNodes/prompts/factor/correlation.py +77 -0
  279. QuantNodes/prompts/factor/group_backtest.py +86 -0
  280. QuantNodes/prompts/factor/ic_analysis.py +91 -0
  281. QuantNodes/prompts/strategy/__init__.py +18 -0
  282. QuantNodes/prompts/strategy/market_neutral.py +96 -0
  283. QuantNodes/prompts/strategy/mean_reversion.py +107 -0
  284. QuantNodes/prompts/strategy/momentum.py +160 -0
  285. QuantNodes/prompts/strategy/pairs_trading.py +107 -0
  286. QuantNodes/prompts/strategy/trend_following.py +96 -0
  287. QuantNodes/research/README.md +106 -0
  288. QuantNodes/research/__init__.py +154 -0
  289. QuantNodes/research/_legacy_3c/__init__.py +61 -0
  290. QuantNodes/research/_legacy_3c/auto_researcher.py +289 -0
  291. QuantNodes/research/_legacy_3c/factor_evaluator.py +560 -0
  292. QuantNodes/research/_legacy_3c/factor_miner.py +318 -0
  293. QuantNodes/research/_legacy_3c/mcts_search.py +324 -0
  294. QuantNodes/research/factor_test/__init__.py +25 -0
  295. QuantNodes/research/factor_test/config.py +184 -0
  296. QuantNodes/research/factor_test/config_builder.py +276 -0
  297. QuantNodes/research/factor_test/e2e/data_prep.py +163 -0
  298. QuantNodes/research/factor_test/e2e/run_evolution_e2e.py +309 -0
  299. QuantNodes/research/factor_test/evolution_adapter.py +231 -0
  300. QuantNodes/research/factor_test/feedback_wrapper.py +102 -0
  301. QuantNodes/research/factor_test/ifind_db/__init__.py +7 -0
  302. QuantNodes/research/factor_test/ifind_db/fetcher.py +224 -0
  303. QuantNodes/research/factor_test/ifind_db/ifind_database.py +689 -0
  304. QuantNodes/research/factor_test/nodes/__init__.py +1 -0
  305. QuantNodes/research/factor_test/nodes/_base.py +91 -0
  306. QuantNodes/research/factor_test/nodes/adjust_date_node.py +48 -0
  307. QuantNodes/research/factor_test/nodes/configs.py +240 -0
  308. QuantNodes/research/factor_test/nodes/factor_neutralize_node.py +87 -0
  309. QuantNodes/research/factor_test/nodes/factor_preprocess_node.py +222 -0
  310. QuantNodes/research/factor_test/nodes/factor_score_node.py +141 -0
  311. QuantNodes/research/factor_test/nodes/factor_test_report_node.py +153 -0
  312. QuantNodes/research/factor_test/nodes/group_analyzer_node.py +317 -0
  313. QuantNodes/research/factor_test/nodes/ic_analyzer_node.py +112 -0
  314. QuantNodes/research/factor_test/nodes/load_data_node.py +100 -0
  315. QuantNodes/research/factor_test/nodes/long_short_node.py +93 -0
  316. QuantNodes/research/factor_test/nodes/neutralizers.py +222 -0
  317. QuantNodes/research/factor_test/nodes/preprocess_strategies.py +277 -0
  318. QuantNodes/research/factor_test/nodes/risk_correlation_node.py +112 -0
  319. QuantNodes/research/factor_test/nodes/sample_pool_filter_node.py +110 -0
  320. QuantNodes/research/factor_test/nodes/tradability_filter_node.py +92 -0
  321. QuantNodes/research/factor_test/pipeline_runner.py +305 -0
  322. QuantNodes/research/factor_test/pipeline_spec.py +216 -0
  323. QuantNodes/research/factor_test/utils/__init__.py +26 -0
  324. QuantNodes/research/factor_test/utils/constants.py +86 -0
  325. QuantNodes/research/factor_test/utils/data_loader.py +141 -0
  326. QuantNodes/research/factor_test/utils/date_utils.py +232 -0
  327. QuantNodes/research/factor_test/utils/file_loaders.py +150 -0
  328. QuantNodes/research/factor_test/utils/labels.py +37 -0
  329. QuantNodes/research/factor_test/utils/metrics_extractor.py +55 -0
  330. QuantNodes/research/factor_test/utils/performance_metrics.py +175 -0
  331. QuantNodes/research/factor_test/utils/safe_load.py +106 -0
  332. QuantNodes/research/quant_alpha/CHANGELOG.md +80 -0
  333. QuantNodes/research/quant_alpha/README.md +142 -0
  334. QuantNodes/research/quant_alpha/__init__.py +45 -0
  335. QuantNodes/research/quant_alpha/adapters/__init__.py +99 -0
  336. QuantNodes/research/quant_alpha/adapters/calculator.py +503 -0
  337. QuantNodes/research/quant_alpha/adapters/expression.py +387 -0
  338. QuantNodes/research/quant_alpha/alpha101_design/__init__.py +50 -0
  339. QuantNodes/research/quant_alpha/alpha101_design/few_shot_examples.py +243 -0
  340. QuantNodes/research/quant_alpha/alpha101_design/philosophy.py +474 -0
  341. QuantNodes/research/quant_alpha/alpha158_design/__init__.py +63 -0
  342. QuantNodes/research/quant_alpha/alpha158_design/few_shot_examples.py +219 -0
  343. QuantNodes/research/quant_alpha/alpha158_design/philosophy.py +240 -0
  344. QuantNodes/research/quant_alpha/evaluation/__init__.py +47 -0
  345. QuantNodes/research/quant_alpha/evaluation/baselines/__init__.py +8 -0
  346. QuantNodes/research/quant_alpha/evaluation/baselines/g1_handcrafted.py +135 -0
  347. QuantNodes/research/quant_alpha/evaluation/baselines/g2_llm_only.py +269 -0
  348. QuantNodes/research/quant_alpha/evaluation/baselines/g3_alpha_gpt.py +152 -0
  349. QuantNodes/research/quant_alpha/evaluation/clickhouse_data_loader.py +227 -0
  350. QuantNodes/research/quant_alpha/evaluation/contracts.py +376 -0
  351. QuantNodes/research/quant_alpha/evaluation/evaluators/__init__.py +6 -0
  352. QuantNodes/research/quant_alpha/evaluation/evaluators/polars_evaluator.py +545 -0
  353. QuantNodes/research/quant_alpha/evaluation/mock_data_loader.py +226 -0
  354. QuantNodes/research/quant_alpha/evaluation/runner.py +243 -0
  355. QuantNodes/research/quant_alpha/llm/__init__.py +38 -0
  356. QuantNodes/research/quant_alpha/llm/parser.py +681 -0
  357. QuantNodes/research/quant_alpha/logic_driven_pipeline.py +411 -0
  358. QuantNodes/research/quant_alpha/logic_mining/__init__.py +74 -0
  359. QuantNodes/research/quant_alpha/logic_mining/compiler.py +457 -0
  360. QuantNodes/research/quant_alpha/logic_mining/generator.py +366 -0
  361. QuantNodes/research/quant_alpha/logic_mining/models.py +252 -0
  362. QuantNodes/research/quant_alpha/logic_mining/parser.py +287 -0
  363. QuantNodes/research/quant_alpha/logic_mining/pipelines.py +297 -0
  364. QuantNodes/research/quant_alpha/logic_mining/sources.py +149 -0
  365. QuantNodes/research/quant_alpha/mcts/__init__.py +66 -0
  366. QuantNodes/research/quant_alpha/mcts/cache.py +262 -0
  367. QuantNodes/research/quant_alpha/mcts/extension_ops.py +320 -0
  368. QuantNodes/research/quant_alpha/mcts/feedback.py +825 -0
  369. QuantNodes/research/quant_alpha/mcts/op_prior.py +180 -0
  370. QuantNodes/research/quant_alpha/mcts/search.py +540 -0
  371. QuantNodes/research/quant_alpha/mcts/tree.py +201 -0
  372. QuantNodes/research/quant_alpha/operator_vocab/__init__.py +50 -0
  373. QuantNodes/research/quant_alpha/operator_vocab/config.py +54 -0
  374. QuantNodes/research/quant_alpha/operator_vocab/metadata.py +263 -0
  375. QuantNodes/research/quant_alpha/operator_vocab/vocabulary.py +481 -0
  376. QuantNodes/research/quant_alpha/pipeline.py +1027 -0
  377. QuantNodes/research/quant_alpha/types/__init__.py +27 -0
  378. QuantNodes/research/quant_alpha/types/constants.py +28 -0
  379. QuantNodes/research/quant_alpha/types/state.py +205 -0
  380. QuantNodes/research/quant_alpha/workflow/__init__.py +32 -0
  381. QuantNodes/research/quant_alpha/workflow/alpha_gpt.py +911 -0
  382. QuantNodes/research/quant_alpha/workflow/alpha_logics.py +416 -0
  383. QuantNodes/research/quant_alpha/workflow/state.py +27 -0
  384. QuantNodes/research/report_reproducer.py +485 -0
  385. QuantNodes/research/wiki.py +1155 -0
  386. QuantNodes/symbolic/__init__.py +51 -0
  387. QuantNodes/symbolic/compiler.py +113 -0
  388. QuantNodes/symbolic/dialect.py +260 -0
  389. QuantNodes/symbolic/executor.py +147 -0
  390. QuantNodes/symbolic/expression.py +234 -0
  391. QuantNodes/symbolic/functions.py +433 -0
  392. QuantNodes/symbolic/optimizer.py +165 -0
  393. QuantNodes/ui_node/__init__.py +30 -0
  394. QuantNodes/ui_node/base.py +222 -0
  395. quantnodes-3.0.0.dist-info/METADATA +463 -0
  396. quantnodes-3.0.0.dist-info/RECORD +399 -0
  397. quantnodes-3.0.0.dist-info/WHEEL +5 -0
  398. quantnodes-3.0.0.dist-info/entry_points.txt +24 -0
  399. quantnodes-3.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,175 @@
1
+ # coding: utf-8
2
+ """评价指标工具 / Performance Metrics
3
+
4
+ Migrated from ~/Public/单因子回测/factor_performance.py
5
+ """
6
+
7
+ import pandas as pd
8
+ import numpy as np
9
+ from .constants import ANNUAL_DAYS
10
+
11
+
12
+ def calc_max_drawdown(net_day: pd.Series) -> dict:
13
+ """计算最大回撤 (复利净值曲线)
14
+
15
+ Returns:
16
+ dict: MDD, MDD_date, Lastingtime, Endingtime, DD (每日回撤序列)
17
+ """
18
+ DD = 1 - net_day / net_day.cummax()
19
+ DD = DD.dropna()
20
+ if DD.empty:
21
+ return {'MDD': 0, 'MDD_date': None, 'Lastingtime': 0, 'Endingtime': 0, 'DD': DD}
22
+
23
+ MDD = DD.max()
24
+ maxdraw_idx = DD.idxmax()
25
+
26
+ # 最大回撤开始时间: 回撤为 0 的最后一天
27
+ try:
28
+ index_bg = DD.loc[:maxdraw_idx][DD.loc[:maxdraw_idx] == 0].index[-1]
29
+ except (IndexError, KeyError):
30
+ index_bg = DD.index[0]
31
+
32
+ lasting_time = (pd.Index(DD.index).get_indexer([maxdraw_idx])[0]
33
+ - pd.Index(DD.index).get_indexer([index_bg])[0] + 1)
34
+
35
+ # 最大回撤结束时间: 回撤恢复为 0 的第一天
36
+ try:
37
+ index_end = DD.loc[maxdraw_idx:][DD.loc[maxdraw_idx:] == 0].idxmax()
38
+ except (ValueError, KeyError):
39
+ index_end = DD.index[-1]
40
+
41
+ ending_time = (pd.Index(DD.index).get_indexer([index_end])[0]
42
+ - pd.Index(DD.index).get_indexer([maxdraw_idx])[0] + 1)
43
+
44
+ return {
45
+ 'MDD': MDD,
46
+ 'MDD_date': maxdraw_idx,
47
+ 'Lastingtime': lasting_time,
48
+ 'Endingtime': ending_time,
49
+ 'DD': DD,
50
+ }
51
+
52
+
53
+ def evaluation(
54
+ account_net: pd.Series, adj_dates: list, annual_days: int = ANNUAL_DAYS,
55
+ ) -> pd.DataFrame:
56
+ """输入净值曲线返回评价结果 (全期 + 分年)
57
+
58
+ Args:
59
+ account_net: 单利净值曲线
60
+ adj_dates: 调仓日列表
61
+ annual_days: M11 年化天数 (默认全局 ANNUAL_DAYS=250, 美股 252, 24h 365)
62
+
63
+ Returns:
64
+ DataFrame: Year, AnnualRt, AccumRt, SR, MDD, WinRatio, WinLossRatio, Calmar, ...
65
+ """
66
+ result = []
67
+ account_net = account_net.copy()
68
+ account_net.name = 'net'
69
+
70
+ if isinstance(account_net, pd.DataFrame):
71
+ account_net = account_net.iloc[:, 0]
72
+
73
+ # 日收益率
74
+ net = account_net.to_frame()
75
+ net['ret_daily'] = 0.0
76
+ if adj_dates[0] != net.index[0]:
77
+ all_dates = [net.index[0]] + adj_dates
78
+ else:
79
+ all_dates = adj_dates
80
+
81
+ for i in range(len(all_dates)):
82
+ current_date = all_dates[i]
83
+ next_date = all_dates[i + 1] if i < len(all_dates) - 1 else all_dates[-1]
84
+ current_net = net.loc[current_date:next_date, 'net']
85
+ current_net = current_net - current_net.iloc[0] + 1
86
+ net.loc[current_net.index[1:], 'ret_daily'] = current_net.pct_change()[1:]
87
+
88
+ daily_ret = net['ret_daily']
89
+
90
+ # 每期收益
91
+ every_return = account_net.loc[adj_dates].to_frame().diff(1)
92
+ adj_cycle = len(account_net.loc[adj_dates[0]:adj_dates[-1]]) / (len(adj_dates) - 1)
93
+
94
+ # 全期指标
95
+ accum_rt = account_net.iloc[-1] / account_net.iloc[0] - 1
96
+ annual_rt = every_return.mean().iloc[0] / adj_cycle * annual_days
97
+ annu_std = daily_ret.std(ddof=1) * np.sqrt(annual_days)
98
+ SR = np.nan if annu_std == 0 else annual_rt / annu_std
99
+ mdd = calc_max_drawdown(account_net)
100
+ winRatio = (every_return.dropna() > 0).mean().iloc[0]
101
+ winlossRatio = (every_return[every_return > 0].mean().iloc[0]
102
+ / every_return[every_return < 0].mean().iloc[0] * -1)
103
+ calmar = np.nan if mdd['MDD'] == 0 else annual_rt / mdd['MDD']
104
+ trade_times = every_return.notna().sum().iloc[0]
105
+
106
+ result.append([
107
+ 'all', annual_rt, accum_rt, SR, mdd['MDD'], winRatio, winlossRatio,
108
+ calmar, mdd['MDD_date'], mdd['Lastingtime'], mdd['Endingtime'], trade_times
109
+ ])
110
+
111
+ # 分年
112
+ account_net_df = account_net.to_frame()
113
+ account_net_df['trade_dt'] = account_net_df.index.values
114
+ account_net_df['year'] = pd.to_datetime(
115
+ account_net_df['trade_dt'].astype(str), format='%Y%m%d'
116
+ ).dt.year
117
+
118
+ every_return_cp = every_return.copy()
119
+ every_return_cp['year'] = list(map(
120
+ lambda x: pd.to_datetime(str(x), format='%Y%m%d').year,
121
+ every_return.index.tolist()
122
+ ))
123
+
124
+ for year_i in account_net_df['year'].unique():
125
+ account_net_i = account_net_df[account_net_df['year'] == year_i]['net']
126
+ every_return_i = every_return[every_return_cp['year'] == year_i]
127
+
128
+ accum_rt_i = every_return_i.sum().iloc[0]
129
+ annual_rt_i = every_return_i.mean().iloc[0] / adj_cycle * annual_days
130
+ annu_std_i = daily_ret[account_net_df['year'] == year_i].std(ddof=1) * np.sqrt(annual_days)
131
+ SR_i = np.nan if annu_std_i == 0 else annual_rt_i / annu_std_i
132
+
133
+ mdd_i = calc_max_drawdown(account_net_i) if len(account_net_i) > 1 else {'MDD': 0}
134
+
135
+ winRatio_i = (every_return_i.dropna() > 0).mean().iloc[0]
136
+ wl_i = every_return_i[every_return_i > 0].mean().iloc[0]
137
+ wl_j = every_return_i[every_return_i < 0].mean().iloc[0]
138
+ winlossRatio_i = wl_i / wl_j * -1 if pd.notna(wl_j) and wl_j != 0 else np.nan
139
+ calmar_i = np.nan if mdd_i['MDD'] == 0 else annual_rt_i / mdd_i['MDD']
140
+ trade_times_i = every_return_i.notna().sum().iloc[0]
141
+
142
+ result.append([
143
+ year_i, annual_rt_i, accum_rt_i, SR_i, mdd_i['MDD'], winRatio_i,
144
+ winlossRatio_i, calmar_i, mdd_i.get('MDD_date'), mdd_i.get('Lastingtime', 0),
145
+ mdd_i.get('Endingtime', 0), trade_times_i
146
+ ])
147
+
148
+ columns = [
149
+ 'Year', 'AnnualRt', 'AccumRt', 'SR', 'MDD', 'WinRatio', 'WinLossRatio',
150
+ 'Calmar', 'MDD_date', 'MDD_lastdays', 'MDD_recoverdays', 'Periods'
151
+ ]
152
+ return pd.DataFrame(result, columns=columns)
153
+
154
+
155
+ def cal_net_simple(net: pd.Series, adj_dates: list) -> pd.Series:
156
+ """将复利净值转换为单利净值"""
157
+ data_net = net.to_frame()
158
+ data_net.columns = ['account']
159
+ data_net['simp'] = np.nan
160
+
161
+ # 第一个调仓日之前
162
+ data_net.loc[:adj_dates[1], 'simp'] = data_net.loc[:adj_dates[1], 'account']
163
+ benchmark_i = data_net.loc[adj_dates[1], 'account']
164
+
165
+ for i in range(1, len(adj_dates) - 1):
166
+ adj_i = adj_dates[i]
167
+ net_i = net.loc[adj_i:adj_dates[i + 1]]
168
+ ret_i = net_i / net_i.iloc[0] - 1
169
+ net_i_update = ret_i + benchmark_i
170
+ data_net.loc[adj_i:adj_dates[i + 1], 'simp'] = net_i_update.values
171
+ benchmark_i = data_net.loc[adj_dates[i + 1], 'simp']
172
+
173
+ result = data_net['simp'].to_frame()
174
+ result.columns = ['net']
175
+ return result['net']
@@ -0,0 +1,106 @@
1
+ """Safe data-load helpers (Phase J3+J4, 2026-06-20).
2
+
3
+ Consolidates 11 ``try: ... except Exception: pass`` patterns that swallow
4
+ H5 / CSV load failures silently. Each helper logs a warning instead of
5
+ silently dropping data, so users can debug "where did my factor go?".
6
+
7
+ Used by:
8
+ - LoadDataNode (load_data_node.py): 4 silent-fail sites (price,
9
+ load_keys fallback, index_cp, etc.)
10
+ - FactorNeutralizeNode: 1 risk-factor load fallback
11
+ - RiskCorrelationNode: 1 risk-factor load fallback
12
+ - GroupAnalyzerNode: 1 hedge_path load
13
+
14
+ All helpers return None on failure (instead of raising), so existing
15
+ control flow is preserved. Switch to logger.warning() from silent pass.
16
+ """
17
+ from __future__ import annotations
18
+
19
+ import logging
20
+ from typing import TYPE_CHECKING
21
+
22
+ if TYPE_CHECKING:
23
+ import pandas as pd
24
+
25
+ logger = logging.getLogger(__name__)
26
+
27
+
28
+ def safe_load_h5(
29
+ loader: object,
30
+ filename: str,
31
+ key: str,
32
+ *,
33
+ axis_type: str = "stock",
34
+ add_index: bool = True,
35
+ ) -> "pd.DataFrame | None":
36
+ """Load a single H5 key, returning None on failure.
37
+
38
+ Args:
39
+ loader: DataLoader instance.
40
+ filename: H5 filename relative to loader.api (e.g. 'stk_daily.h5').
41
+ key: H5 key (auto-prefixed with '/' if missing).
42
+ axis_type: 'stock' or 'index' (passed to loader.add_index).
43
+ add_index: if True, also add stock/index axis index to result.
44
+
45
+ Returns:
46
+ DataFrame or None on KeyError/FileNotFoundError/Exception.
47
+ Logs at DEBUG level on failure (visible only when logging enabled).
48
+ """
49
+ try:
50
+ data = loader.load_h5(filename, key)
51
+ if add_index and hasattr(loader, "add_index"):
52
+ return loader.add_index(data, axis_type=axis_type)
53
+ return data
54
+ except Exception as e:
55
+ logger.debug("safe_load_h5(%s, %s) failed: %s", filename, key, e)
56
+ return None
57
+
58
+
59
+ def try_load_panels(
60
+ loader: object,
61
+ key: str,
62
+ *,
63
+ axis_type: str = "stock",
64
+ candidates: tuple[str, ...] = ("stk_daily.h5", "index_daily.h5"),
65
+ ) -> "pd.DataFrame | None":
66
+ """Try each candidate filename, return first non-None panel.
67
+
68
+ Used when a key may exist in either stk_daily.h5 or index_daily.h5
69
+ and we don't know which one ahead of time.
70
+
71
+ Returns None if none of the candidates have the key (logs at DEBUG).
72
+ """
73
+ for fn in candidates:
74
+ result = safe_load_h5(loader, fn, key, axis_type=axis_type)
75
+ if result is not None:
76
+ return result
77
+ logger.debug("try_load_panels(%s) - key not in any candidate %s", key, candidates)
78
+ return None
79
+
80
+
81
+ def safe_load_custom(
82
+ loader: object,
83
+ data_dir: tuple,
84
+ ) -> "pd.DataFrame | None":
85
+ """Wrap loader.load_custom(), return None on failure.
86
+
87
+ Replaces bare ``except Exception: pass`` around load_custom calls.
88
+ """
89
+ try:
90
+ return loader.load_custom(data_dir)
91
+ except Exception as e:
92
+ logger.debug("safe_load_custom(%s) failed: %s", data_dir, e)
93
+ return None
94
+
95
+
96
+ def safe_load_factor(
97
+ loader: object,
98
+ factor_dir: str,
99
+ factor_name: str,
100
+ ) -> "pd.DataFrame | None":
101
+ """Wrap loader.load_factor(), return None on failure."""
102
+ try:
103
+ return loader.load_factor(factor_dir, factor_name)
104
+ except Exception as e:
105
+ logger.debug("safe_load_factor(%s, %s) failed: %s", factor_dir, factor_name, e)
106
+ return None
@@ -0,0 +1,80 @@
1
+ # Changelog - QuantAlpha
2
+
3
+ All notable changes to QuantAlpha subpackage will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
+
7
+ ## [Unreleased]
8
+
9
+ ## [0.1.0] - 2026-06-23 (M1)
10
+
11
+ ### Added
12
+
13
+ - **OperatorVocab 主类**:统一算子查询/调用/元数据化接口
14
+ - `OperatorVocab.default()`:模块级单例
15
+ - `OperatorVocab(config)`:自定义配置
16
+ - `build_namespace(data, date_column, code_column, cross_sectional=True)`:构造 eval 沙箱
17
+ - `list_operators(category=None)`:列出算子
18
+ - `get_operator(name)`:按名称获取
19
+ - `get_metadata(name)`:按名称获取元数据
20
+ - `evaluate(formula, data, ...)`:端到端评估(先 build_namespace 再 eval)
21
+
22
+ - **5 个新算子**(修复 Alpha 101 关键缺口):
23
+ - `signedpower(x, a)` = `sign(x) * abs(x) ** a`
24
+ - `ts_decay_linear(x, d)` = `decay_linear(x, d)` 别名
25
+ - `IndNeutralize(x, ind_class)` = `industry_neutralize(x, ind_class)` 别名
26
+ - `ts_skew(x, w)` = `rolling_skew(x, w)` 别名
27
+ - `ts_kurt(x, w)` = `rolling_kurt(x, w)` 别名
28
+
29
+ - **算子元数据 schema 扩展**(从 5 字段到 12 字段):
30
+ - 旧字段:name, category, func, doc, signature, parameters
31
+ - 新字段:difficulty, category_tags, default_window, requires_group_by, output_dtype, examples, composes_with
32
+
33
+ - **per-date over() 语义修复**:
34
+ - `rank(x)` → `x.rank().over(date_column)`(per-date)
35
+ - `zscore(x)` → `(x - x.mean().over(date)) / (x.std().over(date) + 1e-8)`(per-date)
36
+ - `winsorize(x, l, u)` → per-date quantile clip
37
+ - `IndNeutralize(x, ind)` → per-date demean
38
+ - 提供 `cross_sectional=False` 关闭开关(兼容旧全局语义)
39
+
40
+ - **DeprecationWarning**:旧 4 个文件加 import-time warning:
41
+ - `QuantNodes/research/factor_miner.py`
42
+ - `QuantNodes/research/factor_evaluator.py`
43
+ - `QuantNodes/research/mcts_search.py`
44
+ - `QuantNodes/research/auto_researcher.py`
45
+
46
+ - **migration.md**:旧 API → 新 API 完整映射表
47
+
48
+ ### Fixed
49
+
50
+ - **BUG 1(API 不存在)**:`pl.Series.rolling_corr` / `rolling_cov` 不存在
51
+ - **BUG 2(维度错误)**:`rank` / `zscore` 全局计算而非 per-date
52
+ - **BUG 3(静默失败)**:异常被 `except: return None` 吞掉 → 改为完整错误抛出
53
+
54
+ ### Changed
55
+
56
+ - 旧 4 文件仍可用,行为完全兼容(旧 12-lambda 保留为内部实现,可通过 `cross_sectional=False` 切换回全局语义)
57
+
58
+ ### Deprecated
59
+
60
+ - `QuantNodes.research.factor_miner.FactorMiner` → use `QuantNodes.research.quant_alpha.OperatorVocab`
61
+ - `QuantNodes.research.factor_evaluator.FactorEvaluator` → use `QuantNodes.research.quant_alpha.OperatorVocab`
62
+ - `QuantNodes.research.mcts_search.MCTSSearch` → use `QuantNodes.research.quant_alpha.mcts.MCTSSearch` (M2)
63
+ - `QuantNodes.research.auto_researcher.AutoResearcher` → use `QuantNodes.research.quant_alpha.AutoResearcher` (M5+)
64
+
65
+ ### Performance
66
+
67
+ - 算子可用数:从 12 → 285(+ 23×)
68
+ - 元数据字段:从 5 → 12(+ 7 字段 LLM 友好)
69
+ - per-date 正确性:修复维度 bug 后 IC 计算准确
70
+
71
+ ### Migration Path
72
+
73
+ - **Phase A** (M1, current): 旧 4 文件 + DeprecationWarning,新子包并行
74
+ - **Phase B** (M5+): 旧类变 thin wrapper,行为等价
75
+ - **Phase C** (v3.0.0): 旧实现归档到 `_legacy_3c/`,破坏性变更
76
+
77
+ ---
78
+
79
+ [Unreleased]: https://github.com/sn0wfree/QuantNodes/compare/v2.7.0...HEAD
80
+ [0.1.0]: https://github.com/sn0wfree/QuantNodes/releases/tag/quant_alpha-v0.1.0
@@ -0,0 +1,142 @@
1
+ # QuantAlpha
2
+
3
+ > 自动化因子挖掘引擎 — 从"人工设计"到"机器发现"的范式升级
4
+
5
+ [![Status](https://img.shields.io/badge/status-M1%20in%20progress-yellow)]()
6
+ [![Python](https://img.shields.io/badge/python-3.9%2B-blue)]()
7
+ [![Coverage](https://img.shields.io/badge/coverage-%E2%89%A580%25-brightgreen)]()
8
+
9
+ ---
10
+
11
+ ## 1. 是什么
12
+
13
+ **QuantAlpha** 是 QuantNodes 的自动化因子挖掘子包,参考业界 4 大因子库演进链:
14
+
15
+ | 因子库 | 年份 | 范式 |
16
+ |--------|------|------|
17
+ | Alpha 101 | 2015 | 公式化因子 |
18
+ | Alpha 158/360 | 2020 | ML 友好特征 |
19
+ | AutoAlpha | 2020 | 层次化进化 |
20
+ | AlphaGen / Alpha-GPT | 2023+ | RL / LLM 驱动 |
21
+
22
+ 完整规划见 [`docs/quant_alpha/PROJECT_PLAN.md`](../../docs/quant_alpha/PROJECT_PLAN.md)。
23
+
24
+ ---
25
+
26
+ ## 2. 当前状态:M1 (OperatorVocab)
27
+
28
+ ### 2.1 解决的问题
29
+
30
+ QuantNodes 实际有 **285 个算子**(157 L0 + 109 talib + 20 L1 composite),但自动挖掘链路只能访问 **12 个硬编码 lambda**:
31
+
32
+ - `factor_evaluator.py:202-215` 的 namespace 是 12 个手写 lambda
33
+ - 3 个 latent bug:
34
+ - `ts_corr` / `ts_cov` 用 `Series.rolling_corr`(Series 上不存在)
35
+ - `rank` / `zscore` 全局计算(不是 per-date 截面)
36
+ - 异常被 `except: return None` 静默吞掉
37
+
38
+ ### 2.2 M1 交付
39
+
40
+ - ✅ **OperatorVocab**:统一算子查询/调用/元数据化接口
41
+ - ✅ **5 个新算子**:`signedpower` / `ts_decay_linear` / `IndNeutralize` / `ts_skew` / `ts_kurt`
42
+ - ✅ **per-date over() 修复**:默认走 per-date,可通过 `cross_sectional=False` 关闭
43
+ - ✅ **算子元数据 schema 扩展**:7 个新字段(difficulty / category_tags / default_window / requires_group_by / output_dtype / examples / composes_with)
44
+ - ✅ **DeprecationWarning**:旧 4 文件加 warning,进入 deprecation 周期
45
+ - ✅ **migration.md**:旧 API → 新 API 完整映射
46
+
47
+ ### 2.3 快速开始
48
+
49
+ ```python
50
+ from QuantNodes.research.quant_alpha import OperatorVocab
51
+ import polars as pl
52
+
53
+ # 构造数据
54
+ df = pl.DataFrame({
55
+ "date": [...],
56
+ "code": [...],
57
+ "close": [...],
58
+ "open": [...],
59
+ "high": [...],
60
+ "low": [...],
61
+ "vol": [...],
62
+ })
63
+
64
+ # 构造 eval namespace(285 个算子 + per-date over())
65
+ vocab = OperatorVocab.default()
66
+ namespace = vocab.build_namespace(
67
+ data=df,
68
+ date_column="date",
69
+ code_column="code",
70
+ cross_sectional=True, # 默认 per-date
71
+ )
72
+
73
+ # 评估公式
74
+ result = vocab.evaluate(
75
+ "rank(ts_argmax(signedpower(close, 2), 5))",
76
+ data=df,
77
+ date_column="date",
78
+ )
79
+
80
+ # 列出所有算子
81
+ all_ops = vocab.list_operators()
82
+ ts_ops = vocab.list_operators(category="time")
83
+ print(f"总算子数: {len(all_ops)}, 时序算子: {len(ts_ops)}")
84
+
85
+ # 查询元数据
86
+ meta = vocab.get_metadata("ts_argmax")
87
+ print(f"difficulty={meta.difficulty}, requires_group_by={meta.requires_group_by}")
88
+ ```
89
+
90
+ ### 2.4 旧 API 迁移
91
+
92
+ | 旧 API | 新 API | 行为差异 |
93
+ |--------|--------|----------|
94
+ | `from QuantNodes.research.factor_evaluator import FactorEvaluator` | `from QuantNodes.research.quant_alpha import OperatorVocab` | 行为等价 + 修复 3 bug |
95
+ | `FactorEvaluator(config).evaluate(candidate, data)` | `OperatorVocab.default().evaluate(candidate, data)` | 算子从 12 增到 285 |
96
+ | `eval(formula, namespace, data)` (12 ops) | `vocab.build_namespace(data)` (285 ops) | per-date over() 修复 |
97
+ | `rank: col.rank()` (全局) | `rank: col.rank().over(date_column)` (per-date) | 修复维度 bug |
98
+
99
+ 完整迁移指南见 [`docs/quant_alpha/migration.md`](../../docs/quant_alpha/migration.md)。
100
+
101
+ ---
102
+
103
+ ## 3. 后续路线
104
+
105
+ | 里程碑 | 周 | 路线 | 交付物 |
106
+ |--------|----|----|--------|
107
+ | M1 | 1 | 路线 0 | OperatorVocab + 5 算子 + per-date over() |
108
+ | M2 | 2 | 路线 7 | MCTS + 5 通道反馈 |
109
+ | M3 | 3 | 路线 1+2 借鉴 | alpha101/158 设计文档 + few-shot |
110
+ | M4 | 4 | 路线 4 | PolarsAlphaCalculator 适配器 |
111
+ | M5 | 5-6 | 路线 6 启动 | 算子元数据回填 + 3 智能体 + 4 层 RAG |
112
+ | M6 | 7-10 | 路线 6 完成 | Alpha-GPT 完整工作流 |
113
+ | M7 | 11 | 整合 | 跨路线 A/B + v2.7.0 release |
114
+
115
+ ---
116
+
117
+ ## 4. 测试
118
+
119
+ ```bash
120
+ # 单元测试
121
+ pytest tests/quant_alpha/ -v
122
+
123
+ # 覆盖率
124
+ pytest tests/quant_alpha/ --cov=QuantNodes.research.quant_alpha --cov-report=term-missing
125
+
126
+ # 集成测试(含旧 4 文件兼容)
127
+ pytest tests/quant_alpha/ tests/research/ -v
128
+ ```
129
+
130
+ ---
131
+
132
+ ## 5. 文档
133
+
134
+ - [`docs/quant_alpha/PROJECT_PLAN.md`](../../docs/quant_alpha/PROJECT_PLAN.md) - 完整调研与规划
135
+ - [`docs/quant_alpha/migration.md`](../../docs/quant_alpha/migration.md) - 旧 API → 新 API 迁移指南
136
+ - [`CHANGELOG.md`](./CHANGELOG.md) - 子包变更日志
137
+
138
+ ---
139
+
140
+ ## 6. 许可
141
+
142
+ MIT License(与 QuantNodes 主项目一致)
@@ -0,0 +1,45 @@
1
+ # coding=utf-8
2
+ """
3
+ QuantAlpha - 自动化因子挖掘引擎
4
+
5
+ 从"人工设计因子"到"机器发现因子"的范式升级。
6
+
7
+ 参考 4 大因子库演进链(见 docs/quant_alpha/PROJECT_PLAN.md):
8
+ - Alpha 101 (WorldQuant 2015) - 公式化因子范式
9
+ - Alpha 158/360 (Qlib 2020) - ML 友好特征集
10
+ - AutoAlpha (清华 2020) - 层次化进化
11
+ - AlphaGen/Alpha-GPT (2023+) - RL/LLM 驱动
12
+
13
+ M1 PR 范围(v2.7.0+):
14
+ - 算子词表 OperatorVocab:统一 285 个算子的查询/调用接口
15
+ - 5 个新算子:signedpower / ts_decay_linear / IndNeutralize / ts_skew / ts_kurt
16
+ - per-date over() 语义修复:修复旧 12-lambda namespace 的 3 个 latent bug
17
+ - 旧 4 文件 DeprecationWarning:标记进入 deprecation 周期
18
+
19
+ M2+ 路线:MCTS+5通道反馈 / Alpha 101+158/360 借鉴 / PolarsAlphaCalculator / Alpha-GPT。
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ # M1 公开 API
25
+ from QuantNodes.research.quant_alpha.operator_vocab import (
26
+ OperatorVocab,
27
+ OperatorVocabConfig,
28
+ OperatorMetadata,
29
+ build_namespace,
30
+ list_vocab_operators,
31
+ get_vocab_operator,
32
+ get_vocab_metadata,
33
+ )
34
+
35
+ __all__ = [
36
+ # 主类
37
+ "OperatorVocab",
38
+ "OperatorVocabConfig",
39
+ "OperatorMetadata",
40
+ # 便捷函数
41
+ "build_namespace",
42
+ "list_vocab_operators",
43
+ "get_vocab_operator",
44
+ "get_vocab_metadata",
45
+ ]
@@ -0,0 +1,99 @@
1
+ # coding=utf-8
2
+ """
3
+ adapters - AlphaGen 兼容适配器
4
+
5
+ 让任何 RL 训练(AlphaGen / Alpha² / 自研)通过标准接口
6
+ 使用 QuantNodes 算子 + factor_test 评估。
7
+
8
+ 参考:AlphaGen (KDD 2023) 抽象接口 AlphaCalculator
9
+
10
+ M4 范围:
11
+ - Expression AST(极简子集,11 个算子)
12
+ - BaseAlphaCalculator ABC(7 个抽象方法)
13
+ - PolarsAlphaCalculator(参考实现,用 polars + OperatorVocab)
14
+ - expression_to_formula 转换器
15
+
16
+ 后续路线(Phase 2):
17
+ - 全栈 AlphaGen 复刻(40+ 人天)
18
+ - Alpha² 完整实现(45+ 人天)
19
+ - 自主 RL 训练(基于 PolarsAlphaCalculator)
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ from QuantNodes.research.quant_alpha.adapters.calculator import (
25
+ BaseAlphaCalculator,
26
+ PolarsAlphaCalculator,
27
+ )
28
+ from QuantNodes.research.quant_alpha.adapters.expression import (
29
+ # 基础
30
+ Expression,
31
+ Feature,
32
+ Literal,
33
+ Ref,
34
+ # 二元
35
+ BinaryOp,
36
+ Add,
37
+ Sub,
38
+ Mul,
39
+ Div,
40
+ Greater,
41
+ Less,
42
+ # 一元
43
+ UnaryOp,
44
+ Abs,
45
+ Neg,
46
+ Log,
47
+ Sign,
48
+ Sqrt,
49
+ # 滚动
50
+ RollingOp,
51
+ Mean,
52
+ Std,
53
+ Sum,
54
+ Max,
55
+ Min,
56
+ Delta,
57
+ # 工具
58
+ expression_to_formula,
59
+ collect_feature_fields,
60
+ collect_rolling_windows,
61
+ )
62
+
63
+ __all__ = [
64
+ # ABC
65
+ "BaseAlphaCalculator",
66
+ "PolarsAlphaCalculator",
67
+ # Expression 基类
68
+ "Expression",
69
+ "Feature",
70
+ "Literal",
71
+ "Ref",
72
+ # 二元
73
+ "BinaryOp",
74
+ "Add",
75
+ "Sub",
76
+ "Mul",
77
+ "Div",
78
+ "Greater",
79
+ "Less",
80
+ # 一元
81
+ "UnaryOp",
82
+ "Abs",
83
+ "Neg",
84
+ "Log",
85
+ "Sign",
86
+ "Sqrt",
87
+ # 滚动
88
+ "RollingOp",
89
+ "Mean",
90
+ "Std",
91
+ "Sum",
92
+ "Max",
93
+ "Min",
94
+ "Delta",
95
+ # 工具
96
+ "expression_to_formula",
97
+ "collect_feature_fields",
98
+ "collect_rolling_windows",
99
+ ]