mql5语言的特点、微妙之处以及技巧 - 页 31

 
阿尔乔姆-特里什金

你甚至看了我给你看的代码吗?你运行它了吗?

我不是问如何填充指标缓冲区,而是问为什么如果我从AO中取值而不是从当前条形图中取值,会返回空值。
我明白了--没有历史记录,正在加载,当它从一个非本地时间框架加载AO时,返回错误 "没有数据"。

我想检查历史记录是否已经完全加载,以便不进入指标循环。

如果 在指标中使用CopyBuffer 来接收另一个指标的数据,你需要。

  1. 翻转你的指标缓冲区,使图表上最右边的条形图与指标缓冲区的索引 "0 "相对应。
  2. 因此,"iMTF_AO.mq5 "指标中的 "当前栏 "将是图表中最右边的栏,它将对应于指标缓冲区 "Buffer[]"中的索引 "0"。
  3. 而要从指标(CopyBuffer(handle,0,shift,1,array))中获得 "当前栏","shift "参数必须等于 "0"。

如果你不想翻转指标缓冲区,可以这样做(暂时):AO(0) - 了解如何从一个INDICATOR中获取另一个指标的值。你可能会出现一两次错误,但那是在建立时间序列之前,然后数值会很稳定。

 
阿尔乔姆-特里什金
你看到我的答案了吗?你试过吗?
 
弗拉基米尔-卡尔普托夫

如果 在一个指标中使用CopyBuffer 来检索另一个指标的数据,你应该。

  1. 反转你的指标缓冲区,使图表中最右边的柱子与指标缓冲区中的索引 "0 "相对应。
  2. 因此,"iMTF_AO.mq5 "指标中的 "当前栏 "将是图表中最右边的栏,它将对应于指标缓冲区 "Buffer[]"中的索引 "0"。
  3. 而要从指标(CopyBuffer(handle,0,shift,1,array))中获得 "当前栏","shift "参数必须等于 "0"。

如果你不想翻转指标缓冲区,可以这样做(暂时):AO(0) - 了解如何从一个INDICATOR中获取另一个指标的值。你可能会出现一两次错误--但那是在建立一个时间序列之前,然后数值会很稳定。

1.我的代码,而且马上就有了。

   ArraySetAsSeries(Buffer,true);
   int bars=Bars(NULL,PeriodForWork);
   datetime time_limit=GetTime(Symbol(),PeriodForWork,bars-1);
   int limit_p=GetBarShift(Symbol(),Period(),time_limit);
   if(rates_total<1) return(0);

2.确实如此。

3.移位等于周期指数i。循环从历史数据的开始(rate_total-1)到结束(到当前数据)。

另一个问题是,我们应该相对于一个非本土的TF来计算这个数据,以避免从缺失的条形图中得到数据。而且我们需要在周期之前确定所需的TF的历史是完全同步的。

 
阿尔乔姆-特里什金

1.我的代码,而且马上就有了。

2.它是它的方式。

3.移位等于周期指数i。循环从历史数据的开始(rate_total-1)到结束(到当前数据)。

另一个问题是,我们需要结合非本地的时间框架来计算这个数据,这样我们就不会从缺失的条形图中获得数据。而且我们应该在循环之前确定所需时间段的历史是完全同步的。


重做调用AO的循环:把从 "0 "到某个值(现在从某个值到0)。当错误发生时 - 一次性比较:计算的条数("limit_p")和当前指标的比率_总数。


补充:在这里,这些线条抹去了所有计算 "极限 "的努力(如果我们指的是非本地的时间框架)。

   if(limit>1) 
     {
      limit=rates_total-1;
     }

粗略地说,一开始(当访问一个非本地的时间框架时),"limit "等于156,但低于BACK!,"limit "就变成了 "1545666666"。



 
阿列克谢-科齐岑
你是否尝试过同步化?另外,开发者建议通过计时器保持所需的TF/符号的数据的有效性。

不,我还没有试过。我已经看到关于数据相关性的支持,我记得--我知道。

但最初,如果指定时间段的数据和当前时间段的数据还没有同步,就有必要退出OnCalculate()。

我理解当前的情况。

if(rates_total<1) return(0);

关于给定--有必要检查其Bars()--它们的数量而不是 rates_total。

但我不知道限制 - 它可以在当前时间框架上检查(以另一个指标为例)。

   int limit=rates_total-prev_calculated;
   if(limit>1) {
      limit=rates_total-4;
      ArrayInitialize(BufferAoDN,EMPTY_VALUE);
      ArrayInitialize(BufferAoUP,EMPTY_VALUE);
      ArrayInitialize(BufferMacdDN,EMPTY_VALUE);
      ArrayInitialize(BufferMacdUP,EMPTY_VALUE);
      ArrayInitialize(BufferRsiDN,EMPTY_VALUE);
      ArrayInitialize(BufferRsiUP,EMPTY_VALUE);
      ArrayInitialize(BufferStochDN,EMPTY_VALUE);
      ArrayInitialize(BufferStochUP,EMPTY_VALUE);
      }

但在这个测试指标中,我们既从当前时间段(它在OnCalculate()中显示了计算结果)又从指定时间段获得数据--从指定时间段获得AO数据。

我仍然不记得如何计算条数 的所有必要数据--因为循环应该从与历史条的时间相对应的条开始,其中有当前或指定条的第一个现有数据--如果它较少--从该条开始循环。极限也应该被正确计算,以检测一个新条形的出现,这应该导致完全重新计算或只重新计算当前条形(取决于发生了什么--新条形的打开或历史加载)。

也许,我想一下子把所有的事情都想好了,我想了很多不必要的事情......。

 
弗拉基米尔-卡尔普托夫


