feat(data): 中证1000/2000 定期更新 schtask + schtask 路径坑修复

sanguo-index 增强: index_monthly_wrapper 加 STEP0 parse_csindex_announce
(治偏差全集, 月度16号自动刷新 constituent_unified)

register_akshare_schtasks 修 PowerShell schtasks /tr 反斜杠路径丢前缀坑:
$ws 变量在双引号被原生命令解析吃掉 -> Arguments 存成 \xxx.ps1 ->
schtasks /run 返回成功但 wrapper 静默不跑从不写日志。改全路径硬编码 + --%。
ak-* 5 schtask 路径全坏已批量修(register_akshare 旧版"已部署Ready"是假成功)。

诊断: Get-ScheduledTask 中文Win报 0x80070057 无用, 改 schtasks /query /xml
看 Arguments 才发现丢前缀。

schtask 全链路验证 STEP0-3 exit=0, constituent_unified
000852=1672(was_removed=672) / 932000=2684(684) 治偏差保持。
This commit is contained in:
2026-07-24 00:20:36 +08:00
parent d5582fd6f2
commit e7465c342f
4 changed files with 228 additions and 18 deletions
@@ -1,13 +1,16 @@
# index_monthly_wrapper.ps1 — sanguo-index schtask wrapper (monthly 16号 19:50 成份股刷新)
# 1. index_const_hist_download 深证(A adjust_cni)+中证(B snapshot) akshare parquet 刷新(成份股随时间变)
# 2. migrate_constituent 重建 staging(从 bs_index_constituent_old baostock 全集 + 深证/中证 parquet)
# 3. merge_constituent staging -> constituent_unified (幂等 DROP+CREATE)
# 不碰 baostock online(全集已在 _old, migrate 读它); 不跑 C 新浪(baostock 权威)
# STEP0: parse_csindex_announce (csindex 调整公告 -> announce_union, 治幸存者偏差全集, 2026-07-23 新增)
# STEP1: index_const_hist_download --parts A B (深证 A adjust_cni + 中证 B snapshot) akshare parquet 刷新
# STEP2: migrate_constituent 重建 staging (baostock _old 全集 + 深证 union + 中证 announce_union 全集)
# STEP3: merge_constituent staging -> constituent_unified (幂等 DROP+CREATE)
# 不碰 baostock online (全集已在 _old, migrate 读它); 不跑 C 新浪 (baostock 权威)
# STEP0 失败不阻塞 (csindex 网络抖动时 migrate 回退 snapshot, 治偏差降级但 pipeline 不死)
$env:http_proxy = ''
$env:https_proxy = ''
$env:all_proxy = ''
$env:PYTHONIOENCODING = 'utf-8'
$env:INDEX_HIST_OUT_DIR = 'C:\sanguo_vnpy_v2\data\index_const_hist'
$env:CSINDEX_CACHE = 'C:\sanguo_vnpy_v2\data\csindex_raw'
Set-Location C:\sanguo_vnpy_v2
$ts = Get-Date -Format 'yyyyMMdd_HHmmss'
$logDir = 'C:\sanguo_vnpy_v2\data\migration_logs'
@@ -16,11 +19,15 @@ $log = Join-Path $logDir "index_monthly_$ts.txt"
$py = 'C:\Python310\python.exe'
$dir = 'C:\sanguo_vnpy_v2\scripts\data_platform'
"[$ts] STEP1 index_const_hist_download --parts A B (深证 adjust + 中证 snapshot)" | Out-File $log -Encoding UTF8
"[$ts] STEP0 parse_csindex_announce --only both (csindex 公告 -> announce_union, 治偏差全集)" | Out-File $log -Encoding UTF8
& $py -X utf8 "$dir\parse_csindex_announce.py" --only both *>> $log
"[$ts] STEP0 done exit=$LASTEXITCODE (失败不阻塞, migrate 回退 snapshot)" | Out-File $log -Append -Encoding UTF8
"[$ts] STEP1 index_const_hist_download --parts A B (深证 adjust + 中证 snapshot)" | Out-File $log -Append -Encoding UTF8
& $py -X utf8 "$dir\index_const_hist_download.py" --parts A B *>> $log
"[$ts] STEP1 done exit=$LASTEXITCODE" | Out-File $log -Append -Encoding UTF8
"[$ts] STEP2 migrate_constituent (rebuild staging from _old + parquet)" | Out-File $log -Append -Encoding UTF8
"[$ts] STEP2 migrate_constituent (rebuild staging from _old + parquet + announce_union)" | Out-File $log -Append -Encoding UTF8
& $py -X utf8 "$dir\migrate_constituent.py" *>> $log
"[$ts] STEP2 done exit=$LASTEXITCODE" | Out-File $log -Append -Encoding UTF8
@@ -1,15 +1,22 @@
# register_akshare_schtasks.ps1 — 注册 akshare 低频 5 schtask (spec §14.5 A+B+C)
# akshare per-stock 全量慢+东财限流 → 夜间/周末/财报季; akshare_static_download 内置断路器(连30 failed exit)+0.8s sleep
# 时间错开 bs-eod(18:05)/xt-eod(18:40) 之后, 无并发
$ws = 'C:\sanguo_vnpy_v2\scripts\data_platform'
schtasks /create /tn sanguo-ak-eod /tr "powershell -ExecutionPolicy Bypass -File $ws\ak_eod_wrapper.ps1" /sc daily /st 19:00 /ru SYSTEM /rl HIGHEST /f
schtasks /create /tn sanguo-ak-events /tr "powershell -ExecutionPolicy Bypass -File $ws\ak_events_wrapper.ps1" /sc daily /st 19:30 /ru SYSTEM /rl HIGHEST /f
schtasks /create /tn sanguo-ak-stock /tr "powershell -ExecutionPolicy Bypass -File $ws\ak_stock_wrapper.ps1" /sc weekly /d SAT /st 03:00 /ru SYSTEM /rl HIGHEST /f
schtasks /create /tn sanguo-ak-quarter /tr "powershell -ExecutionPolicy Bypass -File $ws\ak_quarter_wrapper.ps1" /sc monthly /m APR,MAY,SEP,NOV /st 02:00 /ru SYSTEM /rl HIGHEST /f
schtasks /create /tn sanguo-index /tr "powershell -ExecutionPolicy Bypass -File $ws\index_monthly_wrapper.ps1" /sc monthly /d 16 /st 19:50 /ru SYSTEM /rl HIGHEST /f
Write-Output "=== VERIFY ==="
#
# 坑(2026-07-24 实证): PowerShell 调 `schtasks /tr "...$ws\xxx.ps1"` 时, 双引号内反斜杠路径被
# 原生命令参数解析吃掉 → Arguments 丢前缀变 `\xxx.ps1` → schtask 触发成功但 powershell 找不到文件静默退出, 不写日志。
# (Get-ScheduledTask 在中文 Win 报 0x80070057, 用 `schtasks /query /tn X /xml` 查 Arguments 才发现)
# 修复: 全路径硬编码 + `--%` stop-parsing 让 PowerShell 原样传参给 schtasks (反斜杠不丢)。
schtasks --% /create /tn sanguo-ak-eod /tr "powershell -ExecutionPolicy Bypass -File C:\sanguo_vnpy_v2\scripts\data_platform\ak_eod_wrapper.ps1" /sc daily /st 19:00 /ru SYSTEM /rl HIGHEST /f
schtasks --% /create /tn sanguo-ak-events /tr "powershell -ExecutionPolicy Bypass -File C:\sanguo_vnpy_v2\scripts\data_platform\ak_events_wrapper.ps1" /sc daily /st 19:30 /ru SYSTEM /rl HIGHEST /f
schtasks --% /create /tn sanguo-ak-stock /tr "powershell -ExecutionPolicy Bypass -File C:\sanguo_vnpy_v2\scripts\data_platform\ak_stock_wrapper.ps1" /sc weekly /d SAT /st 03:00 /ru SYSTEM /rl HIGHEST /f
schtasks --% /create /tn sanguo-ak-quarter /tr "powershell -ExecutionPolicy Bypass -File C:\sanguo_vnpy_v2\scripts\data_platform\ak_quarter_wrapper.ps1" /sc monthly /m APR,MAY,SEP,NOV /st 02:00 /ru SYSTEM /rl HIGHEST /f
schtasks --% /create /tn sanguo-index /tr "powershell -ExecutionPolicy Bypass -File C:\sanguo_vnpy_v2\scripts\data_platform\index_monthly_wrapper.ps1" /sc monthly /d 16 /st 19:50 /ru SYSTEM /rl HIGHEST /f
Write-Output "=== VERIFY Arguments 路径(应全路径, 非 \xxx.ps1)==="
foreach ($t in @('sanguo-ak-eod','sanguo-ak-events','sanguo-ak-stock','sanguo-ak-quarter','sanguo-index')) {
$q = schtasks /query /tn $t /fo list 2>&1 | Out-String
$status = ($q -split "`n" | Where-Object { $_ -match 'Status' } | Select-Object -First 1).Trim()
Write-Output (" {0,-22} {1}" -f $t, $status)
$xml = schtasks /query /tn $t /xml 2>&1 | Out-String
if ($xml -match 'File\s+([^<"]+)') {
Write-Output (" {0,-20} File {1}" -f $t, $matches[1])
} else {
Write-Output (" {0,-20} (路径未找到)" -f $t)
}
}