diff --git a/docs/交易执行手册与行为准则.xmind b/docs/交易执行手册与行为准则.xmind index 25e8eb0..9f54460 100644 Binary files a/docs/交易执行手册与行为准则.xmind and b/docs/交易执行手册与行为准则.xmind differ diff --git a/scripts/build_playbook_xmind.py b/scripts/build_playbook_xmind.py index f92b557..9363117 100644 --- a/scripts/build_playbook_xmind.py +++ b/scripts/build_playbook_xmind.py @@ -1,25 +1,83 @@ #!/usr/bin/env python3 -"""Generate XMind (Zen/2020+) mind map from playbook + behavior rules.""" +"""Generate business-style XMind (Zen/2020+) from playbook + behavior rules.""" from __future__ import annotations import json import uuid import zipfile from pathlib import Path +from typing import Any, Optional OUT = Path(__file__).resolve().parents[1] / "docs" / "交易执行手册与行为准则.xmind" +# 商务配色:深蓝主调 + 灰蓝辅色 + 强调色 +C_ROOT = "#0F2942" +C_L1 = "#1B4F72" +C_L2 = "#2E86AB" +C_PASS = "#1E8449" +C_FAIL = "#922B21" +C_WARN = "#B9770E" +C_MUTED = "#566573" +C_TEXT = "#FFFFFF" +C_TEXT_DARK = "#1C2833" + def tid() -> str: - return uuid.uuid4().hex + return uuid.uuid4().hex[:26] -def topic(title: str, children: list | None = None, notes: str | None = None) -> dict: - node: dict = { +def style( + *, + fill: Optional[str] = None, + color: Optional[str] = None, + font_size: str = "12pt", + bold: bool = False, + shape: str = "org.xmind.topicShape.roundedRect", + line: Optional[str] = None, +) -> dict[str, Any]: + props: dict[str, str] = { + "shape-class": shape, + "fo:font-family": "Microsoft YaHei", + "fo:font-size": font_size, + "fo:font-weight": "bold" if bold else "normal", + "border-line-width": "0pt", + "line-width": "1.5pt", + "line-class": "org.xmind.branchConnection.roundedelbow", + } + if fill: + props["svg:fill"] = fill + if color: + props["fo:color"] = color + if line: + props["line-color"] = line + return {"id": tid(), "properties": props} + + +def topic( + title: str, + children: list | None = None, + *, + markers: list[str] | None = None, + labels: list[str] | None = None, + notes: str | None = None, + fill: Optional[str] = None, + color: Optional[str] = None, + font_size: str = "12pt", + bold: bool = False, + line: Optional[str] = None, +) -> dict: + node: dict[str, Any] = { "id": tid(), "class": "topic", "title": title, + "style": style( + fill=fill, color=color, font_size=font_size, bold=bold, line=line + ), } + if markers: + node["markers"] = [{"markerId": m} for m in markers] + if labels: + node["labels"] = labels if notes: node["notes"] = {"plain": {"content": notes}} if children: @@ -27,280 +85,564 @@ def topic(title: str, children: list | None = None, notes: str | None = None) -> return node +def t1(title: str, children: list, markers: list[str], label: str) -> dict: + return topic( + title, + children, + markers=markers, + labels=[label], + fill=C_L1, + color=C_TEXT, + font_size="16pt", + bold=True, + line=C_L1, + ) + + +def t2(title: str, children: list | None = None, markers: list[str] | None = None) -> dict: + return topic( + title, + children, + markers=markers or ["flag-dark-blue"], + fill=C_L2, + color=C_TEXT, + font_size="13pt", + bold=True, + line=C_L2, + ) + + +def leaf( + title: str, + *, + markers: list[str] | None = None, + fill: Optional[str] = None, + color: Optional[str] = C_TEXT_DARK, +) -> dict: + return topic( + title, + markers=markers or ["symbol-right"], + fill=fill or "#EBF5FB", + color=color, + font_size="11pt", + line="#AED6F1", + ) + + +def ok(title: str) -> dict: + return leaf(title, markers=["other-yes", "symbol-right"], fill="#E8F8F5", color=C_PASS) + + +def no(title: str) -> dict: + return leaf(title, markers=["other-no", "symbol-wrong"], fill="#FDEDEC", color=C_FAIL) + + +def warn(title: str) -> dict: + return leaf(title, markers=["symbol-attention"], fill="#FEF9E7", color=C_WARN) + + def build_content() -> list: root = topic( - "交易执行体系\n(手册 v2 + 开单三检)", + "交易执行体系\n手册 v2 · 开单三检", [ - topic( - "设计理念", + t1( + "① 设计理念", [ - topic("少而精,珍惜机会,样本干净"), - topic("不保证收益;过程可控,结果随缘"), - topic("过滤比频率重要;日更不是目标"), - topic("看不懂不做;不为开单找理由"), - topic("丢掉对冲:无「有保护就能多做」幻觉"), - topic( - "工具只留期权与合约", + t2( + "核心主张", [ - topic("OKX 期权:方向单(虚值等)"), - topic("Gate 合约:结构清楚时的波段"), - topic("同一时段尽量只让一边说话"), + leaf("少而精,珍惜机会,样本干净", markers=["star-dark-blue"]), + leaf("不保证收益;过程可控,结果随缘", markers=["symbol-info"]), + leaf("过滤比频率重要;日更不是目标", markers=["symbol-info"]), + leaf("看不懂不做;不为开单找理由", markers=["symbol-attention"]), + warn("丢掉对冲:无「有保护就能多做」幻觉"), ], + markers=["other-lightbulb"], ), - topic( + t2( + "工具边界", + [ + leaf("OKX 期权:方向单(虚值等)", markers=["flag-blue"]), + leaf("Gate 合约:结构清楚时的波段", markers=["flag-dark-blue"]), + leaf("同一时段尽量只让一边说话", markers=["symbol-equality"]), + no("不做期期对冲 / 偏置壳"), + ], + markers=["symbol-pin"], + ), + t2( "文档分工", [ - topic("行为准则:能不能动手(防火墙)"), - topic("执行手册:怎么做单(玩法/仓位/离场)"), + leaf("行为准则:能不能动手(防火墙)", markers=["other-lock"]), + leaf("执行手册:怎么做单(玩法/仓位/离场)", markers=["other-note"]), ], + markers=["other-businesscard"], ), ], + markers=["priority-1", "other-lightbulb"], + label="理念", ), - topic( - "资金要求", + t1( + "② 资金要求", [ - topic("总资金参考:约 800U"), - topic( + t2( + "总盘约 800U", + [ + leaf("单笔约 1.25% 量级", markers=["symbol-info"]), + leaf("全错一天约 2.5% 量级——防守优先", markers=["symbol-attention"]), + ], + markers=["other-businesscard"], + ), + t2( "单笔期权", [ - topic("约 10U 权利金预算"), - topic("一次只持有一个期权仓位"), - topic("按可用打满 = min(余额, 单笔预算)"), + leaf("约 10U 权利金预算", markers=["priority-1"]), + leaf("一次只持有一个期权仓位", markers=["symbol-pin"]), + leaf("打满 = min(余额, 单笔预算)", markers=["symbol-equality"]), ], + markers=["flag-blue"], ), - topic( + t2( "Gate 合约", [ - topic("日内保证金约 50U、约 10 倍"), - topic("止损一般约 5U"), - topic("单笔最大亏损不超过约 10U"), - topic("有单才用保证金,无单为 0"), + leaf("日内保证金约 50U · 约 10 倍", markers=["symbol-info"]), + leaf("止损一般约 5U", markers=["symbol-attention"]), + leaf("单笔最大亏损不超过约 10U", markers=["symbol-no-entry"]), + leaf("有单才用保证金,无单为 0", markers=["task-done"]), ], + markers=["flag-dark-blue"], ), - topic( + t2( "日损失心理框", [ - topic("期权+合约都错:合计大约 ≤20U"), - topic("都对:期望可到 40U+(理想,非每日目标)"), - topic("相对 800U:单笔约 1.25%;全错一天约 2.5%"), - ], - ), - topic( - "叠加红线", - [ - topic("同日双开按合计最坏约 20U 接受"), - topic("尽量少同向双开"), - topic("不为「好像有保护」放大仓位"), + warn("都错:合计大约 ≤20U"), + ok("都对:期望可到 40U+(理想,非每日目标)"), + no("不为「好像有保护」放大仓位"), + warn("尽量少同向双开;双开按合计最坏约 20U"), ], + markers=["symbol-attention"], ), ], + markers=["priority-2", "other-businesscard"], + label="资金", ), - topic( - "操盘思路", + t1( + "③ 操盘思路", [ - topic( - "行为准则(开单三检)", + t2( + "行为准则 · 开单三检", [ topic( - "一句话", + "一句话防火墙", [ - topic("信号够不够清晰?"), - topic("流程有没有跑通?"), - topic("情绪是不是在证明自己?"), - topic("三检不过 → 不开"), + leaf("信号够不够清晰?", markers=["symbol-question"]), + leaf("流程有没有跑通?", markers=["symbol-question"]), + leaf("情绪是不是在证明自己?", markers=["symbol-question"]), + no("三检不过 → 不开"), ], + markers=["other-lock", "priority-1"], + fill="#154360", + color=C_TEXT, + font_size="12pt", + bold=True, + labels=["防火墙"], ), topic( "总循环", [ - topic("信号判断 → 流程确认 → 情绪自检"), - topic("全部通过 → 开仓"), - topic("等待系统结果(止盈/止损/到期)"), - topic("复盘整环 → 等待下一信号"), - topic("任一步否决 → 空仓离开"), + leaf("信号判断 → 流程确认 → 情绪自检", markers=["arrow-right"]), + leaf("全部通过 → 开仓", markers=["other-yes"]), + leaf("等待系统结果(止盈/止损/到期)", markers=["other-clock"]), + leaf("复盘整环 → 等待下一信号", markers=["arrow-refresh"]), + no("任一步否决 → 空仓离开"), ], + markers=["arrow-right"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, ), topic( "开单前三秒停顿", [ - topic("核心信号是什么?"), - topic("安全流程跑通了吗?"), - topic("冷静执行,还是怕踏空/回本/证明自己?"), + leaf("核心信号是什么?", markers=["symbol-pin"]), + leaf("安全流程跑通了吗?", markers=["task-start"]), + leaf("冷静执行,还是怕踏空/回本/证明自己?", markers=["symbol-attention"]), ], + markers=["other-clock"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, ), topic( - "检1·信号判断", + "检1 · 信号判断", [ - topic("通过:一句话说清唯一核心确认"), - topic("通过:点位/结构本身已够清楚"), - topic("否决:说不清、靠宏观故事自圆"), - topic("否决:「好像有戏」但确认模糊"), - topic("对照主链条:1H→空间→结构→定损盈→工具"), + ok("一句话说清唯一核心确认"), + ok("点位/结构本身已够清楚"), + no("说不清、靠宏观故事自圆"), + no("「好像有戏」但确认模糊"), + leaf("对照:1H→空间→结构→定损盈→工具", markers=["arrow-right"]), ], + markers=["priority-1", "symbol-info"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, + labels=["Signal"], ), topic( - "检2·流程确认", + "检2 · 流程确认", [ - topic("通过:资金与当日额度符合"), - topic("通过:单笔/组合敞口在预算内"), - topic("否决:资金或次数已触限"), - topic("否决:单笔或日最坏超限 → 暂停"), - topic("否决:「先开了再说」跳步"), + ok("资金与当日额度符合"), + ok("单笔/组合敞口在预算内"), + no("资金或次数已触限"), + no("单笔或日最坏超限 → 暂停"), + no("「先开了再说」跳步"), ], + markers=["priority-2", "task-start"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, + labels=["Process"], ), topic( - "检3·情绪自检", + "检3 · 情绪自检", [ - topic("通过:符合系统 + 账户没问题 → 开"), - topic("通过:可接受空仓,旁观者视角"), - topic("否决:怕踏空"), - topic("否决:上回亏了要回本"), - topic("否决:必须证明我是对的"), - topic("红灯亮了,信号再好看也不开"), + ok("符合系统 + 账户没问题 → 开"), + ok("可接受空仓,旁观者视角"), + no("怕踏空"), + no("上回亏了要回本"), + no("必须证明我是对的"), + warn("红灯亮了,信号再好看也不开"), ], + markers=["priority-3", "smiley-smile"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, + labels=["Emotion"], ), topic( "复盘只记什么", [ - topic("信号:是否做了?核心写了什么?"), - topic("流程:资金/敞口是否过关?有无跳步?"), - topic("情绪:当时是哪一类心态?"), - topic("结果不推翻「三检是否完成」评分"), + leaf("信号:是否做了?核心写了什么?", markers=["other-note"]), + leaf("流程:资金/敞口是否过关?有无跳步?", markers=["other-note"]), + leaf("情绪:当时是哪一类心态?", markers=["other-note"]), + warn("结果不推翻「三检是否完成」评分"), ], + markers=["other-note"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, ), ], + markers=["other-lock", "flag-purple"], ), - topic( + t2( "开仓逻辑", [ topic( "主链条(强制)", [ - topic("1H 方向:明显 N 字;跟 1H 波段"), - topic("空间:空看支撑、多看阻力;至少约 ≥2%"), - topic("结构:15m/5m;量级约 8h+(约 48×15m)"), - topic("定损盈:外沿/针尖;RR 须接受"), - topic("选工具:期权 或 合约(不对冲)"), - topic("任一步不过 → 空仓等待"), + leaf("1H 方向:明显 N 字;跟 1H 波段", markers=["priority-1"]), + leaf("空间:空看支撑、多看阻力;≥约 2%", markers=["priority-2"]), + leaf("结构:15m/5m;量级约 8h+(约 48×15m)", markers=["priority-3"]), + leaf("定损盈:外沿/针尖;RR 须接受", markers=["priority-4"]), + leaf("选工具:期权 或 合约(不对冲)", markers=["priority-5"]), + no("任一步不过 → 空仓等待"), ], + markers=["arrow-right", "symbol-pin"], + fill="#154360", + color=C_TEXT, + font_size="12pt", + bold=True, + labels=["主链"], ), topic( "结构形态参考", [ - topic("收敛"), - topic("两段式回调"), - topic("箱体"), - topic("假突破"), + leaf("收敛", markers=["flag-blue"]), + leaf("两段式回调", markers=["flag-dark-blue"]), + leaf("箱体", markers=["flag-gray"]), + leaf("假突破", markers=["flag-orange"]), ], + markers=["symbol-image"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, ), topic( "期权入场", [ - topic("主链条全过;结构突破/假突破成立"), - topic("一天期方向单;空间够优先虚值"), - topic("默认先只开期权,不上合约"), - topic("尽量下午 4 点后开次日到期(完整会话)"), - topic("不做:期期对冲、偏置壳、为开而开"), + ok("主链条全过;结构突破/假突破成立"), + leaf("一天期方向单;空间够优先虚值", markers=["star-blue"]), + leaf("默认先只开期权,不上合约", markers=["symbol-pin"]), + leaf("尽量 16:00 后开次日到期", markers=["other-clock"]), + no("不做:期期对冲、偏置壳、为开而开"), ], + markers=["flag-blue", "symbol-plus"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, + labels=["期权"], ), topic( "合约入场(Gate)", [ - topic("主链条过关;位置极明确"), - topic("想清进场:假突破 / 结构突破"), - topic("止损挂模型位(外沿/针尖)"), - topic("独立假突破:只做合约或空仓"), - topic("勿与「突破期权后再加仓」混仓"), + ok("主链条过关;位置极明确"), + leaf("想清进场:假突破 / 结构突破", markers=["symbol-info"]), + leaf("止损挂模型位(外沿/针尖)", markers=["symbol-attention"]), + warn("独立假突破:只做合约或空仓"), + no("勿与「突破期权后再加仓」混仓"), ], + markers=["flag-dark-blue", "symbol-plus"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, + labels=["合约"], ), ], + markers=["symbol-plus", "arrow-up-right"], ), - topic( + t2( "平仓逻辑", [ topic( "期权离场", [ - topic("只认:系统/规则止盈"), - topic("只认:到期"), - topic("开仓后中间不手动平仓"), - topic("紧急手平 → 标记非策略样本"), + ok("只认:系统/规则止盈"), + ok("只认:到期"), + no("开仓后中间不手动平仓"), + warn("紧急手平 → 标记非策略样本"), ], + markers=["flag-green", "symbol-minus"], + fill="#145A32", + color=C_TEXT, + font_size="12pt", + bold=True, + labels=["期权"], ), topic( "合约离场", [ - topic("结构止盈为准"), - topic("结构止损为准(约 5U 量级)"), - topic("等待系统/挂单结果,不情绪手平"), + ok("结构止盈为准"), + ok("结构止损为准(约 5U 量级)"), + leaf("等待系统/挂单结果,不情绪手平", markers=["other-clock"]), ], + markers=["flag-dark-green", "symbol-minus"], + fill="#145A32", + color=C_TEXT, + font_size="12pt", + bold=True, + labels=["合约"], ), topic( - "开仓后盯什么", + "持仓期盯什么", [ - topic("程序与纪律是否正常"), - topic("不是浮盈浮亏数字本身"), - topic("无信号空档:空跑三检也是训练"), + leaf("程序与纪律是否正常", markers=["task-done"]), + no("不是浮盈浮亏数字本身"), + leaf("无信号空档:空跑三检也是训练", markers=["other-lightbulb"]), ], + markers=["symbol-info"], + fill="#1A5276", + color=C_TEXT, + font_size="12pt", + bold=True, ), ], + markers=["symbol-minus", "flag-green"], ), ], + markers=["priority-3", "arrow-right"], + label="操盘", ), - topic( - "纪律执行", + t1( + "④ 纪律执行", [ - topic( + t2( "Gate 日纪律", [ - topic("只做很明确的位置"), - topic("同一位置最多两次机会(突破/假突破)"), - topic("两次都错 → 当日不再做单"), - topic("离场以结构止盈/止损为准"), + leaf("只做很明确的位置", markers=["symbol-pin"]), + leaf("同一位置最多两次机会(突破/假突破)", markers=["priority-2"]), + no("两次都错 → 当日不再做单"), + ok("离场以结构止盈/止损为准"), ], + markers=["flag-dark-blue", "task-done"], ), - topic( + t2( "期权日纪律", [ - topic("不手平;等规则止盈或到期"), - topic("一次一仓;约 10U 权利金"), - topic("不对冲;不做每天默认开期权"), - topic("损位跟模型:外沿/针尖"), + no("不手平;等规则止盈或到期"), + leaf("一次一仓;约 10U 权利金", markers=["symbol-pin"]), + no("不对冲;不做每天默认开期权"), + leaf("损位跟模型:外沿/针尖", markers=["symbol-attention"]), ], + markers=["flag-blue", "task-done"], ), - topic( + t2( "开仓前自检清单", [ - topic("今日只动期权/合约?未开对冲?"), - topic("1H 方向清楚(含 N 字)?"), - topic("空间足够?"), - topic("结构出现且量级够?"), - topic("止损/止盈与 RR 定好?"), - topic("工具选期权还是合约?理由写清?"), - topic("期权:止盈与接受到期写清?"), - topic("合约:本位置第几次?今日两次用完?"), + leaf("今日只动期权/合约?未开对冲?", markers=["task-start"]), + leaf("1H 方向清楚(含 N 字)?", markers=["task-start"]), + leaf("空间足够?结构量级够?", markers=["task-start"]), + leaf("止损/止盈与 RR 定好?", markers=["task-start"]), + leaf("工具选期权还是合约?理由写清?", markers=["task-start"]), + leaf("合约:本位置第几次?今日两次用完?", markers=["task-start"]), ], + markers=["other-yes", "task-start"], ), - topic( + t2( "一句话版本", [ - topic("1H→空间→结构→定损盈→期权/合约"), - topic("不对冲;期权不手平"), - topic("一位置两次,错完收工"), - topic("珍惜机会,日更不是目标"), + leaf("1H→空间→结构→定损盈→期权/合约", markers=["arrow-right"]), + leaf("不对冲;期权不手平", markers=["symbol-no-entry"]), + leaf("一位置两次,错完收工", markers=["priority-2"]), + leaf("珍惜机会,日更不是目标", markers=["star-dark-blue"]), ], + markers=["star-dark-blue", "symbol-right"], ), ], + markers=["priority-4", "task-done"], + label="纪律", ), ], + markers=["other-people", "star-dark-blue"], + labels=["商务版"], + fill=C_ROOT, + color=C_TEXT, + font_size="20pt", + bold=True, + line=C_ROOT, + notes="个人交易执行体系 · 向右逻辑图 · 商务标识版\n来源:交易执行手册 v2 + 交易行为准则-开单三检", ) root["structureClass"] = "org.xmind.ui.logic.right" + # XMind Zen 内置主题名;客户端可识别 business sheet = { "id": tid(), "class": "sheet", - "title": "执行手册与行为准则", + "title": "执行手册与行为准则 · 商务版", "rootTopic": root, + "theme": { + "id": tid(), + "title": "business", + "centralTopic": { + "id": "centralTopic", + "properties": { + "svg:fill": C_ROOT, + "fo:color": C_TEXT, + "fo:font-family": "Microsoft YaHei", + "fo:font-size": "20pt", + "fo:font-weight": "bold", + "shape-class": "org.xmind.topicShape.roundedRect", + "line-color": C_L1, + "line-width": "2pt", + "line-class": "org.xmind.branchConnection.roundedelbow", + }, + }, + "mainTopic": { + "id": "mainTopic", + "properties": { + "svg:fill": C_L1, + "fo:color": C_TEXT, + "fo:font-family": "Microsoft YaHei", + "fo:font-size": "15pt", + "fo:font-weight": "bold", + "shape-class": "org.xmind.topicShape.roundedRect", + "line-color": C_L2, + "line-width": "1.5pt", + }, + }, + "subTopic": { + "id": "subTopic", + "properties": { + "svg:fill": C_L2, + "fo:color": C_TEXT, + "fo:font-family": "Microsoft YaHei", + "fo:font-size": "12pt", + "shape-class": "org.xmind.topicShape.roundedRect", + "line-color": "#85C1E9", + }, + }, + "floatingTopic": { + "id": "floatingTopic", + "properties": { + "svg:fill": C_MUTED, + "fo:color": C_TEXT, + "fo:font-family": "Microsoft YaHei", + }, + }, + "importantTopic": { + "id": "importantTopic", + "properties": { + "svg:fill": C_WARN, + "fo:color": C_TEXT, + }, + }, + "minorTopic": { + "id": "minorTopic", + "properties": { + "svg:fill": "#EBF5FB", + "fo:color": C_TEXT_DARK, + }, + }, + "expiredTopic": { + "id": "expiredTopic", + "properties": { + "svg:fill": "#D5D8DC", + "fo:color": C_MUTED, + }, + }, + "calloutTopic": { + "id": "calloutTopic", + "properties": { + "svg:fill": "#FEF9E7", + "fo:color": C_WARN, + }, + }, + "summaryTopic": { + "id": "summaryTopic", + "properties": { + "svg:fill": "#145A32", + "fo:color": C_TEXT, + }, + }, + "boundary": { + "id": "boundary", + "properties": { + "svg:fill": "#D6EAF8", + "fo:color": C_L1, + "line-color": C_L2, + }, + }, + "summary": { + "id": "summary", + "properties": { + "line-color": C_L1, + "line-width": "2pt", + }, + }, + "relationship": { + "id": "relationship", + "properties": { + "line-color": C_MUTED, + "line-pattern": "dash", + }, + }, + "map": { + "id": "map", + "properties": { + "svg:fill": "#F4F6F7", + "color-list": f"{C_L1} {C_L2} #2874A6 #1ABC9C #B9770E", + "line-tapered": "none", + }, + }, + }, } return [sheet] @@ -308,7 +650,7 @@ def build_content() -> list: def main() -> None: content = build_content() metadata = { - "creator": {"name": "crypto_monitor", "version": "1.0"}, + "creator": {"name": "crypto_monitor", "version": "1.1"}, "activeSheetId": content[0]["id"], } manifest = {