Australian (ASX) Stock Market Forum

Amibroker AFL Code - Keep Stoch RSI Crossover Signal Valid Until K Crosses 50

Joined
30 June 2021
Posts
5
Reactions
2
Question for Amibroker users:

I am coding a system to backtest.

One of the signals is a crossover of the K & D lines of the Stochastic RSI. I want the signal to be valid until the K reaches a certain threshold.

(E.g. There is a cross down in the overbought region (K>80) and this signal should be valid as long as K >50).

The code I have written:

stochrsishort = 0; // Initialise the variable used to store whether the signal is valid or not
stochrsishort = IIf(StochRSICrossDown,1,0); // Set value to 1 if there is a Cross Down from the Overbought region.
stochrsishort = IIf(Ref(stochrsishort,-1) == 1 AND SK > kShortThreshold,1,stochrsishort); // If the previous value was 1 AND K is still greater than threshold value, return 1

However, when I plot the value of stochrsishort, the signal stays open for MAX 1 bar, instead of staying at 1 as long as it is above the K threshold?

I am not sure what I have done wrong as the logic should be correct? (I have used the same logic in TradingView PineScript and it executes as intended.)

Thanks in advance for any help!
 
I have figured out the solution. Reference for anyone who will need it in the future:


stochrsishort = 0;

for( i=1; i < BarCount; i++)
{
if(StochRSICrossDown == 1)
{
stochrsishort = 1;
}
else if(stochrsishort[i-1] == 1 AND SK > kShortThreshold)
{
stochrsishort = 1;
}
}
 
Thanks for the update. Glad we could help. ;)
Although I assume you thought of the solution while posting the problem.
 
Question for Amibroker users:

I am coding a system to backtest.

One of the signals is a crossover of the K & D lines of the Stochastic RSI. I want the signal to be valid until the K reaches a certain threshold.

(E.g. There is a cross down in the overbought region (K>80) and this signal should be valid as long as K >50).
Would the flip function be any good to you?

From the Amibroker function reference library:
_________________________
flip( ARRAY1, ARRAY2 )
works as a flip/flop device or "latch" (electronic/electric engineers will know what I mean)
returns 1 from the first occurence of "true" signal in Array1
until a "true" occurs in Array2 which resets the state back to zero
unil next "true" is detected in Array1...
_________________________

So something like:
stochrsishort = Flip(StochRSICrossDown, Kbelow50)

The code I have written:

stochrsishort = 0; // Initialise the variable used to store whether the signal is valid or not
stochrsishort = IIf(StochRSICrossDown,1,0); // Set value to 1 if there is a Cross Down from the Overbought region.
stochrsishort = IIf(Ref(stochrsishort,-1) == 1 AND SK > kShortThreshold,1,stochrsishort); // If the previous value was 1 AND K is still greater than threshold value, return 1

