初学者的问题 MQL5 MT5 MetaTrader 5 - 页 984

 
Ihor Herasko:


但事实是。睡眠不应影响指标中数据的重新计算。缓冲区的填充有问题。也许有一段可重复的代码?

该指标是按顺序写的--这是一个疯狂的OOP,我不明白:(

我在这个问题上花了一整夜的时间,而我找到了测试者和真实账户 之间的分歧的原因,也许在睡觉之后,我将删除一些秘密的逻辑,并张贴出来供人审查。

 
Aleksey Vyazmikin:

我面临一个问题,基于指标的EA在真实账户上工作正常,但它在测试器中是躺着的,在按OHLC和按所有ticks的tick生成模式 下,结果是一样的。错误的结果是指标在零点的缓冲区是空的(只有当上层TF有一个新的柱子,用于计算指标的时候)。但是,我已经设法通过在我的专家顾问中添加睡眠来使指标得到计算。 但是我发现,根据生成ticks的模式,这个睡眠应该是不同的--对于从所有ticks产生的睡眠(15000)就足够了,而对于OHLC需要睡眠(30000)。

那么问题来了--睡眠的情况是否正常,因为从逻辑上看,不同的延迟时间是根据刻度线生成的模式来模拟的!这就是为什么我们要把睡眠的情况作为一个例子。

亲爱的开发者,请解释一下指标的情况,因为我自己也不明白是什么原因--是代码中的错误还是测试人员的错误!

我准备在PM中给你指标和专家顾问,但请告诉我给谁。

如果你想把价格复制到一个数组中,你必须检查历史记录是否可用,并检查价格是否没有变化。为此,我们必须检查TF的历史记录是否可用,如果没有,我们应该尝试再次复制它,并等待它被载入循环中。

这是程序员的坏手,如果他不知道的话。

滑倒是不正常的
 
void OnChartEvent(            const int id,        // идентификатор события   
                              const long& lparam,  // параметр события типа long 
                              const double& dparam,// параметр события типа double 
                              const string& sparam // параметр события типа string 
                              )
   {
   Print(My_Name, " ---  ", id, "    lparam = ", lparam, "    dparam = ", dparam, "    sparam = ", sparam, "    ChartID() = ", ChartID() );        // <<|+|+|+<<  // 

   }                              

请解释...

我按下键 = 我得到事件ID = 0。这可以重复许多次。只要不按空格键,其结果是一样的。

按下空格键=我得到的事件ID=0。此后,在键盘上的所有操作都不会产生任何事件。

为了摆脱昏迷,我按下鼠标按钮=我得到的事件ID=4。之后,你可以再次点击键盘=每一次点击都有事件发生。只要不按空格键=,结果一样。

问题:我是个傻瓜,不明白什么,还是不应该这样?请提供一个链接。

 
Nikita Chernyshov:

同事们好。

问: 在mql4中,为了计算位置的数量,你可以这样写函数

它在mql5中是如何实现的?我怎样才能按神奇的数字或类型来计算位置?

在MQL4-函数前添加这一行

#include <MT4Orders.mqh> // https://www.mql5.com/ru/code/16006

并能在MT5中工作。

 
Maxim Dmitrievsky:

指标的问题是,时间序列可能还没有准备好,也就是说,它不能一下子把价格复制到数组中。为此,我们应该检查TF的历史记录是否可用,如果没有,我们应该尝试再次复制它,并等待它被载入循环中。

如果程序员不知道这一点,这是他/她的坏手。

溜号是不行的

在测试器中,这怎么可能呢?我明白,如果问题出现在真实的或测试器中,就没有历史...然而,这个测试应该是什么样子的?

开发人员无视我的信息,很不幸。

 
Aleksey Vyazmikin:

在测试器中,这怎么可能呢?我明白,如果问题是在真实的或在测试器中,那里没有历史。然而,这个测试应该是什么样子的?

开发人员无视我的信息,很不幸。

检查价格是否被复制,如果Copyclose 或其他什么返回-1,那么价格就没有被复制。

 
Maxim Dmitrievsky:

检查价格是否被复制,如果Copyclose或其他什么东西返回-1,那么它们就没有被复制。

该指标在一个新条形图出现时计算一次,如果我理解正确的话,是以这种方式实现的。

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
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[])
  {
   static int counted_bars=0;
   if(rates_total==prev_calculated) return(rates_total);

它也被一个简单的印刷品所证实。

这就是为什么情况不清楚,如果我们假设没有价格需要计算,那么指标 将被计算 1次,缓冲区将保持未填充状态,但事实并非如此--如果我们向EA添加睡眠并等待,它将填充。也许,指标的计算速度很慢,而测试者只是没有等到它?但如何检查呢?

 
Aleksey Vyazmikin:

该指标在新条形图出现时计算1次,如果我理解正确的话,是以这种方式实现的。

这也被一个简单的印刷品所证实。

这就是为什么情况不清楚,如果我们假设没有价格需要计算,那么指标 将被计算 一次,而缓冲区将保持未填充状态,但情况并非如此--如果我们向EA添加睡眠并等待,它将被填充。也许,指标的计算速度很慢,而测试者只是没有等到它?但如何检查呢?

也许那时应该计时

 
Maxim Dmitrievsky:

也许我们应该使用计时器,然后。

是的,在EA中使用定时器,测试比不使用定时器时更进一步,但比使用"睡眠"时更糟,而定时器基本上与 "睡眠 "相同。

我想我明白了问题所在,指标是用另外两个指标的数据计算的,代码要求提供其他指标的计算条数。

//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
int CChannel::BarsCalculated(void)
  {
   int upchbars=BarsCalculated(m_upch);
   int dnchbars=BarsCalculated(m_dnch);
   if(upchbars<=dnchbars) return(upchbars);
   return(dnchbars);
  }

和预期计算的条数

int barsch=(InpChPeriod==PERIOD_CURRENT?rates_total:Bars(_Symbol,InpChPeriod));

如果这两个值不一致,缓冲区就不会被填充。

   if(!channel.CreateChannel() || barsch<=0 || barsch!=channel.BarsCalculated() || channel.FillChBuffers(rates_total,calculated,time)==0)
     {
      for(;counted_bars<rates_total;counted_bars++)
        {
         ZigzagBuffer[counted_bars]=0.0;
         ZigzagStepBuffer[counted_bars]=0.0;
         UpChBuffer[counted_bars]=0.0;
         DnChBuffer[counted_bars]=0.0;
         InfoZigzagBuffer[counted_bars]=0.0;
         InfoUpChBuffer[counted_bars]=0.0;
         InfoDnChBuffer[counted_bars]=0.0;
         InfoDirectBuffer[counted_bars]=0.0;
         InfoBegPriceBuffer[counted_bars]=0.0;
         InfoEndPriceBuffer[counted_bars]=0.0;
         InfoBegTimeBuffer[counted_bars]=0.0;
         InfoEndTimeBuffer[counted_bars]=0.0;
         InfoStartPriceBuffer[counted_bars]=0.0;
         InfoStartTimeBuffer[counted_bars]=0.0;
         InfoZigzagTotal[counted_bars]=InfoZigzagTotal[counted_bars-1];
        }
      if(InpInfEnd) CopyInfoBuffers(rates_total-1,(int)InfoZigzagTotal[rates_total-1]);
      return(calculated);
     }

如果我理解正确的话,指标是在一个线程中执行的,它们的优先级是按创建时间分配的,也就是说,事实证明,我从EA中找到的指标具有较高的优先级,并首先执行其计算,之后它将线程传递给那些应该执行计算的指标(基于缓冲区的数据)。

在打印中我们可以看到,如果我设置了足够大的睡眠,在指标中就会进行重新计算(我还不明白是如何进行的),为什么只在13秒后进行?

2019.01.22 19:50:16.992 2019.01.21 23:45:00   barsch=6275
2019.01.22 19:50:16.992 2019.01.21 23:45:00   BarsCalculated=6274

2019.01.22 19:50:16.993 2019.01.21 23:45:13   barsch=6275
2019.01.22 19:50:16.993 2019.01.21 23:45:13   BarsCalculated=6275

指示器中没有计时器。

我应该怎么做才能得到正确的计算,在等待缓冲区中的值之前,试图在EA中使用while也没有用--挂起。

 
你好,我想在我的EA中实现一个带步骤的追踪止损。除了Kodobase和Macd Sample中的模板外,我找不到其他东西。也许还有其他选择?