文章 "在 MetaTrader 5 中实施多货币模式" - 页 5

 
Lazarev:

请告诉我

1. 如果我只需要其他货币的买入价和卖出价,使用 "间谍 "是否公平?

2. 这只是一个想法,在onChartEvent 函数 中是否不能检查其他货币的事件,而不仅仅是当前货币的事件?

3. 是否有可能在 onTimer 事件中将定时器值设置为小于 1,这样就能更频繁地下载报价值,并相应地以最小时间滞后于最后一次跳动的时间?

4. 在我的情况下,是否可以使用 "CHARTEVENT_CUSTOM+n "来检查其他图表上的交叉点?

1.使用。

2.有一个选项。来自其他货币的事件应发送到设置了 OnChartEvent() 的 EA 所在的图表。

3.否。

4.可以。

 

我创建了一个简单的 "间谍指标 "SendEvent.mq5,当有新的报价到达时,它会发送一个事件:

#property indicator_chart_window
#property indicator_plots 0
int OnInit()
  {
   return(0);
  }

int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   EventChartCustom(0,1,0,0,_Symbol);
   return(rates_total);
  }

我创建了一个简单的 "智能交易系统"(Expert Advisor),它可以接收来自该指标的事件并尝试进行交易操作(以下是部分内容,全文见附件):

void OnChartEvent(const int id, // 图表事件处理程序
                  const long &lparam,
                  const double &dparam,
                  const string &sparam)            // sparam 包含仪器名称
  {
      // 申请发生事件的金融工具的位数、点数、卖出价和买入价
      if(!SymbolInfoInteger(sparam,SYMBOL_DIGITS,dig)) Print("SymbolInfoInteger(SYMBOL_DIGITS) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_POINT,p)) Print("SymbolInfoDouble(SYMBOL_POINT) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_BID,Bid)) Print("SymbolInfoDouble(SYMBOL_BID) ERROR!");
      if(!SymbolInfoDouble(sparam,SYMBOL_ASK,Ask)) Print("SymbolInfoDouble(SYMBOL_ASK) ERROR!");
      d=(int)dig;
      if(1>0) // 我们总是购买
        {
         q.action=TRADE_ACTION_DEAL; // 填充 MqlTradeRequest 结构并尝试进行交易操作
         q.symbol=sparam; // sparam 包含工具名称
         q.volume=Lot;
         q.price=NormalizeDouble(Ask,d);
         q.sl=NormalizeDouble(Ask-p*StopLoss,d);
         q.tp=NormalizeDouble(Ask+p*TakeProfit,d);
         q.deviation=0;
         q.type=ORDER_TYPE_BUY;
         q.type_filling=ORDER_FILLING_FOK;
         // 检查当前工具属性
         Print("Bid=",DoubleToString(Bid,8),", Ask=",DoubleToString(Ask,8),", Digits=",d,", Points=",DoubleToString(p,8));
         // 检查我们将发送的交易请求的结构
         Print("q.action=",q.action,", q.symbol=",q.symbol,", q.volume=",q.volume,", q.price=",DoubleToString(q.price,d),", q.sl=",DoubleToString(q.sl,d),", q.tp=",DoubleToString(q.tp,d),", q.deviation=",q.deviation,", q.type=",q.type,", q.type_filling=",q.type_filling);
         Print(OrderCheck(q,ch));                                  // 检查是否可以执行交易操作
         Print("ch.retcode=",ch.retcode,", ch.comment=",ch.comment); // 结果
         Print("OrderSend:",OrderSend(q,s));                        // 尝试进行交易操作
         Print("s.retcode=",s.retcode,", s.comment=",s.comment);     // 结果
        }
      if(0>0) // 如果条件得到纠正,我们将出售
        {
         // аналогично для продажи
        }
     }
  }

智能交易系统从指标接收事件,但在测试器中(有可视化和无可视化)无法执行交易操作--返回错误 "无效请求",返回代码为 10013。而在实时状态下则正常运行。如果在智能交易系统中通过 OnTick() 而不是 OnChartEvent() 执行交易操作,也可以正常工作。

我将发送交易请求插入了文章作者在 CodeBase 中提供的Expert Advisor 模板 中,但交易操作也不起作用(同样的错误)。

谁能告诉我原因是什么?我在这个主题中读到, OnChartEvent() 在测试器中不处理,但在这种情况下,指标发送的事件在测试器中被处理,但在测试器中无法通过OnChartEvent() 执行交易操作。

附加的文件:
ea.mq5  4 kb
SendEvent.mq5  1 kb
 
zdd:

我创建了一个简单的 "指标-间谍 "SendEvent.mq5,当有新的报价到达时,它会发送一个事件:

创建了一个简单的 "智能交易系统"(Expert Advisor),用于接收来自该指标的事件并尝试进行交易操作(我提供了其中的一部分,全文见附件):

智能交易系统从指标接收事件,但在测试器中(有可视化和无可视化)无法执行交易操作--返回错误 "无效请求",返回代码为 10013。而在实时状态下则正常运行。如果在 Expert Advisor 中通过 OnTick() 而不是 OnChartEvent() 执行交易操作,也可以正常运行。

我将发送交易请求插入了文章作者在 CodeBase 中提供的Expert Advisor 模板 中 - 交易操作也不起作用(同样的错误)。

谁能告诉我原因是什么?我在这个主题中读到, OnChartEvent() 在测试器中不处理,但在这种情况下,指标发送的事件在测试器中被处理,但在测试器中不可能通过OnChartEvent() 执行交易操作。

