仓位风险计算器
这个技能做什么,不做什么(先读这段)
做:在你已经决定了「买/卖、在哪进、在哪认错」之后,帮你把「能开多大」算清楚。
不做:
- ❌ 不判断方向、不预测行情、不推荐买什么
- ❌ 不给目标价、不给进出场建议
- ❌ 不联网取行情(数字由用户自己给)
边界为什么划这么死:手数算错 = 真金白银的敞口失控,而这类算术 LLM 极易出错。
所以所有风险数字必须由 scripts/position_calc.py 计算——你可以写"为什么",但一个数字都不许自己心算或编造。
> 反过来说:也正因为不算命,这个技能零合规风险、零网络依赖,A股 / 期货 / 外汇 / Crypto 通用。
核心公式(理解它,才不会用错)
每手风险 = |进场价 − 止损价| × 合约乘数 × 汇率
手数 = 风险预算 ÷ 每手风险 (向下取整)
实际风险 = 手数 × 每手风险
名义敞口 = 手数 × 合约乘数 × 现价 × 汇率
盈亏比 = |目标价 − 进场价| ÷ |进场价 − 止损价|
关键洞察:止损越窄,手数越大,但风险不变。
很多人以为"止损放紧一点更安全"——错了,那只会让你开更重的仓位,名义杠杆反而更高。
本技能会同时盯住风险和杠杆两个维度。
风险预算硬规则
| 层级 | 上限 | 超限处理 |
|---|---|---|
| 单笔 | ≤ 1.0% 账户 | 砍手数 |
| 组合(多单同时持有) | ≤ 1.5% | 砍到 1.5% 以内 |
| 情景树(互斥分支合计) | > 2.0% 必须砍 | 删分支或减手数 |
| 名义杠杆 | ≤ 3.0x | 优先砍"名义大、风险贡献小"的单子 |
| 盈亏比 | ≥ 2.0R | 不足则不下单(或标注"低盈亏比,小仓试探") |
详细理由与常见错误见 references/仓位规则与常见错误.md。
用法
① 单笔:算手数
import sys; sys.path.insert(0, "scripts")
from position_calc import Instrument, build_plan, plan_to_md
plan = build_plan(
Instrument.A_SHARE, # 标的
account=100_000, # 账户总资金
risk_pct=0.01, # 单笔风险 1%
direction="long", # long / short
entry=10.0, stop=9.5, # 进场 / 止损(这两个必须由用户给)
targets=[11.0, 12.0], # 目标位(可多个)
label="某某股份",
)
print(plan_to_md(plan))
② 标的怎么选
| 场景 | 写法 |
|---|---|
| 期货/贵金属 | Instrument.GC MGC SI SIL AU AG |
| A股 | Instrument.A_SHARE(100 股/手) |
| 美股 | Instrument.US_STOCK(1 股/手) |
| 外汇 | Instrument.FX_STD / FX_MINI / FX_MICRO |
| 任意标的(Crypto、港股、 uncommon 合约) | Instrument.custom(name, mult, unit, tick) |
custom 的 mult = 每手代表多少标的量:
# Binance BTCUSDT U本位:1 张 = 0.01 BTC
btc = Instrument.custom("BTC 永续", mult=0.01, unit="BTC", tick=0.1)
# 港股腾讯:1 手 = 100 股
hk = Instrument.custom("腾讯控股", mult=100, unit="股", tick=0.2)
# 外汇非美账户(账户是人民币,EURUSD 报价美元)
build_plan(Instrument.FX_MINI, account=500_000, risk_pct=0.01,
direction="long", entry=1.1000, stop=1.0950,
targets=[1.1100], ccy_rate=7.1) # ← 折算回账户货币
③ 组合体检(最有价值的一步)
from position_calc import build_plan, portfolio_check, check_to_md
plans = [plan_a, plan_b, plan_c]
chk = portfolio_check(plans, account=1_000_000, mode="tree") # 情景树用 tree
print(check_to_md(chk))
不只告诉你"超了",还告诉你砍哪一笔、砍到几手:
❌ 风险体检:FAIL(情景树,3 笔)
| 合计风险 | 29,810.00(2.98%) | 20,000.00(2.00%) |
**怎么改(具体到大盘)**
- 需削减风险 9810(当前合计 29810,上限 20000):
- · 删除「C 情景」(37 手,省 9990)
④ 交易计划书骨架
from position_calc import skeleton_md
md = skeleton_md(plan=plan, tree=tree, check=chk, date_str="2026-09-10")
输出 T0–T10 骨架:T0 指令卡、T9 数字速查、体检结果自动填好,其余给写作提示。
各块怎么填见 references/T0-T10填写指南.md。
铁律
- 所有手数、风险、盈亏、杠杆、R 倍数必须调用脚本算,禁止心算、禁止口算、禁止"大约是"
- 取不到输入就问用户,不要替他假设进场价/止损价——这两个数字是责任分界线
- 方向校验由脚本做(多单止损必须在下方、空单止损必须在上方),别自己判断
- 体检 FAIL 时必须给出具体砍法,不能只说"风险超了"
- 输出必须带免责:纸上计划,非投资建议
- 本技能不得联网取行情——它的价值恰恰在于不依赖任何数据源
常见问答
Q:用户只给了"我想买某某股票",没给止损怎么办?
A:反问止损位,或用 suggest_stop(last, atr_val, direction, k) 给一个波动自适应的建议位,
但必须说明"这是按 ATR 倍数给的参考,不是预测,最终止损位你自己定"。绝不替用户决定方向。
Q:算出来是 0 手?
A:脚本会返回 zero_lot=True + 提示。原因通常是:账户太小、止损太宽、合约太大。
解法提示:换更小合约(GC→MGC)、放宽风险比例、或缩小止损距离。
Q:用户想算"最多能亏多少"?
A:那不是本技能的场景。本技能是先定风险再倒推仓位,不是先定仓位再算亏损。