Show trading playbook in hub strategy docs.

Add an 执行手册 tab that renders docs/交易执行手册-期权与Gate.md as the default strategy view.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-07-21 22:16:54 +08:00
parent 301a464f29
commit e7f8e9201e
6 changed files with 32 additions and 12 deletions
+1
View File
@@ -4,6 +4,7 @@
| 文档 | 实例 | 状态 |
|------|------|------|
| [交易执行手册-期权与Gate.md](../交易执行手册-期权与Gate.md) | 中控「策略说明」·执行手册 | 个人开单纪律 |
| [binance-alt-trend-long.md](./binance-alt-trend-long.md) | 币安山寨·多头趋势 | v0.4 讨论稿 |
| [okx-trend-both.md](./okx-trend-both.md) | OKX·多空趋势 | v0.4 讨论稿 |
| [gate-intraday.md](./gate-intraday.md) | Gate·BTC 日内 | v0.2 |
+10 -1
View File
@@ -10,9 +10,15 @@ from typing import Any
from lib.paths import REPO_ROOT
STRATEGY_EXCHANGES: tuple[str, ...] = ("binance", "okx", "gate")
STRATEGY_EXCHANGES: tuple[str, ...] = ("playbook", "binance", "okx", "gate")
STRATEGY_META: dict[str, dict[str, str]] = {
"playbook": {
"label": "执行手册",
"title": "交易执行手册(期权为主 · Gate 为辅)",
# 相对仓库根;其余条目用 md_file 相对 docs/strategy
"md_rel": "docs/交易执行手册-期权与Gate.md",
},
"binance": {
"label": "币安",
"title": "币安·山寨多头趋势",
@@ -43,6 +49,9 @@ def _md_path(exchange_key: str) -> Path:
meta = STRATEGY_META.get((exchange_key or "").strip().lower())
if not meta:
raise KeyError(exchange_key)
md_rel = (meta.get("md_rel") or "").strip()
if md_rel:
return REPO_ROOT / md_rel
return _strategy_dir() / meta["md_file"]
+1 -1
View File
@@ -7,7 +7,7 @@
| **资金概况** | 总资金曲线、分户权益、回撤与 24h 变化 |
| **开仓计划** | 事前写下计划、跟踪进行中、统计历史胜率 |
| **监控区** | **核心操作台**:三所持仓卡片、全平/撤单、关键位与趋势计划摘要 |
| **策略说明** | 三所策略 playbook + 开仓检查清单(非系统操作手册) |
| **策略说明** | 执行手册 + 三所策略 playbook + 开仓检查清单(非系统操作手册) |
| **使用说明** | 本页:中控与实例怎么用 |
| **行情区** | K 线、指标、画线;可从持仓跳转带币种 |
| **计算器** | 趋势回调 / 滚仓张数与盈亏测算(手动填价) |
+2 -2
View File
@@ -960,7 +960,7 @@
<div class="page-head strategy-page-head">
<div>
<h1><span class="head-tag">STR</span> 策略说明</h1>
<p class="page-desc">策略正文(带目录) · 执行清单(打印对照) · 三所切换</p>
<p class="page-desc">执行手册 · 三所策略正文(带目录) · 执行清单(打印对照)</p>
</div>
<div class="strategy-page-actions no-print">
<button type="button" id="strategy-btn-download" class="ghost">下载 HTML</button>
@@ -1405,7 +1405,7 @@
<script src="/assets/quotes.js?v=20260717-quotes-feed"></script>
<script src="/assets/funds.js?v=20260717-funds-scroll-fix"></script>
<script src="/assets/dashboard.js?v=20260720-dash-sl-tp"></script>
<script src="/assets/strategy.js?v=8"></script>
<script src="/assets/strategy.js?v=9"></script>
<script src="/assets/help.js?v=1"></script>
<script src="/assets/logs.js?v=1"></script>
<script src="/assets/ai_review_render.js?v=3"></script>
+7 -6
View File
@@ -21,7 +21,7 @@
const btnPrintChecklistInline = document.getElementById("strategy-btn-print-checklist-inline");
const btnDownload = document.getElementById("strategy-btn-download");
let activeKey = "binance";
let activeKey = "playbook";
let activeView = "doc";
let tabsMeta = [];
let cache = {};
@@ -128,13 +128,14 @@
function sectionTag(title) {
const t = String(title || "");
if (/账户|定位/.test(t)) return "账户";
if (/开仓类型|开仓|入场|反转|顺势|波段|假破|结构/.test(t)) return "入场";
if (/总原则|原则/.test(t)) return "原则";
if (/账户|定位|分工/.test(t)) return "账户";
if (/开仓类型|开仓|入场|反转|顺势|波段|假破|结构|对冲|方向单/.test(t)) return "入场";
if (/周期/.test(t)) return "周期";
if (/方向/.test(t)) return "方向";
if (/纪律|出场|笔数|节奏/.test(t)) return "纪律";
if (/持仓|离场|强平/.test(t)) return "离场";
if (/资金|杠杆|计仓/.test(t)) return "仓位";
if (/纪律|出场|笔数|节奏|止损|次数/.test(t)) return "纪律";
if (/持仓|离场|强平|到期/.test(t)) return "离场";
if (/资金|杠杆|计仓|仓位|预算/.test(t)) return "仓位";
if (/系统|字段|对接/.test(t)) return "系统";
if (/修订|记录/.test(t)) return "版本";
if (/边界|关系|行情状态/.test(t)) return "边界";
+11 -2
View File
@@ -12,10 +12,19 @@ from lib.hub.hub_strategy_lib import (
class TestHubStrategyLib(unittest.TestCase):
def test_meta_has_three_exchanges(self):
def test_meta_has_playbook_and_exchanges(self):
meta = strategy_meta_payload()
keys = [x["key"] for x in meta["exchanges"]]
self.assertEqual(keys, ["binance", "okx", "gate"])
self.assertEqual(keys, ["playbook", "binance", "okx", "gate"])
def test_load_playbook_payload(self):
p = load_strategy_payload("playbook")
self.assertTrue(p["ok"])
self.assertEqual(p["label"], "执行手册")
self.assertIn("交易执行手册", p["md_source"])
self.assertIn("strategy_html", p)
self.assertIn("<h2", p["strategy_html"].lower())
self.assertIn("总原则", p["strategy_html"])
def test_load_binance_payload(self):
p = load_strategy_payload("binance")