mirror of
https://github.com/shy3130/tick-stock-panel.git
synced 2026-11-02 10:26:13 +00:00
- 策略: 引擎只加载 data/strategies/{custom,ai,composite} 与研究模板目录,
原 25 个内置策略一次性迁移为用户自定义文件(ID 不变, 引用零迁移);
研究模板移至 app/strategy/research, 打包 spec 同步; 新装环境策略库为空
- 信号: 管线不再硬编码任何信号表达式; 涨跌停判定价成为运行时列
limit_up_price/limit_down_price(生效价∓0.005 容差), 20 个信号转为
data/user_data/custom_signals 定义(显式 column 沿用 signal_* 原列名);
依赖解析/注入顺序/当日路径 prev-join 全部定义驱动; 语义统一为历史路径
口径(顺带修正当日路径 BOLL 比较符与翘板/炸板空值两处既有偏差)
- 前端: 信号库单列表(全部可编辑), SignalPicker/监控选项/信号标签全走
定义接口; 回测页新增免责声明(模拟性质/数据源准确性不作保证/不构成
投资建议)
- 测试: 25 个策略夹具与 20 个信号种子入库 tests/fixtures, 受影响测试
全部自包含化(不依赖运行目录用户数据); 77 万行 MA 死叉新旧表达式对拍
逐行一致; 回测实跑 45 笔卖点信号出场验证矩阵链路
- 同批包含工作区既有进度: 策略结果 ext 列同日投影修复(含测试)、数据源插件、fuyao/auth/api_gateway/data_integrity 调整、README 信号库
描述与 strategy.md 导入路径补充
验证: 后端 2592 passed(空数据目录 CI 模拟 2588 passed, 4 例为模拟环境
伪影复验排除); 前端 vitest 125 passed + tsc 0 错 + vite build 通过
66 lines
2.3 KiB
Python
66 lines
2.3 KiB
Python
"""每日信号路径的字段依赖展开回归测试。
|
|
|
|
挖掘发布的 FactorRankResearchMatrixStrategy 把因子权重放在类级 SCORING,
|
|
META["scoring"] 为空。每日信号/实时矩阵路径通过 _matrix_field_columns 决定
|
|
矩阵字段, 必须展开 required_fields_for_params 的虚拟因子依赖
|
|
(limit_up_count_* -> consecutive_limit_ups), 否则 compute_signals 抛
|
|
"MarketDataMatrix missing field: consecutive_limit_ups"。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import types
|
|
from datetime import date, timedelta
|
|
|
|
import polars as pl
|
|
|
|
from app.backtest.matrix import build_market_data_matrix
|
|
from app.strategy.engine import StrategyEngine
|
|
from app.strategy.research.factor_rank_research import FactorRankResearchMatrixStrategy
|
|
|
|
|
|
def _mined_limit_up_strategy() -> types.SimpleNamespace:
|
|
strategy = FactorRankResearchMatrixStrategy(
|
|
{"amplitude": 2.0, "limit_up_count_60d": 1.0},
|
|
{"amplitude": "low", "limit_up_count_60d": "low"},
|
|
)
|
|
return types.SimpleNamespace(
|
|
matrix_strategy=strategy,
|
|
basic_filter=None,
|
|
meta={"scoring": {}},
|
|
)
|
|
|
|
|
|
def test_matrix_field_columns_expand_parameter_scoring_dependencies():
|
|
strategy = _mined_limit_up_strategy()
|
|
fields = StrategyEngine._matrix_field_columns(strategy, None, {})
|
|
assert "consecutive_limit_ups" in fields
|
|
assert "amplitude" in fields
|
|
|
|
|
|
def test_mined_limit_up_strategy_signals_build_from_panel_fields():
|
|
rows = []
|
|
start = date(2024, 1, 1)
|
|
for offset in range(80):
|
|
close = 10.0 + offset * 0.04
|
|
rows.append({
|
|
"symbol": "000001.SZ",
|
|
"date": start + timedelta(days=offset),
|
|
"open": close - 0.05,
|
|
"high": close + 0.15,
|
|
"low": close - 0.15,
|
|
"close": close,
|
|
"volume": 1000.0 + offset * 5.0,
|
|
"amount": 100000.0,
|
|
"amplitude": 1.5,
|
|
"turnover_rate": 5.0,
|
|
"consecutive_limit_ups": (offset % 17) + 1 if offset % 17 == 0 else 0,
|
|
})
|
|
panel = pl.DataFrame(rows)
|
|
strategy = _mined_limit_up_strategy()
|
|
market = build_market_data_matrix(
|
|
panel,
|
|
field_columns=StrategyEngine._matrix_field_columns(strategy, None, {}),
|
|
)
|
|
signals = strategy.matrix_strategy.compute_signals(market, {})
|
|
assert signals.shape == market.shape
|