使用电子表格建立交易策略·进阶篇
(2/3)· 跳过繁琐手动计算,用表格公式把历史行情变成可验证的策略沙盘
「MT5表格里批量灌公式的两种实操」
在 MT5 自带的表格工具里填公式,小范围直接拖右下角那个小方块就行:光标变成细十字后往下拉,图2那种玩法只适合几十行。真要处理上千行报价或指标缓存,手动拖拽会累到怀疑人生。 第一种办法是先框死范围。顶部单元格写公式回车,然后用名称框跳到该列最底行,按 Ctrl+Shift+↑ 选回整段,再 Ctrl+D 向下填充。缺点很实在——你得提前知道最底行是几行,不然跳不准。 第二种借相邻列当跳板更顺手。写好公式的单元格按 Shift+← 选中左边一格,Tab 把光标挪回公式格,Ctrl+Shift+↓ 直接吞掉两列连续区的最底行,Shift+→ 丢掉左列只留公式列,Ctrl+D 完成填充。 复制带链接的公式时,默认是相对引用,光标挪到哪链接就跟着改。要锁死不动,选中链接按 F4,行号列名前冒出 $ 就焊死了。只锁行或只锁列,就多按一两下 F4 让 $ 只挂在一边。外汇和贵金属行情跳空多,这类表格计算仅作本地验证,实盘高风险。
◍ 用均线穿越做进出场
MT5 自带的 Examples\Moving Average EA 里就有一套可直接验证的均线穿越逻辑,核心只看价格与一条移动平均线的相对位置。 开仓条件很直白:当前无持仓,且某根 K 线的实体整体穿越了 MA——也就是这根 K 线在 MA 的一侧开盘、另一侧收盘。 平仓则反过来:已有未平仓位,且后续 K 线实体向与开仓相反的方向穿越同一条 MA。这套规则不预测幅度,只在趋势反向穿越时退出,外汇与贵金属杠杆高,实盘前务必先在策略测试器跑历史数据确认信号频率。
在表格里拼出可自定义的均线指标
把 6038 行原始报价导进电子表格后,先留一行空白把表头区和数据区隔开,这样两个区块能被程序当成独立表,顶部合并单元格、底部挂过滤器互不打架。删掉这行空白,后续筛选和引用大概率会串味。 先在另一张表里建变量页,给 MovingPeriod、MovingShift 这类参数写清楚名字,公式里直接调名称,比满屏 $B$4 好读也好改。回到数据表,G 列写引号索引,公式就是行号减 3,拖到全列,MA 计算就能保持通用。 H4 里塞的是带条件判断的 SMA 公式:用 IF 看 G4 是否大于 MovingPeriod+MovingShift,不够数就留空串,够数才用 AVERAGE 套 INDIRECT 算区间均值。INDIRECT 吃文本拼出来的地址,& 把列名、行号、冒号拼成 "E"&(ROW()-MovingShift-MovingPeriod)&":"&"E"&(ROW()-MovingShift),收盘价列 E 的滑动窗口就这么动态圈出来了。 公式向下拖完,H 列数字从第 22 行(第 19 个数据项)才开始冒头,因为前面行数不够一个完整 MA 周期。到此原始价和指标值同表共存,策略逻辑可以往上叠了。 别把正态当圣经 INDIRECT 拼地址虽灵活,但MovingPeriod设太大而数据只有几千行时,H列前半段全空,回测起点会被悄悄截掉,外汇与贵金属波动剧烈,这种截断会直接改掉样本分布。
=ROW()-class="num">3 =IF(G4>(MovingPeriod+MovingShift), AVERAGE( INDIRECT( "E" & (ROW()-MovingShift-MovingPeriod) & ":" & "E" & (ROW()-MovingShift) ) ), "" )
「用表格公式把均线交叉转成可跟踪的交易状态」
先把信号做成最朴素的形态:MA 向下交叉给单元赋 -1,向上交叉给 1,无交叉留空串。I4 的基础公式只判断交叉方向,属于反转逻辑,能直接在图表上看出交叉点,但缺点是无法记录持仓状态,不适合直接拿去回测整段策略。 要让每一行都记住当前是持仓还是空仓,J 列更合适。J4 的逻辑是:若发生反向交叉且上一行无持仓,则开仓;若已有持仓且出现反向交叉,则平仓;其余情况沿用上一行状态。这样逐行滚下去,就得到一条连续的状态链。 为了肉眼核对买卖点,再开 K 列写交易名称。注意信号在下一根 K 线开盘才触发,所以公式里索引要偏移一行(如用 J3 而非 J4 去对照 J2)。DealTypes 是用名称框圈选整块范围定义的辅助表,INDEX 第一个参数是范围名,第二个是行号,多列时还要补列号。 把三套公式向下拖满,再上条件格式,就能看到类似「交易信号」标注的整表。外汇和贵金属波动剧烈,这类表格策略仅用于历史区间验证,实盘触发概率和滑点影响需自行在 MT5 导出数据复算。
=<b><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);">IF</span></b>( <span style="background-class="type">class="kw">color:rgb(class="num">232, class="num">183, class="num">215);"><b><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);">AND</span></b>( <b>B4</b>><b>H4</b>,<b>E4</b><<b>H4</b> )</span>,<span style="background-class="type">class="kw">color:rgb(class="num">164, class="num">192, class="num">228);">-class="num">1 </span>, <span style="background-class="type">class="kw">color:rgb(class="num">177, class="num">210, class="num">143);"><b><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);">IF</span></b>( <span style="background-class="type">class="kw">color:rgb(class="num">232, class="num">183, class="num">215);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>AND</b></span>( <b>B4</b><<b>H4</b>,<b>E4</b>><b>H4</b> )</span>,<span style="background-class="type">class="kw">color:rgb(class="num">164, class="num">192, class="num">228);"> class="num">1 </span>, <span class="class="type">class="kw">string">""</span>)</span> ) =<span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>IF</b></span>(<span style="background-class="type">class="kw">color:rgb(class="num">232, class="num">183, class="num">215);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>AND</b></span>(<b>I4</b>=<span class="number">-class="num">1</span>,<b>J3</b>=<span class="class="type">class="kw">string">""</span>)</span>,<span style="background-class="type">class="kw">color:rgb(class="num">164, class="num">192, class="num">228);"> <span class="number">-class="num">1 </span></span>,<span style="background-class="type">class="kw">color:rgb(class="num">177, class="num">210, class="num">143);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>IF</b></span>(<span style="background-class="type">class="kw">color:rgb(class="num">232, class="num">183, class="num">215);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>AND</b></span>(<b>I4</b>=<span class="number">class="num">1</span>,<b>J3</b>=<span class="class="type">class="kw">string">""</span>)</span>,<span class="number" style="background-class="type">class="kw">color:rgb(class="num">164, class="num">192, class="num">228);"> class="num">1 </span>,<span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>IF</b></span>(<span style="background-class="type">class="kw">color:rgb(class="num">232, class="num">183, class="num">215);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>OR</b></span>(<span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>AND</b></span>(<b>I4</b>=<span class="class="type">class="kw">string">""</span>,<b>J3</b>=<span class="number">class="num">1</span>),<span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>AND</b></span>(<b>I4</b>=<span class="class="type">class="kw">string">""</span>,<b>J3</b>=-<span class="number">class="num">1</span>),<b>I4</b>=<b>J3</b>)</span>,<span style="background-class="type">class="kw">color:rgb(class="num">164, class="num">192, class="num">228);"><b> J3 </b></span>,<span class="class="type">class="kw">string">""</span>))</span>) =<span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>IF</b></span>(<span style="background-class="type">class="kw">color:rgb(class="num">232, class="num">183, class="num">215);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>AND</b></span>(<b>J3</b>=<span class="number">class="num">1</span>,<b>J2</b>=<span class="class="type">class="kw">string">""</span>)</span>,<span style="background-class="type">class="kw">color:rgb(class="num">164, class="num">192, class="num">228);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>INDEX</b></span>(DealTypes,<span class="number">class="num">1</span>)</span>,<span style="background-class="type">class="kw">color:rgb(class="num">177, class="num">210, class="num">143);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>IF</b></span>(<span style="background-class="type">class="kw">color:rgb(class="num">232, class="num">183, class="num">215);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>AND</b></span>(<b>J3</b>=-<span class="number">class="num">1</span>,<b>J2</b>=<span class="class="type">class="kw">string">""</span>)</span>,<span style="background-class="type">class="kw">color:rgb(class="num">164, class="num">192, class="num">228);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>INDEX</b></span>(DealTypes,<span class="number">class="num">2</span>)</span>,<span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>IF</b></span>(<span style="background-class="type">class="kw">color:rgb(class="num">232, class="num">183, class="num">215);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>OR</b></span>(<span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>AND</b></span>(<b>J3</b>=<span class="class="type">class="kw">string">""</span>,<b>J2</b>=<span class="number">class="num">1</span>),<span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>AND</b></span>(<b>J3</b>=<span class="class="type">class="kw">string">""</span>,<b>J2</b>=-<span class="number">class="num">1</span>))</span>,<span style="background-class="type">class="kw">color:rgb(class="num">164, class="num">192, class="num">228);"><span style="class="type">class="kw">color:rgb(class="num">44, class="num">114, class="num">199);"><b>INDEX</b></span>(DealTypes,<span class="number">class="num">3</span>)</span>,<span class="class="type">class="kw">string">""</span>))</span>)
◍ 用电子表给策略盈利画概率分布
要把一个裸策略的盈利能力看清楚,先得算每笔交易平仓前价格实际走过的距离。做法是在 L 列填交易起始价:信号列 K 写 Buy 时取烛形开盘价加点差,写 Sell 只取开盘价,写 Close 或前格无数字就留空,否则沿用上一格。下面这段是 L4 的判定逻辑。 [CODE] =IF(K4=INDEX(DealTypes;1);B4+Spread;IF(K4=INDEX(DealTypes;2); B4 ;IF(OR(K4=INDEX(DealTypes;3);N(L3)=0); "" ;L3))) [/CODE] 逐行拆解:先比 K4 是否等于 DealTypes 第1项(买),是就 B4+Spread;否则比是否第2项(卖),是就 B4;再否则若 K4 是第3项(平)或 L3 非数字,输出空串,都不是就复制 L3。 N 列放每笔的价差点数,公式按买卖方向用 ROUND((B4-L3)/Point) 或反向。M 列给 N 里的唯一条目编号:用 COUNTIF(N$3:N4;N4)=1 判断首次出现,是就 MAX(M3:M$4)+1。 [CODE] =IF(K4=INDEX(DealTypes;3);IF(I3=-1;ROUND((B4-L3)/Point);ROUND((L3-B4)/Point)); "" ) =IF(N4<>"";IF(COUNTIF(N$3:N4;N4)=1;MAX(M3:M$4)+1;"");"") [/CODE] 第一句只在平仓信号时算点数差;第二句对右边 N4 非空且全区间首次见的数字编序号,之前最大号加1,重复则留空。 把 M 列非空对应的 N 值迁到新表,用 Vlookup 按行号抓唯一值,再 COUNTIF 算每个利润值的频率。文中样例区间公式初算太大,除以4后得 344 点一组,分布图显示峰值在 -942 与 2154,还有一笔 8944 点的极端盈利。 用 Sumproduct 把频率乘损益求和得期望收益,结果接近 0 且低于累计利润。该策略在强趋势中可能抓到巨幅单笔,但横盘期回撤可能极大,外汇与贵金属属高风险品种,实盘前需加趋势过滤或约 420–500 点获利单。
=IF(K4=INDEX(DealTypes;class="num">1);B4+Spread;IF(K4=INDEX(DealTypes;class="num">2); B4 ;IF(OR(K4=INDEX(DealTypes;class="num">3);N(L3)=class="num">0); "" ;L3))) =IF(K4=INDEX(DealTypes;class="num">3);IF(I3=-class="num">1;ROUND((B4-L3)/Point);ROUND((L3-B4)/Point)); "" ) =IF(N4<>"";IF(COUNTIF(N$class="num">3:N4;N4)=class="num">1;MAX(M3:M$class="num">4)+class="num">1;"");"")