在 MQL4 和 MQL5 框架下开发 OpenAI 的 ChatGPT 功能·综合运用
◍ 布林带与相对ATR的底层算路
这段实现里,布林带中轨先用一段收盘价的简单求和取平均(prevBB),等价于把首值当成普通 SMA 处理;随后对同样区间跑第二遍循环,逐根把 (收盘价 - prevBB) 的平方累加到 sumSquares,最后 standardDeviation = sqrt(sumSquares / PeriodBB)。上下轨则挂在 prevEMA 上:upperBand = prevEMA + DeviationBB * standardDeviation,lowerBand = prevEMA - DeviationBB * standardDeviation。 相对 ATR 的写法值得留意:它在 True Range 求和之外,额外累加每根 K 线的开高低收四价之和 sumPrice,再用 100.0 * (sumTrueRange / PeriodATR) / (sumPrice / (PeriodATR * 4.0)) 得到百分比形式的波动率。相比传统 ATR 绝对值,这种相对值在高价贵金属与低价交叉盘之间更有可比性,但外汇和贵金属杠杆高,波动率突变时信号可能快速失效。 下面两段是核心片段,可直接贴进 MT5 自定义指标或 EA 里验证:第一块算布林带,第二块算相对 ATR。开 MT5 把 PeriodBB、DeviationBB、PeriodATR 调成你常用的参数,看上下轨与百分比 ATR 是否符合盘感。
class="type">class="kw">double sumSquares = class="num">0.0; class=class="str">"cmt">// Calculate the initial value for BB(the first value is considered as a normal SMA) for (class="type">int i = StartIndex; i >= barIndex; i--) { class="type">class="kw">double closePrice = Charts[chartindex].CloseI[i]; sum += closePrice; } prevBB = sum / PeriodBB; class=class="str">"cmt">//this is the starting value for the bar(StartIndex-class="num">1) class=class="str">"cmt">// Calculation of standard deviation for (class="type">int i = StartIndex; i >= barIndex; i--) { class="type">class="kw">double closePrice = Charts[chartindex].CloseI[i]; sumSquares += pow(closePrice - prevBB, class="num">2); } class="type">class="kw">double standardDeviation = sqrt(sumSquares / PeriodBB); class=class="str">"cmt">// Calculate Bollinger Bands class="type">class="kw">double upperBand = prevEMA + DeviationBB * standardDeviation; class="type">class="kw">double lowerBand = prevEMA - DeviationBB * standardDeviation; rez.upper = upperBand; rez.middle = prevEMA; rez.lower = lowerBand; LastUpdateDateTime = TimeCurrent(); class="kw">return rez; } class=class="str">"cmt">//class="num">5 Function for calculating Average True Range(Relative) class="type">class="kw">double calculateRelativeATR(class="type">int PeriodATR,class="type">int Shift=class="num">0) { class="type">int barIndex = Shift+class="num">1; class=class="str">"cmt">// bar index ATR is calculated for (with a shift) class="type">int StartIndex = barIndex + PeriodATR - class="num">1; class=class="str">"cmt">// starting bar index for calculating the first ATR if (StartIndex >= LastBars) class="kw">return -class="num">1.0; class=class="str">"cmt">// Check for the availability of the bars for calculating ATR and True Range(if not valid, then the value is -class="num">1) class="type">class="kw">double sumPrice=class="num">0.0; class="type">class="kw">double sumTrueRange = class="num">0.0; class="type">class="kw">double ATR; class=class="str">"cmt">// Calculating True Range for bars and the sum of values for calculating the first ATR for (class="type">int i = StartIndex; i >= barIndex; i--) { sumPrice+=Charts[chartindex].HighI[i]+Charts[chartindex].LowI[i]+Charts[chartindex].CloseI[i]+Charts[chartindex].OpenI[i];class=class="str">"cmt">//added by me class="type">class="kw">double high = Charts[chartindex].HighI[i]; class="type">class="kw">double low = Charts[chartindex].LowI[i]; class="type">class="kw">double trueRange = high - low; sumTrueRange += trueRange; } class=class="str">"cmt">// ATR calculation class=class="str">"cmt">//ATR = sumTrueRange / PeriodATR; - conventional calculation ATR = class="num">100.0 * (sumTrueRange / PeriodATR)/(sumPrice/(PeriodATR*class="num">4.0));class=class="str">"cmt">//calculation of relative ATR in % LastUpdateDateTime = TimeCurrent(); class="kw">return ATR; }
用持仓遍历和指标边界卡死开平仓
这段逻辑先把当前账户里所有持仓扫一遍,避免同一魔术码(MagicF)重复开仓。用 PositionGetTicket 按索引取 ticket,再 PositionSelectByTicket 选中,比对 POSITION_MAGIC 相等就置 bOpened=true 并直接返回 false,说明已经有同策略单在跑。 开多条件被收得很窄:必须没有同魔术码持仓,且 EMA 已算出(EMAValues[1]>0)。核心过滤是收盘价相对 EMA 的偏离 Val1 要大于 0 且小于 ATR*(1/K),同时 RSI[1] 低于 RSIPercentBorder——也就是价格在均线上方但不远离、动量还没过热时才倾向进场。 平仓看 bCloseBuy:当 SMA1 有效时,若收盘价跌破 SMA1 或刺穿布林带上轨,就返回 true 触发 CloseBuyF。最后在主流程里依次跑指标重算、平买、平卖、开买、开卖四个判断,顺序固定。 外汇与贵金属杠杆高,这套边界参数 K 和 RSIPercentBorder 若乱填,可能在震荡里频繁挨耳光,上 MT5 用策略测试器先跑历史段再动真金。
for ( class="type">int i=class="num">0; i<PositionsTotal(); i++ ) { ticket=PositionGetTicket(i); ord=PositionSelectByTicket(ticket); if ( ord && PositionGetInteger(POSITION_MAGIC) == MagicF) { bOpened=true; class="kw">return class="kw">false; } } if (!bOpened && EMAValues[class="num">1] > class="num">0.0)class=class="str">"cmt">//only if nothing is open and the indicator has been calculated { class=class="str">"cmt">//K - control ratio class=class="str">"cmt">//RSIPercentBorder - control RSI class="type">class="kw">double Val1=Charts[chartindex].CloseI[class="num">1]-EMAValues[class="num">1]; class="type">class="kw">double Val2=ATRValues[class="num">1]*(class="num">1.0/K); if (Val1 > class="num">0 && Val1 < Val2 && RSIValues[class="num">1] < RSIPercentBorder) class="kw">return true; } class="kw">return class="kw">false; } class=class="str">"cmt">//to close a buy position class="type">bool bCloseBuy() { if (SMA1Values[class="num">1] > class="num">0.0) { if (Charts[chartindex].CloseI[class="num">1] < SMA1Values[class="num">1] || Charts[chartindex].CloseI[class="num">1] > BollingerBandsUpperValues[class="num">1] ) { class="kw">return true; } } class="kw">return class="kw">false; } IndicatorDataRecalculate();class=class="str">"cmt">//recalculate indicators if ( bCloseBuy() ) { CloseBuyF(); } if ( bCloseSell() ) { CloseSellF(); } if ( bBuy() ) { BuyF(); } if ( bSell() ) { SellF(); }
「多币种优化与结果判读」
MetaTrader 5 优化器支持多币种并行优化,配合模板能力可直接对全部 28 个货币对跑 EA 寻优。相对单品种逐个调参,这种方式的显性好处是自动搜多币种形态、形态权重更高且更跟市场、成交次数因品种互补而更多、整体省去逐品种优化时间。 代价也直接:单品种无法精细优调,若要补这块得加附加逻辑,不在本篇范围。跑完优化不等于结束,从输出集里挑对结果才是关键。 我取过一组较优解:H4 周期,样本 2018–2023,并把 2023 全年六个月留作前向验算。优化段权益曲线不算漂亮,但多月盈利交易成立,说明策略并非无意义,存在实盘可用的概率。很多可优化系统连这水平都摸不到。 把 ChatGPT 当开发伙计,不背锅也不神化:编程是必修,数学期望有,模块思维和拆任务能力决定上限。模型必错,但省下的劳动力成本是真的。伙伴强度看你耐心和机变,越会用越值。
◍ 把这条线请下神坛
把 GPT 写 MQL5 这件事请下神坛:它不是一个能替你赚钱的圣杯,只是一个能把你从重复敲代码里拽出来的加速器。作者原话里提过,一开始用「两行给我写个圣杯」的思路只会撞墙,真正好用的是把逻辑拆块、逐函数下指令,比如让模型写 void findSMA(int index){} 比丢一句「写个布林带交叉 EA」有用得多。
评论区有人实测拿 MT5 代码失败、只拿到 MT4 版本,说明模型对 MQL5 语法的覆盖仍有缝隙,最终编译和边界处理还得人肉兜底。外汇与贵金属杠杆极高,用 AI 生成的策略未经严格回测就上实盘,爆仓概率不小。
腾出几个晚上跑通那套 145 KB 的 mq5 示例,比反复追问「能不能稳」更有价值;工具早晚会嵌进开发链,但踩坑的部分永远是你自己的功课。