DRAKON可视化编程语言 - 面向MQL开发人员和客户的通信工具·综合运用
(3/3)·多数EA需求在文字里说不清,用图标画出来客户与开发才真正对齐
◍ NR4 指标的头文件与缓冲区声明
窄幅区间 NR4 的核心定义是:当前 K 线振幅(high-low)在最近 4 根内最小。要在 MT5 里把它画在主图,第一步是把指标属性与缓冲区先钉死。 代码头部用 #property indicator_chart_window 指定主图叠加,indicator_buffers 2 与 indicator_plots 2 声明两个绘图缓冲:NRBarsUp 与 NRBarsDn,都用 DRAW_ARROW 画箭头、clrRed 实心红。 input int NRPeriod=4 是唯一的外部参数,直接决定“N 根内最窄”的 N 值;调成 7 就是 NR7,逻辑不变。 两个 double 数组 NRBarsBufferUp[] / NRBarsBufferDn[] 承接箭头坐标,分开写是为了上涨窄幅与下跌窄幅都能标,但颜色暂统一为红,实战中可改 clrGreen 区分方向。 OnCalculate 入口先判 rates_total < NRPeriod 直接 return 0,避免前几根数据不足算出脏信号;prev_calculated < NRPeriod 时 limit = NRPeriod,保证首次计算只刷足够根数。外汇与贵金属杠杆高,NR 信号仅提示波动收敛,突破方向须结合结构确认,概率而非必然。
class=class="str">"cmt">//| NR4.mq5 | class=class="str">"cmt">//| Oleg Fedorov(aka certain) | class=class="str">"cmt">//| mailto:coder.fedorov@gmail.com | class=class="str">"cmt">//+------------------------------------------------------------------+ class="macro">#class="kw">property copyright "Oleg Fedorov(aka certain)" class="macro">#class="kw">property link "mailto:coder.fedorov@gmail.com" class="macro">#class="kw">property version "class="num">1.00" class="macro">#class="kw">property indicator_chart_window class="macro">#class="kw">property indicator_buffers class="num">2 class="macro">#class="kw">property indicator_plots class="num">2 class=class="str">"cmt">//--- plot NRBars class="macro">#class="kw">property indicator_label1 "NRBarsUp" class="macro">#class="kw">property indicator_type1 DRAW_ARROW class="macro">#class="kw">property indicator_color1 clrRed class="macro">#class="kw">property indicator_style1 STYLE_SOLID class="macro">#class="kw">property indicator_width1 class="num">0 class=class="str">"cmt">//--- plot NRBars class="macro">#class="kw">property indicator_label2 "NRBarsDn" class="macro">#class="kw">property indicator_type2 DRAW_ARROW class="macro">#class="kw">property indicator_color2 clrRed class="macro">#class="kw">property indicator_style2 STYLE_SOLID class="macro">#class="kw">property indicator_width2 class="num">0 class=class="str">"cmt">//--- class="kw">input variables class="kw">input class="type">int NRPeriod=class="num">4; class=class="str">"cmt">//--- indicator buffers class="type">class="kw">double NRBarsBufferUp[]; class="type">class="kw">double NRBarsBufferDn[]; class Main { class="type">int OnCalculate(const class="type">int rates_total, const class="type">int prev_calculated, const class="type">class="kw">datetime &time[], const class="type">class="kw">double &open[], const class="type">class="kw">double &high[], const class="type">class="kw">double &low[], const class="type">class="kw">double &close[], const class="type">long &tick_volume[], const class="type">long &volume[], const class="type">int &spread[]) { class=class="str">"cmt">// item class="num">15 class="type">int i,j, limit; class=class="str">"cmt">// item class="num">16 if (rates_total < NRPeriod) { class=class="str">"cmt">// item class="num">19 class="kw">return class="num">0; } else { class=class="str">"cmt">// item class="num">20 if (prev_calculated < NRPeriod) { class=class="str">"cmt">// item class="num">23 limit = NRPeriod;
「窄幅K线的遍历判定逻辑」
在指标计算的主循环里,先用 ArrayInitialize 把上下缓冲数组填成 EMPTY_VALUE,避免上一轮残留值干扰绘图;若不是首根预处理,则 limit 设为 rates_total - NRPeriod,保证前面 NRPeriod 根不被越界访问。 随后 i 从 limit 起步做倒序 while 死循环,靠 i<rates_total-1 控制退出:只处理已有收盘价的历史柱,未走完的当前柱直接 break,防止半根 K 线误判。 内层 j 从 1 跑到 NRPeriod-1,逐根比对:若当前柱的「最高-最低」跨度大于 i-j 那根,说明近期出现了更宽振幅,立刻 break 判定失败;只有 j 一路累加到等于 NRPeriod,才确认当前柱是 NRPeriod 窗口内最窄的一根。 命中时把 high[i]、low[i] 写进 NRBarsBufferUp / Dn,图表上便标出窄幅区间边界。外汇与贵金属波动受数据面驱动,窄幅形态仅代表概率意义上的收敛,实盘须以 MT5 加载验证并自担高风险。
ArrayInitialize(NRBarsBufferUp, EMPTY_VALUE); ArrayInitialize(NRBarsBufferDn, EMPTY_VALUE); } else { limit = rates_total - NRPeriod; } i = limit; class="kw">while (true) { if (i<rates_total-class="num">1) { } else { break; } j=class="num">1; class="kw">while (true) { if (j<NRPeriod) { } else { break; } if (high[i]-low[i]>high[i-j]-low[i-j]) { break; } else { } j++; } if (j==NRPeriod) { NRBarsBufferUp[i]=high[i]; NRBarsBufferDn[i]=low[i]; } else {
指标缓冲与箭头符号的初始化落点
这段初始化代码决定了 NR4 指标在 MT5 图表上的实际呈现方式。两个数据缓冲 NRBarsBufferUp 与 NRBarsBufferDn 分别承载向上和向下的窄幅标记,必须在 OnInit 里用 SetIndexBuffer 完成映射,否则编译通过也画不出东西。 箭头外观走的是 Wingdings 字符集路线:索引 0 绑 218 号字符(向上箭头),索引 1 绑 217 号字符(向下箭头),由 PlotIndexSetInteger 配合 PLOT_ARROW 写入。换字符编码就能改标记形态,比如改成 159/160 会得到不同的视觉符号。 短名直接用 NR4(周期) 动态拼接,NRPeriod 是外部输入的回顾窗口。开 MT5 新建指标把这段拷进去,调 NRPeriod 从 4 改到 10,能直观看到标记密度随窗口拉长而下降——外汇与贵金属波动随机性高,窄幅统计只作概率参考,实盘须控仓。
class="type">int OnInit() { class=class="str">"cmt">// item class="num">11 class=class="str">"cmt">//--- indicator buffers mapping SetIndexBuffer(class="num">0,NRBarsBufferUp,INDICATOR_DATA); SetIndexBuffer(class="num">1,NRBarsBufferDn,INDICATOR_DATA); class=class="str">"cmt">// item class="num">12 class=class="str">"cmt">//--- setting a code from the Wingdings charset as the class="kw">property of PLOT_ARROW PlotIndexSetInteger(class="num">0,PLOT_ARROW,class="num">218); PlotIndexSetInteger(class="num">1,PLOT_ARROW,class="num">217); class=class="str">"cmt">// item class="num">13 class=class="str">"cmt">//--- IndicatorSetString(INDICATOR_SHORTNAME,"NR4("+IntegerToString(NRPeriod)+")"); class=class="str">"cmt">// item class="num">14 class=class="str">"cmt">//--- class="kw">return(INIT_SUCCEEDED); }
◍ 别急着下结论
DRAKON 这套图形化编排思路,对 MT5 指标和 EA 的开发未必适合每个人。上面提到的 DRAKON Editor 项目文件(FullIndicator.zip,3.28 KB)里已经塞了 NR4 指标的完整可运行算法,你下载解压后直接用编辑器打开,就能看到图标怎么转成 MQL5 源码。 如果你手头有自己写的裸逻辑,不妨也拖进 Drakon.Tech 或 drakonhub 试排一遍——有读者反馈它比 Flowgorithm 更接近 Grafcet,事件驱动的结构对交易算法挺顺手,但传统软件工程里没人真拿 UML 当规范,DRAKON 的实用性也得看你怎么用。 作者留了话:需要文中其他算法源码可以私信拿,也欢迎在评论区聊 DRAGON 在交互演示、记忆编排上的坑。外汇和贵金属本身高风险,这类工具只帮你理清楚结构,不替你兜底任何实盘结果。