单一资产交易顺序中的风险评估. 续篇(基础篇)
📘

单一资产交易顺序中的风险评估. 续篇(基础篇)

第 1/3 篇

从单资产顺序交易切入风险评估

这篇接着前一篇没讲完的风险评估思路,把重心放在单一资产按固定顺序开平仓时的暴露测算上,并用两个具体例子把推导收口。外汇与贵金属杠杆高、跳空频繁,这类顺序化风险模型只能给出概率层面的参考,不能当作确定性结论。 原文先列了收益分布、固定止损/获利、固定跟踪止损几个前置假定,说明后续例子都建立在同样的统计底座上。对 MT5 用户来说,这意味着你回测时若改了止损逻辑,下面那套推导就得重算,不能直接套用。 除收口例子外,作者还顺带点出概率论在统计跳空、机器学习特征构造、系统参数优化上的其他落点。想验证的话,开 MT5 用策略测试器跑一遍固定跟踪止损的 equity 曲线,对照本文的分布假设即可。

「把价格和系统先降维成随机游走」

上一篇文章的方法并不能直接套到任意交易系统上。前提是它的交易序列必须是独立且同分布的(i.i.d.),但实战里这个条件经常被打破——要么交易之间互相依赖,要么每笔的分布都不一样。 Ralph Vince 在《资金管理的数学》里给过一种拆法:把系统切成满足 i.i.d. 的子系统。比如把奇数、偶数笔交易当成两个不同系统;金字塔加仓则把每一步加仓视作独立系统。但切完还得用类似马科维茨组合理论把“片段”拼成微型投资组合,复杂度直接起飞。

更麻烦的是固定止盈止损比的系统。设 k=p_takeprofit-p_enter/p_stoploss-p_enter,若每笔 k 都不同,单笔收益只在 -1 和 k 两个值间跳,但每笔分布都不同,切出来的“片段”数等于交易数,毫无意义。实务上常取一个平均 k 做简化版系统来分析。

真要做风险分析,可以三条路并行:拆系统、研究简化版、不验 i.i.d. 直接用其他手段微调风险值。但这套不通用。更系统的做法是先对价格和系统做假定。 假定价格序列近似随机波动:真实价格做某种计算后能当随机游走用,结果等价。系统吃随机波动报价时,“平均来看”随机价要贴近真价——高周期动荡类似、分时波动分布类似。两种情况下交易间的依赖结构类似,但收益分布可能差很多;比如所有收益同额平移,分布右移但相关系数不变。 系统自身假定为:交易基本随机分布,仅当第二笔紧接第一笔平仓后开启时才出现强内部依赖。随机游走分离散/连续两类,计算机建模只用离散;可对称(无趋势)或有偏移(有趋势),最常讨论对称情形。 对称随机游走下两个推论很关键:一是交易结果无法用任何指标预测,建模只需研究出场部分,入场在哪、怎么开都无所谓;二是长期期望利润为 0,单笔可赚任何数,但交易多了结果聚集服从某概率分布,期望恒为零。 外汇与贵金属属高风险市场,这些假定只是建模起点,实盘前必须用真价回测验证偏离对称游走的显著性。系统限制也随之而来:入场出场规则要简单、统一、透明,不能让交易间额外耦合(如引用余额曲线)、不能随机改止盈止损比、交易不能过频。理论上可检查,也可直接用蒙特卡洛在计算机上跑出来看近似程度。

◍ 混合分布下的退出机制与风险反算

收益分布并不只有离散和连续两种教科书形态。实际平仓逻辑里,固定止损/止盈给出的是离散台阶,而按持仓时间 t 强平则落在连续区间,两者加权叠加就构成混合分布:P(x)=γc·Pc(x)+γd·Pd(x),其中 γc、γd 非负且和为 1。 若把时间退出阈值设得足够大,γc 可近似忽略,分布退化成纯离散 Pd(x);而启用固定跟踪止损时 γd=0,属纯连续情形。更现实的是 γd 与 γc 均非零——比如前 N 根 K 线锁死初始止损、满足条件后才转为移动止损,这段静默期就是离散成分。 下面给出的脚本面向单一种类分布算最优风险值 ropt。但实战常反过来:已知风险额度,要反推可靠性 δ 或最大平均收益 G0。这时不必改架构,换输入重跑或微调脚本即可,外汇/贵金属杠杆放大下这类反算误差会直接放大爆仓概率,建议先在 MT5 策略测试器跑通再上实盘。

用离散收益模型给系统判生死

