iMA() 参数 shift=-3 在 设置为"INDICATOR_DATA"的buffer上,结果怎么与参数 shift=3 的数组array相同?

 

今天做项目刚好遇到这个情况,难道是系统错误?

代码如下:

//--- indicator settings
#property indicator_buffers 2

//--- indicator buffers
double Buffer0[], Buffer1[];
double Array0[], Array1[];

//--- handles for MAs
int    Buffer_Handle0, Buffer_Handle1;
int    Array_Handle0, Array_Handle1;

//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
 {
//--- Only Two Buffer,这里只把Buffer设置成INDICATOR_DATA,Array依然是数组。
  SetIndexBuffer(0, Buffer0, INDICATOR_DATA);
  SetIndexBuffer(1, Buffer1, INDICATOR_DATA);
  //--- 注意shift的参数!
  Buffer_Handle0 = iMA(_Symbol, _Period, 20, 3, MODE_SMA, PRICE_CLOSE);
  Buffer_Handle1 = iMA(_Symbol, _Period, 20, -3, MODE_SMA, PRICE_CLOSE);
  Array_Handle0 = iMA(_Symbol, _Period, 20, 3, MODE_SMA, PRICE_CLOSE);
  Array_Handle1 = iMA(_Symbol, _Period, 20, -3, MODE_SMA, PRICE_CLOSE);
 }
//+------------------------------------------------------------------+
//|  Accelerator/Decelerator Oscillator                              |
//+------------------------------------------------------------------+
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[])
 {
//--- we can copy not all data
  if(prev_calculated == 0)
   {
    ArrayInitialize(Buffer0,0);
    ArrayInitialize(Buffer1,0);

    int size;
    
    //---
    Print("=== All start_pos is 0 ==="); // 这里开始的位置全部为0
    Print("---Buffer0_Shift=", 3);
    size = CopyBuffer(Buffer_Handle0, 0, 0, 100, Buffer0);
    Print(size, " ", ArraySize(Buffer0));
    Print(Buffer0[ArraySize(Buffer0) - 2], " ", Buffer0[ArraySize(Buffer0) - 1]);
    //---
    Print("---Buffer1_Shift=", -3);
    size = CopyBuffer(Buffer_Handle1, 0, 0, 100, Buffer1);
    Print(size, " ", ArraySize(Buffer1));
    Print(Buffer1[ArraySize(Buffer1) - 2], " ", Buffer1[ArraySize(Buffer1) - 1]);
    //---
    Print("---Array0_Shift=", 3);
    size = CopyBuffer(Array_Handle0, 0, 0, 100, Array0);
    Print(size, " ", ArraySize(Array0));
    Print(Array0[ArraySize(Array0) - 2], " ", Array0[ArraySize(Array0) - 1]);
    //---
    Print("---Array1_Shift=", -3);
    size = CopyBuffer(Array_Handle1, 0, 0, 100, Array1);
    Print(size, " ", ArraySize(Array1));
    Print(Array1[ArraySize(Array1) - 2], " ", Array1[ArraySize(Array1) - 1]);
    

   }
//--- return value of prev_calculated for next call
  return(rates_total);
 }
/*
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   === All start_pos is 0 ===
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   ---Buffer0_Shift=3
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   100 5900
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   0.0 0.0
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   ---Buffer1_Shift=-3
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   97 5900
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   1.160745499999989 1.160360999999989
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   ---Array0_Shift=3
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   100 100
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   1.160745499999989 1.160360999999989
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   ---Array1_Shift=-3
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   97 97
2021.10.27 15:39:14.650 CopyBuffer()指标中比较 (EURUSD,D1)   1.159491499999989 1.159546999999989
*/

结果如上,iMA的shift参数是平移,如果是array,结果符合逻辑。但是为什么buffer上,结果是这样子的?

 

iMA shift=3,请求数据时从-3位置可以请求到全部数据。

但是我全部都是从位置0请求的数据。

 
Yu Zhang:

今天做项目刚好遇到这个情况,难道是系统错误?

代码如下:

结果如上,iMA的shift参数是平移,如果是array,结果符合逻辑。但是为什么buffer上,结果是这样子的?

系统是会出错,但一般都不会错,仔细看了你的问题。结果我发现你这个问题本身就有问题,你不管是-3还是-100,数据都是从0开始的,换句话说你的正3跟负3都是从第一根K线拿走数据,如果你不好理解,我再换种说法你应该不难理解,因为K线的最新数据是当前第一根K为第一手数据,你偏要把还没出来的数据获取,我请问K线都没走出来你怎么获取,当出现这种矛盾时系统会默认把一根K线数据给你,所以你会看到参数不同但数据相同的这种诡异事件,但你真正的理解下面的话一点也不诡异。

你这个问题就等同于,你现在就想把明天的K线数据获取了,明天是什么数据天师都不会知道,你又怎么会获取到呢。所以那个0是代表当前的数据,你可以获取之前的,但还没形成的没人能获取到,也就是说你负100他们俩的数据都是一样的。我也已经够通俗的了,希望你能理解 。

 
annine #:

系统是会出错,但一般都不会错,仔细看了你的问题。结果我发现你这个问题本身就有问题,你不管是-3还是-100,数据都是从0开始的,换句话说你的正3跟负3都是从第一根K线拿走数据,如果你不好理解,我再换种说法你应该不难理解,因为K线的最新数据是当前第一根K为第一手数据,你偏要把还没出来的数据获取,我请问K线都没走出来你怎么获取,当出现这种矛盾时系统会默认把一根K线数据给你,所以你会看到参数不同但数据相同的这种诡异事件,但你真正的理解下面的话一点也不诡异。

