mirror of
https://ghfast.top/https://github.com/aeroxw/tick-stock-panel.git
synced 2026-09-12 19:04:15 +08:00
feat(ext-data): 扩展表字段接入信号与因子(数值因子/评分 + string 归属筛选)
数值字段(int/float) → 信号+因子双通道: - ext_factors: 帧组装时 join 扩展列并注册 kind=base 因子(分组「扩展数据」), 时序模式按 (symbol,交易日) 精确对齐无未来函数, 快照模式仅当日单日帧 注入(历史帧跳过防未来函数) - registry.all_factors 惰性同步(配置目录签名幂等, 以注册表为权威增删); custom_signals.allowed_fields 自动并入 → 信号下拉/因子库/AI提示词/检验 同一份清单; factor 补算入口按需注入 - 失效链: 上传/拉取/配置变更自动清扩展帧缓存+策略缓存, API层补 repo.clear_cache; 写入后下一次计算立即生效 - 列名保留中文(预设表字段名), 非ASCII数值字段只进信号不注册因子 (DSL标识符ASCII-only) string 字段(概念/行业归属) → 仅信号条件通道: - 运算符 包含(contains,字面量匹配非正则)/等于/不等于, 右值为字符串字面量, 可与数值条件混合(强势板块归属 AND 热度阈值) - 前端信号编辑器按字段类型切换运算符与右值输入; /options 暴露 stringFields; AI 提示词含字符串字段清单与 contains 用法 - string 不注册为因子(数值口径), 空值不误报 测试: test_ext_factors 18个(PIT对齐/跨日不泄露/快照门控/写入失效/ contains字面量/中文列名端到端等); 存量因子计数测试补 data/ 运行时隔离 夹具(黄金断言不依赖本机扩展表); 受影响回归148个全过; pnpm build 通过; ruff 对齐 main 基线
This commit is contained in:
@@ -352,6 +352,7 @@ def create_config(request: Request, body: CreateExtReq):
|
||||
code_map=body.code_map,
|
||||
)
|
||||
store.upsert(config)
|
||||
_refresh_views(request)
|
||||
return config.to_dict()
|
||||
|
||||
|
||||
@@ -373,6 +374,7 @@ def update_config(request: Request, config_id: str, body: UpdateExtReq):
|
||||
if body.code_map is not None:
|
||||
config.code_map = body.code_map
|
||||
store.upsert(config)
|
||||
_refresh_views(request)
|
||||
return config.to_dict()
|
||||
|
||||
|
||||
@@ -382,6 +384,7 @@ def delete_config(request: Request, config_id: str):
|
||||
store = _store(request)
|
||||
if not store.delete(config_id):
|
||||
raise HTTPException(404, f"配置 '{config_id}' 不存在")
|
||||
_refresh_views(request)
|
||||
return {"status": "deleted"}
|
||||
|
||||
|
||||
@@ -1180,3 +1183,9 @@ def _refresh_views(request: Request) -> None:
|
||||
db.execute(sql)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 扩展列已接入 enriched 帧 (compute_signals/compute_enriched_today 注入):
|
||||
# repo 内存 enriched 缓存 (_enriched_cache/_etf_/_index_) 持有含旧扩展列的
|
||||
# 帧, 必须一并清理, 否则写入后监控/列表仍用旧值 (服务层已清扩展帧与策略缓存)。
|
||||
if hasattr(repo, "clear_cache"):
|
||||
repo.clear_cache()
|
||||
|
||||
@@ -119,11 +119,24 @@ def get_options():
|
||||
groups.append({"key": f"factor:{group_label}", "label": f"因子 · {group_label}", "fields": group_fields})
|
||||
fields.extend(group_fields)
|
||||
|
||||
# string 扩展字段 (概念/行业归属等): 只进信号条件, 不注册为因子。
|
||||
# stringFields 标记 + 独立分组, 前端据此切换运算符 (包含/等于/不等于)
|
||||
# 与右值输入 (字符串文本, 不支持字段引用)。
|
||||
from app.factors.ext_factors import ext_string_field_entries
|
||||
|
||||
str_entries = ext_string_field_entries()
|
||||
if str_entries:
|
||||
str_group = {"key": "ext_string", "label": "扩展 · 字符串", "fields": str_entries}
|
||||
groups.append(str_group)
|
||||
fields.extend(str_entries)
|
||||
|
||||
return {
|
||||
"fields": fields,
|
||||
"groups": groups,
|
||||
"maxDays": custom_signals.MAX_DAYS,
|
||||
"operators": [">", ">=", "<", "<=", "==", "!="],
|
||||
"stringFields": [e["key"] for e in str_entries],
|
||||
"stringOperators": ["contains", "==", "!="],
|
||||
"kinds": [
|
||||
{"key": "entry", "label": "入场"},
|
||||
{"key": "exit", "label": "出场"},
|
||||
|
||||
Reference in New Issue
Block a user