重做循环调用AO:从 "0 "到某个值(现在从某个值到0)。当错误发生时 - 一次性比较:计算的条数("limit_p")和当前指标的比率_总数。


补充说:而这些线条抹去了计算的 "极限 "的所有努力(如果指的是一个非本地的时间框架)

大致说来,一开始(在处理非本地时间段时),"limit "变成了156,而在BATCH下面!而 "limit "已经变成了 "1545666666"

是的,我马上写到,我在这里匆匆忙忙地搞砸了。

但我不会改变循环--有一个相当复杂的指标,其中一切都建立在从头到尾的历史计算上--重新计算限制和获得数据比重写整个指标--其所有的逻辑更容易。

 
Artyom Trishkin:

不,我还没有试过。我已经看到关于数据相关性的支持,我记得--我知道。

但最初,如果指定时间段的数据和当前时间段的数据还没有同步,就有必要退出OnCalculate()。

目前的情况很清楚。

这不完全是这样。当你最初用指示器加载终端时,你可能得到的不是你期望的结果。在白天,如果有连接中断--也可能有错误。

关于OnCalculate()的退出 第一个请求Bars()应该在初始化阶段完成,然后在OnCalculate()中检查当前和必要的TF的同步情况。如果没有同步,请离开。

 
阿尔乔姆-特里什金

是的,这就是我马上说的,我匆忙中搞砸了。

我不想改变循环,有一个相当复杂的指标,它是基于从头到尾 的历史计算 - 重新计算限制和正确接收数据,比重写整个指标 - 所有的逻辑更容易。

Artem,你说 "从头到尾 "是什么意思?

你认为翻转所有数组是最好的出路吗?

为什么?

ArraySetAsSeries(Buffer,true);

如果你只复制一个值?

当复制除当前TF以外的其他TF时,最好将需要的条形图的时间传递给CopyBuffer()函数。否则,它将不会复制你想要的酒吧。

 
阿列克谢-维克多罗夫

1、Artyom,你说的 "从头到尾 "是什么意思?

2.你认为翻转所有数组是最好的出路吗?

3.为什么?

4.如果你只复制1个值?

当把所需的条形图的时间复制到不是当前时间段的函数CopyBuffer() 时,最好是将其传递。否则,它将不会复制你想要的酒吧。

1.历史数据的起点是历史上第一个开盘时间最短的柱子,历史数据的终点是当前柱子。

2.我从4分抄到了5分。

嗯,因为在Buffer[]中,数据是以循环方式从rate_total-1写到0的。如果我们不把它作为一个时间序列,它将在图表上前后显示。

4.我想在某一时刻复制一个值,该值对应于给定时间框架的第i条的数据。

看看在mql4中获得非当前时间段的数据是多么的简洁和容易。我想知道怎么可能在mql5中接收指标数据而不工作--如果我在接收AO数据的功能中传递与指标工作的图表时间段不一致的时间段,总是出现4806错误。

//+------------------------------------------------------------------+
double GetDataAO(string sy, int timeframe, int shift) {
   double array[1];
   ZeroMemory(array);
#ifdef __MQL4__
   array[0]=iAO(sy,timeframe,shift);
#else 
   ResetLastError();
   if(CopyBuffer(handle_ao,0,shift,1,array)==WRONG_VALUE) {
      Print(__FUNCTION__," > Error: ",GetLastError());
      return(0);
      }
#endif 
   return(array[0]);
}
//+------------------------------------------------------------------+

同时,在OnInit()中创建了指标句柄,与我们想要接收数据的当前价格相对应。

handle_ao=iAO(symbol,periodForWork);

也就是说,在任何时候,无论我们如何切换f,都会用必要的(在设置中选择的)f创建手柄。但只有当设置中的选定函数和当前函数一致时,才能获得AO数据。如果它们不重合,那么从函数中返回的总是零。

问题是:为什么?

 
阿尔乔姆-特里什金

1.历史数据的起点是历史上第一个开盘时间最短的柱子,历史数据的终点是当前柱子。

2.我正在从四条改写成五条。

嗯,因为在Buffer[]中,数据是以循环方式从rate_total-1写到0的。如果我们不把它作为一个时间序列,它将在图表上前后显示。

4.我每次复制一个与给定时间框架的第i条数据相对应的值。

看看在mql4中获得不是currentfactor的数据是多么的简洁和容易;它是成功的,一切都按计划进行。我想知道怎么可能在mql5中接收指标数据而不工作--如果我在接收AO数据的功能中传递与指标工作的图表时间段不一致的时间段,总是出现4806错误。

同时,在OnInit()中创建了指标句柄,与我们想要接收数据的当前价格相对应。

也就是说,在任何时候,无论我们如何切换f,都会用必要的(在设置中选择的)f创建手柄。但只有当设置中的选定函数和当前函数一致时,才能获得AO数据。如果它们不匹配,函数总是返回0。

问题是:为什么?

1.只是澄清一下。现在我明白了,我们说的是同一件事。

我理解,但我不同意有必要反转数组。是否有必要为两个终端配备一个指标?几乎是把镰刀和斧头合二为一。

3.据我所知,Buffer[]在函数CopyBuffer() 中被接收器使用,只获得一个指标值。

4.你没有注意到最重要的事情。拷贝指标值的开始不应该由条形指数决定,而是由第i个条形的时间决定。

int  CopyBuffer( 
   int       indicator_handle,     // handle индикатора 
   int       buffer_num,           // номер буфера индикатора 
   datetime  start_time,           // с какой даты 
   int       count,                // сколько копируем 
   double    buffer[]              // массив, куда будут скопированы данные 
   );