你这个问题就等同于,你现在就想把明天的K线数据获取了,明天是什么数据天师都不会知道,你又怎么会获取到呢。所以那个0是代表当前的数据,你可以获取之前的,但还没形成的没人能获取到,也就是说你负100他们俩的数据都是一样的。我也已经够通俗的了,希望你能理解 。

感谢回复,但完全不是你说的这样的。

你不要把现实逻辑等同于函数。

你再看看 Buffer0_Shift=3 的结果,为什么前两个是0?它不完全是定位到第一根K线。

我的这个问题已经得到解决了。说起来有点复杂,总之就是内存中缓冲区复制到数组,与缓冲区复制到缓冲区不一样。

 
问题已经解决。 说起来有点复杂,总之就是内存中缓冲区复制到数组,与缓冲区复制到缓冲区不一样。
 
Yu Zhang:

今天做项目刚好遇到这个情况,难道是系统错误?

代码如下:

结果如上,iMA的shift参数是平移,如果是array,结果符合逻辑。但是为什么buffer上,结果是这样子的?

 SetIndexBuffer(0, Buffer0, INDICATOR_DATA);
 SetIndexBuffer(1, Buffer1, INDICATOR_DATA);

问题在这里

SetIndexBuffer()

这个函数会造成一些影响,应该是地址上面的,我能力不够,查不出来。

但是我通过检测发现Buffer0和1 这两个数组在经过SetIndexBuffer函数后,与普通数组会不一致,可能是地址指针问题。而且经过这个函数的数组不会是动态数组了。

这两个Buffer数组在经过CopyBuffer函数后实际大小不是100(显然不是我们要的结果),我预估可能是分配了更多的地址给他

应该是地址方面的问题。

我测了下发现:

Buffer0 是shift 3。 Buffer0[0]、 Buffer0[1]、 Buffer0[2]他实际上是空的,你的数据在 Buffer0[3]、 Buffer0[4]、 Buffer0[5], 这感觉就是图表上左移3个的数据组存在了,Buffer0这个数组地址也往左移动了3个的方式,导致Buffer0开始三个空了,而此刻,Buffer0原本只存数据到Buffer[99],但是实际上他多存了3个,也就是地址整体移动了(我感觉是这样),所以你测试下就发现,第103号是有数据的,而且数据也是对的,然后104又空了。

发现了吗,打印104号不会显示数组超出范围,这就是SenIndexBuffer的奇怪地方。

Buffer1 是shift -3。 Buffer1[0]、 Buffer1[2] 、Buffer1[3] 。那么应该就可以理解,-3是地址往右移动了三位。

这感觉好像Buffer的储存地址发生变化了

而普通数组Array他们

Array0 是shift 3。Array0[0]、 Array0[1]、 Array0[2]的数据就是图表上左移了3个的数据 (因为左边有很多数据,所以也就是100个数据)

Array1 是shift -3。Array1[0]、 Array1[1]、 Array1[2]的数据就是图标右移了3个的数据(因为右边没有数据了,是未来,所以从图表上0开始显示,所以是97个数据)

 
Mage He #:

问题在这里

这个函数会造成一些影响,应该是地址上面的,我能力不够,查不出来。

但是我通过检测发现Buffer0和1 这两个数组在经过SetIndexBuffer函数后,与普通数组会不一致,可能是地址指针问题。而且经过这个函数的数组不会是动态数组了。

这两个Buffer数组在经过CopyBuffer函数后实际大小不是100(显然不是我们要的结果),我预估可能是分配了更多的地址给他

应该是地址方面的问题。

我测了下发现:

Buffer0 是shift 3。 Buffer0[0]、 Buffer0[1]、 Buffer0[2]他实际上是空的,你的数据在 Buffer0[3]、 Buffer0[4]、 Buffer0[5], 这感觉就是图表上左移3个的数据组存在了,Buffer0这个数组地址也往左移动了3个的方式,导致Buffer0开始三个空了,而此刻,Buffer0原本只存数据到Buffer[99],但是实际上他多存了3个,也就是地址整体移动了(我感觉是这样),所以你测试下就发现,第103号是有数据的,而且数据也是对的,然后104又空了。

发现了吗,打印104号不会显示数组超出范围,这就是SenIndexBuffer的奇怪地方。

Buffer1 是shift -3。 Buffer1[0]、 Buffer1[2] 、Buffer1[3] 。那么应该就可以理解,-3是地址往右移动了三位。

这感觉好像Buffer的储存地址发生变化了

而普通数组Array他们

Array0 是shift 3。Array0[0]、 Array0[1]、 Array0[2]的数据就是图表上左移了3个的数据 (因为左边有很多数据,所以也就是100个数据)

Array1 是shift -3。Array1[0]、 Array1[1]、 Array1[2]的数据就是图标右移了3个的数据(因为右边没有数据了,是未来,所以从图表上0开始显示,所以是97个数据)

问题就在 SetIndexBuffer() 这句声明,就是我上面说的从数组变成了缓存区。

缓存区之间的数据复制与位置,说起来有点复杂。

官方文档上CopyBuffer()函数的那个说明图片,是针对数组的。文档并没有说明缓存到缓存的位置问题。

 
Yu Zhang #:

感谢回复,但完全不是你说的这样的。

你不要把现实逻辑等同于函数。

你再看看 Buffer0_Shift=3 的结果,为什么前两个是0?它不完全是定位到第一根K线。

我的这个问题已经得到解决了。说起来有点复杂,总之就是内存中缓冲区复制到数组,与缓冲区复制到缓冲区不一样。

不客气,我只是根据你的字面意思解答,因为你的标题是指-3跟3两个不同参数为什么获取的数据是相同的,如果你是这个意思,我的回答也可以解决你的问题,正如你所说有时候问题太复杂也是个问题,因为很难描述。