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,1293 @@
1
+ # coding=utf-8
2
+ """
3
+ TA-Lib 技术指标算子
4
+
5
+ 本模块包含 TA-Lib 算子的实际实现。
6
+ TA-Lib 算子通过 map_batches 桥接 Polars 与 NumPy。
7
+
8
+ 注意:本模块为实现层,operators/talib.py 为代理层。
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ from typing import Union, Tuple
14
+
15
+ import polars as pl
16
+ from polars import Expr
17
+
18
+ from QuantNodes.factor_node.factor_functions._helpers import (
19
+ OperatorCategory,
20
+ register_operator,
21
+ )
22
+
23
+
24
+ def _ensure_expr(f: Union[Expr, str, float]) -> Expr:
25
+ """将输入规范化为 Polars Expr"""
26
+ if isinstance(f, Expr):
27
+ return f
28
+ if isinstance(f, str):
29
+ return pl.col(f)
30
+ return pl.lit(f)
31
+
32
+
33
+ def _to_numpy(expr: Union[Expr, str]) -> Expr:
34
+ """将列转为 numpy 数组的 Expr(用于 map_batches)"""
35
+ e = _ensure_expr(expr)
36
+ return e.cast(pl.Float64)
37
+
38
+
39
+ def sma(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
40
+ """简单移动平均线 (Simple Moving Average)"""
41
+ import talib
42
+ e = _ensure_expr(expr)
43
+ return e.map_batches(
44
+ lambda s: pl.Series(talib.SMA(s.to_numpy(), timeperiod=timeperiod)),
45
+ return_dtype=pl.Float64,
46
+ )
47
+
48
+
49
+ def ema(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
50
+ """指数移动平均线 (Exponential Moving Average)"""
51
+ import talib
52
+ e = _ensure_expr(expr)
53
+ return e.map_batches(
54
+ lambda s: pl.Series(talib.EMA(s.to_numpy(), timeperiod=timeperiod)),
55
+ return_dtype=pl.Float64,
56
+ )
57
+
58
+
59
+ def wma(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
60
+ """加权移动平均线 (Weighted Moving Average)"""
61
+ import talib
62
+ e = _ensure_expr(expr)
63
+ return e.map_batches(
64
+ lambda s: pl.Series(talib.WMA(s.to_numpy(), timeperiod=timeperiod)),
65
+ return_dtype=pl.Float64,
66
+ )
67
+
68
+
69
+ def dema(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
70
+ """双重指数移动平均线 (Double Exponential Moving Average)"""
71
+ import talib
72
+ e = _ensure_expr(expr)
73
+ return e.map_batches(
74
+ lambda s: pl.Series(talib.DEMA(s.to_numpy(), timeperiod=timeperiod)),
75
+ return_dtype=pl.Float64,
76
+ )
77
+
78
+
79
+ def tema(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
80
+ """三重指数移动平均线 (Triple Exponential Moving Average)"""
81
+ import talib
82
+ e = _ensure_expr(expr)
83
+ return e.map_batches(
84
+ lambda s: pl.Series(talib.TEMA(s.to_numpy(), timeperiod=timeperiod)),
85
+ return_dtype=pl.Float64,
86
+ )
87
+
88
+
89
+ def trima(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
90
+ """三角移动平均线 (Triangular Moving Average)"""
91
+ import talib
92
+ e = _ensure_expr(expr)
93
+ return e.map_batches(
94
+ lambda s: pl.Series(talib.TRIMA(s.to_numpy(), timeperiod=timeperiod)),
95
+ return_dtype=pl.Float64,
96
+ )
97
+
98
+
99
+ def kama(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
100
+ """考夫曼自适应移动平均线 (Kaufman Adaptive Moving Average)"""
101
+ import talib
102
+ e = _ensure_expr(expr)
103
+ return e.map_batches(
104
+ lambda s: pl.Series(talib.KAMA(s.to_numpy(), timeperiod=timeperiod)),
105
+ return_dtype=pl.Float64,
106
+ )
107
+
108
+
109
+ def t3(expr: Union[Expr, str], timeperiod: int = 5, vfactor: float = 0.7) -> Expr:
110
+ """T3 移动平均线 (Triple Exponential Moving Average with volume factor)"""
111
+ import talib
112
+ e = _ensure_expr(expr)
113
+ return e.map_batches(
114
+ lambda s: pl.Series(talib.T3(s.to_numpy(), timeperiod=timeperiod, vfactor=vfactor)),
115
+ return_dtype=pl.Float64,
116
+ )
117
+
118
+
119
+ def ht_trendline(expr: Union[Expr, str]) -> Expr:
120
+ """希尔伯特变换趋势线 (Hilbert Transform Trendline)"""
121
+ import talib
122
+ e = _ensure_expr(expr)
123
+ return e.map_batches(
124
+ lambda s: pl.Series(talib.HT_TRENDLINE(s.to_numpy())),
125
+ return_dtype=pl.Float64,
126
+ )
127
+
128
+
129
+ def mama(expr: Union[Expr, str], fastlimit: float = 0.5, slowlimit: float = 0.05) -> Expr:
130
+ """MAMA 移动平均 (MESA Adaptive Moving Average)"""
131
+ import talib
132
+ e = _ensure_expr(expr)
133
+ def _mama(s: pl.Series) -> pl.Series:
134
+ mama_line, _ = talib.MAMA(s.to_numpy(), fastlimit=fastlimit, slowlimit=slowlimit)
135
+ return pl.Series(mama_line)
136
+ return e.map_batches(_mama, return_dtype=pl.Float64)
137
+
138
+
139
+ def mavp(expr: Union[Expr, str], periods: Union[Expr, str], minperiod: int = 2, maxperiod: int = 30) -> Expr:
140
+ """移动平均变动周期 (MA with Variable Period)"""
141
+ import talib
142
+ e = _ensure_expr(expr)
143
+ return e.map_batches(
144
+ lambda s: pl.Series(talib.MAVP(s.to_numpy(), s.to_numpy(), minperiod=minperiod, maxperiod=maxperiod)),
145
+ return_dtype=pl.Float64,
146
+ )
147
+
148
+
149
+ def midpoint(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
150
+ """价格中点 (Midpoint over period)"""
151
+ import talib
152
+ e = _ensure_expr(expr)
153
+ return e.map_batches(
154
+ lambda s: pl.Series(talib.MIDPOINT(s.to_numpy(), timeperiod=timeperiod)),
155
+ return_dtype=pl.Float64,
156
+ )
157
+
158
+
159
+ def midprice(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
160
+ """中间价格 (Midpoint Price over period)"""
161
+ import talib
162
+ e = _ensure_expr(expr)
163
+ return e.map_batches(
164
+ lambda s: pl.Series(talib.MIDPRICE(s.to_numpy(), timeperiod=timeperiod)),
165
+ return_dtype=pl.Float64,
166
+ )
167
+
168
+
169
+ def sar(expr: Union[Expr, str], acceleration: float = 0.02, maximum: float = 0.2) -> Expr:
170
+ """抛物线 SAR"""
171
+ import talib
172
+ e = _ensure_expr(expr)
173
+ return e.map_batches(
174
+ lambda s: pl.Series(talib.SAR(s.to_numpy(), s.to_numpy(), acceleration=acceleration, maximum=maximum)),
175
+ return_dtype=pl.Float64,
176
+ )
177
+
178
+
179
+ def ma(expr: Union[Expr, str], timeperiod: int = 30, matype: int = 0) -> Expr:
180
+ """通用移动平均线 (Moving Average)"""
181
+ import talib
182
+ e = _ensure_expr(expr)
183
+ return e.map_batches(
184
+ lambda s: pl.Series(talib.MA(s.to_numpy(), timeperiod=timeperiod, matype=matype)),
185
+ return_dtype=pl.Float64,
186
+ )
187
+
188
+
189
+ def bbands(expr: Union[Expr, str], timeperiod: int = 5, nbdevup: float = 2.0,
190
+ nbdevdn: float = 2.0, matype: int = 0) -> Tuple[Expr, Expr, Expr]:
191
+ """布林带 — 返回 (upper, middle, lower)"""
192
+ import talib
193
+ e = _ensure_expr(expr)
194
+ return (
195
+ e.map_batches(lambda s: pl.Series(talib.BBANDS(s.to_numpy(), timeperiod=timeperiod, nbdevup=nbdevup, nbdevdn=nbdevdn, matype=matype)[0]), return_dtype=pl.Float64),
196
+ e.map_batches(lambda s: pl.Series(talib.BBANDS(s.to_numpy(), timeperiod=timeperiod, nbdevup=nbdevup, nbdevdn=nbdevdn, matype=matype)[1]), return_dtype=pl.Float64),
197
+ e.map_batches(lambda s: pl.Series(talib.BBANDS(s.to_numpy(), timeperiod=timeperiod, nbdevup=nbdevup, nbdevdn=nbdevdn, matype=matype)[2]), return_dtype=pl.Float64),
198
+ )
199
+
200
+
201
+ def bbands_upper(expr: Union[Expr, str], timeperiod: int = 5, nbdevup: float = 2.0,
202
+ nbdevdn: float = 2.0, matype: int = 0) -> Expr:
203
+ """布林带上轨"""
204
+ import talib
205
+ e = _ensure_expr(expr)
206
+ return e.map_batches(
207
+ lambda s: pl.Series(talib.BBANDS(s.to_numpy(), timeperiod=timeperiod, nbdevup=nbdevup, nbdevdn=nbdevdn, matype=matype)[0]),
208
+ return_dtype=pl.Float64,
209
+ )
210
+
211
+
212
+ def bbands_middle(expr: Union[Expr, str], timeperiod: int = 5, nbdevup: float = 2.0,
213
+ nbdevdn: float = 2.0, matype: int = 0) -> Expr:
214
+ """布林带中轨"""
215
+ import talib
216
+ e = _ensure_expr(expr)
217
+ return e.map_batches(
218
+ lambda s: pl.Series(talib.BBANDS(s.to_numpy(), timeperiod=timeperiod, nbdevup=nbdevup, nbdevdn=nbdevdn, matype=matype)[1]),
219
+ return_dtype=pl.Float64,
220
+ )
221
+
222
+
223
+ def bbands_lower(expr: Union[Expr, str], timeperiod: int = 5, nbdevup: float = 2.0,
224
+ nbdevdn: float = 2.0, matype: int = 0) -> Expr:
225
+ """布林带下轨"""
226
+ import talib
227
+ e = _ensure_expr(expr)
228
+ return e.map_batches(
229
+ lambda s: pl.Series(talib.BBANDS(s.to_numpy(), timeperiod=timeperiod, nbdevup=nbdevup, nbdevdn=nbdevdn, matype=matype)[2]),
230
+ return_dtype=pl.Float64,
231
+ )
232
+
233
+
234
+ def rsi(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
235
+ """相对强弱指标 (Relative Strength Index)"""
236
+ import talib
237
+ e = _ensure_expr(expr)
238
+ return e.map_batches(
239
+ lambda s: pl.Series(talib.RSI(s.to_numpy(), timeperiod=timeperiod)),
240
+ return_dtype=pl.Float64,
241
+ )
242
+
243
+
244
+ def macd(expr: Union[Expr, str], fastperiod: int = 12, slowperiod: int = 26,
245
+ signalperiod: int = 9) -> Tuple[Expr, Expr, Expr]:
246
+ """MACD — 返回 (macd_line, signal_line, histogram)"""
247
+ import talib
248
+ e = _ensure_expr(expr)
249
+ return (
250
+ e.map_batches(lambda s: pl.Series(talib.MACD(s.to_numpy(), fastperiod=fastperiod, slowperiod=slowperiod, signalperiod=signalperiod)[0]), return_dtype=pl.Float64),
251
+ e.map_batches(lambda s: pl.Series(talib.MACD(s.to_numpy(), fastperiod=fastperiod, slowperiod=slowperiod, signalperiod=signalperiod)[1]), return_dtype=pl.Float64),
252
+ e.map_batches(lambda s: pl.Series(talib.MACD(s.to_numpy(), fastperiod=fastperiod, slowperiod=slowperiod, signalperiod=signalperiod)[2]), return_dtype=pl.Float64),
253
+ )
254
+
255
+
256
+ def macd_line(expr: Union[Expr, str], fastperiod: int = 12, slowperiod: int = 26,
257
+ signalperiod: int = 9) -> Expr:
258
+ """MACD 线"""
259
+ import talib
260
+ e = _ensure_expr(expr)
261
+ return e.map_batches(
262
+ lambda s: pl.Series(talib.MACD(s.to_numpy(), fastperiod=fastperiod, slowperiod=slowperiod, signalperiod=signalperiod)[0]),
263
+ return_dtype=pl.Float64,
264
+ )
265
+
266
+
267
+ def macd_signal(expr: Union[Expr, str], fastperiod: int = 12, slowperiod: int = 26,
268
+ signalperiod: int = 9) -> Expr:
269
+ """MACD 信号线"""
270
+ import talib
271
+ e = _ensure_expr(expr)
272
+ return e.map_batches(
273
+ lambda s: pl.Series(talib.MACD(s.to_numpy(), fastperiod=fastperiod, slowperiod=slowperiod, signalperiod=signalperiod)[1]),
274
+ return_dtype=pl.Float64,
275
+ )
276
+
277
+
278
+ def macd_hist(expr: Union[Expr, str], fastperiod: int = 12, slowperiod: int = 26,
279
+ signalperiod: int = 9) -> Expr:
280
+ """MACD 柱状图 (histogram)"""
281
+ import talib
282
+ e = _ensure_expr(expr)
283
+ return e.map_batches(
284
+ lambda s: pl.Series(talib.MACD(s.to_numpy(), fastperiod=fastperiod, slowperiod=slowperiod, signalperiod=signalperiod)[2]),
285
+ return_dtype=pl.Float64,
286
+ )
287
+
288
+
289
+ def stoch(expr: Union[Expr, str], fastk_period: int = 5, slowk_period: int = 3,
290
+ slowk_matype: int = 0, slowd_period: int = 3, slowd_matype: int = 0) -> Tuple[Expr, Expr]:
291
+ """随机指标 (Stochastic) — 返回 (slowk, slowd)"""
292
+ import talib
293
+ e = _ensure_expr(expr)
294
+ return (
295
+ e.map_batches(lambda s: pl.Series(talib.STOCH(s.to_numpy(), s.to_numpy(), s.to_numpy(), fastk_period=fastk_period, slowk_period=slowk_period, slowk_matype=slowk_matype, slowd_period=slowd_period, slowd_matype=slowd_matype)[0]), return_dtype=pl.Float64),
296
+ e.map_batches(lambda s: pl.Series(talib.STOCH(s.to_numpy(), s.to_numpy(), s.to_numpy(), fastk_period=fastk_period, slowk_period=slowk_period, slowk_matype=slowk_matype, slowd_period=slowd_period, slowd_matype=slowd_matype)[1]), return_dtype=pl.Float64),
297
+ )
298
+
299
+
300
+ def stoch_k(expr: Union[Expr, str], fastk_period: int = 5, slowk_period: int = 3, slowk_matype: int = 0) -> Expr:
301
+ """随机指标 K 线 (Stochastic %K)"""
302
+ import talib
303
+ e = _ensure_expr(expr)
304
+ return e.map_batches(
305
+ lambda s: pl.Series(talib.STOCH(s.to_numpy(), s.to_numpy(), s.to_numpy(), fastk_period=fastk_period, slowk_period=slowk_period, slowk_matype=slowk_matype)[0]),
306
+ return_dtype=pl.Float64,
307
+ )
308
+
309
+
310
+ def stoch_d(expr: Union[Expr, str], fastk_period: int = 5, slowk_period: int = 3, slowk_matype: int = 0,
311
+ slowd_period: int = 3, slowd_matype: int = 0) -> Expr:
312
+ """随机指标 D 线 (Stochastic %D)"""
313
+ import talib
314
+ e = _ensure_expr(expr)
315
+ return e.map_batches(
316
+ lambda s: pl.Series(talib.STOCH(s.to_numpy(), s.to_numpy(), s.to_numpy(), fastk_period=fastk_period, slowk_period=slowk_period, slowk_matype=slowk_matype, slowd_period=slowd_period, slowd_matype=slowd_matype)[1]),
317
+ return_dtype=pl.Float64,
318
+ )
319
+
320
+
321
+ def cci(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
322
+ """商品通道指标 (Commodity Channel Index)"""
323
+ import talib
324
+ e = _ensure_expr(expr)
325
+ return e.map_batches(
326
+ lambda s: pl.Series(talib.CCI(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
327
+ return_dtype=pl.Float64,
328
+ )
329
+
330
+
331
+ def willr(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
332
+ """威廉指标 (Williams %R)"""
333
+ import talib
334
+ e = _ensure_expr(expr)
335
+ return e.map_batches(
336
+ lambda s: pl.Series(talib.WILLR(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
337
+ return_dtype=pl.Float64,
338
+ )
339
+
340
+
341
+ def mfi(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
342
+ """资金流量指标 (Money Flow Index)"""
343
+ import talib
344
+ e = _ensure_expr(expr)
345
+ return e.map_batches(
346
+ lambda s: pl.Series(talib.MFI(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
347
+ return_dtype=pl.Float64,
348
+ )
349
+
350
+
351
+ def roc(expr: Union[Expr, str], timeperiod: int = 10) -> Expr:
352
+ """变动率 (Rate of Change)"""
353
+ import talib
354
+ e = _ensure_expr(expr)
355
+ return e.map_batches(
356
+ lambda s: pl.Series(talib.ROC(s.to_numpy(), timeperiod=timeperiod)),
357
+ return_dtype=pl.Float64,
358
+ )
359
+
360
+
361
+ def rocp(expr: Union[Expr, str], timeperiod: int = 10) -> Expr:
362
+ """变动率百分比 (Rate of Change Percentage)"""
363
+ import talib
364
+ e = _ensure_expr(expr)
365
+ return e.map_batches(
366
+ lambda s: pl.Series(talib.ROCP(s.to_numpy(), timeperiod=timeperiod)),
367
+ return_dtype=pl.Float64,
368
+ )
369
+
370
+
371
+ def rocr(expr: Union[Expr, str], timeperiod: int = 10) -> Expr:
372
+ """变动率比率 (Rate of Change Ratio)"""
373
+ import talib
374
+ e = _ensure_expr(expr)
375
+ return e.map_batches(
376
+ lambda s: pl.Series(talib.ROCR(s.to_numpy(), timeperiod=timeperiod)),
377
+ return_dtype=pl.Float64,
378
+ )
379
+
380
+
381
+ def rocr100(expr: Union[Expr, str], timeperiod: int = 10) -> Expr:
382
+ """变动率比率*100 (Rate of Change Ratio 100 scale)"""
383
+ import talib
384
+ e = _ensure_expr(expr)
385
+ return e.map_batches(
386
+ lambda s: pl.Series(talib.ROCR100(s.to_numpy(), timeperiod=timeperiod)),
387
+ return_dtype=pl.Float64,
388
+ )
389
+
390
+
391
+ def mom(expr: Union[Expr, str], timeperiod: int = 10) -> Expr:
392
+ """动量 (Momentum)"""
393
+ import talib
394
+ e = _ensure_expr(expr)
395
+ return e.map_batches(
396
+ lambda s: pl.Series(talib.MOM(s.to_numpy(), timeperiod=timeperiod)),
397
+ return_dtype=pl.Float64,
398
+ )
399
+
400
+
401
+ def adx(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
402
+ """平均趋向指标 (Average Directional Movement Index)"""
403
+ import talib
404
+ e = _ensure_expr(expr)
405
+ return e.map_batches(
406
+ lambda s: pl.Series(talib.ADX(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
407
+ return_dtype=pl.Float64,
408
+ )
409
+
410
+
411
+ def adxr(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
412
+ """平均趋向指标评估 (Average Directional Movement Index Rating)"""
413
+ import talib
414
+ e = _ensure_expr(expr)
415
+ return e.map_batches(
416
+ lambda s: pl.Series(talib.ADXR(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
417
+ return_dtype=pl.Float64,
418
+ )
419
+
420
+
421
+ def apo(expr: Union[Expr, str], fastperiod: int = 12, slowperiod: int = 26, matype: int = 0) -> Expr:
422
+ """绝对价格震荡 (Absolute Price Oscillator)"""
423
+ import talib
424
+ e = _ensure_expr(expr)
425
+ return e.map_batches(
426
+ lambda s: pl.Series(talib.APO(s.to_numpy(), fastperiod=fastperiod, slowperiod=slowperiod, matype=matype)),
427
+ return_dtype=pl.Float64,
428
+ )
429
+
430
+
431
+ def ppo(expr: Union[Expr, str], fastperiod: int = 12, slowperiod: int = 26, matype: int = 0) -> Expr:
432
+ """百分比价格震荡 (Percentage Price Oscillator)"""
433
+ import talib
434
+ e = _ensure_expr(expr)
435
+ return e.map_batches(
436
+ lambda s: pl.Series(talib.PPO(s.to_numpy(), fastperiod=fastperiod, slowperiod=slowperiod, matype=matype)),
437
+ return_dtype=pl.Float64,
438
+ )
439
+
440
+
441
+ def cmo(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
442
+ """钱德动量摆动指标 (Chande Momentum Oscillator)"""
443
+ import talib
444
+ e = _ensure_expr(expr)
445
+ return e.map_batches(
446
+ lambda s: pl.Series(talib.CMO(s.to_numpy(), timeperiod=timeperiod)),
447
+ return_dtype=pl.Float64,
448
+ )
449
+
450
+
451
+ def dx(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
452
+ """趋向指标 (Directional Movement Index)"""
453
+ import talib
454
+ e = _ensure_expr(expr)
455
+ return e.map_batches(
456
+ lambda s: pl.Series(talib.DX(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
457
+ return_dtype=pl.Float64,
458
+ )
459
+
460
+
461
+ def minus_di(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
462
+ """负向指标 (Minus Directional Indicator)"""
463
+ import talib
464
+ e = _ensure_expr(expr)
465
+ return e.map_batches(
466
+ lambda s: pl.Series(talib.MINUS_DI(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
467
+ return_dtype=pl.Float64,
468
+ )
469
+
470
+
471
+ def plus_di(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
472
+ """正向指标 (Plus Directional Indicator)"""
473
+ import talib
474
+ e = _ensure_expr(expr)
475
+ return e.map_batches(
476
+ lambda s: pl.Series(talib.PLUS_DI(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
477
+ return_dtype=pl.Float64,
478
+ )
479
+
480
+
481
+ def minus_dm(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
482
+ """负向动量 (Minus Directional Movement)"""
483
+ import talib
484
+ e = _ensure_expr(expr)
485
+ return e.map_batches(
486
+ lambda s: pl.Series(talib.MINUS_DM(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
487
+ return_dtype=pl.Float64,
488
+ )
489
+
490
+
491
+ def plus_dm(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
492
+ """正向动量 (Plus Directional Movement)"""
493
+ import talib
494
+ e = _ensure_expr(expr)
495
+ return e.map_batches(
496
+ lambda s: pl.Series(talib.PLUS_DM(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
497
+ return_dtype=pl.Float64,
498
+ )
499
+
500
+
501
+ def aroon(expr: Union[Expr, str], timeperiod: int = 14) -> Tuple[Expr, Expr]:
502
+ """阿隆指标 — 返回 (aroondown, aroonup)"""
503
+ import talib
504
+ e = _ensure_expr(expr)
505
+ return (
506
+ e.map_batches(lambda s: pl.Series(talib.AROON(s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)[0]), return_dtype=pl.Float64),
507
+ e.map_batches(lambda s: pl.Series(talib.AROON(s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)[1]), return_dtype=pl.Float64),
508
+ )
509
+
510
+
511
+ def aroondown(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
512
+ """阿隆下降线"""
513
+ import talib
514
+ e = _ensure_expr(expr)
515
+ return e.map_batches(
516
+ lambda s: pl.Series(talib.AROON(s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)[0]),
517
+ return_dtype=pl.Float64,
518
+ )
519
+
520
+
521
+ def aroonup(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
522
+ """阿隆上升线"""
523
+ import talib
524
+ e = _ensure_expr(expr)
525
+ return e.map_batches(
526
+ lambda s: pl.Series(talib.AROON(s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)[1]),
527
+ return_dtype=pl.Float64,
528
+ )
529
+
530
+
531
+ def aroonosc(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
532
+ """阿隆振荡指标 (Aroon Oscillator)"""
533
+ import talib
534
+ e = _ensure_expr(expr)
535
+ return e.map_batches(
536
+ lambda s: pl.Series(talib.AROONOSC(s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
537
+ return_dtype=pl.Float64,
538
+ )
539
+
540
+
541
+ def bop(expr: Union[Expr, str]) -> Expr:
542
+ """力量指标 (Balance of Power)"""
543
+ import talib
544
+ e = _ensure_expr(expr)
545
+ return e.map_batches(
546
+ lambda s: pl.Series(talib.BOP(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
547
+ return_dtype=pl.Float64,
548
+ )
549
+
550
+
551
+ def trix(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
552
+ """三重指数平滑变动率 (1-day Rate of Change of Triple Smooth EMA)"""
553
+ import talib
554
+ e = _ensure_expr(expr)
555
+ return e.map_batches(
556
+ lambda s: pl.Series(talib.TRIX(s.to_numpy(), timeperiod=timeperiod)),
557
+ return_dtype=pl.Float64,
558
+ )
559
+
560
+
561
+ def ultosc(expr: Union[Expr, str], timeperiod1: int = 7, timeperiod2: int = 14, timeperiod3: int = 28) -> Expr:
562
+ """终极振荡指标 (Ultimate Oscillator)"""
563
+ import talib
564
+ e = _ensure_expr(expr)
565
+ return e.map_batches(
566
+ lambda s: pl.Series(talib.ULTOSC(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod1=timeperiod1, timeperiod2=timeperiod2, timeperiod3=timeperiod3)),
567
+ return_dtype=pl.Float64,
568
+ )
569
+
570
+
571
+ def stochf(expr: Union[Expr, str], fastk_period: int = 5, fastd_period: int = 3, fastd_matype: int = 0) -> Tuple[Expr, Expr]:
572
+ """快速随机指标 — 返回 (fastk, fastd)"""
573
+ import talib
574
+ e = _ensure_expr(expr)
575
+ return (
576
+ e.map_batches(lambda s: pl.Series(talib.STOCHF(s.to_numpy(), s.to_numpy(), s.to_numpy(), fastk_period=fastk_period, fastd_period=fastd_period, fastd_matype=fastd_matype)[0]), return_dtype=pl.Float64),
577
+ e.map_batches(lambda s: pl.Series(talib.STOCHF(s.to_numpy(), s.to_numpy(), s.to_numpy(), fastk_period=fastk_period, fastd_period=fastd_period, fastd_matype=fastd_matype)[1]), return_dtype=pl.Float64),
578
+ )
579
+
580
+
581
+ def stochrsi(expr: Union[Expr, str], timeperiod: int = 14, fastk_period: int = 5, fastd_period: int = 3, fastd_matype: int = 0) -> Tuple[Expr, Expr]:
582
+ """随机 RSI — 返回 (fastk, fastd)"""
583
+ import talib
584
+ e = _ensure_expr(expr)
585
+ return (
586
+ e.map_batches(lambda s: pl.Series(talib.STOCHRSI(s.to_numpy(), timeperiod=timeperiod, fastk_period=fastk_period, fastd_period=fastd_period, fastd_matype=fastd_matype)[0]), return_dtype=pl.Float64),
587
+ e.map_batches(lambda s: pl.Series(talib.STOCHRSI(s.to_numpy(), timeperiod=timeperiod, fastk_period=fastk_period, fastd_period=fastd_period, fastd_matype=fastd_matype)[1]), return_dtype=pl.Float64),
588
+ )
589
+
590
+
591
+ def stochrsi_k(expr: Union[Expr, str], timeperiod: int = 14, fastk_period: int = 5, fastd_period: int = 3, fastd_matype: int = 0) -> Expr:
592
+ """随机 RSI %K"""
593
+ import talib
594
+ e = _ensure_expr(expr)
595
+ return e.map_batches(
596
+ lambda s: pl.Series(talib.STOCHRSI(s.to_numpy(), timeperiod=timeperiod, fastk_period=fastk_period, fastd_period=fastd_period, fastd_matype=fastd_matype)[0]),
597
+ return_dtype=pl.Float64,
598
+ )
599
+
600
+
601
+ def stochrsi_d(expr: Union[Expr, str], timeperiod: int = 14, fastk_period: int = 5, fastd_period: int = 3, fastd_matype: int = 0) -> Expr:
602
+ """随机 RSI %D"""
603
+ import talib
604
+ e = _ensure_expr(expr)
605
+ return e.map_batches(
606
+ lambda s: pl.Series(talib.STOCHRSI(s.to_numpy(), timeperiod=timeperiod, fastk_period=fastk_period, fastd_period=fastd_period, fastd_matype=fastd_matype)[1]),
607
+ return_dtype=pl.Float64,
608
+ )
609
+
610
+
611
+ def macdext(expr: Union[Expr, str], fastperiod: int = 12, fastmatype: int = 0, slowperiod: int = 26, slowmatype: int = 0,
612
+ signalperiod: int = 9, signalmatype: int = 0) -> Tuple[Expr, Expr, Expr]:
613
+ """扩展 MACD — 返回 (macd, signal, hist)"""
614
+ import talib
615
+ e = _ensure_expr(expr)
616
+ return (
617
+ e.map_batches(lambda s: pl.Series(talib.MACDEXT(s.to_numpy(), fastperiod=fastperiod, fastmatype=fastmatype, slowperiod=slowperiod, slowmatype=slowmatype, signalperiod=signalperiod, signalmatype=signalmatype)[0]), return_dtype=pl.Float64),
618
+ e.map_batches(lambda s: pl.Series(talib.MACDEXT(s.to_numpy(), fastperiod=fastperiod, fastmatype=fastmatype, slowperiod=slowperiod, slowmatype=slowmatype, signalperiod=signalperiod, signalmatype=signalmatype)[1]), return_dtype=pl.Float64),
619
+ e.map_batches(lambda s: pl.Series(talib.MACDEXT(s.to_numpy(), fastperiod=fastperiod, fastmatype=fastmatype, slowperiod=slowperiod, slowmatype=slowmatype, signalperiod=signalperiod, signalmatype=signalmatype)[2]), return_dtype=pl.Float64),
620
+ )
621
+
622
+
623
+ def macdfix(expr: Union[Expr, str], signalperiod: int = 9) -> Tuple[Expr, Expr, Expr]:
624
+ """固定周期 MACD — 返回 (macd, signal, hist)"""
625
+ import talib
626
+ e = _ensure_expr(expr)
627
+ return (
628
+ e.map_batches(lambda s: pl.Series(talib.MACDFIX(s.to_numpy(), signalperiod=signalperiod)[0]), return_dtype=pl.Float64),
629
+ e.map_batches(lambda s: pl.Series(talib.MACDFIX(s.to_numpy(), signalperiod=signalperiod)[1]), return_dtype=pl.Float64),
630
+ e.map_batches(lambda s: pl.Series(talib.MACDFIX(s.to_numpy(), signalperiod=signalperiod)[2]), return_dtype=pl.Float64),
631
+ )
632
+
633
+
634
+ def atr(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
635
+ """平均真实范围 (Average True Range)"""
636
+ import talib
637
+ e = _ensure_expr(expr)
638
+ return e.map_batches(
639
+ lambda s: pl.Series(talib.ATR(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
640
+ return_dtype=pl.Float64,
641
+ )
642
+
643
+
644
+ def natr(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
645
+ """归一化平均真实范围 (Normalized Average True Range)"""
646
+ import talib
647
+ e = _ensure_expr(expr)
648
+ return e.map_batches(
649
+ lambda s: pl.Series(talib.NATR(s.to_numpy(), s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
650
+ return_dtype=pl.Float64,
651
+ )
652
+
653
+
654
+ def trange(expr: Union[Expr, str]) -> Expr:
655
+ """真实范围 (True Range)"""
656
+ import talib
657
+ e = _ensure_expr(expr)
658
+ return e.map_batches(
659
+ lambda s: pl.Series(talib.TRANGE(s.to_numpy(), s.to_numpy(), s.to_numpy())),
660
+ return_dtype=pl.Float64,
661
+ )
662
+
663
+
664
+ def ad(expr: Union[Expr, str]) -> Expr:
665
+ """累积/派发线 (Accumulation/Distribution Line)"""
666
+ import talib
667
+ e = _ensure_expr(expr)
668
+ return e.map_batches(
669
+ lambda s: pl.Series(talib.AD(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
670
+ return_dtype=pl.Float64,
671
+ )
672
+
673
+
674
+ def adosc(expr: Union[Expr, str], fastperiod: int = 3, slowperiod: int = 10) -> Expr:
675
+ """累积/派发震荡 (Chaikin A/D Oscillator)"""
676
+ import talib
677
+ e = _ensure_expr(expr)
678
+ return e.map_batches(
679
+ lambda s: pl.Series(talib.ADOSC(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy(), fastperiod=fastperiod, slowperiod=slowperiod)),
680
+ return_dtype=pl.Float64,
681
+ )
682
+
683
+
684
+ def obv(expr: Union[Expr, str]) -> Expr:
685
+ """能量潮 (On Balance Volume)"""
686
+ import talib
687
+ e = _ensure_expr(expr)
688
+ return e.map_batches(
689
+ lambda s: pl.Series(talib.OBV(s.to_numpy(), s.to_numpy())),
690
+ return_dtype=pl.Float64,
691
+ )
692
+
693
+
694
+ def cdl_doji(expr: Union[Expr, str]) -> Expr:
695
+ """十字星 (Doji)"""
696
+ import talib
697
+ e = _ensure_expr(expr)
698
+ return e.map_batches(
699
+ lambda s: pl.Series(talib.CDLDOJI(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
700
+ return_dtype=pl.Int32,
701
+ )
702
+
703
+
704
+ def cdl_hammer(expr: Union[Expr, str]) -> Expr:
705
+ """锤子线 (Hammer)"""
706
+ import talib
707
+ e = _ensure_expr(expr)
708
+ return e.map_batches(
709
+ lambda s: pl.Series(talib.CDLHAMMER(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
710
+ return_dtype=pl.Int32,
711
+ )
712
+
713
+
714
+ def cdl_engulfing(expr: Union[Expr, str]) -> Expr:
715
+ """吞没形态 (Engulfing Pattern)"""
716
+ import talib
717
+ e = _ensure_expr(expr)
718
+ return e.map_batches(
719
+ lambda s: pl.Series(talib.CDLENGULFING(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
720
+ return_dtype=pl.Int32,
721
+ )
722
+
723
+
724
+ def cdl_morningstar(expr: Union[Expr, str], penetration: float = 0.0) -> Expr:
725
+ """晨星 (Morning Star)"""
726
+ import talib
727
+ e = _ensure_expr(expr)
728
+ return e.map_batches(
729
+ lambda s: pl.Series(talib.CDLMORNINGSTAR(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy(), penetration=penetration)),
730
+ return_dtype=pl.Int32,
731
+ )
732
+
733
+
734
+ def cdl_eveningstar(expr: Union[Expr, str], penetration: float = 0.0) -> Expr:
735
+ """暮星 (Evening Star)"""
736
+ import talib
737
+ e = _ensure_expr(expr)
738
+ return e.map_batches(
739
+ lambda s: pl.Series(talib.CDLEVENINGSTAR(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy(), penetration=penetration)),
740
+ return_dtype=pl.Int32,
741
+ )
742
+
743
+
744
+ def cdl_hangingman(expr: Union[Expr, str]) -> Expr:
745
+ """上吊线 (Hanging Man)"""
746
+ import talib
747
+ e = _ensure_expr(expr)
748
+ return e.map_batches(
749
+ lambda s: pl.Series(talib.CDLHANGINGMAN(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
750
+ return_dtype=pl.Int32,
751
+ )
752
+
753
+
754
+ def cdl_shootingstar(expr: Union[Expr, str]) -> Expr:
755
+ """射击之星 (Shooting Star)"""
756
+ import talib
757
+ e = _ensure_expr(expr)
758
+ return e.map_batches(
759
+ lambda s: pl.Series(talib.CDLSHOOTINGSTAR(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
760
+ return_dtype=pl.Int32,
761
+ )
762
+
763
+
764
+ def cdl_harami(expr: Union[Expr, str]) -> Expr:
765
+ """孕线形态 (Harami Pattern)"""
766
+ import talib
767
+ e = _ensure_expr(expr)
768
+ return e.map_batches(
769
+ lambda s: pl.Series(talib.CDLHARAMI(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
770
+ return_dtype=pl.Int32,
771
+ )
772
+
773
+
774
+ def cdl_piercing(expr: Union[Expr, str]) -> Expr:
775
+ """刺透形态 (Piercing Pattern)"""
776
+ import talib
777
+ e = _ensure_expr(expr)
778
+ return e.map_batches(
779
+ lambda s: pl.Series(talib.CDLPIERCING(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
780
+ return_dtype=pl.Int32,
781
+ )
782
+
783
+
784
+ def cdl_darkcloudcover(expr: Union[Expr, str], penetration: float = 0.0) -> Expr:
785
+ """乌云盖顶 (Dark Cloud Cover)"""
786
+ import talib
787
+ e = _ensure_expr(expr)
788
+ return e.map_batches(
789
+ lambda s: pl.Series(talib.CDLDARKCLOUDCOVER(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy(), penetration=penetration)),
790
+ return_dtype=pl.Int32,
791
+ )
792
+
793
+
794
+ def cdl_spinningtop(expr: Union[Expr, str]) -> Expr:
795
+ """纺锤顶 (Spinning Top)"""
796
+ import talib
797
+ e = _ensure_expr(expr)
798
+ return e.map_batches(
799
+ lambda s: pl.Series(talib.CDLSPINNINGTOP(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
800
+ return_dtype=pl.Int32,
801
+ )
802
+
803
+
804
+ def cdl_3whitesoldiers(expr: Union[Expr, str]) -> Expr:
805
+ """三只白兵 (Three White Soldiers)"""
806
+ import talib
807
+ e = _ensure_expr(expr)
808
+ return e.map_batches(
809
+ lambda s: pl.Series(talib.CDL3WHITESOLDIERS(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
810
+ return_dtype=pl.Int32,
811
+ )
812
+
813
+
814
+ def cdl_3blackcrows(expr: Union[Expr, str]) -> Expr:
815
+ """三只乌鸦 (Three Black Crows)"""
816
+ import talib
817
+ e = _ensure_expr(expr)
818
+ return e.map_batches(
819
+ lambda s: pl.Series(talib.CDL3BLACKCROWS(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
820
+ return_dtype=pl.Int32,
821
+ )
822
+
823
+
824
+ def avgprice(expr: Union[Expr, str]) -> Expr:
825
+ """平均价格 (Average Price)"""
826
+ import talib
827
+ e = _ensure_expr(expr)
828
+ return e.map_batches(
829
+ lambda s: pl.Series(talib.AVGPRICE(s.to_numpy(), s.to_numpy(), s.to_numpy(), s.to_numpy())),
830
+ return_dtype=pl.Float64,
831
+ )
832
+
833
+
834
+ def medprice(expr: Union[Expr, str]) -> Expr:
835
+ """中间价格 (Median Price)"""
836
+ import talib
837
+ e = _ensure_expr(expr)
838
+ return e.map_batches(
839
+ lambda s: pl.Series(talib.MEDPRICE(s.to_numpy(), s.to_numpy())),
840
+ return_dtype=pl.Float64,
841
+ )
842
+
843
+
844
+ def typprice(expr: Union[Expr, str]) -> Expr:
845
+ """典型价格 (Typical Price)"""
846
+ import talib
847
+ e = _ensure_expr(expr)
848
+ return e.map_batches(
849
+ lambda s: pl.Series(talib.TYPPRICE(s.to_numpy(), s.to_numpy(), s.to_numpy())),
850
+ return_dtype=pl.Float64,
851
+ )
852
+
853
+
854
+ def wclprice(expr: Union[Expr, str]) -> Expr:
855
+ """加权收盘价 (Weighted Close Price)"""
856
+ import talib
857
+ e = _ensure_expr(expr)
858
+ return e.map_batches(
859
+ lambda s: pl.Series(talib.WCLPRICE(s.to_numpy(), s.to_numpy(), s.to_numpy())),
860
+ return_dtype=pl.Float64,
861
+ )
862
+
863
+
864
+ def beta(expr: Union[Expr, str], timeperiod: int = 5) -> Expr:
865
+ """Beta 系数"""
866
+ import talib
867
+ e = _ensure_expr(expr)
868
+ return e.map_batches(
869
+ lambda s: pl.Series(talib.BETA(s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
870
+ return_dtype=pl.Float64,
871
+ )
872
+
873
+
874
+ def correl(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
875
+ """相关系数 (Pearson's Correlation Coefficient)"""
876
+ import talib
877
+ e = _ensure_expr(expr)
878
+ return e.map_batches(
879
+ lambda s: pl.Series(talib.CORREL(s.to_numpy(), s.to_numpy(), timeperiod=timeperiod)),
880
+ return_dtype=pl.Float64,
881
+ )
882
+
883
+
884
+ def linearreg(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
885
+ """线性回归值 (Linear Regression)"""
886
+ import talib
887
+ e = _ensure_expr(expr)
888
+ return e.map_batches(
889
+ lambda s: pl.Series(talib.LINEARREG(s.to_numpy(), timeperiod=timeperiod)),
890
+ return_dtype=pl.Float64,
891
+ )
892
+
893
+
894
+ def linearreg_angle(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
895
+ """线性回归角度 (Linear Regression Angle)"""
896
+ import talib
897
+ e = _ensure_expr(expr)
898
+ return e.map_batches(
899
+ lambda s: pl.Series(talib.LINEARREG_ANGLE(s.to_numpy(), timeperiod=timeperiod)),
900
+ return_dtype=pl.Float64,
901
+ )
902
+
903
+
904
+ def linearreg_intercept(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
905
+ """线性回归截距 (Linear Regression Intercept)"""
906
+ import talib
907
+ e = _ensure_expr(expr)
908
+ return e.map_batches(
909
+ lambda s: pl.Series(talib.LINEARREG_INTERCEPT(s.to_numpy(), timeperiod=timeperiod)),
910
+ return_dtype=pl.Float64,
911
+ )
912
+
913
+
914
+ def linearreg_slope(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
915
+ """线性回归斜率 (Linear Regression Slope)"""
916
+ import talib
917
+ e = _ensure_expr(expr)
918
+ return e.map_batches(
919
+ lambda s: pl.Series(talib.LINEARREG_SLOPE(s.to_numpy(), timeperiod=timeperiod)),
920
+ return_dtype=pl.Float64,
921
+ )
922
+
923
+
924
+ def stddev(expr: Union[Expr, str], timeperiod: int = 5, nbdev: int = 1) -> Expr:
925
+ """标准差 (Standard Deviation)"""
926
+ import talib
927
+ e = _ensure_expr(expr)
928
+ return e.map_batches(
929
+ lambda s: pl.Series(talib.STDDEV(s.to_numpy(), timeperiod=timeperiod, nbdev=nbdev)),
930
+ return_dtype=pl.Float64,
931
+ )
932
+
933
+
934
+ def tsf(expr: Union[Expr, str], timeperiod: int = 14) -> Expr:
935
+ """时间序列预测 (Time Series Forecast)"""
936
+ import talib
937
+ e = _ensure_expr(expr)
938
+ return e.map_batches(
939
+ lambda s: pl.Series(talib.TSF(s.to_numpy(), timeperiod=timeperiod)),
940
+ return_dtype=pl.Float64,
941
+ )
942
+
943
+
944
+ def var(expr: Union[Expr, str], timeperiod: int = 5, nbdev: int = 1) -> Expr:
945
+ """方差 (Variance)"""
946
+ import talib
947
+ e = _ensure_expr(expr)
948
+ return e.map_batches(
949
+ lambda s: pl.Series(talib.VAR(s.to_numpy(), timeperiod=timeperiod, nbdev=nbdev)),
950
+ return_dtype=pl.Float64,
951
+ )
952
+
953
+
954
+ def ht_dcperiod(expr: Union[Expr, str]) -> Expr:
955
+ """希尔伯特变换主导周期 (Hilbert Transform Dominant Cycle Period)"""
956
+ import talib
957
+ e = _ensure_expr(expr)
958
+ return e.map_batches(
959
+ lambda s: pl.Series(talib.HT_DCPERIOD(s.to_numpy())),
960
+ return_dtype=pl.Float64,
961
+ )
962
+
963
+
964
+ def ht_dcphase(expr: Union[Expr, str]) -> Expr:
965
+ """希尔伯特变换主导周期相位 (Hilbert Transform Dominant Cycle Phase)"""
966
+ import talib
967
+ e = _ensure_expr(expr)
968
+ return e.map_batches(
969
+ lambda s: pl.Series(talib.HT_DCPHASE(s.to_numpy())),
970
+ return_dtype=pl.Float64,
971
+ )
972
+
973
+
974
+ def ht_phasor(expr: Union[Expr, str]) -> Expr:
975
+ """希尔伯特变换相位 (Hilbert Transform Phasor)"""
976
+ import talib
977
+ e = _ensure_expr(expr)
978
+ return e.map_batches(
979
+ lambda s: pl.Series(talib.HT_PHASOR(s.to_numpy())[0]),
980
+ return_dtype=pl.Float64,
981
+ )
982
+
983
+
984
+ def ht_sine(expr: Union[Expr, str]) -> Expr:
985
+ """希尔伯特变换正弦 (Hilbert Transform SineWave)"""
986
+ import talib
987
+ e = _ensure_expr(expr)
988
+ return e.map_batches(
989
+ lambda s: pl.Series(talib.HT_SINE(s.to_numpy())[0]),
990
+ return_dtype=pl.Float64,
991
+ )
992
+
993
+
994
+ def ht_trendmode(expr: Union[Expr, str]) -> Expr:
995
+ """希尔伯特变换趋势模式 (Hilbert Transform Trend vs Cycle Mode)"""
996
+ import talib
997
+ e = _ensure_expr(expr)
998
+ return e.map_batches(
999
+ lambda s: pl.Series(talib.HT_TRENDMODE(s.to_numpy())),
1000
+ return_dtype=pl.Float64,
1001
+ )
1002
+
1003
+
1004
+ def acos(expr: Union[Expr, str]) -> Expr:
1005
+ """反余弦 (Inverse Cosine)"""
1006
+ import talib
1007
+ e = _ensure_expr(expr)
1008
+ return e.map_batches(lambda s: pl.Series(talib.ACOS(s.to_numpy())), return_dtype=pl.Float64)
1009
+
1010
+
1011
+ def asin(expr: Union[Expr, str]) -> Expr:
1012
+ """反正弦 (Inverse Sine)"""
1013
+ import talib
1014
+ e = _ensure_expr(expr)
1015
+ return e.map_batches(lambda s: pl.Series(talib.ASIN(s.to_numpy())), return_dtype=pl.Float64)
1016
+
1017
+
1018
+ def atan(expr: Union[Expr, str]) -> Expr:
1019
+ """反正切 (Inverse Tangent)"""
1020
+ import talib
1021
+ e = _ensure_expr(expr)
1022
+ return e.map_batches(lambda s: pl.Series(talib.ATAN(s.to_numpy())), return_dtype=pl.Float64)
1023
+
1024
+
1025
+ def cos(expr: Union[Expr, str]) -> Expr:
1026
+ """余弦 (Cosine)"""
1027
+ import talib
1028
+ e = _ensure_expr(expr)
1029
+ return e.map_batches(lambda s: pl.Series(talib.COS(s.to_numpy())), return_dtype=pl.Float64)
1030
+
1031
+
1032
+ def cosh(expr: Union[Expr, str]) -> Expr:
1033
+ """双曲余弦 (Hyperbolic Cosine)"""
1034
+ import talib
1035
+ e = _ensure_expr(expr)
1036
+ return e.map_batches(lambda s: pl.Series(talib.COSH(s.to_numpy())), return_dtype=pl.Float64)
1037
+
1038
+
1039
+ def sin(expr: Union[Expr, str]) -> Expr:
1040
+ """正弦 (Sine)"""
1041
+ import talib
1042
+ e = _ensure_expr(expr)
1043
+ return e.map_batches(lambda s: pl.Series(talib.SIN(s.to_numpy())), return_dtype=pl.Float64)
1044
+
1045
+
1046
+ def sinh(expr: Union[Expr, str]) -> Expr:
1047
+ """双曲正弦 (Hyperbolic Sine)"""
1048
+ import talib
1049
+ e = _ensure_expr(expr)
1050
+ return e.map_batches(lambda s: pl.Series(talib.SINH(s.to_numpy())), return_dtype=pl.Float64)
1051
+
1052
+
1053
+ def sqrt(expr: Union[Expr, str]) -> Expr:
1054
+ """平方根 (Square Root)"""
1055
+ import talib
1056
+ e = _ensure_expr(expr)
1057
+ return e.map_batches(lambda s: pl.Series(talib.SQRT(s.to_numpy())), return_dtype=pl.Float64)
1058
+
1059
+
1060
+ def tan(expr: Union[Expr, str]) -> Expr:
1061
+ """正切 (Tangent)"""
1062
+ import talib
1063
+ e = _ensure_expr(expr)
1064
+ return e.map_batches(lambda s: pl.Series(talib.TAN(s.to_numpy())), return_dtype=pl.Float64)
1065
+
1066
+
1067
+ def tanh(expr: Union[Expr, str]) -> Expr:
1068
+ """双曲正切 (Hyperbolic Tangent)"""
1069
+ import talib
1070
+ e = _ensure_expr(expr)
1071
+ return e.map_batches(lambda s: pl.Series(talib.TANH(s.to_numpy())), return_dtype=pl.Float64)
1072
+
1073
+
1074
+ def exp(expr: Union[Expr, str]) -> Expr:
1075
+ """指数函数 (Exponential)"""
1076
+ import talib
1077
+ e = _ensure_expr(expr)
1078
+ return e.map_batches(lambda s: pl.Series(talib.EXP(s.to_numpy())), return_dtype=pl.Float64)
1079
+
1080
+
1081
+ def ln(expr: Union[Expr, str]) -> Expr:
1082
+ """自然对数 (Natural Log)"""
1083
+ import talib
1084
+ e = _ensure_expr(expr)
1085
+ return e.map_batches(lambda s: pl.Series(talib.LN(s.to_numpy())), return_dtype=pl.Float64)
1086
+
1087
+
1088
+ def log10(expr: Union[Expr, str]) -> Expr:
1089
+ """常用对数 (Log10)"""
1090
+ import talib
1091
+ e = _ensure_expr(expr)
1092
+ return e.map_batches(lambda s: pl.Series(talib.LOG10(s.to_numpy())), return_dtype=pl.Float64)
1093
+
1094
+
1095
+ def ceil(expr: Union[Expr, str]) -> Expr:
1096
+ """向上取整 (Ceiling)"""
1097
+ import talib
1098
+ e = _ensure_expr(expr)
1099
+ return e.map_batches(lambda s: pl.Series(talib.CEIL(s.to_numpy())), return_dtype=pl.Float64)
1100
+
1101
+
1102
+ def floor(expr: Union[Expr, str]) -> Expr:
1103
+ """向下取整 (Floor)"""
1104
+ import talib
1105
+ e = _ensure_expr(expr)
1106
+ return e.map_batches(lambda s: pl.Series(talib.FLOOR(s.to_numpy())), return_dtype=pl.Float64)
1107
+
1108
+
1109
+ def add(expr_a: Union[Expr, str], expr_b: Union[Expr, str]) -> Expr:
1110
+ """加法 (Add)"""
1111
+ import talib
1112
+ e_a = _ensure_expr(expr_a)
1113
+ e_b = _ensure_expr(expr_b)
1114
+ return e_a.map_batches(lambda s: pl.Series(talib.ADD(s.to_numpy(), e_b.eval(pl.col(s.name))[0].to_numpy())))
1115
+
1116
+
1117
+ def sub(expr_a: Union[Expr, str], expr_b: Union[Expr, str]) -> Expr:
1118
+ """减法 (Subtract)"""
1119
+ return _ensure_expr(expr_a) - _ensure_expr(expr_b)
1120
+
1121
+
1122
+ def mult(expr_a: Union[Expr, str], expr_b: Union[Expr, str]) -> Expr:
1123
+ """乘法 (Multiply)"""
1124
+ return _ensure_expr(expr_a) * _ensure_expr(expr_b)
1125
+
1126
+
1127
+ def div(expr_a: Union[Expr, str], expr_b: Union[Expr, str]) -> Expr:
1128
+ """除法 (Divide)"""
1129
+ return _ensure_expr(expr_a) / _ensure_expr(expr_b)
1130
+
1131
+
1132
+ def max(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
1133
+ """滚动最大值 (Rolling Maximum)"""
1134
+ import talib
1135
+ e = _ensure_expr(expr)
1136
+ return e.map_batches(
1137
+ lambda s: pl.Series(talib.MAX(s.to_numpy(), timeperiod=timeperiod)),
1138
+ return_dtype=pl.Float64,
1139
+ )
1140
+
1141
+
1142
+ def min(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
1143
+ """滚动最小值 (Rolling Minimum)"""
1144
+ import talib
1145
+ e = _ensure_expr(expr)
1146
+ return e.map_batches(
1147
+ lambda s: pl.Series(talib.MIN(s.to_numpy(), timeperiod=timeperiod)),
1148
+ return_dtype=pl.Float64,
1149
+ )
1150
+
1151
+
1152
+ def sum(expr: Union[Expr, str], timeperiod: int = 30) -> Expr:
1153
+ """滚动求和 (Rolling Sum)"""
1154
+ import talib
1155
+ e = _ensure_expr(expr)
1156
+ return e.map_batches(
1157
+ lambda s: pl.Series(talib.SUM(s.to_numpy(), timeperiod=timeperiod)),
1158
+ return_dtype=pl.Float64,
1159
+ )
1160
+
1161
+
1162
+ def _wrap_and_register(name: str, func, param_docs: str = ""):
1163
+ """包装函数并注册到算子注册表"""
1164
+ def wrapper(*args, **kwargs):
1165
+ return func(*args, **kwargs)
1166
+
1167
+ wrapper.__name__ = f"talib_{name}"
1168
+ wrapper.__doc__ = f"TA-Lib {name}\n\n {param_docs}\n "
1169
+ register_operator(OperatorCategory.TALIB, f"talib_{name}")(wrapper)
1170
+ globals()[f"talib_{name}"] = wrapper
1171
+ return wrapper
1172
+
1173
+
1174
+ _wrap_and_register("sma", sma, "简单移动平均 (Simple Moving Average)")
1175
+ _wrap_and_register("ema", ema, "指数移动平均 (Exponential Moving Average)")
1176
+ _wrap_and_register("wma", wma, "加权移动平均 (Weighted Moving Average)")
1177
+ _wrap_and_register("dema", dema, "双重指数移动平均 (Double EMA)")
1178
+ _wrap_and_register("tema", tema, "三重指数移动平均 (Triple EMA)")
1179
+ _wrap_and_register("trima", trima, "三角移动平均 (Triangular MA)")
1180
+ _wrap_and_register("kama", kama, "考夫曼自适应移动平均 (KAMA)")
1181
+ _wrap_and_register("t3", t3, "T3 移动平均")
1182
+ _wrap_and_register("ht_trendline", ht_trendline, "希尔伯特变换趋势线")
1183
+ _wrap_and_register("bbands_upper", bbands_upper, "布林带上轨")
1184
+ _wrap_and_register("bbands_middle", bbands_middle, "布林带中轨")
1185
+ _wrap_and_register("bbands_lower", bbands_lower, "布林带下轨")
1186
+ _wrap_and_register("ma", ma, "通用移动平均")
1187
+
1188
+ _wrap_and_register("rsi", rsi, "相对强弱指标 (RSI)")
1189
+ _wrap_and_register("macd_line", macd_line, "MACD 线")
1190
+ _wrap_and_register("macd_signal", macd_signal, "MACD 信号线")
1191
+ _wrap_and_register("macd_hist", macd_hist, "MACD 柱状图")
1192
+ _wrap_and_register("stoch_k", stoch_k, "随机指标 K")
1193
+ _wrap_and_register("stoch_d", stoch_d, "随机指标 D")
1194
+ _wrap_and_register("willr", willr, "威廉指标")
1195
+ _wrap_and_register("cci", cci, "商品通道指标")
1196
+ _wrap_and_register("adx", adx, "平均趋向指数")
1197
+ _wrap_and_register("adxr", adxr, "平均趋向指数评级")
1198
+ _wrap_and_register("mfi", mfi, "资金流量指标")
1199
+ _wrap_and_register("mom", mom, "动量指标")
1200
+ _wrap_and_register("roc", roc, "变动率指标")
1201
+ _wrap_and_register("rocp", rocp, "变动率百分比")
1202
+ _wrap_and_register("trix", trix, "三重指数移动平均线")
1203
+ _wrap_and_register("ultosc", ultosc, "终极波动指标")
1204
+ _wrap_and_register("dx", dx, "方向指标")
1205
+ _wrap_and_register("minus_di", minus_di, "负方向指标")
1206
+ _wrap_and_register("plus_di", plus_di, "正方向指标")
1207
+ _wrap_and_register("ppo", ppo, "价格振荡器")
1208
+
1209
+ _wrap_and_register("atr", atr, "平均真实范围")
1210
+ _wrap_and_register("natr", natr, "标准化平均真实范围")
1211
+ _wrap_and_register("trange", trange, "真实范围")
1212
+
1213
+ _wrap_and_register("ad", ad, "累积/派发线")
1214
+ _wrap_and_register("adosc", adosc, "蔡金震荡器")
1215
+ _wrap_and_register("obv", obv, "能量潮")
1216
+
1217
+ _wrap_and_register("avgprice", avgprice, "平均价格")
1218
+ _wrap_and_register("medprice", medprice, "中间价格")
1219
+ _wrap_and_register("typprice", typprice, "典型价格")
1220
+ _wrap_and_register("wclprice", wclprice, "加权收盘价")
1221
+
1222
+ _wrap_and_register("beta", beta, "贝塔系数")
1223
+ _wrap_and_register("correl", correl, "相关系数")
1224
+ _wrap_and_register("linearreg", linearreg, "线性回归")
1225
+ _wrap_and_register("linearreg_angle", linearreg_angle, "线性回归角度")
1226
+ _wrap_and_register("linearreg_intercept", linearreg_intercept, "线性回归截距")
1227
+ _wrap_and_register("linearreg_slope", linearreg_slope, "线性回归斜率")
1228
+ _wrap_and_register("stddev", stddev, "标准差")
1229
+ _wrap_and_register("tsf", tsf, "时间序列预测")
1230
+ _wrap_and_register("var", var, "方差")
1231
+
1232
+ _wrap_and_register("ht_dcperiod", ht_dcperiod, "希尔伯特变换主导周期")
1233
+ _wrap_and_register("ht_dcphase", ht_dcphase, "希尔伯特变换主导周期相位")
1234
+ _wrap_and_register("ht_phasor", ht_phasor, "希尔伯特变换相位")
1235
+ _wrap_and_register("ht_sine", ht_sine, "希尔伯特变换正弦")
1236
+ _wrap_and_register("ht_trendmode", ht_trendmode, "希尔伯特变换趋势模式")
1237
+
1238
+ _wrap_and_register("acos", acos, "反余弦")
1239
+ _wrap_and_register("asin", asin, "反正弦")
1240
+ _wrap_and_register("atan", atan, "反正切")
1241
+ _wrap_and_register("cos", cos, "余弦")
1242
+ _wrap_and_register("cosh", cosh, "双曲余弦")
1243
+ _wrap_and_register("sin", sin, "正弦")
1244
+ _wrap_and_register("sinh", sinh, "双曲正弦")
1245
+ _wrap_and_register("sqrt", sqrt, "平方根")
1246
+ _wrap_and_register("tan", tan, "正切")
1247
+ _wrap_and_register("tanh", tanh, "双曲正切")
1248
+ _wrap_and_register("exp", exp, "指数函数")
1249
+ _wrap_and_register("ln", ln, "自然对数")
1250
+ _wrap_and_register("log10", log10, "常用对数")
1251
+ _wrap_and_register("ceil", ceil, "向上取整")
1252
+ _wrap_and_register("floor", floor, "向下取整")
1253
+
1254
+ _wrap_and_register("add", add, "加法")
1255
+ _wrap_and_register("sub", sub, "减法")
1256
+ _wrap_and_register("mult", mult, "乘法")
1257
+ _wrap_and_register("div", div, "除法")
1258
+
1259
+ _wrap_and_register("max", max, "滚动最大值")
1260
+ _wrap_and_register("min", min, "滚动最小值")
1261
+ _wrap_and_register("sum", sum, "滚动求和")
1262
+
1263
+ _wrap_and_register("macd", macd, "MACD (完整)")
1264
+ _wrap_and_register("stoch", stoch, "随机指标 (完整)")
1265
+ _wrap_and_register("minus_dm", minus_dm, "负向动量")
1266
+ _wrap_and_register("plus_dm", plus_dm, "正向动量")
1267
+ _wrap_and_register("aroon", aroon, "阿隆指标")
1268
+ _wrap_and_register("aroondown", aroondown, "阿隆下降线")
1269
+ _wrap_and_register("aroonup", aroonup, "阿隆上升线")
1270
+ _wrap_and_register("aroonosc", aroonosc, "阿隆振荡指标")
1271
+ _wrap_and_register("bop", bop, "力量指标")
1272
+ _wrap_and_register("stochf", stochf, "快速随机指标")
1273
+ _wrap_and_register("stochrsi", stochrsi, "随机 RSI (完整)")
1274
+ _wrap_and_register("stochrsi_k", stochrsi_k, "随机 RSI %K")
1275
+ _wrap_and_register("stochrsi_d", stochrsi_d, "随机 RSI %D")
1276
+ _wrap_and_register("macdext", macdext, "扩展 MACD")
1277
+ _wrap_and_register("macdfix", macdfix, "固定周期 MACD")
1278
+ _wrap_and_register("cmo", cmo, "钱德动量摆动指标")
1279
+ _wrap_and_register("apo", apo, "绝对价格震荡")
1280
+
1281
+ _wrap_and_register("cdl_doji", cdl_doji, "十字星")
1282
+ _wrap_and_register("cdl_hammer", cdl_hammer, "锤子线")
1283
+ _wrap_and_register("cdl_engulfing", cdl_engulfing, "吞没形态")
1284
+ _wrap_and_register("cdl_morningstar", cdl_morningstar, "晨星")
1285
+ _wrap_and_register("cdl_eveningstar", cdl_eveningstar, "暮星")
1286
+ _wrap_and_register("cdl_hangingman", cdl_hangingman, "上吊线")
1287
+ _wrap_and_register("cdl_shootingstar", cdl_shootingstar, "射击之星")
1288
+ _wrap_and_register("cdl_harami", cdl_harami, "孕线形态")
1289
+ _wrap_and_register("cdl_piercing", cdl_piercing, "刺透形态")
1290
+ _wrap_and_register("cdl_darkcloudcover", cdl_darkcloudcover, "乌云盖顶")
1291
+ _wrap_and_register("cdl_spinningtop", cdl_spinningtop, "纺锤顶")
1292
+ _wrap_and_register("cdl_3whitesoldiers", cdl_3whitesoldiers, "三只白兵")
1293
+ _wrap_and_register("cdl_3blackcrows", cdl_3blackcrows, "三只乌鸦")