iMAOnArray + iRSIOnArray + invers fisher transform rsi

 

hi guys

i'm working with the indi https://www.mql5.com/en/code/10351# and i now wonder about the details/behavior of iMAOnArray() and iRSIOnArray().

i found some problems in the calculation of indicators that use xxxOnArray() :

- i often see that indicator buffers for the calculation are used in this way (with full / limited bar count)

for(i=limit; i>=0; i--) rainbow[i] = (5*wma0[i]+4*wma1[i]+3*wma2[i]+2*wma3[i]+wma4[i]+wma5[i]+wma6[i]+wma7[i]+wma8[i]+wma9[i])/20;

for(i=limit; i>=0; i--) rsi[i] = 0.1 *(iRSIOnArray(rainbow,0,RsiPeriod,i)-50);
- all indicator buffers are initialized with EMPTY_VALUE, if one uses WHOLE_ARRAY / 0 with xxxOnArray() you get wrong results? no matter what start you use, you always include the FULL ARRAY!
- in this case the coder minimized the error by using the full bar count, that is still not correct + and bad for performance? - in 98 % i see the same calculation for both, source array and the following xxxOnArray() nobody cares about the initial values or RsiPeriod? - calculation starts with non existent values? that also gives you false values?
SDC: erroneous beginnings to the iMAOnArray lines (the dotted ones) when regular arrays are used for counting instead of drawing buffers so I was wrong in my original theory, 
the error is not within the averageing algorithm itself, it is caused by the implementation of iMAOnArray and its behaviour with drawing buffers that have empty indexes, 
there may be a way to fix this another way so to be able to use drawing buffers without errors, but I was unable to find it. (https://www.mql5.com/en/forum/132647)
so i decided to find a final solution for this and to code my own version - goal : remove wrong values + reduce the array size / calculations to the needed amount...
@ OnInit()
 
///////////////////////////////////////////////// 

IndicatorBuffers(1); 
   
SetIndexBuffer(0 , fish , INDICATOR_DATA);
 
/////////////////////////////////////////////////
 
int cnt = MaxBars; // extern ie 500
 
///////////////////////////////////////////////// global var LWMA_PRD is 2
    
ArrayResize(wma0 , cnt); ArraySetAsSeries(wma0 , TRUE); cnt = cnt - LWMA_PRD + 1; // 1 wma0(2) has array size 500, can start its calculations from 499 -> 0
ArrayResize(wma1 , cnt); ArraySetAsSeries(wma1 , TRUE); cnt = cnt - LWMA_PRD + 1; // 2 wma1(2) has array size 499, can start its calculations from 498 -> 0
ArrayResize(wma2 , cnt); ArraySetAsSeries(wma2 , TRUE); cnt = cnt - LWMA_PRD + 1; // this works well, lwma with period 2 needs bar[i] and bar[i+1] to start its calculations, is this correct?
ArrayResize(wma3 , cnt); ArraySetAsSeries(wma3 , TRUE); cnt = cnt - LWMA_PRD + 1;
ArrayResize(wma4 , cnt); ArraySetAsSeries(wma4 , TRUE); cnt = cnt - LWMA_PRD + 1;
ArrayResize(wma5 , cnt); ArraySetAsSeries(wma5 , TRUE); cnt = cnt - LWMA_PRD + 1;
ArrayResize(wma6 , cnt); ArraySetAsSeries(wma6 , TRUE); cnt = cnt - LWMA_PRD + 1;
ArrayResize(wma7 , cnt); ArraySetAsSeries(wma7 , TRUE); cnt = cnt - LWMA_PRD + 1;
ArrayResize(wma8 , cnt); ArraySetAsSeries(wma8 , TRUE); cnt = cnt - LWMA_PRD + 1;
ArrayResize(wma9 , cnt); ArraySetAsSeries(wma9 , TRUE);
 
/////////////////////////////////////////////////
  
ArrayResize(rnbw , cnt); ArraySetAsSeries(rnbw , TRUE); cnt = cnt - RsiPeriod + 1; // <<< here i get a problem, see the logs
ArrayResize(rsi0 , cnt); ArraySetAsSeries(rsi0 , TRUE); cnt = cnt - EmaPeriod + 1; 
ArrayResize(ema0 , cnt); ArraySetAsSeries(ema0 , TRUE); cnt = cnt - EmaPeriod + 1;
ArrayResize(ema1 , cnt); ArraySetAsSeries(ema1 , TRUE);
ArrayResize(srsi , cnt); ArraySetAsSeries(srsi , TRUE);    
 
///////////////////////////////////////////////// 
i only need the fish for my output, so i tried to reduce all other arrays to minimal needed count, currently this speeds up the time by ~ factor 12! i was surprised and after a few minutes i had a clue why, the xxxOnArray() in the original calculates the full bar count (> 500.000 bars in M1) my version counts only max 500 --------------------------------------------------- final questions:
- i was not able to use the "total" parameter in xxxOnArray() for selecting the correct range, strange results happen if you use other values then 0 for total... any working example? - where do i start calculations with iRSIOnArray(), i get a wrong value and i can't find out why?
 ///////////////////////////////////////////////// 
 
 if(limit > 1) Print("ArraySize(rnbw) " + (string)ArraySize(rnbw) + " | limit " + (string)limit);  

 for(i = limit; i >= 0; i--) {
 
  rnbw[i] = (5 * wma0[i] + 4 * wma1[i] + 3 * wma2[i] + 2 * wma3[i] + wma4[i] + wma5[i] + wma6[i] + wma7[i] + wma8[i] + wma9[i]) / 20.00; 
 
  if(limit > 1 && i > limit - 12) Print("rnbw[" + (string)i + "] " + (string)rnbw[i]);
 
 }  

 /////////////////////////////////////////////////
 
 if(limit > 1) limit = limit - RsiPeriod + 1;   // >>>>>>>>>>>>>>>>>>>>>> is this correct? it works with iMaOnArray(), does iRsiOnArray() need 1 more buffer to initialize?
 
 if(limit > 1) Print("ArraySize(rsi0) " + (string)ArraySize(rsi0) + " | RsiPeriod "+(string)RsiPeriod+" | limit " + (string)limit);

 for(i = limit; i >= 0; i--) { 
 
  rsi0[i] = 0.1 * (iRSIOnArray(rnbw , 0 , RsiPeriod , i) - 50.00);
      
  if(limit > 1 && i > limit - 12) Print("rsi0[" + (string)i + "] " + (string)rsi0[i]);
  
 } 
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[470] 1.24132387014073
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[471] 1.514199565177549
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[472] 1.792494411071378
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[473] 1.6971050716042
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[474] 1.383162270606721
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[475] 0.3436872472935143
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[476] -1.547488764276929
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[477] -2.796415009304886
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[478] -2.368508721395537
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[479] -1.151315973906664
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[480] -0.2791743987770374
2016.02.23 17:37:25.430 xxx USDJPY,M1: rsi0[481] -5 <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< rsi0[481] is calculated from rnbw[490] to rnbw[481] = 10 bars = RsiPeriod
2016.02.23 17:37:25.427 xxx USDJPY,M1: ArraySize(rsi0) 482 | RsiPeriod 10 | limit 481
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[479] 112.0633625787918
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[480] 112.0722714683006
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[481] 112.0786204112677
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[482] 112.084975750053
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[483] 112.0887195780591
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[484] 112.0862503118553
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[485] 112.0848452705608
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[486] 112.0876022503561
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[487] 112.0834503677377
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[488] 112.0740482166982
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[489] 112.0708548662593
2016.02.23 17:37:25.427 xxx USDJPY,M1: rnbw[490] 112.0747104689497
2016.02.23 17:37:25.427 xxx USDJPY,M1: ArraySize(rnbw) 491 | limit 490
the question is why RsiOnArray() produces a wrong value even if the source array has no empty values or wrong values?
if(limit > 1) limit = limit - RsiPeriod + 1;
is + 1 correct? it works with iMaOnArray(), does iRsiOnArray() need 1 more buffer to initialize? regards and many many thx! ;)
 

