感谢作者的文章。我注意到了很多简单(但同时也很优雅)的解决方案,我一定会在我的程序中使用它们。
哦,真漂亮!我把它添加到我的纪念册中;)
我想再次提请您注意,在应用使用 CustomGUI 类实现的同一指标的多个副本时,Create() 方法中的名称必须不同。 示例如下。
#property version "1.00" #property indicator_chart_window #property indicator_plots 0 //--- #include <CustomGUI\CustomGUI.mqh> CCircleSection ind; //+------------------------------------------------------------------+ //| 指标的输入参数| //+------------------------------------------------------------------+ input ENUM_TIMEFRAMES tf=PERIOD_CURRENT; input int period=10; input int indsize=50; input ENUM_ORIENTATION orient=VERTICAL; input int X=100; input int Y=100; //--- int IndHandle; double rsi[]; //+------------------------------------------------------------------+ //| 自定义指示器初始化函数 //+------------------------------------------------------------------+ int OnInit() { //--- 获取指标句柄 IndHandle=iRSI(Symbol(),tf,period,PRICE_CLOSE); if(IndHandle==INVALID_HANDLE) { Print("Failed to get indicator handle"); return(INIT_FAILED); } ArraySetAsSeries(rsi,true); //--- ind.Radius(indsize); ind.LabelSize(15); ind.LabelValue("RSI "+"("+IntegerToString(period)+")"); ind.Orientation(orient); ind.Create("rsi_custom"+IntegerToString(MathRand()),X,Y); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 自定义指标迭代函数 //+------------------------------------------------------------------+ int OnCalculate(const int rates_total, const int prev_calculated, const datetime &time[], const double &open[], const double &high[], const double &low[], const double &close[], const long &tick_volume[], const long &volume[], const int &spread[]) { //--- if(CopyBuffer(IndHandle,0,0,1,rsi)<1) return(0); ind.NewValue(rsi[0]); //--- 为下一次调用返回 prev_calculated 的值 return(rates_total); } //+------------------------------------------------------------------+ //| 自定义指标去初始化功能 //+------------------------------------------------------------------+ void OnDeinit(const int reason) { ind.Delete(); ChartRedraw(); } //+------------------------------------------------------------------+
Create() 方法有一个唯一的名称。
附加的文件:
RSI_CustomGUI.mq5
6 kb
Alexander Fedosov:
这种方法的本质是,当任何条件发生变化时,都会重新绘制一幅图片。它不响应热键或鼠标点击事件。
这种方法的本质是,当任何条件发生变化时,都会重新绘制一幅图片。它不响应热键或鼠标点击事件。
得了吧。鼠标点击是什么?不是 "改变任何条件"。它会产生一个事件,用来重新绘制画布。伊尔米尔,你的问题的正确答案是当然可以。
好主题。感谢作者,我将在 canvas..... 上制作一个tick 指标。
我注意到这一点。
//+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ class CCanvasBase { private: //--- 画布名称 string m_canvas_name; //--- 画布坐标 int m_x; int m_y; //--- 画布尺寸 int m_x_size; int m_y_size; protected: CCanvas m_canvas; //--- 为对象创建图形资源 bool CreateCanvas(void); //-- 删除图形资源 bool DeleteCanvas(void); public: CCanvasBase(void); ~CCanvasBase(void); //--- 设置并返回坐标 void X(const int x) { m_x=x; } void Y(const int y) { m_y=y; } int X(void) { return(m_x); } int Y(void) { return(m_y); } //--- 设置并返回尺寸 void XSize(const int x_size) { m_x_size=x_size; } void YSize(const int y_size) { m_y_size=y_size; } int XSize(void) { return(m_x_size); } int YSize(void) { return(m_y_size); } //--- 创建时设置指标名称 void Name(const string canvas_name) { m_canvas_name=canvas_name; } };
有一个私有 数据成员m_canvas_name,但设置其值的方法Name() 是公共的。我认为这违反了封装原则。我将把这个方法设为私有。
fxsaber:
它确实去了,确实去了。我自己也贴出了这样一个指标,但它并没有到人民那里去。
我甚至正试图在此基础上制作一个滴答速度指示器。
新文章 利用 CCanvas 类开发自定义指标已发布:
本文利用 CCanvas 类的图形基元应对自定义图形指标的开发。
不同于简单的弧形指示, 扇区图看起来好像具有间隔相等的标签。当创建这类指标的布局时, 我决定制作十个扇区并添加一个新的元素 – 内框。具有弧形扇区指示的基本结构如图例. 5 所示。
图例. 5. 带有弧形指示的圆形指标的基本结构
作者:Alexander Fedosov