可视化!类似于 R 语言
📘

可视化!类似于 R 语言 "plot (绘图)" 的 MQL5 图形库(基础篇)

第 1/2 篇

「用几行代码在 MT5 里画出函数曲线」

做价格行为研究时,把数学函数或指标逻辑画成图,比盯数字直观得多。R 语言里靠 plot 几行出图,MQL5 标准库也给了对等能力:引入 Graphics\Graphic.mqh,建一个 CGraphic 对象就能交给我们画图。 下面这段脚本在 [-1.2, 1.2] 区间、以 0.005 为步长同时绘出三条曲线。BlueFunction 返回 10*x*sin(1/x),RedFunction 是 sin(100*x)/sqrt(x),OrangeFunction 是 sin(100*x)/sqrt(-x),靠近 0 的区域会出现剧烈振荡,图形能直接暴露奇点附近的数值行为。 代码里 RESULT_OR_NAN 宏把 x==0 的除零结果转成 NaN,避免曲线在原点崩掉。CurveAdd 的 CURVE_LINES 参数指定连线模式,CurvePlotAll 一次性把三条线刷到窗口。开 MT5 新建脚本粘进去,编译运行就能看到 780x380 的弹窗图。 外汇与贵金属行情的高波动常让这类函数在实盘映射时失真,用图形库做逻辑预检只是辅助,实盘仍属高风险。

MQL5 / C++
class="macro">#include <Graphics\Graphic.mqh>
class="macro">#define RESULT_OR_NAN(x,expression) ((x==class="num">0)?(class="type">class="kw">double)"nan":expression)
class=class="str">"cmt">//--- 函数
class="type">class="kw">double BlueFunction(class="type">class="kw">double x)   { class="kw">return (RESULT_OR_NAN(x, class="num">10*x*sin(class="num">1/x)));      }
class="type">class="kw">double RedFunction(class="type">class="kw">double x)    { class="kw">return (RESULT_OR_NAN(x, sin(class="num">100*x)/sqrt(x))); }
class="type">class="kw">double OrangeFunction(class="type">class="kw">double x) { class="kw">return (RESULT_OR_NAN(x, sin(class="num">100*x)/sqrt(-x)));}
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 脚本的 start 函数                                                 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnStart()
  {
   class="type">class="kw">double from=-class="num">1.2;
   class="type">class="kw">double to=class="num">1.2;
   class="type">class="kw">double step=class="num">0.005;
   CGraphic graphic;
   graphic.Create(class="num">0, "G", class="num">0, class="num">30, class="num">30, class="num">780, class="num">380);
class=class="str">"cmt">//--- 颜色
   CColorGenerator generator;
   class="type">uint blue=generator.Next();
   class="type">uint red=generator.Next();
   class="type">uint orange=generator.Next();
class=class="str">"cmt">//--- 绘制所有曲线
   graphic.CurveAdd(RedFunction,from,to,step,red,CURVE_LINES, "红色");
   graphic.CurveAdd(OrangeFunction,from,to,step,orange,CURVE_LINES, "橙色");
   graphic.CurveAdd(BlueFunction,from,to,step,blue,CURVE_LINES, "蓝色");
   graphic.CurvePlotAll();
   graphic.Update();
  }

在MT5图表上直接画图的CCanvas玩法

标准库里的 CCanvas 基类,本质是在价格图表上开一块位图画板,直接往上面点像素、画线、填色、写文字。它把点、直线、折线、圆、三角形、多边形这些基元封装好,还支持指定字体、颜色和字号显示文本,省掉自己调 GDI 的麻烦。 早期 CCanvas 只有抗锯齿(AA)和无抗锯齿两种画模式。后来补进一套基于吴小林算法的函数:LineWu、PolylineWu、PolygonWu、TriangleWu、CircleWu、EllipseWu。吴小林算法混叠消隐质量高,速度又接近无抗锯齿的 Bresenham,和原 AA 在视觉上能看出差别。 用三种函数画同样半径 25 的圆,位置分别是 (70,70)、(120,70)、(170,70):Circle 边缘硬,CircleAA 线条偏粗,CircleWu 因为线更细、过渡色调算得好,看起来更整洁自然。下面这段可直接丢进脚本跑,改坐标就能对比。 除了圆,椭圆也加了 EllipseAA 和 EllipseWu 双选项;区域填充函数做了重载,多出一个“填充敏感度”阀值参数,控制边界容差更细。外汇和贵金属图表叠加自绘图形时波动剧烈,先在模拟盘验证渲染开销。

MQL5 / C++
class="macro">#include<Canvas\Canvas.mqh>
CCanvas canvas;
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 脚本的 start 函数                                                 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnStart()
  {
   class="type">int       Width=class="num">800;
   class="type">int       Height=class="num">600;
class=class="str">"cmt">//--- 创建画板
   if(!canvas.CreateBitmapLabel(class="num">0,class="num">0,"CirclesCanvas",class="num">30,class="num">30,Width,Height))
     {
      Print("创建画板错误: ",GetLastError());
     }
class=class="str">"cmt">//--- 绘图
   canvas.Erase(clrWhite);
   canvas.Circle(class="num">70,class="num">70,class="num">25,clrBlack);
   canvas.CircleAA(class="num">120,class="num">70,class="num">25,clrBlack);
   canvas.CircleWu(class="num">170,class="num">70,class="num">25,clrBlack);
class=class="str">"cmt">//---
   canvas.Update();
  }

◍ 用 CGraphic 在 MT5 里徒手画图

