Dmitriy Gizlyk:
这篇文章的目的不是提供现成的产品供大家使用,而是向大家展示和传授如何根据自己的要求创建自己的个性化交易面板。
这篇文章的目的不是提供现成的产品供大家使用,而是向大家展示和传授如何根据自己的要求创建自己的个性化交易面板。
德米特里,今天我开始按照您的教程在 µl 4 上制作一个面板。几乎一切正常,但当我点击面板或任何按钮时,打开的只有买入。原因是什么?

//+------------------------------------------------------------------+ //|TradePanel.mq4 ///2015年,MetaQuotes Software Corp.版权所有。 //|https://www.mql5.com || //+------------------------------------------------------------------+ #property copyright "Copyright 2015, MetaQuotes Software Corp." #property link "https://www.mql5.com" #property version "1.00" #property strict #include <Controls\Dialog.mqh> #include <Controls\Label.mqh> #include <Controls\Button.mqh> //--- 输入 extern double Lot = 0.1; // lot extern int StopLoss = 500; // 驼鹿 extern int TakeProfit = 500; // yazi extern int Slip = 30; // 重新报价 extern int Magic = 0; // 魔法 //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ enum label_align { left=-1, right=1, center=0 }; //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ class CTradePanel : public CAppDialog { private: CLabel Lots_label; // 显示标签 " 乐ots CEdit Lots; // 显示下一个订单的数量 CButton SELL,BUY; // 出售和购买按钮 CButton CloseAll; // 关闭按钮 //--- 创建标签对象 bool CreateLabel(const long chart,const int subwindow,CLabel &object,const string text,const uint x,const uint y,label_align align); //--- 创建按钮 bool CreateButton(const long chart,const int subwindow,CButton &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size); //--- 创建编辑对象 bool CreateEdit(const long chart,const int subwindow,CEdit &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size); //--- 事件功能 void LotsEndEdit(void); // 编辑地块大小 //--- 当前值的变量 double cur_lot; // 下一个订单的批量 void BuyClick(); // 点击购买按钮 void SellClick(); // 点击销售按钮 void CloseClick(); // 点击关闭按钮 public: CTradePanel(void){}; ~CTradePanel(void){}; virtual bool Create(const long chart,const string name,const int subwin=0,const int x1=20,const int y1=20,const int x2=320,const int y2=420); virtual bool OnEvent(const int id,const long &lparam,const double &dparam,const string &sparam); virtual void Destroy(const int reason); }; CTradePanel TradePanel; //+------------------------------------------------------------------+ //| 专家初始化函数| //+------------------------------------------------------------------+ int OnInit() { //--- // 创建贸易面板 TradePanel.Create(ChartID(),"Panelka",0,20,20,150,200); //--- return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| 专家去初始化函数| //+------------------------------------------------------------------+ void OnDeinit(const int reason) { TradePanel.Destroy(reason); } //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ bool CTradePanel::CreateLabel(const long chart,const int subwindow,CLabel &object,const string text,const uint x,const uint y,label_align align) { // 所有对象都必须有单独的名称 string name=m_name+"Label"+(string)ObjectsTotal(chart,-1,OBJ_LABEL); //--- 调用创建函数 if(!object.Create(chart,name,subwindow,x,y,0,0)) { return false; } //--- 调整文本 if(!object.Text(text)) { return false; } //--- 将文本对齐对话框的网格 ObjectSetInteger(chart,object.Name(),OBJPROP_ANCHOR,(align==left ? ANCHOR_LEFT_UPPER :(align==right ? ANCHOR_RIGHT_UPPER : ANCHOR_UPPER))); //--- 为控件添加对象 if(!Add(object)) { return false; } return true; } //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ bool CTradePanel::CreateButton(const long chart,const int subwindow,CButton &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size) { // 所有对象都必须有单独的名称 string name=m_name+"Button"+(string)ObjectsTotal(chart,-1,OBJ_BUTTON); //--- 调用创建函数 if(!object.Create(chart,name,subwindow,x,y,x+x_size,y+y_size)) { return false; } //--- 调整文本 if(!object.Text(text)) { return false; } //--- 设置按钮标志为解锁 object.Locking(false); //--- 将按钮标志设置为未按下 if(!object.Pressed(false)) { return false; } //--- 为控件添加对象 if(!Add(object)) { return false; } return true; } //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ bool CTradePanel::CreateEdit(const long chart,const int subwindow,CEdit &object,const string text,const uint x,const uint y,const uint x_size,const uint y_size) { // 所有对象都必须有单独的名称 string name=m_name+"Edit"+(string)ObjectsTotal(chart,-1,OBJ_EDIT); //--- 调用创建函数 if(!object.Create(chart,name,subwindow,x,y,x+x_size,y+y_size)) { return false; } //--- 调整文本 if(!object.Text(text)) { return false; } //--- 对齐编辑框中的文本 if(!object.TextAlign(ALIGN_CENTER)) { return false; } //--- 将只读标记设为 false if(!object.ReadOnly(false)) { return false; } //--- 为控件添加对象 if(!Add(object)) { return false; } return true; } //+------------------------------------------------------------------+ //|| //+------------------------------------------------------------------+ bool CTradePanel::Create(const long chart,const string name,const int subwin=0,const int x1=20,const int y1=20,const int x2=320,const int y2=420) { // 首次调用父类的创建函数 CAppDialog::Create(chart,name,subwin,x1,y1,x2,y2); // 计算 BID 对象的坐标和大小 // 创建对象 CreateLabel(chart,subwin,Lots_label,"LOT",55,5,0); CreateEdit(chart,subwin,Lots,"0.1",33,35,60,20); CreateButton(chart,subwin,BUY,"BUY",33,65,60,20); CreateButton(chart,subwin,SELL,"SELL",33,95,60,20); CreateButton(chart,subwin,CloseAll,"CLOSE",33,125,60,20); return(true); } //+------------------------------------------------------------------+ //| 事件处理| //+------------------------------------------------------------------+ EVENT_MAP_BEGIN(CTradePanel) ON_EVENT(ON_END_EDIT,Lots,LotsEndEdit) ON_EVENT(ON_CLICK,BUY,BuyClick) ON_EVENT(ON_CLICK,SELL,SellClick) ON_EVENT(ON_CLICK,CloseAll,CloseClick) EVENT_MAP_END(CAppDialog) //+------------------------------------------------------------------+ //| 点击购买按钮| //+------------------------------------------------------------------+ void CTradePanel::BuyClick(void) { PutOrder(0,Ask); } //+------------------------------------------------------------------+ //| 点击购买按钮| //+------------------------------------------------------------------+ void CTradePanel::SellClick(void) { PutOrder(1,Bid); } //+------------------------------------------------------------------+ //| 点击购买按钮| //+------------------------------------------------------------------+ void CTradePanel::CloseClick(void) { CloseAll(); } //+------------------------------------------------------------------+ //| 编辑后读取地段值| //+------------------------------------------------------------------+ void CTradePanel::LotsEndEdit(void) { //--- 读取地段值并将其标准化 cur_lot=NormalizeDouble(StringToDouble(Lots.Text()),2); } //+------------------------------------------------------------------+ //| 应用程序去初始化功能 //+------------------------------------------------------------------+ void CTradePanel::Destroy(const int reason) { CAppDialog::Destroy(reason); return; } //+------------------------------------------------------------------+ //| 设置订单| //+------------------------------------------------------------------+ void PutOrder(int type,double price) { int r=0; color clr=Green; double sl=0,tp=0; if(type==1 || type==3 || type==5) { clr=Red; if(StopLoss>0) sl=NormalizeDouble(price+StopLoss*Point,Digits); if(TakeProfit>0) tp=NormalizeDouble(price-TakeProfit*Point,Digits); } if(type==0 || type==2 || type==4) { clr=Blue; if(StopLoss>0) sl=NormalizeDouble(price-StopLoss*Point,Digits); if(TakeProfit>0) tp=NormalizeDouble(price+TakeProfit*Point,Digits); } r=OrderSend(NULL,type,Lot,NormalizeDouble(price,Digits),Slip,sl,tp,"",Magic,0,clr); return; } //+------------------------------------------------------------------+ //| 按订单类型关闭仓位| //+------------------------------------------------------------------+ void CloseAll(int ot=-1) { bool cl; for(int i=OrdersTotal()-1;i>=0;i--) { if(OrderSelect(i,SELECT_BY_POS,MODE_TRADES)) { if(OrderSymbol()==Symbol() && OrderMagicNumber()==Magic) { if(OrderType()==0 && (ot==0 || ot==-1)) { RefreshRates(); cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Bid,Digits),Slip,White); } if(OrderType()==1 && (ot==1 || ot==-1)) { RefreshRates(); cl=OrderClose(OrderTicket(),OrderLots(),NormalizeDouble(Ask,Digits),Slip,White); } } } } } //+------------------------------------------------------------------+ //| 专家勾选功能| //+------------------------------------------------------------------+ void OnTick() { //--- } //+------------------------------------------------------------------+ //| 图表事件函数| //+------------------------------------------------------------------+ void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { //--- TradePanel.OnEvent(id,lparam,dparam,sparam); } //+------------------------------------------------------------------+
Andrew Kornishkin:
德米特里,今天我开始按照你的教程在 µl 4 上制作一个面板。几乎一切正常,但当点击面板或任何按钮时,却只能打开 "购买"。这是什么原因呢?
晚安,安德鲁。
你在课程描述中做的一切都很正确。你唯一的错误是在创建 交易面板类后 的 OnInit 函数中没有使用 Run 函数开始执行。
int OnInit() { //--- // 创建贸易面板 TradePanel.Create(ChartID(),"Panelka",0,20,20,150,200); TradePanel.Run(); //--- return(INIT_SUCCEEDED); }
谢谢、
德米特里
我下载了您的交易面板到 metatrader,但它不能用。这太糟糕了。
19681:
我将您的交易面板下载到了 metatrader 上,但它不起作用。真遗憾。
它是如何表现出来的?我将您的交易面板下载到了 metatrader 上,但它不起作用。真遗憾。
为了使面板和其他交易程序一样正常工作,必须在终端中激活自动交易功能。
Dmitriy Gizlyk:
它的表现形式是什么? 要使面板发挥作用,就像其他交易程序一样,必须在终端中激活自动交易功能。
自动交易当然已启用。它表现为按钮不起作用(当您点击卖出或买入时,会出现 "未结买入订单错误")。
它的表现形式是什么? 要使面板发挥作用,就像其他交易程序一样,必须在终端中激活自动交易功能。
新文章 创建一个人工交易助手已发布:
近来,货币市场上的交易机器人已经大幅增加,它们执行着各种各样的策略和概念,然而,它们还都没有能够成功创造人工智能双赢、多赢的实例,所以,很多交易者还是进行人工交易。但是,即使对于这样的专家,还是可以为他们创建被称为机器人助手的交易面板。本文就是从头开始创建交易面板的一个实例。
让我们使用一个新的页面,并在其中绘制我们未来的面板,把所有所需软件放置其中。
当进行交易面板的设计开发时,应该考虑实现的可行性。首先,交易面板应该包含足够的信息,容易阅读并不包括多余的元件,我们应该永远记住它不只是屏幕上一幅好看的图片,而是交易者的基本工具,
这是我的版本。
作者:Dmitriy Gizlyk