迭代13: 盘口内存快照(QuoteSync/QuoteHub)+ 同步指示灯 + 行情列

- QuoteSync/QuoteHub 替换 MarketFeed/MarketDataHub(方案A 删除重写):
  5s REST 同步 watch 集合 + 涨停/跌停经 /data/instrument 按交易日内存缓存
  + 读穿透走适配层 getTicks(修正旧 hub 绕适配层的层级破洞)
- WS 数据通路移除(从无生效结论;ingest 留 source 标签回归口子)
- market_quotes_cache 表退役 DROP(幂等);价格单一入口 = QuoteHub
- 数据同步指示灯组: QMT连接|持仓数据|行情数据(绿/黄/灰,点击即同步/即时探测)
  + sync-status 端点(吸收 market-stats)+ sync-now;修复 runtime 漏传 positionSync 致持灯恒灰
- 策略持仓表行情列: 涨停价/跌停价/今开/最高(COLUMN_META defaultVisible=false,纯价格)
- 回归 test-quote-sync.mjs 27 项(含 DROP 幂等真实 SQLite 验证)
- 文档链: R-015 + PLAN-014 + 迭代三件套 + 技术约束-010/012变更、018新增 + 产品约束-012

需求: R-015(老师五拍板: 替换/WS移除/纯内存DROP/watch现状/指示灯)
This commit is contained in:
2026-09-03 13:26:25 +08:00
parent 245fcad95c
commit d793d2cf35
26 changed files with 1075 additions and 589 deletions
+9 -3
View File
@@ -49,6 +49,11 @@ export const COLUMN_META = [
{ key: 'avgPrice', label: '成本价', fixed: false },
{ key: 'lastTradePrice', label: '最后一笔成交价', fixed: false },
{ key: 'shares', label: '策略份额', fixed: false },
// R-015/迭代 13:行情列(盘口快照 + 合约信息;defaultVisible=false 默认隐藏,列设置勾选开启)
{ key: 'upStopPrice', label: '涨停价', fixed: false, defaultVisible: false },
{ key: 'downStopPrice', label: '跌停价', fixed: false, defaultVisible: false },
{ key: 'open', label: '今开', fixed: false, defaultVisible: false },
{ key: 'high', label: '最高', fixed: false, defaultVisible: false },
];
/** 策略设置 schemaschemastery 定义,settings.register 要求 schema 对象) */
@@ -438,8 +443,8 @@ export function normalizeStrategyColumns(scope, strategyId) {
const configSchema = Array.isArray(strategy?.configSchema) ? strategy.configSchema : [];
const raw = (value.strategyColumns && value.strategyColumns[strategyId]) || [];
// 1. 默认全列(基础列全显默认序 + 字段列全显 configSchema 序)
const baseCols = COLUMN_META.map((c) => ({ key: c.key, label: c.label, fixed: false, kind: 'base' }));
// 1. 默认全列(基础列默认序 + 字段列 configSchema 序;显隐缺省跟随 defaultVisibleR-015 行情列默认隐藏
const baseCols = COLUMN_META.map((c) => ({ key: c.key, label: c.label, fixed: false, kind: 'base', defaultVisible: c.defaultVisible !== false }));
const fieldCols = configSchema.map((f) => ({ key: f.key, label: f.label || f.key, fixed: false, kind: 'field' }));
const defaults = [...baseCols, ...fieldCols];
@@ -461,7 +466,8 @@ export function normalizeStrategyColumns(scope, strategyId) {
}
for (const d of defaults) {
if (!placed.has(d.key)) {
ordered.push({ ...d, visible: visibleMap.has(d.key) ? visibleMap.get(d.key) : true });
const dv = visibleMap.has(d.key) ? visibleMap.get(d.key) : d.defaultVisible !== false;
ordered.push({ ...d, visible: dv });
}
}
return ordered;