包含图形⽤户界⾯(GUI)的EA交易:创建⾯板(第⼀部分)
⽬录
简介
GUI 元件
组装 GUI
⽤于控件的表单
statusbar是什么意思状态条
页⾯组
输⼊栏位
按钮
带有下拉列表的组合框
复选框
表格
标准图表
进度条
EasyAndFast 开发库的更新
结论
简介
尽管算法交易的发展⾮常活跃,很多交易者还是倾向于⼈⼯交易。然⽽,很难完全避免⼀些重复性操作的⾃动化。
本⽂展⽰了⼀个⽤于⼈⼯交易的多交易品种信号 EA 交易的开发,作为例⼦,让我们使⽤来⾃终端标准发布的随机振荡指标(Stochastic)的信号。您可以使⽤这⾥的代码来开发您⾃⼰的含有图形界⾯(GUI)的 EA 交易:可以在其中包含任何其他指标,也可以根据某些计算结果来做交易决定。
对于执⾏其它交易者订单的⼈来说,本⽂也是有⽤的,可以⽤于向客户演⽰⼀些技术任务的实例。这个例⼦可以在您准备开发含有 GUI 的程序需求规格的时候节约您的时间。
这⾥是本⽂详细讨论的⼀些问题:
创建 GUI.
使⽤指定的属性取得交易品种的列表。
交易操作的控制。
在图表上快速切换交易品种和时段⽽不⽤重新初始化 EA 交易。
通过⽤户界⾯管理图表的属性。
从多个交易品种中使⽤颜⾊指⽰接收指标信号。
操作已经开启的仓位。
EasyAndFast开发库的更新。
本⽂将分为两部分发表,在这篇⽂章中,我们会探讨开发⾯板,⽽下⼀篇则描述使⽤功能来填补它。
GUI 元件
我们将要开发⼀个含有 GUI 的 EA 交易,这可以使⽤户和程序之间实现交互,并且可以把数据可视化。可以使⽤标准库的功能来创建 GUI,但是在我的例⼦中,它是基于EasyAndFast开发库来实现的。它的功能很丰富,可以集中精⼒于程序的功能⽅⾯,⽽不⽤被图形部分的优化来分神。
⾸先,让我们规划⼀下⼤致的 GUI 结构,下⾯的图表显⽰,GUI 窗⼝含有两个页⾯,下⾯的列表显⽰了它们要有的功能。这是⼀个简化过的例⼦,客户和开发者可以在讨论的时候更加详细地合作。
图 1. 含有注释的 GUI 总体视图
可能会有很多的 GUI 控件,所以,让我们⾸先以分级表单⽅式列出它们:
⽤于控件的表单
⽤于显⽰额外总体信息的状态栏
页⾯组:
交易:
带有复选框的输⼊栏位,⽤于给交易品种列表排序
请求按钮⽤于开始构建交易品种列表
卖出按钮
买⼊按钮
交易量输⼊栏位
⽤于关闭所有开启仓位的按钮
⽤于设置卖出信号⽔平的输⼊栏位
⽤于设置买⼊信号⽔平的输⼊栏位
交易品种表格
⽤于可视化交易品种数据的图表为了更加⽅便,让我们把⼀些图表属性使⽤下⾯的元件组来进⾏管理:
⽤于选择时段开关的带有下拉列表的组合框
⽤于启⽤/禁⽌时间伸缩的复选框
⽤于启⽤/禁⽌价格伸缩的复选框
管理伸缩的输⼊栏位
⽤于启⽤缩进的按钮
⽤于显⽰指标的复选框
仓位:
仓位的表格
⽤于重放帧的指⽰
在主程序类 (CProgram) 中, 声明⽅法类以上列出的元件类的实例。⽤于创建元件的⽅法的代码位于单独的⽂件中,使⽤ MQL 程序类包含在⽂件中:
// ------------------------------------------------------------------ //| 应⽤程序开发类                          | // ------------------------------------------------------------------ class CProgram : public CWndEvents  { private:    //--- 窗⼝    CWindow          m_window1;    //--- 状态条CStatusBar        m_status_bar;    //--- 页⾯    CTabs            m_tabs1;    //--- 输⼊栏位    CTextEdit        m_symb_filter;  CTextEdit        m_lot;    CTextEdit        m_up_level;    CTextEdit        m_down_level;    CTextEdit        m_chart_scale;  //--- 按钮    CButton          m_request;    CButton          m_chart_shift;    CButton          m_buy;    CButton          m_sell;  CButton          m_close_all;    //--- 组合框    CComboBox        m_timeframes;    //--- 复选框    CCheckBox
m_date_scale;    CCheckBox        m_price_scale;    CCheckBox        m_show_indicator;    //--- 表格
CTable            m_table_positions;    CTable            m_table_symb;    //--- 标准图表    CStandardChart   
m_sub_chart1;  //--- 进度条    CProgressBar      m_progress_bar;    //--- public:    //--- 创建 GUI    bool              CreateGUI(void);    //---private:    //--- 表单    bool              CreateWindow(const string text);    //--- 状态条    bool              CreateStatusBar(const int x_gap,const int y_gap);    //--- 页⾯    bool              CreateTabs1(const int x_gap,const int y_gap);    //--- 输⼊栏位
bool              CreateSymbFilter(const int x_gap,const int y_gap,const string text);    bool              CreateLot(const int
x_gap,const int y_gap,const string text);    bool              CreateUpLevel(const int x_gap,const int y_gap,const string text);
bool              CreateDownLevel(const int x_gap,const int y_gap,const string text);
bool              CreateChartScale(const int x_gap,const int y_gap,const string text);    //--- 按钮
bool              CreateRequest(const int x_gap,const int y_gap,const string text);    bool              CreateChartShift(const int x_gap,const int y_gap,const string text);    bool              CreateBuy(const int x_gap,const int y_gap,const string text);  bool              CreateSell(const int x_gap,const int y_gap,const string text);    bool              CreateCloseAll(const int
x_gap,const int y_gap,const string text);    //--- 组合框    bool              CreateComboBoxTF(const int x_gap,const int
y_gap,const string text);    //--- 复选框    bool              CreateDateScale(const int x_gap,const int y_gap,const string text);  bool              CreatePriceScale(const int x_gap,const int y_gap,const string text);
bool              CreateShowIndicator(const int x_gap,const int y_gap,const string text);    //--- 表格
bool              CreatePositionsTable(const int x_gap,const int y_gap);    bool              CreateSymbolsTable(const int
x_gap,const int y_gap);    //--- 标准图表    bool              CreateSubChart1(const int x_gap,const int y_gap);    //--- 进度条bool              CreateProgressBar(const int x_gap,const int y_gap,const string text);  }; // ------------------------------------------------------------------ //| ⽤于创建控件的代码                    | // ------------------------------------------------------------------ #include
'CreateGUI.mqh' // ------------------------------------------------------------------
下⼀步,让我们着重于 GUI 的组装,⽤于创建它的元件以及属性的⽅法。
组装 GUI
在程序 GUI 的开发中,我们将使⽤10类 GUI 元件。
控件表单 (CWindow)
状态条 (CStatusBar)
页⾯组 (CTabs)
输⼊栏位 (CTextEdit)
按钮 (CButton)
带有下拉列表的组合框 (CComboBox)
复选框 (CCheckBox)
表格 (CTable)
标准图表 (CStandardChart)
进度条 (CProgressBar)
在这个列表的⼀些种类中,我们会需要多个元件,所以我们每个组只会讨论⼀个元件,让我们使⽤相同的顺序来探讨创建它们的⽅法。
⽤于控件的表单
下⾯是⽤于创建容纳所有其他元件的表单的⽅法,⾸先,我们需要把表单加到程序 GUI 元件列表中,为此,调⽤CWndContainer::AddWindow() ⽅法,传⼊ CWindow 类型的元件对象。然后,在创建表单之前设置它的属性,我们要设置以下属性 (和下⾯列表中顺序相同):
表单的⼤⼩ (宽度和⾼度)
抬头字体⼤⼩
表单的移动模式 (在图表之内)
⼈⼯改变表单⼤⼩的模式 (通过拖曳边框)
表单的按钮. 每个按钮是否可见是可以⾃定义的. 在本例中,可以使⽤下⾯的按钮:
关闭表单. 当点击按钮时,在程序主表单中出现程序关闭确认窗⼝。
最⼤化/最⼩化表单.
元件的⼯具提⽰. 这个按钮还有两个状态. 如果被启⽤,在控件中会显⽰指定的⼯具提⽰,
把表单展开到整个图表区域,这可以通过再次点击按钮来撤销操作。
可以为每个按钮设置⼯具提⽰。
在设置完属性之后,调⽤创建表单的⽅法 — CWindow::CreateWindow() 并传给它:
图表 ID,
图表⼦窗⼝索引,
表头⽂字,
表单的初始坐标.
// ------------------------------------------------------------------
/
/| 创建控件表单                                                        |
// ------------------------------------------------------------------
bool CProgram::CreateWindow(const string caption_text)
{
//--- 把窗⼝指针加到窗⼝数组中
CWndContainer::AddWindow(m_window1);
//--- 属性
m_window1.XSize(750);
m_window1.YSize(450);
m_window1.FontSize(9);
m_window1.IsMovable(true);
m_window1.ResizeMode(true);
m_window1.CloseButtonIsUsed(true);
m_window1.CollapseButtonIsUsed(true);
m_window1.TooltipsButtonIsUsed(true);
m_window1.FullscreenButtonIsUsed(true);
//--- 设置⼯具提⽰
m_window1.GetCloseButtonPointer().Tooltip('Close');
m_window1.GetTooltipButtonPointer().Tooltip('Tooltips');
m_window1.GetFullscreenButtonPointer().Tooltip('Fullscreen');
m_window1.GetCollapseButtonPointer().Tooltip('Collapse/Expand');
//--- 创建表单
if(!m_window1.CreateWindow(m_chart_id,m_subwin,caption_text,1,1))
return(false);
//---
return(true);
}
推荐每次在您加上新的 GUI 元件的时候都编译程序并检查结果。
图 2. ⽤于控件的表单
所有中间过程的结果都显⽰如下.
状态条
⽤于根据指定的主元件来创建状态条的⽅法的代码,也⽤于计算其中元件的边界以及它们的⼤⼩,这在开发应⽤程序的时候可以节约时间: ⼀组相关元件可以只根据主元件来改变它们的坐标。为了绑定元件,它的指针要传给CElement::MainPointer() ⽅法。在本例中,我们把状态条绑定到表单,所以,要把表单对象传给这个⽅法。
然后,再设置状态条的属性。它包含了三个部分,向⽤户显⽰信息。
为了不必指定相对表单的宽度,要确保宽度在表单宽度改变时⾃动变化,
元件右侧边界的缩进是1个像素。
把状态条绑定到表单的底部,这样它就可以在表单⾼度变化时⾃动根据底部边界调节。
然后,当增加点的时候,设置它们每个的宽度,
在设置了属性之后,再创建元件。现在,它已经可以⼯作了,我们可以在运⾏时刻改变它分段中的⽂字,在我们的例⼦中,第⼀个分段的⽂字设为 'For Help, press F1(如需取得帮助,按F1)' .
在⽅法的最后,要确保把所创建元件的指针保存到总的 GUI 元件列表中,为此,要调⽤
CWndContainer::AddToElementsArray() ⽅法,并且把表单索引和元件对象传给它。因为我们只有⼀个表单,它的索引将是0。
// ------------------------------------------------------------------ //| 创建状态条                              | // ------------------------------------------------------------------ bool CProgram::CreateStatusBar(const int x_gap,const int y_gap)  { #define STATUS_LABELS_TOTAL 3 //--- 保存窗⼝指针    m_status_bar.MainPointer(m_window1); //--- 属性    m_status_bar.AutoXResizeMode(true);
m_status_bar.AutoXResizeRightOffset(1);    m_status_bar.AnchorBottomWindowSide(true); //--- 设置分段的数量以及它们的属性    int width[STATUS_LABELS_TOTAL]={0,200,110};    for(int i=0; i<STATUS_LABELS_TOTAL; i )
m_status_bar.AddItem(width[i]); //--- 创建控件    if(!m_status_bar.CreateStatusBar(x_gap,y_gap))      return(false); //--- 在状态条分段中设置⽂字    m_status_bar.SetValue(0,'For Help, press F1'); //--- 把对象加到总的对象组数组中CWndContainer::AddToElementsArray(0,m_status_bar);    return(true);  }
EasyAndFast开发库中其余元件的创建也是基于相同的原则,所以,我们只会讨论我们 EA 中需要使⽤的可⾃定义的属性。
图 3. 加上状态条
页⾯组
让我们在创建页⾯组的⽅法中设置以下的元件属性:
在页⾯中⽂字为中间对齐.
把页⾯放置在⼯作区域的顶部.
⼤⼩根据主元件(表单)区域⾃动调节. 在本例中,没有必要指定页⾯组区域的⼤⼩.
设置相对于主元件的右侧和底部边缘的缩进. 如果表单⼤⼩改变,它们的缩进会保持不变.
当加上下⾯的页⾯时,页⾯的名称和宽度也会传到这个⽅法中,
下⾯是⽅法的代码:
// ------------------------------------------------------------------
//| 创建页⾯组 1                                                      |
// ------------------------------------------------------------------
bool CProgram::CreateTabs1(const int x_gap,const int y_gap)
{
#define TABS1_TOTAL 2
//--- 保存指向主元件的指针
m_tabs1.MainPointer(m_window1);
//--- 属性
m_tabs1.IsCenterText(true);
m_tabs1.PositionMode(TABS_TOP);
m_tabs1.AutoXResizeMode(true);
m_tabs1.AutoYResizeMode(true);
m_tabs1.AutoXResizeRightOffset(3);
m_tabs1.AutoYResizeBottomOffset(25);