I would like to define the following with a while loop. After falling below a certain price level a loop is started. It ends only when a higher price level is exceeded again. When the loop ends, it should output a value that I can then continue to work with.
For example
a = 0
If the SPX falls below 4000, the loop starts. Only when the SPX then rises again above 4200, the loop stops and changes a := 1
Then I know when a = 1, the scenario has occurred and can take further action based on that.
Can someone give me an example, that shows how to define that?
CodePudding user response:
Revised Answer:
The solution is simply to iterate through each previous bar to check for the fallenBelow condition being withing a certain range of the risenAbove condition using a while loop that looks like this:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © lysergik
//@version=5
indicator("backAboveDectector")
bool belowThenAboveInRange = false // this becomes true when your condition is met
// Inputs
float priceLevel = input.float(23700)
int lookback = input.int(10, 'lookback')
// Logic
bool fallenBelow = close[1] >= priceLevel and close < priceLevel
bool risenAbove = close[1] <= priceLevel and close > priceLevel
i = 1
while belowThenAboveInRange == false and i <= lookback
if risenAbove[0] and fallenBelow[i]
belowThenAboveInRange := true
else
i = 1
// front-end
plotshape(belowThenAboveInRange ? 0 : na, style=shape.diamond, location=location.absolute)
The trick to get a boolean of risenAbove but only when fallenBelow was true within a specified range prior is to use a while loop to look through the previous bars.
The loop checks for the current candle being analyzed by the script for the risenAbove condition and then checks the previous bar for the fallenBelow condition. If it did not fall below on that prior candle, it will add 1 to i
and repeat the check until either both conditions are met or the iteration limit is hit.
Notes:
- There must be a limit (although it can be quite large) because the script is run on every single bar in visible range and therefore Pinescript limits the script to take maximum 500ms to compute.
- If you only want your condition to be true when the level is risen-above the very next bar after falling-below, then you can omit the while loop altogether and just run the check once; replacing
i
with '1'
Additional Example
You can define two different levels for fallenBelow
and risenAbove
like this, where float1
is the threshold for falling below ('starting the loop') and float2
is the threshold it must rise above afterwards:
Uncorrelated; unrelated and individually mutable
bool fallenBelow = close[1] >= [float1] and close < [float1]
bool risenAbove = close[1] <= [float2] and close > [float2]
Correlated; float2 is in this example always 5% higher than float1
bool fallenBelow = close[1] >= [float1] and close < [float1]
bool risenAbove = close[1] <= [float1*1.05] and close > [float1*1.05]