wshy
|
7e99a07270
|
Merge pull request #276 from kevin9327/fix/quotes-flush-quote-ts
fix(kline): 实时行情覆写当日日K分区时补写 quote_ts
|
2026-09-09 09:04:28 +08:00 |
|
kevin9327
|
4bbc7d07a3
|
fix(kline): 实时行情覆写当日日K分区时补写 quote_ts
sync_daily_by_quotes 手工拼 record 时漏了行情响应的 timestamp, 而
flush_live_daily 是整分区覆写, 会把 QuoteService 之前写入的 quote_ts 一并
抹掉。data_integrity 的判据全建立在 quote_ts 上, 分区因此从"盘中快照"
退化为"权威历史": 盘中触发同步后停机, 次日自检漏判, 停机时刻的
close/volume 永久留存并污染 lookback 指标。
|
2026-09-09 07:25:35 +09:00 |
|
kevin9327
|
ea27376e03
|
fix(kline): 分钟K增量同步窗口统一按北京时区
sync_and_persist_minute 的起点取自本地分钟K的北京墙钟, 终点却用服务器
本地墙钟 datetime.now(); _datetime_to_ms 按服务器时区解释两者, UTC 容器上
起点反而晚于终点, time_segments 为空, 增量补拉一个请求都发不出去。
_latest_minute_datetime / _earliest_minute_datetime 返回值带上 CN_TZ,
now 改用 cn_now(), 与 fetch_minute_single 已有的时区纪律保持一致。
|
2026-09-09 07:15:02 +09:00 |
|
0112020179
|
a8bb7a25bf
|
fix(kline): 压缩详情响应并限制无权限分钟回退
|
2026-09-08 18:09:59 +08:00 |
|
0112020179
|
3d6beb3c35
|
fix(fuyao): 根据审查完善流式同步
|
2026-09-06 17:39:43 +08:00 |
|
0112020179
|
1c022a1c7c
|
fix(fuyao): 流式同步历史日K避免内存溢出
|
2026-09-06 12:35:26 +08:00 |
|
shy3130
|
010c484289
|
feat(data): 全量分钟 (full_minute) 数据集开放插件/自定义源接入
像其他能力一样可路由: 声明 full_minute 数据集并在设置页路由, 即接入
盘中全市场分钟落盘服务 (与 TickFlow Expert 同一能力键 intraday.universe)。
- policy: _DATASET_CAP_MAP 增补 full_minute → INTRADAY_UNIVERSE, 自定义源
声明且被路由时自动补授能力, 服务门控对两类源统一口径
- capabilities 注册表: full_minute 从不可路由 (field=None) 改为
full_minute_data_provider 偏好路由; preferences/settings API 收发新字段
- 插件契约: get_intraday_batch (修复轮, 未实现回退 get_minute 当日窗口) +
get_intraday_latest (稳态增量, 可选; 未实现降级仅修复轮, 节奏下限 60s)
- YAML 声明式源: full_minute 数据集与 minute 同形, loader 白名单放行,
源编辑器 UI 可配置; 仅修复轮语义
- kline_sync 边界: fetch_intraday_custom_batch / _fetch_intraday_custom_latest,
帧过北京墙钟守卫, 与 TickFlow 边界函数同纪律
- minute_refresh: 删「自定义分钟源让位」逻辑, 改按路由取数;
status 增 provider / provider_effective / repair_only
- 前端: 监控页卡片按能力驱动, 数据源页路由矩阵, api.ts 类型
- 测试: 门控/路由/降级/增广新增用例, 后端 1332 全过
- 文档: plugin-development / custom-data-source / configuration / features /
CONTRIBUTING 契约细化 (AI 可照文档接入)
|
2026-08-31 22:53:24 +08:00 |
|
shy3130
|
d29f9c0ea8
|
perf(data): TickFlow 取数切换 as_dataframe=False 列式直转; 修复除权因子日期 UTC 偏移一天
- 全部 K 线取数点改走 CompactKlineData 列式直转 polars (无 pandas 中转,
全市场单轮本地转换 ~1.1s → ~0.1s), 时区口径统一 _timestamp_to_beijing_datetime
- 除权因子 trade_date 原取 UTC 日期, 北京零点事件整体早一天 → 转北京墙钟后取日期
- 盘中分钟增量间隔上限 300s → 120s (universe 仅回最新 3 根, 超限必留缺口)
|
2026-08-30 22:29:33 +08:00 |
|
shy3130
|
657d4d9948
|
feat(minute): 全量分钟能力位与两阶段日内分钟落盘
- tickflow SDK 0.1.25: intraday.universe 标的池单请求拉全市场当日分钟
- 新能力位 Cap.INTRADAY_UNIVERSE (TickFlow Expert 专有) + 探测/别名/schema v6
- 分钟刷新两阶段: 冷启动与缺口修复走 intraday_batch 全天突发(分块容错), 稳态走 universe 增量
- 覆盖看门狗: 落后>3min / 无数据 / 连续空轮自动升级全量自愈
- 刷新间隔钳制 [3,300]s 默认 6s; 监控页全量分钟开关与状态入口
- CONTRIBUTING: 分钟 K 北京时间墙钟契约 (naive, 入口强制归一)
|
2026-08-30 19:05:25 +08:00 |
|
shy3130
|
b4aa5918fc
|
feat(data): 能力路由矩阵落地——五档入册、除权独立路由、插件源下限放宽
- 新增能力注册表 capabilities.py 与 /capability-matrix: 六能力(实时/日K/
分钟/五档/除权/财务)统一 candidates/pending/usable, 各页门控以 usable 为准
- 五档盘口 (depth5) 进入矩阵: tf_tier=pro, 插件数据集白名单暂未开放
- 除权「跟随日K」(same_as_daily) 下线: 每能力独立路由, 四处跟随解析移除,
存量旧值经 preferences getter 回退 tickflow 自愈; 矩阵显示与实际拉取口径一致
- 实时轮询下限: 路由到插件/自定义源时不受 TickFlow 档位限速, 通用下限 1s
(默认间隔仍 6s, TickFlow 路由档位查表不变)
- 插件 manifest 新增 homepage 透传; loader 输出 api_key_masked (Key 脱敏
与 TickFlow 同一展示契约); fuyao 声明官网
|
2026-08-30 19:05:21 +08:00 |
|
shy3130
|
5e2358ce48
|
feat(minute): 分钟策略执行后端 + 分钟红7策略 + 盘中增量落盘 (Expert)
一期 · 分钟策略执行链路:
- 引擎新增 minute_filter 执行后端: 策略声明 filter_minute_history(df, params),
timeframes 必须且仅为 ["1m"]; 输入为当日分钟K窗口, 命中行事后联表 enriched
快照补基础过滤列 (name/total_shares/change_pct), close 用最新分钟价
- 内置策略「分钟红7」(minute_red_streak): 最近 N 根(默认7)分钟K至少 5 根
close>open, 且按最高价排序的最高的 2 根全红; 全向量化, 671k 行约 230ms;
参数 bars/min_red/top_red/rank_by_close, 不足 N 根不触发, 同值取更晚K线
- ScreenerService 1m context: 优先读 as_of 当日 kline_minute 分区, 缺失回退
全市场最近分区; 单分区直读与全量 glob 解耦
- run_preset/run_all 分钟周期结果不写日线盘后缓存 (语义隔离)
二期 · 盘中分钟增量落盘 (Expert 专有):
- kline_sync.fetch_intraday_full_market_burst: intraday.batch 独立限流池,
全市场 5546/200=28 块线程池一次打出, 轮内不重试
- MinuteRefreshService: 后台线程, 门控链 = 开关→自定义分钟源让位→INTRADAY_BATCH
能力→连续竞价时段(9:30-11:30/13:00-15:00); 固定节奏 next=max(起点+间隔,完成),
不补跑; 每轮单次合并落盘 (_write_minute_partition unique 幂等)
- 偏好 minute_refresh_enabled(默认关)/minute_refresh_interval([60,300]s 默认60);
GET /api/settings/minute-refresh/status 状态端点
前端:
- 策略页日线/分钟周期切换 (1m 下 ETF 置灰、不触发盘后 runAll、prune 仅日线),
策略卡片「分钟」徽章, 策略池对话框按周期拉取
- 数据页分钟K设置弹窗新增盘中增量区块: 开关/间隔(60-300s)/能力缺失置灰/
服务状态行(运行中·时段暂停·最近一轮)
测试: 26 项新增 (形态7/引擎4/context4/服务11), 更新 3 个 matrix 不变量测试;
全量 1112 passed; 前端 build 通过; 浏览器端到端实测通过
|
2026-08-30 19:05:05 +08:00 |
|
shy3130
|
697c27bb02
|
feat(v0.2): 市场阶段与主线识别 + 因子挖掘全链路 + 数据层完善
- 市场环境: 新增情绪周期6阶段(冰点/启动/主升/高潮/退潮/修复, 连板梯队驱动,
EMA平滑+2日确认+弱档否决, 平均段长9.7天)与概念/行业主线排名(涨停梯队聚合,
可配置宽基/风格标签过滤); 市场环境页重构, regime 透明加列, 与5档state并存
- 挖掘: 因子与策略挖掘全链路(API/worker/进程锁/候选库/前端工作台/文档),
周度调度默认关闭且永不自动发布
- 回测: 财务快照因子(点时口径), 批量回测预计算共享下期收益,
信号路径矩阵列依赖展开修复(consecutive_limit_ups 缺列报错)
- 数据/性能: enriched 生成与预热治理, 重任务限流, 行情/K线缓存复用, 时区修复
- 测试: 后端全量 914 通过; GUI 黑盒验证截图存证 gui-test-screenshots/
|
2026-08-16 23:39:07 +08:00 |
|
shy3130
|
8c00f7a3fd
|
feat(v0.2): 双击价格创建点位监控 + 分钟K补齐修复 + 超时设置独立
点位监控(双击图表):
- 日K/单日分时/多日分时价格主图支持双击, 自动预填目标价并按最新价判断上穿/下穿
- 成交量区与指标子图不触发; 自动生成通知文案, 用户手改后不再覆盖
- 已启用点位监控以横虚线显示 (上穿红/下穿绿), 并纳入三图 Y 轴范围
- 复用现有 PriceAlertDialog, 未改变后端 close>=/<= 规则语义与冷却机制
分钟K数据:
- 个股补齐强制回溯请求天数 (force_full_days), 修复切换日期范围只显示3天
- 单股并发补齐复用仓库写锁, 修复 Windows Parquet 临时文件替换失败
- DuckDB 读路径改用短生命周期 cursor, 释放对 Parquet 文件的占用
设置页:
- 数据任务超时从 DataSources 抽出为独立"超时设置"页签
- 设置侧栏垂直居中
验证: pytest 38 passed, pnpm build ok, git diff --check ok, 浏览器端到端 GUI 验证通过
|
2026-08-10 23:32:44 +08:00 |
|
shy3130
|
4df3062002
|
fix: 完善自定义分钟数据源配置与异常处理
- 补齐资产类型和周期参数在 API、YAML 与前端编辑器中的保存回读
- 权限判断和分时监控统一复用安全的数据源解析边界
- 增加配置往返及解析异常回归测试
|
2026-07-19 17:01:33 +08:00 |
|
intfoo
|
d9a77a534a
|
fix(minute): 承接 #122 review 三处阻断问题整改 + resolver 异常边界加固
|
2026-07-19 16:00:22 +08:00 |
|
intfoo
|
4c85f99633
|
fix(minute): 自定义分钟数据源用户单股补拉/监控页整改 (承接 #121 review)
|
2026-07-19 13:35:35 +08:00 |
|
 intfooandshy3130
|
e2ffde99d5
|
fix(minute,monitoring): 自定义数据源用户单股补拉/监控页打通 (#121)
承接 #126: 能力探测已补 KLINE_MINUTE_BATCH, 但两处取数/UI 仍按 TickFlow
档位拦截, 配了自定义分钟/实时源的 None 档用户依旧被挡。
- kline_sync.fetch_minute_single: 与 sync_minute_batch 一致, 先查
preferences.get_minute_data_provider(), 非 tickflow 且自定义源有
minute dataset 时走 custom provider, 避免分时图首次打开(本地无数据)
补拉返回空。
- Monitoring.tsx: None 档但配了自定义实时源时, 后端
is_realtime_allowed(realtime_mode=full_market) 仍返回 True。
以 quoteStatus.realtime_allowed 作为最终判据, 不再用 isNoneTier
一刀切拦截实时监控页。
Co-authored-by: shy3130 <shy3130@users.noreply.github.com>
|
2026-07-19 13:26:52 +08:00 |
|
shy3130
|
a1e8be58db
|
feat: release v0.1.86
|
2026-07-18 00:49:28 +08:00 |
|
shy3130
|
365f1ccbfb
|
feat(minute-k): 分钟K同步流式落盘 + 段大小可配 + 回测成交修复 + 卡死超时调整
1. 分钟K流式落盘 (修复1年全市场卡死)
- sync_minute_batch 加 on_segment 回调,每段拉完立即写盘
- 抽出 _write_minute_partition 公共函数,消除重复
- 内存峰值从全量(~25GB)降到单段,避免 OOM
2. 段大小可配 (默认20交易日,范围[5,30])
- 新增 minute_sync_segment_days 偏好项
- 「单次获取」与「获取1年」共用此分段设置
- 前端设置弹窗新增分段大小步进器
3. 回测分钟K精确成交修复 (从未成功跑通过)
- _resolve_minute_fill 改接受 DataFrame,避免 to_numpy() 退化为
object 数组后字段名索引抛 IndexError
- _load_minute_for_fills 用 partition_by 向量化分组替换逐行循环
- 新增 test_minute_fill.py 回归测试 (6 用例)
4. 卡死 watchdog 超时阈值按任务类型区分
- 普通任务 600s → 1200s;分钟K长任务 → 1800s
- create(timeout_s=) 支持按 job 存阈值,reap_stale 读 job 自身值
- 修复分钟K正常拉取被误杀导致僵尸线程继续写盘的问题
5. UI 优化
- 设置弹窗按 自动同步/手动获取/清空 三区块分组
- 「单次获取」改为按分段大小拉一段 (天数=分段设置)
- 状态文案: 盘后自动同步 → 自动同步已开启/已关闭
|
2026-07-12 14:23:22 +08:00 |
|
shy3130
|
fc85d53bee
|
feat(minute-k): 分钟K重做 — 前复权 + 向前扩展 + 清空 + 单独拉取 + 进度
- kline_sync: adjust="forward" 前复权; sync_minute_batch 按月分段(57天/段)
突破 count=10000 上限; on_chunk_done 回调带日期段标签
- kline.py: 删除 extend_minute_history; 新增 sync_minute_single(单股拉取落库)
+ clear_minute(仅清分钟K二次确认) + sync_minute 可选 days/extend 参数
- preferences/settings: 默认 5 天上限 30 (恢复原始); 超时强制释放 _heavy_run_lock
- MinuteSyncConfig: 自动同步(5天/关闭) + 往前获取(单次拉满) + 获取1年(分段)
+ 清空按钮 + 进度回调 onJobStart
- StockIntradayChart: 单股获取改用 syncMinuteSingle (落库)
- daily_pipeline: _minute_chunk_progress 兼容 seg_label 参数
|
2026-07-12 11:04:34 +08:00 |
|
 Jinfeng SunandClaude Opus 4.8
|
e5a94c42d5
|
feat: ETF 支持(选股 / 回测 / 监控) (#61)
* feat(screener): 选股引擎支持 ETF
- 12 个内置策略打 asset_types 白名单 + strategy_supports_asset;涨停类
(连板/断板反包)仅股票,其余 10 个技术类对 ETF 开放
- ScreenerService(repo, asset_type) 分流取数,ETF 复用 kline_etf_enriched,
跳过股票专用历史缓存与涨停信号;进程级 _history_cache key 含 asset_type
- API /run、/run_preset 透传 asset_type;/strategies 按资产过滤;
股票专有策略在 ETF 下返回空
- 新增 enriched_dirname(asset_type) 共享 helper;get_enriched_latest_asset
增 refresh 参数(供轮询线程避免冷缓存同步重算)
- 前端「策略」页加 股票/ETF 切换,ETF 走实时单跑(空日期→用 ETF 自身最新日);
QK.screenerStrategies 按 asset_type keyed
- 测试:test_screener_etf.py
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(backtest): 回测支持 ETF(个股/因子/策略组合)
- 三条回测路径 + 共用 BacktestEngine 面板加载按 asset_type 路由到
kline_etf_enriched(复用 enriched_dirname);PanelCache key 隔离资产;
ETF 跳过股票专用 get_enriched_range 缓存
- 面板 compute_all/名称 JOIN 按 asset_type 取维表(get_instruments_asset),
修复 ETF 策略回测用错股票维表致名称为空/涨停信号算错
- BacktestConfig/FactorConfig/StrategyBacktestConfig 增 asset_type
- 三个回测 API + SSE stream 透传 asset_type;_make_job_key 纳入 asset_type
(修复 stream 与 cancel job_key 不对齐致取消失效的回归)
- 前端策略组合页/因子页加 股票/ETF 切换,标的搜索与策略列表跟随资产;
assetType 持久化
- 测试:test_backtest_etf.py(含 job_key 一致性回归);既有回测测试替身同步
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(monitor): 监控规则支持 ETF
- engine.evaluate(df, asset_type) 按规则 asset_type 分轮评估;quote_service
增开 ETF 评估轮(用 ETF enriched 快照),股票轮不受影响、不重置其策略结果
- ETF 评估轮独立 try(异常不丢弃已算出的股票告警)+ refresh=False(不在轮询
线程触发 ETF 冷缓存同步重算)
- ETF 版历史加载器(main.py 注入)+ 按规则 asset_type 选加载器
- _strategy_pools 按 (sid, asset_type) 键,避免同策略股票/ETF 规则互相覆盖
- name_map 仅在有 ETF 规则时补 ETF 维表, setdefault 保股票名优先
- RuleModel/normalize 增 asset_type(默认 stock,持久化往返)
- 前端 RuleEditor 加 股票/ETF 选择,策略列表与标的搜索跟随资产
- 测试:test_monitor_etf.py
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(etf): 前端 API 绑定透传 asset_type + 文档
- api.ts: screener/backtest 绑定加 assetType 参数,MonitorRule 类型加 asset_type
- docs/features.md: 标注选股/回测/监控的 ETF 支持范围与前提
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(reliability): 管道并发/原子写/能力探测/监控告警多处加固
后端可靠性专项修复(均带回归测试, backend 全套 64 passed):
并发与数据完整性:
- 盘后管道单飞: JobStore.create() 去重纳入 pending∨running, 关闭"两次快速点击"
并发双跑窗口; 新增 _heavy_run_lock 执行槽挡住 reap 后僵尸线程并发写 parquet
- adj_factor/minute 全部改走原子写(tmp+replace), 消除 kill/断电致 all.parquet 损坏
- 分块拉取失败聚合 WARNING 可见化(不再静默当成功); 复权失败标的会保持旧价已提示
能力探测:
- 周期重探(60min)热更新 app.state.capabilities, 付费 Key 过期/续费无需重启即可见
- 瞬时探测失败(超时/连接/5xx, 按 _is_transient 判定)不降级、保留旧付费档;
真 401/无权限仍正常降级回落 free-api
监控告警:
- 评估仅在连续竞价(9:30-11:30/13:00-15:00)+ 快照当日新鲜度下进行, 避开集合竞价/
收盘后陈旧价与节假日误告警
- scope=sector fail-closed(validate 拒绝新建 + _apply_scope 返回空), 修复板块规则
对全市场刷屏
- 飞书 webhook 加退避重试并移到独立线程池 fire-and-forget, 不再阻塞行情轮询线程
单标的新鲜度: 新增 repo.symbols_lagging() 检测掉队标的并 WARNING + 计入 job 结果
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
2026-07-08 12:12:29 +08:00 |
|
shy3130
|
fa08981851
|
feat: 自定义数据源扩展 + 限频集中化 (v0.1.80)
|
2026-07-05 22:57:46 +08:00 |
|
 wshyandshy3130
|
57f417e6eb
|
fix(sync): 修复同步卡死在26%及启动期视图注册崩溃 (#47) (#48)
三处根因:
1. 限流逻辑失效 (kline_sync.py ×3, index_sync.py ×2)
条件 `len(chunks) > rpm` 在 free 档恒为 False (56 chunks < 60 rpm),
导致节流 sleep 永不执行, 请求密集打出触发服务端限流 → 卡死。
改为始终按 interval (60/rpm) 节流。
2. 卡死看门狗无法自愈 (pipeline_jobs.py, api/pipeline.py)
原超时检查只在再次点「同步」时触发, 等待中永不回收。
抽出 JobStore.reap_stale() (STALE_JOB_TIMEOUT_S=600), 在
/run 和 /jobs/{id} 轮询端点都调用 — 前端每秒轮询, 10分钟后
必定自动回收卡死 job, UI 不再永久停在 26%。
3. 启动期视图注册异常捕获不足 (repository.py)
_register_views 只捕获 duckdb.IOException, 跨版本/平台空目录
可能抛 CatalogException 等炸掉 lifespan。放宽到 Exception。
Co-authored-by: shy3130 <shy3130@users.noreply.github.com>
|
2026-07-04 15:53:50 +08:00 |
|
shy3130
|
a72445d782
|
fix(pipeline): 修复盘后管道除权因子拉取范围逻辑
daily_pipeline 除权因子改用日K范围回填 (实时增量模式兜底最近数日),
移除 max_date/incremental 依赖;kline_sync 修复 _normalize_adj_factor
重复列重命名崩溃, 新增 fetch_adj_factor_single 单股拉取;
kline.py fallback 改用 compute_enriched 应用复权;
index_sync 指数/ETF 日K同步增加批次进度回调;
同步指数日K步骤输出详细日志。
|
2026-06-29 17:17:44 +08:00 |
|
shy3130
|
2acaa38a2b
|
feat: release v0.1.60
|
2026-06-27 23:23:34 +08:00 |
|
shy3130
|
7369358d08
|
Initial release v0.1.19
|
2026-06-18 17:18:23 +08:00 |
|