However, when I plot the value of stochrsishort, the signal stays open for MAX 1 bar, instead of staying at 1 as long as it is above the K threshold?
If you used the cross functon to determine the value of StochRSICrossDown, the cross function will only return true for the bar the cross occurs on. On the next bar StochRSICrossDown will become false. After that, your second line of code containing IIf(Ref(stochrsishort,-1) ==1 won't do as you want as the previous value was 0. I can’t see all your code so might be giving you a bum steer. I know you've moved on, but it’s always good to understand why something didn’t work as you expect.
 
Thanks @Lone Wolf.

My understanding of how the code was intended to execute:

Bar 1: Crossover occurs on Stoch RSI
stochrsishort = 0; // Initialise the variable used to store whether the signal is valid or not
stochrsishort = IIf(StochRSICrossDown,1,0); // Since a crossover occurs, value will be 1
stochrsishort = IIf(Ref(stochrsishort,-1) == 1 AND SK > kShortThreshold,1,stochrsishort); // The value of stochrsishort in previous bar was zero, so, value is stochrsishort, which is 1 since it was set in previous line

stochrsishort = 1 (Final value)

Bar 2: Stoch RSI K value still above threshold
stochrsishort = 0; // Initialise the variable used to store whether the signal is valid or not
stochrsishort = IIf(StochRSICrossDown,1,0); // No crossover on this bar, so value is 0
stochrsishort = IIf(Ref(stochrsishort,-1) == 1 AND SK > kShortThreshold,1,stochrsishort); // The value of stochrsishort in previous bar was 1 and K is still above threshold, so value set to 1

stochrsishort = 1 (Final value)

Bar 3: Stoch RSI K value still above threshold
stochrsishort = 0; // Initialise the variable used to store whether the signal is valid or not
stochrsishort = IIf(StochRSICrossDown,1,0); // No crossover on this bar, so value is 0
stochrsishort = IIf(Ref(stochrsishort,-1) == 1 AND SK > kShortThreshold,1,stochrsishort); // The value of stochrsishort in previous bar was 1 and K is still above threshold, so value set to 1

stochrsishort = 1 (Final value)

In Amibroker, stochrsishort is 1 for bar 1 and 2, but not 3 onwards.

However, the same code executes perfectly in TradingView Pinescript. Which is why I was so confused.
 
I might see the issue. You listed the same three lines of code under Bars 1, 2, and 3. As if Amibroker were executing your code repeatedly for each bar on the chart. Amibroker doesn’t work like that. It executes each line once only (unless you manually create a loop). Amibroker creates arrays containing a value for every bar on the chart, a then performs operations on those arrays. It doesn’t step through the chart changing values as it goes like a human would. So your variable stochrsishort isn’t a value, it’s an array of values.

So for your three lines of code:
stochrsishort = 0;
// Creates an array called stochrsishort with a number of elements equal to the number of bars on the chart and sets all the values to 0.
Result is below – (imagine the below is your array, the red section is where SK > kShortThreshold)
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

stochrsishort = IIf(StochRSICrossDown,1,0);
// Updates the value of the array so that every bar with a crossdown = 1;
0 0 0 0 0 0 1 0 0 0 0 0 0 0 0

stochrsishort = IIf(Ref(stochrsishort,-1) == 1 AND SK > kShortThreshold,1,stochrsishort);
// Updates the array to give a value of 1 to each element where the previous element value was a 1, and SK > kShortThreshold.
0 0 0 0 0 0 1 1 0 0 0 0 0 0 0

Notice that it only changed one element to 1. Because there was only one element in the array where the previous value was 1.

When I first started, not understanding this created enormous confusion for me. I wanted to do things like, if price moves X amount above the value at buy, do Y. But this doesn’t work as expected since Amibroker creates an array of buy values, so as you step through the chart, your buy value gets updated every time you hit another valid buy setup.

I'd like to get into TradingView, but haven't yet so can't say why Pinescript works.
 
There are a couple things you can do to help troubleshooting your code.

One is to plot the value of your indicator on the chart so you can see when it is true/false. See the orange line on my chart below.

The second is to use the Interpretation window to display the values of your variables for any bar you select. In the image below, I added the following code to the chart:
printf (StrFormat("\nStochRSICrossDown = %g", StochRSICrossDown ));
printf (StrFormat("\nstochrsishort = %g", stochrsishort ));
If you then double click on a bar (or maybe it’s Ctrl+click? not at the computer anymore) you get a vertical line down the page highlighting the selected bar. In the Interpretation window (below the chart in the image below) you can see the values now displayed for StochRSICrossDown and stochrsishort. Press left and right arrows to step through the bars and see how the values change.

Interpretation.png
 
Ohhh I see. Thanks Lone Wolf.

I looked it up and Tradingview's Line Script execution model is based on series, not arrays, which is why the same logic does not work the same (could also explain why Tradingview seems to be a bit slower. It is executing the code bar by bar rather than loading all the data into arrays first).

Thanks again for the explanation. Makes things a lot clearer and will help me coding future strategies.
 
Top