feat(data): hot_rank 挂载+wrapper 时间守卫 [vps]——墙测量5轮收官用户拍板方案A:emappdata 夜间开窗(22:28 实测 OK,晨午4轮全 FAIL),19:30 档失败零连带(单 unit 失败不触断路器 rc 仍 0,不写不标次夜自愈),首夜起 gap_check 即免费持续测量;三处同步=wrapper --types+PANEL_TYPES+EVENT_PANEL_TYPES(15类),零文件=零告警首日成功即成基线;时间守卫=param -Force+非 19:00-23:59 拒绝执行留痕 guard.log(治盘前手动误跑两犯:09-02 08:08/09-04 08:00,盘前拉当日=昨日态错标+marker 锁死当晚真数据);TDD 2 测翻新(白名单拒→放行+注册断言)先红后绿+806 全绿;VPS Parse 预检过+双脚本已 scp 生效位+wall_probe.py 已删 [vps]
CI/CD / test (push) Successful in 0s
CI/CD / nas-deploy (push) Successful in 5m3s
CI/CD / nas-verify (push) Successful in 11s

This commit is contained in:
2026-09-04 18:46:46 +08:00
parent 6adb40e7a0
commit c728f2368c
5 changed files with 33 additions and 10 deletions
+3 -1
View File
@@ -212,13 +212,15 @@ class FundamentalsQueryParams(_QueryBase):
# 事件/快照 panel 白名单(2026-09-02 A 档使用层出口):与采集注册表
# (akshare_static_download.py)及 static_vintage_check.PANEL_TYPES 口径一致;
# hot_rank 墙测量未拍板挂载,故不在列(拍板后三处同步加)。
# hot_rank 2026-09-04 拍板挂载(墙测量5轮收官:emappdata 夜间开窗,19:30 档
# 失败零连带——单 unit 失败不触断路器,次夜自动重试)。
EVENT_PANEL_TYPES = frozenset({
"dragon_tiger", "block_trade", "margin_sse", "restricted",
"zt_pool", "zt_pool_zbgc", "zt_pool_dtgc",
"fund_flow_industry", "fund_flow_concept",
"ths_industry", "ths_concept",
"xueqiu_hot", "sina_sector", "gdhs",
"hot_rank",
})
+17 -2
View File
@@ -1,11 +1,26 @@
# ak_events_wrapper.ps1 — sanguo-ak-events schtask wrapper (daily 19:30 akshare 事件类 per-date 当日)
# dragon_tiger/block_trade/restricted/zt_pool 三件套/新浪资金流×2/同花顺行业概念/雪球热度/新浪行业对账 --start today --end today;
# per-date 每类1 unit 快; zt_pool 系 (2026-09-02 双机实测 push2ex 集群稳定) 供情绪/打板因子;
# hot_rank (东财人气榜) 墙待恢复窗测量, 拍板后加入 --types (fetcher/注册已就位);
# hot_rank (东财人气榜) 已于 2026-09-04 挂载进 --types (fetcher/注册已就位);
# 新浪资金流+同花顺榜 (2026-09-02 用户批 A 档: 东财 push2 墙死后免费无墙替代, 秒级零限流)
# margin_sse 单独拆出 (2026-09-02 巡查+用户批准): SSE 融资融券 T+1 供应,当晚拉当天→空响应
# akshare Length mismatch 崩(07-22 起 43 天慢性失血,已 --force 回补 0722~0901);
# 改拉 T-1~T 两天窗:每晚稳定写昨日;当天失败不写不标,次晚同窗自动重试补上
# hot_rank 2026-09-04 拍板挂载 (墙测量5轮收官: emappdata 夜间开窗, 22:28 实测 OK;
# 19:30 档失败零连带——单 unit 失败不触断路器, 不写不标, 次夜自动重试)
param([switch]$Force)
# time guard (2026-09-04, user approved): pre-market runs save LAST close state
# under today's filename + marker locks out the real 19:30 pull (hit twice:
# 09-02 08:08, 09-04 08:00). Refuse outside 19:00-23:59 unless -Force.
$guardHour = [int](Get-Date -Format HH)
if (-not $Force -and $guardHour -lt 19) {
$logDir = 'C:\sanguo_vnpy_v2\data\migration_logs'
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
$msg = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') REFUSED: ak-events window is 19:00-23:59, now outside. Use -Force to override."
Add-Content -Path (Join-Path $logDir 'ak_events_guard.log') -Value $msg
Write-Output $msg
exit 1
}
$env:http_proxy = ''
$env:https_proxy = ''
$env:all_proxy = ''
@@ -16,7 +31,7 @@ $ts = Get-Date -Format 'yyyyMMdd_HHmmss'
$logDir = 'C:\sanguo_vnpy_v2\data\migration_logs'
if (-not (Test-Path $logDir)) { New-Item -ItemType Directory -Path $logDir -Force | Out-Null }
$log = Join-Path $logDir "ak_events_$ts.txt"
C:\Python310\python.exe -X utf8 C:\sanguo_vnpy_v2\scripts\data_platform\akshare_static_download.py --types dragon_tiger,block_trade,restricted,zt_pool,zt_pool_zbgc,zt_pool_dtgc,fund_flow_industry,fund_flow_concept,ths_industry,ths_concept,xueqiu_hot,sina_sector --start $today --end $today *>> $log
C:\Python310\python.exe -X utf8 C:\sanguo_vnpy_v2\scripts\data_platform\akshare_static_download.py --types dragon_tiger,block_trade,restricted,zt_pool,zt_pool_zbgc,zt_pool_dtgc,fund_flow_industry,fund_flow_concept,ths_industry,ths_concept,xueqiu_hot,sina_sector,hot_rank --start $today --end $today *>> $log
$rc1 = $LASTEXITCODE
C:\Python310\python.exe -X utf8 C:\sanguo_vnpy_v2\scripts\data_platform\akshare_static_download.py --types margin_sse --start $yesterday --end $today *>> $log
$rc2 = $LASTEXITCODE
@@ -39,7 +39,7 @@ PANEL_TYPES = (
"fund_flow_industry", "fund_flow_concept", # 快照族 (永久)
"ths_industry", "ths_concept",
"xueqiu_hot", "sina_sector", # 快照族 (09-02 全量落地)
# hot_rank 待恢复窗测量拍板挂载后再入列 (避免未上线就缺日告警)
"hot_rank", # 快照族 (09-04 拍板挂载;零文件=零告警,首日成功即成告警基线)
)
BACKFILLABLE_PANEL_TYPES = frozenset({"zt_pool", "zt_pool_zbgc", "zt_pool_dtgc"})
PANEL_BACKFILL_CALENDAR_DAYS = 42 # ≈30 交易日回补窗的日历日近似
@@ -201,11 +201,12 @@ class TestPanelGapCheck:
status_panel["fund_flow_industry"]["holes_permanent"])
def test_panel_registry_snapshot_family(self):
"""09-02 全量落地批次注册正确: 快照族在列且不落可回补档; hot_rank 挂载入列。"""
"""快照族在列且不落可回补档; hot_rank 09-04 拍板挂载入列(零文件=零告警)"""
for t in ("xueqiu_hot", "sina_sector", "fund_flow_concept", "ths_concept"):
assert t in svc.PANEL_TYPES
assert t not in svc.BACKFILLABLE_PANEL_TYPES
assert "hot_rank" not in svc.PANEL_TYPES # 拍板挂载后才入列
assert "hot_rank" in svc.PANEL_TYPES # 09-04 拍板挂载
assert "hot_rank" not in svc.BACKFILLABLE_PANEL_TYPES
# ======================== main / JSON 契约 ========================
+9 -4
View File
@@ -29,6 +29,7 @@ from sanguo_portfolio.providers.fetchers import (
EventPanelFetcher,
LimitPoolFetcher,
)
from sanguo_portfolio.providers.fetchers.base import EVENT_PANEL_TYPES
from sanguo_portfolio.providers.local_unified_provider import LocalUnifiedProvider
# 真实列名(VPS 20260819_zt_pool_dtgc.parquet 实测)
@@ -123,10 +124,14 @@ class TestEventPanelQueryParams:
with pytest.raises(ValidationError, match="no_such_type"):
provider.get_event_panel("no_such_type", date="2024-06-18")
def test_hot_rank_not_mounted(self, provider):
"""hot_rank 墙测量未拍板挂载——白名单拒绝(与 PANEL_TYPES 口径一致)。"""
with pytest.raises(ValidationError, match="hot_rank"):
provider.get_event_panel("hot_rank", date="2024-06-18")
def test_hot_rank_mounted(self, provider):
"""hot_rank 2026-09-04 拍板挂载(墙测量5轮收官,19:30档)——白名单放行。
fixture hot_rank 目录=合法缺失,返回空 df(与缺目录语义一致)
"""
assert "hot_rank" in EVENT_PANEL_TYPES
df = provider.get_event_panel("hot_rank", date="2024-06-18")
assert df.empty
def test_date_and_start_exclusive(self, provider):
with pytest.raises(ValidationError, match="互斥"):