想在 MT5 图表上画自定义曲线,先得拿到 CGraphic 的实例再调 Create()。Create() 吃六个参数:图形 ID、对象名、窗口索引、锚点 X/Y、宽高。下面这行把画板放在主图左上角偏移 (30,30),尺寸 830×430,跑完就有块空白板子等着你填。 //--- 创建图形对象 CGraphic graphic; //--- 创建画板 graphic.Create(0,"Graphic",0,30,30,830,430); 填曲线用 CurveAdd(),它支持四种喂数据方式:一维数组(索引当 X、值当 Y)、x[]/y[] 双数组、CPoint2D 数组、或传函数指针加起止和步长。返回的是 CCurve 指针,后面改线型、改名都靠它。上面 x 从 -10 到 8、y 里最大 23 最小 -10,用 CURVE_LINES 连出来就是折线。 double x[]={-10,-4,-1,2,3,4,5,6,7,8}; double y[]={-5,4,-10,23,17,18,-9,13,17,4}; CCurve *curve=graphic.CurveAdd(x,y,CURVE_LINES); 画出来有三种触发:CurvePlotAll() 一把全画、CurvePlot(0) 按索引画一条、或者 curve.Visible(true) 配合 graphic.Redraw() 局部刷。注意改了属性之后若已 Plot 过,必须再 Redraw() 一次才生效,否则屏上还是旧样。 graphic.CurvePlotAll(); graphic.Update(); 库里不少活儿是自动的:对比色随机生成、坐标轴自缩放、曲线名按类型和顺序起、工作区自动排。但 TextAdd()/LineAdd()/MarksToAxisAdd() 加的装饰性元素不落盘,下次 CurvePlotAll 或 Redraw 就冲掉,做标注别指望它常驻。

MQL5 / C++
class="macro">#include <Graphics\Graphic.mqh>
class=class="str">"cmt">//+------------------------------------------------------------------+
class=class="str">"cmt">//| 脚本的 start 函数                                                 |
class=class="str">"cmt">//+------------------------------------------------------------------+
class="type">void OnStart()
  {
   CGraphic graphic;
   graphic.Create(class="num">0,"图形",class="num">0,class="num">30,class="num">30,class="num">780,class="num">380);
   class="type">class="kw">double x[]={-class="num">10,-class="num">4,-class="num">1,class="num">2,class="num">3,class="num">4,class="num">5,class="num">6,class="num">7,class="num">8};
   class="type">class="kw">double y[]={-class="num">5,class="num">4,-class="num">10,class="num">23,class="num">17,class="num">18,-class="num">9,class="num">13,class="num">17,class="num">4};
   CCurve *curve=graphic.CurveAdd(x,y,CURVE_LINES);
   graphic.CurvePlotAll();
   graphic.Update();
  }

「曲线绘制的六种显示模式与属性操控」

MQL5 图形库把曲线绘制抽象成 ENUM_CURVE_TYPE 枚举里的六种模式:CURVE_POINTS 画点、CURVE_LINES 画实线、CURVE_POINTS_AND_LINES 点线结合、CURVE_STEPS 画台阶、CURVE_HISTOGRAM 画直方图、CURVE_NONE 不画。CurveAdd 返回的 CCurve 指针要留好,属性名一律以模式名为前缀,靠指针就能实时改显示。 CURVE_POINTS 最轻量,每个坐标按 PointsSize、PointsFill、PointsColor、PointsType 画成一个几何点,曲线颜色决定点的边框色。点的形状走 ENUM_POINT_TYPE,十个基础形里 POINT_CIRCLE 是默认,POINT_STAR 是星形,POINT_VERTICAL_DASH 是竖线。下面这段把点设成 20 像素、填充红心蓝边: CURVE_LINES 是主用模式,点对之间连直线或平滑曲线。平滑走两阶段:先按派生词给每对点定两个参考点,再用这四个点画指定步长的贝塞尔曲线。LinesSmoothTension 取 (0.0;1.0],设 0 不平滑,调到 0.8 曲线明显更顺。 CURVE_STEPS 用两条线拼出台阶,StepsDimension 为 0 是先横后竖、为 1 是先竖后横。CURVE_HISTOGRAM 只有 HistogramWidth 一个属性,值给太大柱线会重叠,Y 值高的会把旁边低的吞掉。CURVE_NONE 虽不渲染,但自动缩放时它的数值仍被计入坐标范围。 外汇与贵金属图表叠加这类自定义曲线时波动剧烈、高风险,参数先在小周期回测再上实盘。

MQL5 / C++
CCurve *curve=graphic.CurveAdd(x,y, ColorToARGB( clrBlue , class="num">255 ),CURVE_POINTS);    curve.PointsSize( class="num">20 );    curve.PointsFill( true );    curve.PointsColor( ColorToARGB( clrRed , class="num">255 ) );
CCurve *curve=graphic.CurveAdd(x,y, ColorToARGB( clrBlue , class="num">255 ),CURVE_LINES);    curve.LinesStyle( STYLE_DOT );    curve.LinesSmooth( true );    curve.LinesSmoothTension( class="num">0.8 );    curve.LinesSmoothStep( class="num">0.2 );
CCurve *curve=graphic.CurveAdd(x,y, ColorToARGB( clrBlue , class="num">255 ),CURVE_STEPS);    curve.LinesStyle( STYLE_DASH );    curve.StepsDimension( class="num">1 );

常见问题

用 CCanvas 或 CGraphic 类,初始化画布后调用 Line 类方法即可,核心代码通常在十行内可出图。
图表内绘图能叠加在 K 线上实时看形态,不用切软件,改参数立刻重绘,适合快速验证想法。
可以,把你的计算逻辑告诉小布,它能生成绘图代码并在对应品种页直接渲染,省去手动调画布。
常见含线、点、阶跃、直方图等模式,通过图形对象的属性枚举或 Set 方法切换,具体看类成员定义。
在 CGraphic 的线条对象上调用颜色、宽度相关 Set 方法,或改全局画笔属性后重绘即可生效。