试着把我的鱼带到我的脑海中。当然,这个逻辑并不完整,而且非常愚蠢,但似乎与您的需求非常相似。

至少在测试版和演示版中,市场上的头寸都会打开。

我不知道为什么(我懒得去想),但你的例子让我在任何情况下都能得到 10013。

PS

最好绑定到标准对象(如 CAccountInfo 和 CTrade)。但如果您有耐心自己编写一切,我会很高兴的。

顺便说一下,间谍本身的实现最好从文章中获取,或者制作一个可修改的副本(例如,我建议将"(long)_Period " 改为发送事件的日期时间或其他有用信息)。您的变体在某种程度上相当 "原始"。

附加的文件:
DemoEA.mq5  20 kb
 
Interesting:

看看能否让我的鱼发挥作用。虽然逻辑不完整,也很晦涩,但似乎与你需要的非常相似。

谢谢,明白了。如果在全局级别 声明MqlTradeRequestMqlTradeResult 结构,就可以正常工作!
 
非常感谢你的文章!
 

我试图获取 EURUSD、EURGBP 和 GBPUSD 三种货币对的价格。在策略测试器中 选择 "所有刻度线 "或 "仅开盘价 "时,一切正常。但如果我选择 "基于真实刻度线的每个刻度线",那么出于某种原因,一个交易品种在一分钟内会出现多个 "新条形图 "事件。

下面是一个日志示例,请注意第 7 分钟和第 9 分钟:

2016.07.15 00:05:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333

2016.07.15 00:05:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.1119

2016.07.15 00:05:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33399

2016.07.15 00:06:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8334

2016.07.15 00:06:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.1119

2016.07.15 00:06:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33394

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33382

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33381

2016.07.15 00:07:19 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.8333700000000001

2016.07.15 00:07:19 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11174

2016.07.15 00:07:19 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33384

2016.07.15 00:08:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83329

2016.07.15 00:08:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11167

2016.07.15 00:08:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33394

2016.07.15 00:09:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83327

2016.07.15 00:09:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11166

2016.07.15 00:09:00 >  -> id=1:  GBPUSD CHARTEVENT_NEWBAR_M1 price=1.33396

2016.07.15 00:09:00 >  -> id=2:  EURGBP CHARTEVENT_NEWBAR_M1 price=0.83327

2016.07.15 00:09:00 >  -> id=0:  EURUSD CHARTEVENT_NEWBAR_M1 price=1.11166

选择 "基于真实刻度的所有刻度 "模式时,出现这种行为的原因是什么?
 
ooparadise:

我试图获取 EURUSD、EURGBP 和 GBPUSD 三种货币对的价格。在策略测试器中 选择 "所有刻度 "或 "仅开盘价 "时,一切正常。但如果我选择 "基于真实刻度线的每个刻度线",那么出于某种原因,一个工具在一分钟内会出现多个 "新条 "事件。

下面是一个日志示例,请注意第 7 分钟和第 9 分钟:

选择 "基于真实刻度的所有刻度 "模式时,出现这种行为的原因是什么?

如何捕捉 "新条形图 "事件?在第 1375 版中,刻度到达的精确度已提高到毫秒级:

测试器:支持时间精确到毫秒。

  • 事件设置毫秒计时器(EventSetMillisecondTimer)和睡眠(Sleep)函数现在可在策略测试器中更精确地工作。
  • 测试多货币智能交易系统时提交刻度的准确性提高了。以前,如果在一秒内放置多个刻度线(一分钟条形图的刻度线量超过 60 个),所有刻度线都会被分配到相同的时间。在测试单货币智能交易系统时,这并不重要,因为刻度点只是按顺序传递给智能交易系统。但是,在对多个货币对进行测试时,必须知道哪个货币对的刻度点在先。以前,每个符号的刻度都是按顺序传送给智能交易系统的:先是一个符号的所有刻度,然后是另一个符号的所有刻度。

    在对真实刻度线进行测试时,毫秒取自原始刻度线数据。在生成刻度线时,毫秒是根据刻度线量来计算的。例如,如果一秒钟内有 3 个刻度线,它们将被分配为 000、333 和 666 毫秒。
 

我按照文章中的方式捕捉新的条形图。也就是说,指标以这种方式发送 "新栏 "事件(与之前的分钟、小时、天、月相比):

   double price_current=price[rates_total-1];

   TimeCurrent(time);

   if(prev_calculated==0)

     {

      EventCustom(CHARTEVENT_INIT,price_current);

      prev_time=time; 

      return(rates_total);

     }

//--- new tick

   if((flag_event & CHARTEVENT_TICK)!=0) EventCustom(CHARTEVENT_TICK,price_current);       


//--- check change time

   if(time.min==prev_time.min && 

      time.hour==prev_time.hour && 

      time.day==prev_time.day &&

      time.mon==prev_time.mon) return(rates_total);


//--- new minute

   if((flag_event & CHARTEVENT_NEWBAR_M1)!=0) EventCustom(CHARTEVENT_NEWBAR_M1,price_current); 

更新:安装第 1375 版后,问题消失了。

 

感谢您提供这篇大文章。到目前为止,我还没听说过 EventChartCustom。我曾尝试过其他图表事件,但它们只考虑人为操作引起的事件。它解决了很多问题。

顺便说一下,我在 MQL4 上工作,98% 的情况都是一样的。

干杯

 

非常感谢你提供的信息,它非常有用。干得好