Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .planning/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
- [x] Web 工作台已加入近期金油比 SVG 走势图。
- [x] `web serve` 页面已支持 60 秒自动刷新。
- [x] `web serve` 支持 `payload_factory`,每次请求重新生成页面。
- [x] CLI `web serve` 已接入动态 payload_factory。
- [ ] 后续可增加更多研究工作台模块与事件流刷新。

## 验证
Expand Down
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@
- `position_pnl_estimate()` 增加资金成本与净 P&L 估算;
- `summarize_batch_portfolio()`:批量 episode → 持仓模拟 → 资金/保证金高层汇总;
- `contracts portfolio` CLI:从合约 CSV 直接运行批量持仓高层汇总;
- `web serve` 支持 `payload_factory`,每次请求重新生成页面,实现真正自动刷新。
- `web serve` 支持 `payload_factory`,每次请求重新生成页面,实现真正自动刷新;
- CLI `web serve` 已接入动态 payload_factory,每次请求重新加载本地数据。

## [0.1.0-rc1] - 2026-09-02

Expand Down
69 changes: 38 additions & 31 deletions src/goratio/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -525,39 +525,46 @@ def main(
mcp_serve(loader, stdin=stdin, stdout=stdout)
return 0
if args.command == "web":
loaded = loader.load(args.source, timeout=args.timeout)
prepared = prepare_market_data(
loaded.raw,
period=args.period,
completed_before=completed_before,
provenance=loaded.provenance,
cache_stale=loaded.cache_stale,
)
current = summarize_current(
prepared.history.points,
prepared.selected.points,
)
payload = {
"schema_version": "goratio-web-v1",
"source_id": prepared.source.source_id,
"as_of": current["as_of"],
"ratio": current,
"series": [
{
"date": point.date.isoformat(),
"ratio": point.ratio,
}
for point in prepared.selected.points[-252:]
],
"factor": factor_snapshot(prepared),
"evidence": run_v2_evidence_bundle(prepared),
"risk_flags": (
["insufficient_history"] if not prepared.evidence_eligible else []
),
}
def make_web_payload():
loaded = loader.load(args.source, timeout=args.timeout)
prepared = prepare_market_data(
loaded.raw,
period=args.period,
completed_before=today(),
provenance=loaded.provenance,
cache_stale=loaded.cache_stale,
)
current = summarize_current(
prepared.history.points,
prepared.selected.points,
)
return {
"schema_version": "goratio-web-v1",
"source_id": prepared.source.source_id,
"as_of": current["as_of"],
"ratio": current,
"series": [
{
"date": point.date.isoformat(),
"ratio": point.ratio,
}
for point in prepared.selected.points[-252:]
],
"factor": factor_snapshot(prepared),
"evidence": run_v2_evidence_bundle(prepared),
"risk_flags": (
["insufficient_history"] if not prepared.evidence_eligible else []
),
}

if args.web_command == "serve":
serve_dashboard(payload, host=args.host, port=args.port)
serve_dashboard(
payload_factory=make_web_payload,
host=args.host,
port=args.port,
)
Comment on lines 560 to +565
return 0
payload = make_web_payload()
html = render_dashboard_html(payload)
if args.output:
Path(args.output).write_text(html, encoding="utf-8")
Expand Down