Hello nina32,


The iMAOnArray() function it's not working since 890 build.

Stop using it.

I tried more than 2 months to figure out hat is wrong with the returned prices of the iAMOnArray() function, i scratched my code, i wrote on metaqoutes help desk and the conclusion was that the function isn't working any more.

Read those two links ( https://www.mql5.com/en/forum/157331, https://www.mql5.com/en/forum/68159 ),  before continue your searching , 

or use Alain Verleyen 2015.12.04 11:20 , recommendation.( Yes it can. iMAOnArray() is obsolete and ineffective, replace it with calls to functions from MovingAverages.mqh library (standard with MT4, provided in Include folder)).

 
// The iMAOnArray() function it's not working since 890 build.

///--- buffers
double main[100000], signal[100000], dif[1000];

///--- counting from 0 to rates_total
ArraySetAsSeries(main,true);
ArraySetAsSeries(signal,true);
ArraySetAsSeries(dif,true);
   

i answered your question, sorry haven't seen this before... you're using static arrays != series array

ArraySetAsSeries() does not work with static arrays!  
The AS_SERIES flag can't be set for multi-dimensional arrays or static arrays (arrays, whose size in square brackets is preset already on the compilation stage).


iMAOnArray() works, why you think it does not? i use it? but one has to care about the input data. my new version of the indi has arrays that are exactly sized (one time at init) to the needed count. it is running very fast and without problems.


i can use WHOLE_ARRAY because my array only has valid values, no EMPTY_VALUE or other wrong content.

and i got only for example 500 bars to calculate - this version is much faster, because iMAOnArray() has not so much data to calculate. i have to do the shifting of the values (new bar) on my own, but its still faster...

i got 2 last questions:

- why RsiOnArray() gives me 1 wrong result even if i start at the exact count...? i do now start 1 bar later - but i want to understand it all...

- and it would be great to see a working example of the "total" parameter with values != 0 (WHOLE_ARRAY), i never had correct results with other values...?
 
attached you will find 2 (hopefully) working minimized examples , 1 indicator array and 2 very small arrays for calculations...

wrong output
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: limit 490 | --------- end -------------- | gtc 2 ms
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[481] 158.46 | rsi0[481] -3.951261689885971
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[482] 158.746 | rsi0[482] -3.579596894373009
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[483] 159.012 | rsi0[483] -2.980521190575073
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[484] 159.064 | rsi0[484] -2.818653984421504
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[485] 159.061 | rsi0[485] -2.851329556356602
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[486] 159.17 | rsi0[486] -2.511213985853288
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[487] 159.126 | rsi0[487] -2.969522240527172
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[488] 159.084 | rsi0[488] -3.410384068278808
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[489] 159.204 | rsi0[489] -3.146766169154222
2016.02.24 18:55:23.325 rsi-onarray-test GBPJPY,M5: inp0[490] 159.169 | rsi0[490] -5 // i start at pos 490, why does this happen, i got 10 values for my calculation, do i need 11?
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: ArraySize(rsi0) 491 | RsiPeriod 10 | limit 490
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[490] 159.169 <<<< here i got 10 valid entrys?
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[491] 159.209
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[492] 159.347
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[493] 159.261
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[494] 159.359
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[495] 159.517
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[496] 159.624
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[497] 159.619
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[498] 159.733
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: inp0[499] 159.71  
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: ArraySize(inp0) 500 | limit 499
2016.02.24 18:55:23.324 rsi-onarray-test GBPJPY,M5: initialized

correct output
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: limit 489 | --------- end -------------- | gtc 1 ms
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[480] 158.537 | rsi0[480] -3.318608088603618
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[481] 158.474 | rsi0[481] -3.888140296096562
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[482] 158.46 | rsi0[482] -4.011534963716705
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[483] 158.746 | rsi0[483] -3.6727556504674
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[484] 159.012 | rsi0[484] -3.138797342731836
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[485] 159.064 | rsi0[485] -2.99702335162086
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[486] 159.061 | rsi0[486] -3.028778401070293
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[487] 159.17 | rsi0[487] -2.734626236739448
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[488] 159.126 | rsi0[488] -3.177981005979554
2016.02.24 19:00:39.770 rsi-onarray-test GBPJPY,M5: inp0[489] 159.084 | rsi0[489] -3.601553829078765 // now i start 1 bar later, result is correct but why i need 11 bars for rsi(10)?!
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: ArraySize(rsi0) 490 | RsiPeriod 10 | limit 489
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[490] 159.204
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[491] 159.169
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[492] 159.209
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[493] 159.347
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[494] 159.261
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[495] 159.359
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[496] 159.517
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[497] 159.624
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[498] 159.619
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: inp0[499] 159.733
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: ArraySize(inp0) 500 | limit 499
2016.02.24 19:00:39.769 rsi-onarray-test GBPJPY,M5: initialized

any idea? sry for my "own coding style" ;)
 
@Konstantinos

by the way, you're one of only a few guys were i have seen that :

for(i=0; i<rates_total-main_period; i--) {

 signal[i] =  NormalizeDouble(iMAOnArray(main, 0, signal_period, 0, MODE_LWMA, i),6);

}


and i think it is the correct way, i didn't checked your exact counting but you didn't start with the same limit, that's what i mean... but one problem left:

iMAOnArray(main, 0 = WHOLE_ARRAY, signal_period, 0, MODE_LWMA, i)

you have to be absolutely sure that main[] only contains valid entry's, if there is ie. only one EMPTY_VALUE = 2147483647 (EMPTY_VALUE is not 0.0 !!!!) included >>> all further calculations are maybe wrong?

to avoid this one can use the "total" parameter, but i didn't get this working, that's why i choose to use exact sized arrays, this way i can use WHOLE_ARRAY...
Reason: