I am trying to put the values of peak and trough into a single array.
With using for loop and if loops i am getting results but it is taking 87.3 ms to complete, is there any other way to streamline this code.
Have you checked the Docs and simple Debug? Peak() and Trough() don't return values at true states but the latest value at that bar.
Using IsNull() wont work because non peak/trough bars are not Null, only its corresponding recent Close value,
Since array3 is checked after array2, you'll just have array as a copy of array3.
The time taken to traverse from 0 to Barcount is directly proportional to the number of bars, there is nothing much you can streamline except reducing the number of bars actually needed.
And the semi-colon after For, If and Function { } braces are not part of the syntax ( redundant although code will still execute)
For the solution part,
You actually need clean intermediate Arrays that can be done like this:
myPeakArray = Iif( C == array2, C, 0 );
// You need handle obstacles where two successive bars have same close etc
// depending on your strategy
// Similarly
myTroughArray = Iif( C == array3, C, 0 );
The 0 above is very important, don't use NULL or something else,
then merge the Arrays cleverly using Binary OR instead of slower looping
array = myPeakArray | myTroughArray;
I loved this bit
Remember, Binary OR will add the two arrays, so you need to be sure that there is no overlap of values in the two temp arrays otherwise use the old loop way instead which checks each array index.
Well, at that time, it was purely out of a habit its cool too
Ideally, there are two ways to find out,
one is to take a large sample set and test it and the other is TJ for sure knows
Todays compilers (and the processor) are far smarter but traditionally, a binary OR would be faster then a normal Addition.
So in general present scenario, an Addition can be as fast as a Binrary OR (as in equal time)
but choosing a Binary OR would probably guarantee you the fastest addition possible.
This was also related to OP saying it takes a lot of time which may imply a lot of Bars in question.
If you haven't got around it yet, you can try this way.
array2 = Peak( C, 0.1);
array3 = Trough( C, 0.1);
array[0] = Null;
NewP = array2 != Ref( array2, -1); // Every change in value implies new Peak
NewT = array3 != Ref( array3, -1); // Same check in Troughs
array2 = Iif( NewP && !IsNull( array2), C, 0 ); // retain only Close for Peaks
array3 = Iif( NewT && !IsNull( array3), C, 0 ); // while filtering any Null values
array = array2 | array3; // Power Add
In my tests, I get a clean and non-overlap array
one extra check can be thrown in if you really want to be sure, incase there is a Peak and Trough on the same bar which shouldn't happen, but if it does.
so we prioritize peaks over troughs, in that case this line changes to
ORing close prices is bad coding practice. Binary OR should be used on integers only (numbers without fractional parts). Nested iif is better in that case.
Agreed @Tomasz you are right. Add not the same as Binary OR would skip the carry bit.
In this case is it suitable because we are having either value at 0 for sure so its going to be X | 0 or 0 | Y always at any given index?
Just to add more so everything is in right context,
unable to Edit previous post but to emphasize on what TJ says,
Binary OR that I was applying should be used on Integers which was the case in my Test.
It should be highlighted in Bold that its good only for integers because a float would loose its values after the decimal anyway (Fractional part).
This is a quick way for rounding a number to its Floor integer used in some codes.
Its not right to replace my test variable that I had used with Close as OP needed because it carries a float meaning.
Binary OR with Bit representation is also good, so 1, 2, 4, 8, 16.... so on will give a correct value.
Binary OR of random integers will not be a correct Sum.
To cite a good example, https://www.amibroker.com/guide/afl/plot.html
One may see that the style values are Bit Flags.
These bit flags can be Binary OR'd as used like styleNoTitle| styleOwnScale| styleHistogram
Here, test integer variable with | should be fine with a 0 value which I had specified in my first post but overlooked other conditions which didn't seem relevant.
Since integers aren't defined in AFL per se, we should keep in mind that we will consider the integer part of float.
For the code part, if the array will come across float values, then we should Add them array2 + array3