把每笔交易收益压成两个离散值:亏固定 1 单位,赚 k 单位,概率分别是 1-θ 和 θ。期望值 M=(1+k)θ-1,对称随机游走时 M=0 对应 θ0=1/(1+k)。样本里若估算期望 Mapr≤0,这系统直接否掉——任何风控都救不回负期望的盘子,外汇贵金属这种高杠杆品种尤其别幻想补窟窿。 真要留系统,先证它不在随机游走里混。用 S=nk(获利笔数)当检验量,原假设 M=0 下服从 B(n,θ0)。累积概率 P(S) 得超过 P(nθ0)+δ/2,δ 取 0.05 时就是右尾显著,过不了这关也砍。 过了显著性,还要看最小平均收益 G0 够不够。把 S 按实际 θapr 重新套二项规则,G0 必须压过 δ 分位数;不够就逐步加样本量 n 直到满足,算出 nmin。默认脚本里 G0=0.15、kt=3、pk=0.5、na=50,跑出来 ropt=0.011,即单笔冒 1.1% 本金的系统最优风险参考值,MT5 里改 input 就能复算。 蒙特卡洛那段才是落地重点:模拟万组各 n 笔的收益序列,每组按第一部分算法提取 ropt,i,堆出经验分布再取 δ 分位数当实盘风险上限。代码里 NB=10000 控制模拟组数,NR=1000 管风险轴分区,调大 NB 可能让尾部估计更稳但更慢。

MQL5 / C++
class="macro">#include <Math\Stat\Binomial.mqh>
class="macro">#class="kw">property script_show_inputs
class="kw">input class="type">uint na=class="num">50;        class=class="str">"cmt">// 序列中的交易数量
class="kw">input class="type">class="kw">double kt=class="num">3;       class=class="str">"cmt">// 获利对止损的比例
class="kw">input class="type">class="kw">double pk=class="num">0.5;     class=class="str">"cmt">// 获利的概率
class="macro">#define NX class="num">300           class=class="str">"cmt">// 序列中的最大交易数量 (用于搜索 nmin)
class="macro">#define NB class="num">10000         class=class="str">"cmt">//为蒙特卡洛方法生成的样本数量
class="macro">#define NR class="num">1000          class=class="str">"cmt">// 风险的间隔分区数
class="type">class="kw">double G0=class="num">0.15;          class=class="str">"cmt">// 最低平均收益
class="type">class="kw">double D0=class="num">0.9;           class=class="str">"cmt">// 最低最小增益
class="type">class="kw">double dlt=class="num">0.05;         class=class="str">"cmt">// 显著性水平
class="type">void OnStart()
  {
   if (D0<=class="num">0||D0>=class="num">1) {Print("D0 必须是正的并且小于1"); class="kw">return;}
   class="type">class="kw">double m=(class="num">1+kt)*pk-class="num">1;             class=class="str">"cmt">// 期望值
   if(m<=class="num">0) {Print("期望值必须为正"); class="kw">return;}
   class="type">class="kw">double s=na*pk;                   class=class="str">"cmt">// 统计 (获利交易平均数量)
   class="type">class="kw">double s0=na/(class="num">1+kt);              class=class="str">"cmt">// 在0期望值时的获利交易平均数量
   class="type">int ner;
   class="type">class="kw">double p=MathCumulativeDistributionBinomial(s,na,class="num">1/(class="num">1+kt),ner);
   if(!MathIsValidNumber(p)) {Print("MathIsValidNumber(p) 错误 ",ner); class="kw">return;}
   class="type">class="kw">double p0=MathCumulativeDistributionBinomial(s0,na,class="num">1/(class="num">1+kt),ner);
   if(!MathIsValidNumber(p0)) {Print("MathIsValidNumber(p0) 错误 ",ner); class="kw">return;}
   if(p<=p0+dlt/class="num">2) {Print("期望值近似于0"); class="kw">return;}
   class="type">class="kw">double q=MathQuantileBinomial(dlt,na,pk,ner),q0=na*(G0+class="num">1)/(kt+class="num">1);
   if(!MathIsValidNumber(q)) {Print("MathIsValidNumber(q) 错误 ",ner); class="kw">return;}
   if(q0>q)
     {
      Print("G0 大于收益算数平均值的分值 dlt ");
      class="type">uint nmin=na+class="num">1;
      for(;nmin<=NX;++nmin)
        {
         q=MathQuantileBinomial(dlt,nmin,pk,ner); q0=nmin*(G0+class="num">1)/(kt+class="num">1);
         if(!MathIsValidNumber(q)) {Print("MathIsValidNumber(q) 错误 ",ner); class="kw">return;}
         if(q0<=q) class="kw">break;

常见问题

先把价格序列降维成随机游走看步长分布,若连续亏损已超出混合分布下的正常回撤带,就别加仓摊平,优先按退出机制止损。
用离散收益模型把每笔盈亏转成步长,统计均值和方差,再套混合分布反推最大可接受连亏次数,超出就降仓或停手。
小布可自动跑离散收益模型并标出混合分布下的异常连亏,提醒你当前顺序交易是否已触风险线,省去手动回算。
用历史步长拟合混合分布,按目标破产概率反算单笔风险上限,退出位直接取该上限对应的权益回撤阈值。
用离散收益模型算序列的p值,若低于混合分布假定下的显著性水平,系统可能已失效,该停训重测而非硬扛。