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.
- QuantNodes/__init__.py +15 -0
- QuantNodes/__main__.py +14 -0
- QuantNodes/agent/__init__.py +158 -0
- QuantNodes/agent/agents/__init__.py +13 -0
- QuantNodes/agent/agents/definition.py +180 -0
- QuantNodes/agent/agents/manager.py +73 -0
- QuantNodes/agent/config/__init__.py +34 -0
- QuantNodes/agent/config/executor.py +958 -0
- QuantNodes/agent/config/loader.py +427 -0
- QuantNodes/agent/config/templates/bollinger_bands.yaml +84 -0
- QuantNodes/agent/config/templates/dual_ma.yaml +72 -0
- QuantNodes/agent/config/templates/empty.yaml +56 -0
- QuantNodes/agent/config/templates/mean_reversion.yaml +47 -0
- QuantNodes/agent/config/templates/mean_reversion_zscore.yaml +90 -0
- QuantNodes/agent/config/templates/momentum.yaml +81 -0
- QuantNodes/agent/config/templates/momentum_breakout.yaml +84 -0
- QuantNodes/agent/config/templates/rsi_strategy.yaml +72 -0
- QuantNodes/agent/config/templates/volume_price.yaml +86 -0
- QuantNodes/agent/config/types.py +156 -0
- QuantNodes/agent/config_mapper.py +293 -0
- QuantNodes/agent/core/__init__.py +19 -0
- QuantNodes/agent/core/dream.py +47 -0
- QuantNodes/agent/core/quant_dream.py +274 -0
- QuantNodes/agent/cron_jobs.py +314 -0
- QuantNodes/agent/nanobot_bridge.py +242 -0
- QuantNodes/agent/permission/__init__.py +30 -0
- QuantNodes/agent/permission/defaults.py +36 -0
- QuantNodes/agent/permission/evaluate.py +41 -0
- QuantNodes/agent/permission/models.py +59 -0
- QuantNodes/agent/permission/service.py +133 -0
- QuantNodes/agent/providers/__init__.py +11 -0
- QuantNodes/agent/providers/base.py +102 -0
- QuantNodes/agent/providers/quantnodes.py +610 -0
- QuantNodes/agent/providers/rate_limiter.py +326 -0
- QuantNodes/agent/providers/registry.py +163 -0
- QuantNodes/agent/skills/__init__.py +20 -0
- QuantNodes/agent/skills/base.py +118 -0
- QuantNodes/agent/skills/bridge.py +73 -0
- QuantNodes/agent/skills/factor/__init__.py +14 -0
- QuantNodes/agent/skills/factor/correlation.py +99 -0
- QuantNodes/agent/skills/factor/group_backtest.py +114 -0
- QuantNodes/agent/skills/factor/ic_analysis.py +106 -0
- QuantNodes/agent/skills/loader.py +107 -0
- QuantNodes/agent/skills/registry.py +105 -0
- QuantNodes/agent/skills/strategy/__init__.py +16 -0
- QuantNodes/agent/skills/strategy/bollinger.py +86 -0
- QuantNodes/agent/skills/strategy/dual_ma.py +82 -0
- QuantNodes/agent/skills/strategy/momentum.py +74 -0
- QuantNodes/agent/skills/strategy/rsi_reversal.py +99 -0
- QuantNodes/agent/skills_quant/__init__.py +14 -0
- QuantNodes/agent/skills_quant/backtest-analyze/SKILL.md +42 -0
- QuantNodes/agent/skills_quant/config-driven/SKILL.md +72 -0
- QuantNodes/agent/skills_quant/factor-research/SKILL.md +40 -0
- QuantNodes/agent/skills_quant/quant-dream/SKILL.md +55 -0
- QuantNodes/agent/skills_quant/risk-management/SKILL.md +45 -0
- QuantNodes/agent/skills_quant/strategy-design/SKILL.md +43 -0
- QuantNodes/agent/templates/__init__.py +4 -0
- QuantNodes/agent/tools/__init__.py +173 -0
- QuantNodes/agent/tools/_workspace.py +51 -0
- QuantNodes/agent/tools/alpha_backtest.py +328 -0
- QuantNodes/agent/tools/alpha_evaluate.py +493 -0
- QuantNodes/agent/tools/backtest.py +226 -0
- QuantNodes/agent/tools/base.py +133 -0
- QuantNodes/agent/tools/code_search.py +207 -0
- QuantNodes/agent/tools/config_backtest.py +401 -0
- QuantNodes/agent/tools/context.py +97 -0
- QuantNodes/agent/tools/dream_skill.py +77 -0
- QuantNodes/agent/tools/echo.py +38 -0
- QuantNodes/agent/tools/factor.py +231 -0
- QuantNodes/agent/tools/file_ops.py +201 -0
- QuantNodes/agent/tools/git_ops.py +190 -0
- QuantNodes/agent/tools/operator_lookup.py +218 -0
- QuantNodes/agent/tools/output_truncation.py +77 -0
- QuantNodes/agent/tools/path_check.py +43 -0
- QuantNodes/agent/tools/pipeline.py +62 -0
- QuantNodes/agent/tools/registry.py +150 -0
- QuantNodes/agent/tools/sandbox.py +62 -0
- QuantNodes/agent/tools/shell_safety.py +63 -0
- QuantNodes/agent/tools/strategy.py +106 -0
- QuantNodes/agent/tools/task.py +171 -0
- QuantNodes/agent/tools/web_fetch.py +142 -0
- QuantNodes/agent/tools/web_search.py +114 -0
- QuantNodes/agent/tools/wiki.py +370 -0
- QuantNodes/agent/utils/__init__.py +11 -0
- QuantNodes/agent/utils/helpers.py +43 -0
- QuantNodes/agent/utils/prompt_templates.py +30 -0
- QuantNodes/agent/workflows/__init__.py +20 -0
- QuantNodes/agent/workflows/implementations/__init__.py +8 -0
- QuantNodes/agent/workflows/implementations/alpha_gpt.py +508 -0
- QuantNodes/agent/workflows/implementations/mcts.py +442 -0
- QuantNodes/agent/workflows/parsers.py +44 -0
- QuantNodes/agent/workflows/registry.py +119 -0
- QuantNodes/agent/workflows/step_agent.py +219 -0
- QuantNodes/agent/workflows/tool.py +198 -0
- QuantNodes/ai/__init__.py +93 -0
- QuantNodes/ai/llm/__init__.py +75 -0
- QuantNodes/ai/llm/base.py +233 -0
- QuantNodes/ai/llm/decorators.py +281 -0
- QuantNodes/ai/llm/gateway.py +571 -0
- QuantNodes/ai/llm/null.py +76 -0
- QuantNodes/ai/llm/openai.py +435 -0
- QuantNodes/ai/optimizer.py +405 -0
- QuantNodes/ai/prompts/__init__.py +229 -0
- QuantNodes/ai/sandbox.py +371 -0
- QuantNodes/ai/sandbox_pandas_bridge.py +150 -0
- QuantNodes/ai/strategy_gen.py +396 -0
- QuantNodes/backtest/__init__.py +64 -0
- QuantNodes/backtest/backtest_node.py +188 -0
- QuantNodes/backtest/broker_node.py +378 -0
- QuantNodes/backtest/config_runner.py +397 -0
- QuantNodes/backtest/config_strategy.py +64 -0
- QuantNodes/backtest/risk_node.py +360 -0
- QuantNodes/backtest/strategy_node.py +268 -0
- QuantNodes/cache_node/__init__.py +19 -0
- QuantNodes/cache_node/base.py +244 -0
- QuantNodes/cache_node/cache_store.py +99 -0
- QuantNodes/cache_node/metadata.py +100 -0
- QuantNodes/cli/__init__.py +109 -0
- QuantNodes/cli/_helpers.py +511 -0
- QuantNodes/cli/command.py +110 -0
- QuantNodes/cli/commands/__init__.py +69 -0
- QuantNodes/cli/commands/agent.py +158 -0
- QuantNodes/cli/commands/alpha.py +951 -0
- QuantNodes/cli/commands/chat.py +38 -0
- QuantNodes/cli/commands/evolve.py +120 -0
- QuantNodes/cli/commands/factor.py +569 -0
- QuantNodes/cli/commands/init.py +190 -0
- QuantNodes/cli/commands/run.py +259 -0
- QuantNodes/cli/commands/serve.py +398 -0
- QuantNodes/cli/commands/version.py +120 -0
- QuantNodes/cli/enhanced.py +146 -0
- QuantNodes/conf_node/__init__.py +37 -0
- QuantNodes/conf_node/base.py +120 -0
- QuantNodes/conf_node/env_config.py +132 -0
- QuantNodes/conf_node/ini_config.py +70 -0
- QuantNodes/conf_node/json_config.py +69 -0
- QuantNodes/conf_node/yaml_config.py +78 -0
- QuantNodes/constants.py +17 -0
- QuantNodes/core/__init__.py +196 -0
- QuantNodes/core/_lookback_helpers.py +49 -0
- QuantNodes/core/ast_parser.py +198 -0
- QuantNodes/core/base.py +61 -0
- QuantNodes/core/cache_manager.py +344 -0
- QuantNodes/core/cache_utils.py +150 -0
- QuantNodes/core/cond_builder.py +53 -0
- QuantNodes/core/config.py +170 -0
- QuantNodes/core/constants.py +48 -0
- QuantNodes/core/control.py +412 -0
- QuantNodes/core/data_preprocessing.py +453 -0
- QuantNodes/core/data_source.py +46 -0
- QuantNodes/core/events.py +178 -0
- QuantNodes/core/evolution/__init__.py +22 -0
- QuantNodes/core/evolution/loop.py +583 -0
- QuantNodes/core/evolution/operators.py +289 -0
- QuantNodes/core/evolution/settings.py +44 -0
- QuantNodes/core/expression.py +841 -0
- QuantNodes/core/feedback/__init__.py +38 -0
- QuantNodes/core/feedback/channels.py +182 -0
- QuantNodes/core/feedback/collector.py +91 -0
- QuantNodes/core/feedback/dataclass.py +239 -0
- QuantNodes/core/feedback/llm_judge.py +138 -0
- QuantNodes/core/knowledge/__init__.py +69 -0
- QuantNodes/core/knowledge/knowledge_base.py +217 -0
- QuantNodes/core/knowledge/lineage_compress.py +196 -0
- QuantNodes/core/knowledge/lineage_expand.py +123 -0
- QuantNodes/core/knowledge/metrics/__init__.py +43 -0
- QuantNodes/core/knowledge/metrics/evaluator.py +176 -0
- QuantNodes/core/knowledge/metrics/metrics.py +220 -0
- QuantNodes/core/knowledge/rag_prompt.py +196 -0
- QuantNodes/core/knowledge/retriever.py +209 -0
- QuantNodes/core/lambda_node.py +81 -0
- QuantNodes/core/monitoring/__init__.py +22 -0
- QuantNodes/core/monitoring/collector.py +292 -0
- QuantNodes/core/monitoring/dashboard.py +365 -0
- QuantNodes/core/node.py +375 -0
- QuantNodes/core/pandas_utils.py +504 -0
- QuantNodes/core/parallel/__init__.py +15 -0
- QuantNodes/core/parallel/worker.py +140 -0
- QuantNodes/core/parallel/worker_process.py +265 -0
- QuantNodes/core/path_utils.py +73 -0
- QuantNodes/core/pipeline.py +328 -0
- QuantNodes/core/plugin.py +135 -0
- QuantNodes/core/quality_gate/__init__.py +32 -0
- QuantNodes/core/quality_gate/complexity.py +94 -0
- QuantNodes/core/quality_gate/consistency.py +26 -0
- QuantNodes/core/quality_gate/node.py +97 -0
- QuantNodes/core/quality_gate/redundancy.py +51 -0
- QuantNodes/core/quality_gate/settings.py +43 -0
- QuantNodes/core/quality_gate/zoo.py +98 -0
- QuantNodes/core/serializable.py +116 -0
- QuantNodes/core/serialization.py +673 -0
- QuantNodes/core/tools.py +333 -0
- QuantNodes/core/trajectory/__init__.py +25 -0
- QuantNodes/core/trajectory/entry.py +116 -0
- QuantNodes/core/trajectory/lineage.py +67 -0
- QuantNodes/core/trajectory/pool.py +211 -0
- QuantNodes/core/trajectory/selector.py +140 -0
- QuantNodes/core/visualization/__init__.py +33 -0
- QuantNodes/core/visualization/builder.py +233 -0
- QuantNodes/core/visualization/gate_breakdown.py +140 -0
- QuantNodes/core/visualization/lineage_dag.py +203 -0
- QuantNodes/core/visualization/metric_distribution.py +125 -0
- QuantNodes/core/visualization/report.py +68 -0
- QuantNodes/database_node/__init__.py +69 -0
- QuantNodes/database_node/base.py +135 -0
- QuantNodes/database_node/clickhouse_node.py +272 -0
- QuantNodes/database_node/csv_node.py +83 -0
- QuantNodes/database_node/duckdb_node.py +86 -0
- QuantNodes/database_node/factory.py +83 -0
- QuantNodes/database_node/mysql_node.py +100 -0
- QuantNodes/database_node/parquet_node.py +75 -0
- QuantNodes/database_node/sqlite_node.py +67 -0
- QuantNodes/factor_node/__init__.py +50 -0
- QuantNodes/factor_node/factor.py +563 -0
- QuantNodes/factor_node/factor_db.py +421 -0
- QuantNodes/factor_node/factor_functions/__init__.py +252 -0
- QuantNodes/factor_node/factor_functions/_helpers.py +358 -0
- QuantNodes/factor_node/factor_functions/_helpers_debug.py +317 -0
- QuantNodes/factor_node/factor_functions/composite_ops.py +136 -0
- QuantNodes/factor_node/factor_functions/math_ops.py +433 -0
- QuantNodes/factor_node/factor_functions/section_ops.py +290 -0
- QuantNodes/factor_node/factor_functions/talib_ops.py +1293 -0
- QuantNodes/factor_node/factor_functions/time_ops.py +535 -0
- QuantNodes/factor_node/factor_operation.py +1115 -0
- QuantNodes/factor_node/factor_table.py +1073 -0
- QuantNodes/factor_node/quant_nodes_object.py +60 -0
- QuantNodes/mcp_server/__init__.py +27 -0
- QuantNodes/mcp_server/__main__.py +4 -0
- QuantNodes/mcp_server/server.py +272 -0
- QuantNodes/methods/__init__.py +28 -0
- QuantNodes/methods/pipeline.py +100 -0
- QuantNodes/methods/sandbox.py +102 -0
- QuantNodes/monitor/__init__.py +27 -0
- QuantNodes/monitor/agent_tools/__init__.py +5 -0
- QuantNodes/monitor/agent_tools/monitor_tool.py +98 -0
- QuantNodes/monitor/agent_tools/schedule_tool.py +98 -0
- QuantNodes/monitor/agent_tools/version_tool.py +133 -0
- QuantNodes/monitor/monitor/__init__.py +6 -0
- QuantNodes/monitor/monitor/alerter.py +60 -0
- QuantNodes/monitor/monitor/collector.py +164 -0
- QuantNodes/monitor/monitor/dashboard.py +115 -0
- QuantNodes/monitor/monitor/drift.py +190 -0
- QuantNodes/monitor/scheduler/__init__.py +4 -0
- QuantNodes/monitor/scheduler/runner.py +133 -0
- QuantNodes/monitor/scheduler/scheduler.py +184 -0
- QuantNodes/monitor/storage/__init__.py +16 -0
- QuantNodes/monitor/storage/models.py +70 -0
- QuantNodes/monitor/storage/repository.py +407 -0
- QuantNodes/monitor/version/__init__.py +4 -0
- QuantNodes/monitor/version/diff.py +81 -0
- QuantNodes/monitor/version/version_manager.py +182 -0
- QuantNodes/operator_node/__init__.py +28 -0
- QuantNodes/operator_node/base.py +97 -0
- QuantNodes/operator_node/query_node.py +129 -0
- QuantNodes/operator_node/sql_builder.py +125 -0
- QuantNodes/operator_node/sql_utils.py +172 -0
- QuantNodes/operator_node/transform.py +130 -0
- QuantNodes/operators/__init__.py +90 -0
- QuantNodes/operators/_engine.py +108 -0
- QuantNodes/operators/composite.py +161 -0
- QuantNodes/operators/composite_dag.py +667 -0
- QuantNodes/operators/composite_dag_ops.py +343 -0
- QuantNodes/operators/composite_dag_pandas_ops.py +382 -0
- QuantNodes/operators/custom.py +408 -0
- QuantNodes/operators/facade.py +164 -0
- QuantNodes/operators/math.py +163 -0
- QuantNodes/operators/proxy.py +29 -0
- QuantNodes/operators/registry.py +144 -0
- QuantNodes/operators/section.py +99 -0
- QuantNodes/operators/talib.py +757 -0
- QuantNodes/operators/templates.py +95 -0
- QuantNodes/operators/time_series.py +136 -0
- QuantNodes/prompts/__init__.py +20 -0
- QuantNodes/prompts/backtest/__init__.py +12 -0
- QuantNodes/prompts/backtest/factor_based.py +86 -0
- QuantNodes/prompts/backtest/standard.py +73 -0
- QuantNodes/prompts/factor/__init__.py +14 -0
- QuantNodes/prompts/factor/correlation.py +77 -0
- QuantNodes/prompts/factor/group_backtest.py +86 -0
- QuantNodes/prompts/factor/ic_analysis.py +91 -0
- QuantNodes/prompts/strategy/__init__.py +18 -0
- QuantNodes/prompts/strategy/market_neutral.py +96 -0
- QuantNodes/prompts/strategy/mean_reversion.py +107 -0
- QuantNodes/prompts/strategy/momentum.py +160 -0
- QuantNodes/prompts/strategy/pairs_trading.py +107 -0
- QuantNodes/prompts/strategy/trend_following.py +96 -0
- QuantNodes/research/README.md +106 -0
- QuantNodes/research/__init__.py +154 -0
- QuantNodes/research/_legacy_3c/__init__.py +61 -0
- QuantNodes/research/_legacy_3c/auto_researcher.py +289 -0
- QuantNodes/research/_legacy_3c/factor_evaluator.py +560 -0
- QuantNodes/research/_legacy_3c/factor_miner.py +318 -0
- QuantNodes/research/_legacy_3c/mcts_search.py +324 -0
- QuantNodes/research/factor_test/__init__.py +25 -0
- QuantNodes/research/factor_test/config.py +184 -0
- QuantNodes/research/factor_test/config_builder.py +276 -0
- QuantNodes/research/factor_test/e2e/data_prep.py +163 -0
- QuantNodes/research/factor_test/e2e/run_evolution_e2e.py +309 -0
- QuantNodes/research/factor_test/evolution_adapter.py +231 -0
- QuantNodes/research/factor_test/feedback_wrapper.py +102 -0
- QuantNodes/research/factor_test/ifind_db/__init__.py +7 -0
- QuantNodes/research/factor_test/ifind_db/fetcher.py +224 -0
- QuantNodes/research/factor_test/ifind_db/ifind_database.py +689 -0
- QuantNodes/research/factor_test/nodes/__init__.py +1 -0
- QuantNodes/research/factor_test/nodes/_base.py +91 -0
- QuantNodes/research/factor_test/nodes/adjust_date_node.py +48 -0
- QuantNodes/research/factor_test/nodes/configs.py +240 -0
- QuantNodes/research/factor_test/nodes/factor_neutralize_node.py +87 -0
- QuantNodes/research/factor_test/nodes/factor_preprocess_node.py +222 -0
- QuantNodes/research/factor_test/nodes/factor_score_node.py +141 -0
- QuantNodes/research/factor_test/nodes/factor_test_report_node.py +153 -0
- QuantNodes/research/factor_test/nodes/group_analyzer_node.py +317 -0
- QuantNodes/research/factor_test/nodes/ic_analyzer_node.py +112 -0
- QuantNodes/research/factor_test/nodes/load_data_node.py +100 -0
- QuantNodes/research/factor_test/nodes/long_short_node.py +93 -0
- QuantNodes/research/factor_test/nodes/neutralizers.py +222 -0
- QuantNodes/research/factor_test/nodes/preprocess_strategies.py +277 -0
- QuantNodes/research/factor_test/nodes/risk_correlation_node.py +112 -0
- QuantNodes/research/factor_test/nodes/sample_pool_filter_node.py +110 -0
- QuantNodes/research/factor_test/nodes/tradability_filter_node.py +92 -0
- QuantNodes/research/factor_test/pipeline_runner.py +305 -0
- QuantNodes/research/factor_test/pipeline_spec.py +216 -0
- QuantNodes/research/factor_test/utils/__init__.py +26 -0
- QuantNodes/research/factor_test/utils/constants.py +86 -0
- QuantNodes/research/factor_test/utils/data_loader.py +141 -0
- QuantNodes/research/factor_test/utils/date_utils.py +232 -0
- QuantNodes/research/factor_test/utils/file_loaders.py +150 -0
- QuantNodes/research/factor_test/utils/labels.py +37 -0
- QuantNodes/research/factor_test/utils/metrics_extractor.py +55 -0
- QuantNodes/research/factor_test/utils/performance_metrics.py +175 -0
- QuantNodes/research/factor_test/utils/safe_load.py +106 -0
- QuantNodes/research/quant_alpha/CHANGELOG.md +80 -0
- QuantNodes/research/quant_alpha/README.md +142 -0
- QuantNodes/research/quant_alpha/__init__.py +45 -0
- QuantNodes/research/quant_alpha/adapters/__init__.py +99 -0
- QuantNodes/research/quant_alpha/adapters/calculator.py +503 -0
- QuantNodes/research/quant_alpha/adapters/expression.py +387 -0
- QuantNodes/research/quant_alpha/alpha101_design/__init__.py +50 -0
- QuantNodes/research/quant_alpha/alpha101_design/few_shot_examples.py +243 -0
- QuantNodes/research/quant_alpha/alpha101_design/philosophy.py +474 -0
- QuantNodes/research/quant_alpha/alpha158_design/__init__.py +63 -0
- QuantNodes/research/quant_alpha/alpha158_design/few_shot_examples.py +219 -0
- QuantNodes/research/quant_alpha/alpha158_design/philosophy.py +240 -0
- QuantNodes/research/quant_alpha/evaluation/__init__.py +47 -0
- QuantNodes/research/quant_alpha/evaluation/baselines/__init__.py +8 -0
- QuantNodes/research/quant_alpha/evaluation/baselines/g1_handcrafted.py +135 -0
- QuantNodes/research/quant_alpha/evaluation/baselines/g2_llm_only.py +269 -0
- QuantNodes/research/quant_alpha/evaluation/baselines/g3_alpha_gpt.py +152 -0
- QuantNodes/research/quant_alpha/evaluation/clickhouse_data_loader.py +227 -0
- QuantNodes/research/quant_alpha/evaluation/contracts.py +376 -0
- QuantNodes/research/quant_alpha/evaluation/evaluators/__init__.py +6 -0
- QuantNodes/research/quant_alpha/evaluation/evaluators/polars_evaluator.py +545 -0
- QuantNodes/research/quant_alpha/evaluation/mock_data_loader.py +226 -0
- QuantNodes/research/quant_alpha/evaluation/runner.py +243 -0
- QuantNodes/research/quant_alpha/llm/__init__.py +38 -0
- QuantNodes/research/quant_alpha/llm/parser.py +681 -0
- QuantNodes/research/quant_alpha/logic_driven_pipeline.py +411 -0
- QuantNodes/research/quant_alpha/logic_mining/__init__.py +74 -0
- QuantNodes/research/quant_alpha/logic_mining/compiler.py +457 -0
- QuantNodes/research/quant_alpha/logic_mining/generator.py +366 -0
- QuantNodes/research/quant_alpha/logic_mining/models.py +252 -0
- QuantNodes/research/quant_alpha/logic_mining/parser.py +287 -0
- QuantNodes/research/quant_alpha/logic_mining/pipelines.py +297 -0
- QuantNodes/research/quant_alpha/logic_mining/sources.py +149 -0
- QuantNodes/research/quant_alpha/mcts/__init__.py +66 -0
- QuantNodes/research/quant_alpha/mcts/cache.py +262 -0
- QuantNodes/research/quant_alpha/mcts/extension_ops.py +320 -0
- QuantNodes/research/quant_alpha/mcts/feedback.py +825 -0
- QuantNodes/research/quant_alpha/mcts/op_prior.py +180 -0
- QuantNodes/research/quant_alpha/mcts/search.py +540 -0
- QuantNodes/research/quant_alpha/mcts/tree.py +201 -0
- QuantNodes/research/quant_alpha/operator_vocab/__init__.py +50 -0
- QuantNodes/research/quant_alpha/operator_vocab/config.py +54 -0
- QuantNodes/research/quant_alpha/operator_vocab/metadata.py +263 -0
- QuantNodes/research/quant_alpha/operator_vocab/vocabulary.py +481 -0
- QuantNodes/research/quant_alpha/pipeline.py +1027 -0
- QuantNodes/research/quant_alpha/types/__init__.py +27 -0
- QuantNodes/research/quant_alpha/types/constants.py +28 -0
- QuantNodes/research/quant_alpha/types/state.py +205 -0
- QuantNodes/research/quant_alpha/workflow/__init__.py +32 -0
- QuantNodes/research/quant_alpha/workflow/alpha_gpt.py +911 -0
- QuantNodes/research/quant_alpha/workflow/alpha_logics.py +416 -0
- QuantNodes/research/quant_alpha/workflow/state.py +27 -0
- QuantNodes/research/report_reproducer.py +485 -0
- QuantNodes/research/wiki.py +1155 -0
- QuantNodes/symbolic/__init__.py +51 -0
- QuantNodes/symbolic/compiler.py +113 -0
- QuantNodes/symbolic/dialect.py +260 -0
- QuantNodes/symbolic/executor.py +147 -0
- QuantNodes/symbolic/expression.py +234 -0
- QuantNodes/symbolic/functions.py +433 -0
- QuantNodes/symbolic/optimizer.py +165 -0
- QuantNodes/ui_node/__init__.py +30 -0
- QuantNodes/ui_node/base.py +222 -0
- quantnodes-3.0.0.dist-info/METADATA +463 -0
- quantnodes-3.0.0.dist-info/RECORD +399 -0
- quantnodes-3.0.0.dist-info/WHEEL +5 -0
- quantnodes-3.0.0.dist-info/entry_points.txt +24 -0
- quantnodes-3.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""
|
|
3
|
+
Strategy Prompts
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .momentum import MOMENTUM_PROMPT
|
|
7
|
+
from .mean_reversion import MEAN_REVERSION_PROMPT
|
|
8
|
+
from .trend_following import TREND_FOLLOWING_PROMPT
|
|
9
|
+
from .pairs_trading import PAIRS_TRADING_PROMPT
|
|
10
|
+
from .market_neutral import MARKET_NEUTRAL_PROMPT
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"MOMENTUM_PROMPT",
|
|
14
|
+
"MEAN_REVERSION_PROMPT",
|
|
15
|
+
"TREND_FOLLOWING_PROMPT",
|
|
16
|
+
"PAIRS_TRADING_PROMPT",
|
|
17
|
+
"MARKET_NEUTRAL_PROMPT",
|
|
18
|
+
]
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""
|
|
3
|
+
Market Neutral Strategy Prompt
|
|
4
|
+
|
|
5
|
+
Complete prompt for generating market neutral strategies with reference code.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import List, Dict, Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class StrategyPrompt:
|
|
14
|
+
version: str = "1.0.0"
|
|
15
|
+
name: str = "market_neutral"
|
|
16
|
+
description: str = "市场中性策略生成"
|
|
17
|
+
created_at: str = "2025-05-14"
|
|
18
|
+
updated_at: str = "2025-05-14"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def prompt(self) -> str:
|
|
22
|
+
return """你是一个量化策略专家,专注于市场中性策略。
|
|
23
|
+
|
|
24
|
+
## 策略逻辑
|
|
25
|
+
市场中性策略旨在消除市场系统性风险,获取alpha收益。
|
|
26
|
+
核心思想:
|
|
27
|
+
1. 同时持有多头和空头仓位
|
|
28
|
+
2. 确保投资组合对市场涨跌的暴露为0
|
|
29
|
+
3. 通过选股能力获取超额收益
|
|
30
|
+
|
|
31
|
+
## 参数说明
|
|
32
|
+
- `symbols`: 标的列表
|
|
33
|
+
- `lookback`: 计算因子和风险的回看窗口
|
|
34
|
+
- `long_short_ratio`: 多空仓比例 (如 0.5 表示一半多头一半空头)
|
|
35
|
+
- `risk_factor`: 对冲用的风险因子 (如 "market")
|
|
36
|
+
|
|
37
|
+
## 输出要求
|
|
38
|
+
生成完整的 Python 代码"""
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def required_params(self) -> List[str]:
|
|
42
|
+
return ["symbols", "lookback", "long_short_ratio"]
|
|
43
|
+
|
|
44
|
+
@property
|
|
45
|
+
def output_format(self) -> str:
|
|
46
|
+
return "python_code"
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def validation_rules(self) -> Dict[str, Any]:
|
|
50
|
+
return {
|
|
51
|
+
"max_lines": 700,
|
|
52
|
+
"allowed_imports": ["numpy", "pandas", "talib"],
|
|
53
|
+
"forbidden_patterns": ["os.", "subprocess", "eval", "exec"],
|
|
54
|
+
"required_variables": ["strategy", "quote_data"],
|
|
55
|
+
"required_classes": ["StrategyNode"]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def example_code(self) -> str:
|
|
60
|
+
return '''import pandas as pd
|
|
61
|
+
import numpy as np
|
|
62
|
+
from QuantNodes.backtest.strategy_node import StrategyNode, OrdersResult
|
|
63
|
+
|
|
64
|
+
class MarketNeutralStrategyNode(StrategyNode):
|
|
65
|
+
"""市场中性策略节点
|
|
66
|
+
|
|
67
|
+
通过多空对冲消除市场风险
|
|
68
|
+
"""
|
|
69
|
+
def __init__(self, config: dict = None):
|
|
70
|
+
self.lookback = config.get('lookback', 20) if config else 20
|
|
71
|
+
self.long_short_ratio = config.get('long_short_ratio', 0.5) if config else 0.5
|
|
72
|
+
|
|
73
|
+
def execute(self, data: pd.DataFrame) -> OrdersResult:
|
|
74
|
+
returns = data.pct_change()
|
|
75
|
+
|
|
76
|
+
signal = pd.Series(0, index=data.index)
|
|
77
|
+
|
|
78
|
+
result = OrdersResult()
|
|
79
|
+
result.signals = signal
|
|
80
|
+
result.orders = []
|
|
81
|
+
return result
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
strategy = MarketNeutralStrategyNode(config={
|
|
85
|
+
'lookback': 20,
|
|
86
|
+
'long_short_ratio': 0.5
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
quote_data = pd.DataFrame({
|
|
90
|
+
'date': pd.date_range('2020-01-01', periods=100),
|
|
91
|
+
'close': np.random.randn(100).cumsum() + 100
|
|
92
|
+
})
|
|
93
|
+
'''
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
MARKET_NEUTRAL_PROMPT = StrategyPrompt()
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""
|
|
3
|
+
Mean Reversion Strategy Prompt
|
|
4
|
+
|
|
5
|
+
Complete prompt for generating mean reversion strategies with reference code.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import List, Dict, Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class StrategyPrompt:
|
|
14
|
+
version: str = "1.0.0"
|
|
15
|
+
name: str = "mean_reversion"
|
|
16
|
+
description: str = "均值回归策略生成"
|
|
17
|
+
created_at: str = "2025-05-14"
|
|
18
|
+
updated_at: str = "2025-05-14"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def prompt(self) -> str:
|
|
22
|
+
return """你是一个量化策略专家,专注于均值回归策略。
|
|
23
|
+
|
|
24
|
+
## 策略逻辑
|
|
25
|
+
均值回归策略基于"价格围绕价值波动"的假设,当价格偏离均值时迟早会回归。
|
|
26
|
+
核心思想:
|
|
27
|
+
1. 计算移动平均线作为均值
|
|
28
|
+
2. 当价格偏离均值超过阈值时做相反方向的交易
|
|
29
|
+
3. 预期价格会回归到均值
|
|
30
|
+
|
|
31
|
+
## 参数说明
|
|
32
|
+
- `symbol`: 交易标的代码
|
|
33
|
+
- `window`: 计算均值的窗口大小
|
|
34
|
+
- `std_threshold`: 标准差阈值 (如 2.0 表示2个标准差)
|
|
35
|
+
|
|
36
|
+
## 输出要求
|
|
37
|
+
生成完整的 Python 代码,包含:
|
|
38
|
+
1. 导入必要的库
|
|
39
|
+
2. 定义均值回归策略类继承 StrategyNode
|
|
40
|
+
3. 返回交易信号
|
|
41
|
+
|
|
42
|
+
## 约束
|
|
43
|
+
- 代码必须安全,不能包含危险操作
|
|
44
|
+
- 必须创建名为 `strategy` 的 StrategyNode 变量
|
|
45
|
+
- 必须创建名为 `quote_data` 的 DataFrame 变量
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
@property
|
|
49
|
+
def required_params(self) -> List[str]:
|
|
50
|
+
return ["symbol", "window", "std_threshold"]
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def output_format(self) -> str:
|
|
54
|
+
return "python_code"
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def validation_rules(self) -> Dict[str, Any]:
|
|
58
|
+
return {
|
|
59
|
+
"max_lines": 500,
|
|
60
|
+
"allowed_imports": ["numpy", "pandas", "talib"],
|
|
61
|
+
"forbidden_patterns": ["os.", "subprocess", "eval", "exec"],
|
|
62
|
+
"required_variables": ["strategy", "quote_data"],
|
|
63
|
+
"required_classes": ["StrategyNode"]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def example_code(self) -> str:
|
|
68
|
+
return '''import pandas as pd
|
|
69
|
+
import numpy as np
|
|
70
|
+
from QuantNodes.backtest.strategy_node import StrategyNode, OrdersResult
|
|
71
|
+
|
|
72
|
+
class MeanReversionStrategyNode(StrategyNode):
|
|
73
|
+
"""均值回归策略节点
|
|
74
|
+
|
|
75
|
+
当价格偏离均值超过阈值时反向交易
|
|
76
|
+
"""
|
|
77
|
+
def __init__(self, config: dict = None):
|
|
78
|
+
self.window = config.get('window', 20) if config else 20
|
|
79
|
+
self.std_threshold = config.get('std_threshold', 2.0) if config else 2.0
|
|
80
|
+
|
|
81
|
+
def execute(self, data: pd.DataFrame) -> OrdersResult:
|
|
82
|
+
close = data['close']
|
|
83
|
+
ma = close.rolling(window=self.window).mean()
|
|
84
|
+
std = close.rolling(window=self.window).std()
|
|
85
|
+
|
|
86
|
+
z_score = (close - ma) / (std + 1e-8)
|
|
87
|
+
|
|
88
|
+
signal = pd.Series(0, index=data.index)
|
|
89
|
+
signal[z_score < -self.std_threshold] = 1
|
|
90
|
+
signal[z_score > self.std_threshold] = -1
|
|
91
|
+
|
|
92
|
+
result = OrdersResult()
|
|
93
|
+
result.signals = signal
|
|
94
|
+
result.orders = []
|
|
95
|
+
return result
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
strategy = MeanReversionStrategyNode(config={'window': 20, 'std_threshold': 2.0})
|
|
99
|
+
|
|
100
|
+
quote_data = pd.DataFrame({
|
|
101
|
+
'date': pd.date_range('2020-01-01', periods=100),
|
|
102
|
+
'close': np.random.randn(100).cumsum() + 100
|
|
103
|
+
})
|
|
104
|
+
'''
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
MEAN_REVERSION_PROMPT = StrategyPrompt()
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""
|
|
3
|
+
Momentum Strategy Prompt
|
|
4
|
+
|
|
5
|
+
Complete prompt for generating momentum strategies with reference code.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import List, Dict, Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class StrategyPrompt:
|
|
14
|
+
version: str = "1.0.0"
|
|
15
|
+
name: str = "momentum"
|
|
16
|
+
description: str = "动量策略生成"
|
|
17
|
+
created_at: str = "2025-05-14"
|
|
18
|
+
updated_at: str = "2025-05-14"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def prompt(self) -> str:
|
|
22
|
+
return """你是一个量化策略专家,专注于动量策略。
|
|
23
|
+
|
|
24
|
+
## 策略逻辑
|
|
25
|
+
动量策略基于"强者恒强"的假设,过去表现良好的资产未来继续表现良好。
|
|
26
|
+
核心思想:
|
|
27
|
+
1. 计算一定时间窗口的收益率
|
|
28
|
+
2. 买入收益率最高的资产
|
|
29
|
+
3. 持有一定时间后重新平衡
|
|
30
|
+
|
|
31
|
+
## 参数说明
|
|
32
|
+
- `symbol`: 交易标的代码 (如 "BTC", "ETH", "AAPL")
|
|
33
|
+
- `window`: 计算动量的回看窗口 (如 20 表示过去20天)
|
|
34
|
+
- `threshold`: 触发交易的阈值 (如 0.05 表示5%)
|
|
35
|
+
|
|
36
|
+
## 输出要求
|
|
37
|
+
生成完整的 Python 代码,包含:
|
|
38
|
+
1. 导入必要的库 (pandas, numpy)
|
|
39
|
+
2. 定义策略函数 `momentum_strategy(data, window, threshold)`
|
|
40
|
+
3. 返回交易信号 (1=买入, -1=卖出, 0=持有)
|
|
41
|
+
4. 包含完整的 docstring
|
|
42
|
+
|
|
43
|
+
## 约束
|
|
44
|
+
- 代码必须安全,不能包含 os, subprocess, eval 等危险操作
|
|
45
|
+
- 必须创建名为 `strategy` 的 StrategyNode 变量
|
|
46
|
+
- 必须创建名为 `quote_data` 的 DataFrame 变量
|
|
47
|
+
- 使用 QuantNodes 回测框架
|
|
48
|
+
|
|
49
|
+
## 参考代码框架
|
|
50
|
+
```python
|
|
51
|
+
import pandas as pd
|
|
52
|
+
import numpy as np
|
|
53
|
+
from QuantNodes.backtest.strategy_node import StrategyNode, OrdersResult
|
|
54
|
+
|
|
55
|
+
class MomentumStrategyNode(StrategyNode):
|
|
56
|
+
def __init__(self, config: dict = None):
|
|
57
|
+
self.window = config.get('window', 20)
|
|
58
|
+
self.threshold = config.get('threshold', 0.05)
|
|
59
|
+
|
|
60
|
+
def execute(self, data: pd.DataFrame) -> OrdersResult:
|
|
61
|
+
close = data['close']
|
|
62
|
+
returns = close.pct_change(self.window)
|
|
63
|
+
signal = (returns > self.threshold).astype(int)
|
|
64
|
+
signal[returns < -self.threshold] = -1
|
|
65
|
+
|
|
66
|
+
result = OrdersResult()
|
|
67
|
+
result.signals = signal
|
|
68
|
+
result.orders = []
|
|
69
|
+
return result
|
|
70
|
+
|
|
71
|
+
# 创建策略实例
|
|
72
|
+
strategy = MomentumStrategyNode(config={
|
|
73
|
+
'window': 20,
|
|
74
|
+
'threshold': 0.05
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
# 示例数据
|
|
78
|
+
quote_data = pd.DataFrame({
|
|
79
|
+
'date': pd.date_range('2020-01-01', periods=100),
|
|
80
|
+
'close': np.random.randn(100).cumsum() + 100
|
|
81
|
+
})
|
|
82
|
+
```
|
|
83
|
+
"""
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def required_params(self) -> List[str]:
|
|
87
|
+
return ["symbol", "window", "threshold"]
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def output_format(self) -> str:
|
|
91
|
+
return "python_code"
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def validation_rules(self) -> Dict[str, Any]:
|
|
95
|
+
return {
|
|
96
|
+
"max_lines": 500,
|
|
97
|
+
"allowed_imports": ["numpy", "pandas", "talib"],
|
|
98
|
+
"forbidden_patterns": ["os.", "subprocess", "eval", "exec", "open("],
|
|
99
|
+
"required_variables": ["strategy", "quote_data"],
|
|
100
|
+
"required_classes": ["StrategyNode"]
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@property
|
|
104
|
+
def example_code(self) -> str:
|
|
105
|
+
return '''import pandas as pd
|
|
106
|
+
import numpy as np
|
|
107
|
+
from QuantNodes.backtest.strategy_node import StrategyNode, OrdersResult
|
|
108
|
+
|
|
109
|
+
class MomentumStrategyNode(StrategyNode):
|
|
110
|
+
"""动量策略节点
|
|
111
|
+
|
|
112
|
+
基于过去N天收益率计算动量信号
|
|
113
|
+
"""
|
|
114
|
+
def __init__(self, config: dict = None):
|
|
115
|
+
self.window = config.get('window', 20) if config else 20
|
|
116
|
+
self.threshold = config.get('threshold', 0.05) if config else 0.05
|
|
117
|
+
|
|
118
|
+
def execute(self, data: pd.DataFrame) -> OrdersResult:
|
|
119
|
+
close = data['close']
|
|
120
|
+
returns = close.pct_change(self.window)
|
|
121
|
+
|
|
122
|
+
signal = pd.Series(0, index=data.index)
|
|
123
|
+
signal[returns > self.threshold] = 1
|
|
124
|
+
signal[returns < -self.threshold] = -1
|
|
125
|
+
|
|
126
|
+
result = OrdersResult()
|
|
127
|
+
result.signals = signal
|
|
128
|
+
result.orders = self._signals_to_orders(signal, data)
|
|
129
|
+
return result
|
|
130
|
+
|
|
131
|
+
def _signals_to_orders(self, signals, data):
|
|
132
|
+
orders = []
|
|
133
|
+
position = 0
|
|
134
|
+
for i, (idx, row) in enumerate(data.iterrows()):
|
|
135
|
+
sig = signals.iloc[i]
|
|
136
|
+
if sig != position:
|
|
137
|
+
if sig == 1:
|
|
138
|
+
orders.append({
|
|
139
|
+
'date': idx, 'symbol': 'BTC',
|
|
140
|
+
'action': 'buy', 'price': row['close'],
|
|
141
|
+
})
|
|
142
|
+
elif sig == -1:
|
|
143
|
+
orders.append({
|
|
144
|
+
'date': idx, 'symbol': 'BTC',
|
|
145
|
+
'action': 'sell', 'price': row['close'],
|
|
146
|
+
})
|
|
147
|
+
position = sig
|
|
148
|
+
return orders
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
strategy = MomentumStrategyNode(config={'window': 20, 'threshold': 0.05})
|
|
152
|
+
|
|
153
|
+
quote_data = pd.DataFrame({
|
|
154
|
+
'date': pd.date_range('2020-01-01', periods=100),
|
|
155
|
+
'close': np.random.randn(100).cumsum() + 100
|
|
156
|
+
})
|
|
157
|
+
'''
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
MOMENTUM_PROMPT = StrategyPrompt()
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""
|
|
3
|
+
Pairs Trading Strategy Prompt
|
|
4
|
+
|
|
5
|
+
Complete prompt for generating pairs trading strategies with reference code.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import List, Dict, Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class StrategyPrompt:
|
|
14
|
+
version: str = "1.0.0"
|
|
15
|
+
name: str = "pairs_trading"
|
|
16
|
+
description: str = "配对交易策略生成"
|
|
17
|
+
created_at: str = "2025-05-14"
|
|
18
|
+
updated_at: str = "2025-05-14"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def prompt(self) -> str:
|
|
22
|
+
return """你是一个量化策略专家,专注于配对交易策略。
|
|
23
|
+
|
|
24
|
+
## 策略逻辑
|
|
25
|
+
配对交易基于两只相关证券之间的价差会回归均值的假设。
|
|
26
|
+
核心思想:
|
|
27
|
+
1. 选择一对高度相关的证券
|
|
28
|
+
2. 当价差偏离均值时,做空高估的、做多低估的
|
|
29
|
+
3. 价差回归时平仓获利
|
|
30
|
+
|
|
31
|
+
## 参数说明
|
|
32
|
+
- `symbol1`: 第一个标的代码
|
|
33
|
+
- `symbol2`: 第二个标的代码
|
|
34
|
+
- `lookback`: 计算价差均值和标准差的回看窗口
|
|
35
|
+
- `entry_threshold`: 入场阈值 (标准差倍数)
|
|
36
|
+
- `exit_threshold`: 出场阈值
|
|
37
|
+
|
|
38
|
+
## 输出要求
|
|
39
|
+
生成完整的 Python 代码"""
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def required_params(self) -> List[str]:
|
|
43
|
+
return ["symbol1", "symbol2", "lookback", "entry_threshold"]
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def output_format(self) -> str:
|
|
47
|
+
return "python_code"
|
|
48
|
+
|
|
49
|
+
@property
|
|
50
|
+
def validation_rules(self) -> Dict[str, Any]:
|
|
51
|
+
return {
|
|
52
|
+
"max_lines": 600,
|
|
53
|
+
"allowed_imports": ["numpy", "pandas", "talib"],
|
|
54
|
+
"forbidden_patterns": ["os.", "subprocess", "eval", "exec"],
|
|
55
|
+
"required_variables": ["strategy", "quote_data"],
|
|
56
|
+
"required_classes": ["StrategyNode"]
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def example_code(self) -> str:
|
|
61
|
+
return '''import pandas as pd
|
|
62
|
+
import numpy as np
|
|
63
|
+
from QuantNodes.backtest.strategy_node import StrategyNode, OrdersResult
|
|
64
|
+
|
|
65
|
+
class PairsTradingStrategyNode(StrategyNode):
|
|
66
|
+
"""配对交易策略节点
|
|
67
|
+
|
|
68
|
+
当两只股票的价差偏离均值时进行配对交易
|
|
69
|
+
"""
|
|
70
|
+
def __init__(self, config: dict = None):
|
|
71
|
+
self.lookback = config.get('lookback', 20) if config else 20
|
|
72
|
+
self.entry_threshold = config.get('entry_threshold', 2.0) if config else 2.0
|
|
73
|
+
self.exit_threshold = config.get('exit_threshold', 0.5) if config else 0.5
|
|
74
|
+
|
|
75
|
+
def execute(self, data: pd.DataFrame) -> OrdersResult:
|
|
76
|
+
spread = data['close1'] - data['close2']
|
|
77
|
+
ma = spread.rolling(window=self.lookback).mean()
|
|
78
|
+
std = spread.rolling(window=self.lookback).std()
|
|
79
|
+
|
|
80
|
+
z_score = (spread - ma) / (std + 1e-8)
|
|
81
|
+
|
|
82
|
+
signal = pd.Series(0, index=data.index)
|
|
83
|
+
signal[z_score > self.entry_threshold] = -1
|
|
84
|
+
signal[z_score < -self.entry_threshold] = 1
|
|
85
|
+
signal[abs(z_score) < self.exit_threshold] = 0
|
|
86
|
+
|
|
87
|
+
result = OrdersResult()
|
|
88
|
+
result.signals = signal
|
|
89
|
+
result.orders = []
|
|
90
|
+
return result
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
strategy = PairsTradingStrategyNode(config={
|
|
94
|
+
'lookback': 20,
|
|
95
|
+
'entry_threshold': 2.0,
|
|
96
|
+
'exit_threshold': 0.5
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
quote_data = pd.DataFrame({
|
|
100
|
+
'date': pd.date_range('2020-01-01', periods=100),
|
|
101
|
+
'close1': np.random.randn(100).cumsum() + 100,
|
|
102
|
+
'close2': np.random.randn(100).cumsum() + 100
|
|
103
|
+
})
|
|
104
|
+
'''
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
PAIRS_TRADING_PROMPT = StrategyPrompt()
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# coding=utf-8
|
|
2
|
+
"""
|
|
3
|
+
Trend Following Strategy Prompt
|
|
4
|
+
|
|
5
|
+
Complete prompt for generating trend following strategies with reference code.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataclasses import dataclass
|
|
9
|
+
from typing import List, Dict, Any
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class StrategyPrompt:
|
|
14
|
+
version: str = "1.0.0"
|
|
15
|
+
name: str = "trend_following"
|
|
16
|
+
description: str = "趋势跟踪策略生成"
|
|
17
|
+
created_at: str = "2025-05-14"
|
|
18
|
+
updated_at: str = "2025-05-14"
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def prompt(self) -> str:
|
|
22
|
+
return """你是一个量化策略专家,专注于趋势跟踪策略。
|
|
23
|
+
|
|
24
|
+
## 策略逻辑
|
|
25
|
+
趋势跟踪策略旨在捕捉大趋势,一旦趋势形成就持仓直到趋势反转。
|
|
26
|
+
核心思想:
|
|
27
|
+
1. 使用移动平均线判断趋势方向
|
|
28
|
+
2. 当短期均线上穿长期均线时买入 (金叉)
|
|
29
|
+
3. 当短期均线下穿长期均线时卖出 (死叉)
|
|
30
|
+
|
|
31
|
+
## 参数说明
|
|
32
|
+
- `symbol`: 交易标的代码
|
|
33
|
+
- `short_window`: 短期均线窗口
|
|
34
|
+
- `long_window`: 长期均线窗口
|
|
35
|
+
|
|
36
|
+
## 输出要求
|
|
37
|
+
生成完整的 Python 代码"""
|
|
38
|
+
|
|
39
|
+
@property
|
|
40
|
+
def required_params(self) -> List[str]:
|
|
41
|
+
return ["symbol", "short_window", "long_window"]
|
|
42
|
+
|
|
43
|
+
@property
|
|
44
|
+
def output_format(self) -> str:
|
|
45
|
+
return "python_code"
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def validation_rules(self) -> Dict[str, Any]:
|
|
49
|
+
return {
|
|
50
|
+
"max_lines": 500,
|
|
51
|
+
"allowed_imports": ["numpy", "pandas", "talib"],
|
|
52
|
+
"forbidden_patterns": ["os.", "subprocess", "eval", "exec"],
|
|
53
|
+
"required_variables": ["strategy", "quote_data"],
|
|
54
|
+
"required_classes": ["StrategyNode"]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def example_code(self) -> str:
|
|
59
|
+
return '''import pandas as pd
|
|
60
|
+
import numpy as np
|
|
61
|
+
from QuantNodes.backtest.strategy_node import StrategyNode, OrdersResult
|
|
62
|
+
|
|
63
|
+
class TrendFollowingStrategyNode(StrategyNode):
|
|
64
|
+
"""趋势跟踪策略节点
|
|
65
|
+
|
|
66
|
+
使用双均线交叉判断趋势
|
|
67
|
+
"""
|
|
68
|
+
def __init__(self, config: dict = None):
|
|
69
|
+
self.short_window = config.get('short_window', 10) if config else 10
|
|
70
|
+
self.long_window = config.get('long_window', 30) if config else 30
|
|
71
|
+
|
|
72
|
+
def execute(self, data: pd.DataFrame) -> OrdersResult:
|
|
73
|
+
close = data['close']
|
|
74
|
+
short_ma = close.rolling(window=self.short_window).mean()
|
|
75
|
+
long_ma = close.rolling(window=self.long_window).mean()
|
|
76
|
+
|
|
77
|
+
signal = pd.Series(0, index=data.index)
|
|
78
|
+
signal[(short_ma > long_ma) & (short_ma.shift(1) <= long_ma.shift(1))] = 1
|
|
79
|
+
signal[(short_ma < long_ma) & (short_ma.shift(1) >= long_ma.shift(1))] = -1
|
|
80
|
+
|
|
81
|
+
result = OrdersResult()
|
|
82
|
+
result.signals = signal
|
|
83
|
+
result.orders = []
|
|
84
|
+
return result
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
strategy = TrendFollowingStrategyNode(config={'short_window': 10, 'long_window': 30})
|
|
88
|
+
|
|
89
|
+
quote_data = pd.DataFrame({
|
|
90
|
+
'date': pd.date_range('2020-01-01', periods=100),
|
|
91
|
+
'close': np.random.randn(100).cumsum() + 100
|
|
92
|
+
})
|
|
93
|
+
'''
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
TREND_FOLLOWING_PROMPT = StrategyPrompt()
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# QuantNodes.research
|
|
2
|
+
|
|
3
|
+
Wiki 因子库代理层 + 自动因子研究 + 研报复现。
|
|
4
|
+
|
|
5
|
+
- **功能3A**: WikiFactorProxy — 因子库基础设施
|
|
6
|
+
- **功能3B**: ResearchReportReproducer — 研报复现 (PDF→逻辑提取→验证)
|
|
7
|
+
- **功能3C**: AutoResearcher — 自动因子挖掘 (模板枚举 + MCTS + 6维度评估)
|
|
8
|
+
|
|
9
|
+
## 快速开始
|
|
10
|
+
|
|
11
|
+
### 自动因子挖掘
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from QuantNodes.research import AutoResearcher, EvalConfig
|
|
15
|
+
import polars as pl
|
|
16
|
+
|
|
17
|
+
data = pl.read_parquet("market_data.parquet")
|
|
18
|
+
researcher = AutoResearcher(wiki_path="/path/to/wiki")
|
|
19
|
+
|
|
20
|
+
# 模板枚举 + 6维度评估
|
|
21
|
+
result = researcher.run(data=data, max_factors=100)
|
|
22
|
+
|
|
23
|
+
# MCTS 搜索
|
|
24
|
+
result = researcher.run(data=data, use_mcts=True, mcts_iterations=50)
|
|
25
|
+
|
|
26
|
+
# 验证单个因子
|
|
27
|
+
result = researcher.mine_single_factor(
|
|
28
|
+
formula="rank(close / ts_lag(close, 20) - 1)",
|
|
29
|
+
data=data,
|
|
30
|
+
)
|
|
31
|
+
print(result.report_markdown)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### 6维度评估
|
|
35
|
+
|
|
36
|
+
| 维度 | 指标 | 阈值 |
|
|
37
|
+
|------|------|------|
|
|
38
|
+
| 收益 | IC, IC_IR | \|IC\| > 0.03, IC_IR > 0.5 |
|
|
39
|
+
| 稳定性 | 滚动IC | > 0.6 |
|
|
40
|
+
| 分散度 | 因子间相关 | < 0.7 |
|
|
41
|
+
| 换手率 | 排名变化 | < 0.5 |
|
|
42
|
+
| 单调性 | 分组收益 | > 0.7 |
|
|
43
|
+
| 覆盖率 | 非空比例 | > 0.8 |
|
|
44
|
+
|
|
45
|
+
## 研报复现 (功能3B)
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from QuantNodes.research import ResearchReportReproducer
|
|
49
|
+
import polars as pl
|
|
50
|
+
|
|
51
|
+
data = pl.read_parquet("market_data.parquet")
|
|
52
|
+
reproducer = ResearchReportReproducer(
|
|
53
|
+
wiki_path="/path/to/wiki",
|
|
54
|
+
llm_client=llm_client, # 可选, 不传则用规则匹配
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# 处理研报PDF
|
|
58
|
+
report = reproducer.process(
|
|
59
|
+
pdf_path="research_report.pdf",
|
|
60
|
+
data=data,
|
|
61
|
+
store_to_wiki=True,
|
|
62
|
+
)
|
|
63
|
+
print(report.report_markdown)
|
|
64
|
+
# verified: 因子类逻辑通过IC/IR验证
|
|
65
|
+
# pending: 非因子类逻辑存入WikiLogic待人工验证
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Wiki 因子库 (功能3A)
|
|
69
|
+
|
|
70
|
+
### 初始化
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from QuantNodes.research import init_factor_wiki, WikiFactorProxy
|
|
74
|
+
|
|
75
|
+
init_factor_wiki("/path/to/wiki")
|
|
76
|
+
proxy = WikiFactorProxy("/path/to/wiki")
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### 存储/读取因子
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
from QuantNodes.research import WikiFactor, FactorSource, FactorCategory
|
|
83
|
+
|
|
84
|
+
factor = WikiFactor(
|
|
85
|
+
name="momentum_20d",
|
|
86
|
+
formula="close / delay(close, 20) - 1",
|
|
87
|
+
source=FactorSource.RESEARCH_REPORT,
|
|
88
|
+
category=FactorCategory.MOMENTUM,
|
|
89
|
+
ic_mean=0.05, icir=0.5,
|
|
90
|
+
)
|
|
91
|
+
proxy.store_factor(factor)
|
|
92
|
+
factor = proxy.get_factor("momentum_20d")
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 关系管理
|
|
96
|
+
|
|
97
|
+
```python
|
|
98
|
+
proxy.add_relation("Logic/report_001", "Factor/momentum_20d", "derived_from")
|
|
99
|
+
neighbors = proxy.get_neighbors("Factor/momentum_20d")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 测试
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
python3 -m pytest tests/research/ -v
|
|
106
|
+
```
|