Cyclic RSI v2 - Fold-ing integer "to" is expected

mfox

Member
After someone recently commented on Cyclic RSI v1, I mentioned that I don't really trade anymore, and I'm too busy to do much Thinkscript'ing, but it made me start wondering about this script again. I was always disappointed with the fact that I couldn't get the DRO (dominant rhythm oscillator) working to dynamically set the lookback for the Cyclic RSI. So I did some digging...

I realized that if I was lucky, I could tweak the ZigZagHigh lows to count the bars between highs, and it might have already been out there somewhere, but I didn't find it, so I changed a script from Tomsk and got it working:

Code:
# ZigZag High Low Stats
# tomsk
# 11.16.2019

# V1.0 - 11.16.2019 - tomsk - Initial release of ZigZag High Low Stats

# Extracted idea from RDMercer's post #369 of a variant of a massive
# Zig Zag High Low Supply Demand study that comprises many different
# components
#
# https://usethinkscript.com/threads/trend-reversal-indicator-with-signals-for-thinkorswim.183/page-19#post-369
#
# I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High
# Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points
#
# Label for Confirmed/Unconfirmed Status of Current Zigzag
# Price Change between Zigzags
# Price at Zigzag High/Low
# Bar Count between Zigzags
# Volume at Zigzag Reversals

# added by mfox
    input dominantType = {default "Highs", "Lows"};
    def cycleMode;
    switch (dominantType) {
    case "Highs":
        cycleMode = 1;
    case "Lows":
        cycleMode = 2;
    }

    input BubbleOffset = .0005;
    input PercentAmount = .01;
    input RevAmount = .05;
    input ATRreversal = 3.0;
    input ATRlength = 5;

    def zz = ZigZagHighLow("price h" = high, "price l" = low, "percentage reversal" = PercentAmount,
"absolute reversal" = RevAmount, "atr length" = ATRlength, "atr reversal" = ATRreversal);

    def ReversalAmount = if (close * PercentAmount / 100) > Max(RevAmount < ATRreversal * reference ATR(ATRlength), RevAmount)
                     then (close * PercentAmount / 100)
                     else if RevAmount < ATRreversal * reference ATR(ATRlength)
                          then ATRreversal * reference ATR(ATRlength)
                          else RevAmount;
# Zig Zag Specific Data

    plot zzz = zz;
    zzz.EnableApproximation();

    def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
    def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
    def isUp = chg >= 0;

# Bar Count Specific Data

    def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;

# Dom Count Specific Data - Added by mfox
    def zzDomCount = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then 1 else zzDomCount[1] + 1;

    def zzDomTotal = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then zzDomCount[1] else 0;

    def zzCycles = zzCount == 1 and isUp == (if cycleMode == 1 then yes else no);

    def cycleDoms = TotalSum(zzDomTotal);
    def cycleCount = TotalSum(zzCycles);

    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
    dominantCycle.Hide();

    AddLabel(yes, "Dominant Cycle: " + dominantCycle);

Eureka! An average cycle rounded to the nearest 10 (which I will eventually use to perform harmonic reduction on larger values, 40, 80, 120 all go to 40). So I plugged it into my script below, but I ran into a problem. All of my folds now break for some reason. If I read the label from the cycle above I might get exactly 30, in non-decimal form. This goes into a variable CyclicMemory which is domCycle * 2. However, when I started fold'ing, my script compiles, but won't render with the error: "Folding integer 'to' is expected. NaN". I know this has to do with data types and variable lengths, and in a lot of cases I had to break things like Highest() out to a fold to avoid the dreaded "CL constant function parameter 'length'" error. Here's my CyclicRSI v2 script below (assuming domCycle = output of script above), with clutter removed:
Code:
def src = close;
# change 1
# old
# input domcycle = 20; # Works fine
# new
def domcycle = dominantCycle;

def cyclelen = domcycle / 2;
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = domcycle * 2;

def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * (if IsNaN(crsi[1]) then 0 else crsi[1]);

# change 2
# old
# def lm_hist = if crsi > Highest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then crsi
#              else if -crsi < Lowest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then -crsi
#              else 0;
# new
def memHigh = fold hx = 0 to cyclicmemory -1 with lw = double.NEGATIVE_INFINITY do if high > lw then high else lw;
def memLow = fold lx = 0 to cyclicmemory -1 with hw = double.poSITIVE_INFINITY do if low < hw then low else hw;

def lm_hist = if crsi > memHigh and !IsNaN(lm_hist[1])
                then crsi
              else if -crsi < memLow and !IsNaN(lm_hist[1])
                then -crsi
              else 0;

# change 3
# old
#def lmax = -Highest(lm_hist, cyclicmemory -1);
#def lmin = -Lowest(lm_hist, cyclicmemory -1);

def lmax = - (fold lmx = 0 to cyclicmemory -1 with lwx = double.Negative_infinity do if GetValue(lm_hist, lmx) > lwx then GetValue(lm_hist, lmx) else lwx);

def lmin = - (fold lmn = 0 to cyclicmemory -1 with lwn = double.positive_infinity do if GetValue(lm_hist, lmn) < lwn then GetValue(lm_hist, lmn) else lwn);

def mstep = (lmax - lmin) / 100;
def aperc = leveling / 100;

# change 4

# problem: folding to "cyclicmemory - 1" now produces an error: Folding intenger "to" is expected. NaN

# ???

def db = fold dbx = 0 to 100   
            while (fold blx = 0 to cyclicmemory - 1
                     with b
                     do b + if GetValue(crsi, blx) < lmin + mstep * dbx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmin + mstep * dbx;

def ub = fold ubx = 0 to 100   
            while (fold ulx = 0 to cyclicmemory - 1
                     with a
                     do a + if GetValue(crsi, ulx) >= lmax - mstep * ubx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmax - mstep * ubx;

I honestly hope this is a simple mistake, I'll shoulder that shame no problem, I've just always wanted to get this indicator to be truly dynamic. You can see all the folds that go to "cyclicmemory -1" are where this error occurs, but they all seem fine to me. Naturally, if I hard code any integer to the cyclicmemory variable, the code works fine. Is there any possible workaround for this? It's literally the one thing stopping Cyclic RSI v2 from working.
 
After someone recently commented on Cyclic RSI v1, I mentioned that I don't really trade anymore, and I'm too busy to do much Thinkscript'ing, but it made me start wondering about this script again. I was always disappointed with the fact that I couldn't get the DRO (dominant rhythm oscillator) working to dynamically set the lookback for the Cyclic RSI. So I did some digging...

I realized that if I was lucky, I could tweak the ZigZagHigh lows to count the bars between highs, and it might have already been out there somewhere, but I didn't find it, so I changed a script from Tomsk and got it working:

Code:
# ZigZag High Low Stats
# tomsk
# 11.16.2019

# V1.0 - 11.16.2019 - tomsk - Initial release of ZigZag High Low Stats

# Extracted idea from RDMercer's post #369 of a variant of a massive
# Zig Zag High Low Supply Demand study that comprises many different
# components
#
# https://usethinkscript.com/threads/trend-reversal-indicator-with-signals-for-thinkorswim.183/page-19#post-369
#
# I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High
# Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points
#
# Label for Confirmed/Unconfirmed Status of Current Zigzag
# Price Change between Zigzags
# Price at Zigzag High/Low
# Bar Count between Zigzags
# Volume at Zigzag Reversals

# added by mfox
    input dominantType = {default "Highs", "Lows"};
    def cycleMode;
    switch (dominantType) {
    case "Highs":
        cycleMode = 1;
    case "Lows":
        cycleMode = 2;
    }

    input BubbleOffset = .0005;
    input PercentAmount = .01;
    input RevAmount = .05;
    input ATRreversal = 3.0;
    input ATRlength = 5;

    def zz = ZigZagHighLow("price h" = high, "price l" = low, "percentage reversal" = PercentAmount,
"absolute reversal" = RevAmount, "atr length" = ATRlength, "atr reversal" = ATRreversal);

    def ReversalAmount = if (close * PercentAmount / 100) > Max(RevAmount < ATRreversal * reference ATR(ATRlength), RevAmount)
                     then (close * PercentAmount / 100)
                     else if RevAmount < ATRreversal * reference ATR(ATRlength)
                          then ATRreversal * reference ATR(ATRlength)
                          else RevAmount;
# Zig Zag Specific Data

    plot zzz = zz;
    zzz.EnableApproximation();

    def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
    def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
    def isUp = chg >= 0;

# Bar Count Specific Data

    def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;

# Dom Count Specific Data - Added by mfox
    def zzDomCount = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then 1 else zzDomCount[1] + 1;

    def zzDomTotal = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then zzDomCount[1] else 0;

    def zzCycles = zzCount == 1 and isUp == (if cycleMode == 1 then yes else no);

    def cycleDoms = TotalSum(zzDomTotal);
    def cycleCount = TotalSum(zzCycles);

    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
    dominantCycle.Hide();

    AddLabel(yes, "Dominant Cycle: " + dominantCycle);

Eureka! An average cycle rounded to the nearest 10 (which I will eventually use to perform harmonic reduction on larger values, 40, 80, 120 all go to 40). So I plugged it into my script below, but I ran into a problem. All of my folds now break for some reason. If I read the label from the cycle above I might get exactly 30, in non-decimal form. This goes into a variable CyclicMemory which is domCycle * 2. However, when I started fold'ing, my script compiles, but won't render with the error: "Folding integer 'to' is expected. NaN". I know this has to do with data types and variable lengths, and in a lot of cases I had to break things like Highest() out to a fold to avoid the dreaded "CL constant function parameter 'length'" error. Here's my CyclicRSI v2 script below (assuming domCycle = output of script above), with clutter removed:
Code:
def src = close;
# change 1
# old
# input domcycle = 20; # Works fine
# new
def domcycle = dominantCycle;

def cyclelen = domcycle / 2;
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = domcycle * 2;

def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * (if IsNaN(crsi[1]) then 0 else crsi[1]);

# change 2
# old
# def lm_hist = if crsi > Highest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then crsi
#              else if -crsi < Lowest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then -crsi
#              else 0;
# new
def memHigh = fold hx = 0 to cyclicmemory -1 with lw = double.NEGATIVE_INFINITY do if high > lw then high else lw;
def memLow = fold lx = 0 to cyclicmemory -1 with hw = double.poSITIVE_INFINITY do if low < hw then low else hw;

def lm_hist = if crsi > memHigh and !IsNaN(lm_hist[1])
                then crsi
              else if -crsi < memLow and !IsNaN(lm_hist[1])
                then -crsi
              else 0;

# change 3
# old
#def lmax = -Highest(lm_hist, cyclicmemory -1);
#def lmin = -Lowest(lm_hist, cyclicmemory -1);

def lmax = - (fold lmx = 0 to cyclicmemory -1 with lwx = double.Negative_infinity do if GetValue(lm_hist, lmx) > lwx then GetValue(lm_hist, lmx) else lwx);

def lmin = - (fold lmn = 0 to cyclicmemory -1 with lwn = double.positive_infinity do if GetValue(lm_hist, lmn) < lwn then GetValue(lm_hist, lmn) else lwn);

def mstep = (lmax - lmin) / 100;
def aperc = leveling / 100;

# change 4

# problem: folding to "cyclicmemory - 1" now produces an error: Folding intenger "to" is expected. NaN

# ???

def db = fold dbx = 0 to 100  
            while (fold blx = 0 to cyclicmemory - 1
                     with b
                     do b + if GetValue(crsi, blx) < lmin + mstep * dbx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmin + mstep * dbx;

def ub = fold ubx = 0 to 100  
            while (fold ulx = 0 to cyclicmemory - 1
                     with a
                     do a + if GetValue(crsi, ulx) >= lmax - mstep * ubx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmax - mstep * ubx;

I honestly hope this is a simple mistake, I'll shoulder that shame no problem, I've just always wanted to get this indicator to be truly dynamic. You can see all the folds that go to "cyclicmemory -1" are where this error occurs, but they all seem fine to me. Naturally, if I hard code any integer to the cyclicmemory variable, the code works fine. Is there any possible workaround for this? It's literally the one thing stopping Cyclic RSI v2 from working.
There are errors in the code, torque and dominant cycle not defined.
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

After someone recently commented on Cyclic RSI v1, I mentioned that I don't really trade anymore, and I'm too busy to do much Thinkscript'ing, but it made me start wondering about this script again. I was always disappointed with the fact that I couldn't get the DRO (dominant rhythm oscillator) working to dynamically set the lookback for the Cyclic RSI. So I did some digging...

I realized that if I was lucky, I could tweak the ZigZagHigh lows to count the bars between highs, and it might have already been out there somewhere, but I didn't find it, so I changed a script from Tomsk and got it working:

Code:
# ZigZag High Low Stats
# tomsk
# 11.16.2019

# V1.0 - 11.16.2019 - tomsk - Initial release of ZigZag High Low Stats

# Extracted idea from RDMercer's post #369 of a variant of a massive
# Zig Zag High Low Supply Demand study that comprises many different
# components
#
# https://usethinkscript.com/threads/trend-reversal-indicator-with-signals-for-thinkorswim.183/page-19#post-369
#
# I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High
# Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points
#
# Label for Confirmed/Unconfirmed Status of Current Zigzag
# Price Change between Zigzags
# Price at Zigzag High/Low
# Bar Count between Zigzags
# Volume at Zigzag Reversals

# added by mfox
    input dominantType = {default "Highs", "Lows"};
    def cycleMode;
    switch (dominantType) {
    case "Highs":
        cycleMode = 1;
    case "Lows":
        cycleMode = 2;
    }

    input BubbleOffset = .0005;
    input PercentAmount = .01;
    input RevAmount = .05;
    input ATRreversal = 3.0;
    input ATRlength = 5;

    def zz = ZigZagHighLow("price h" = high, "price l" = low, "percentage reversal" = PercentAmount,
"absolute reversal" = RevAmount, "atr length" = ATRlength, "atr reversal" = ATRreversal);

    def ReversalAmount = if (close * PercentAmount / 100) > Max(RevAmount < ATRreversal * reference ATR(ATRlength), RevAmount)
                     then (close * PercentAmount / 100)
                     else if RevAmount < ATRreversal * reference ATR(ATRlength)
                          then ATRreversal * reference ATR(ATRlength)
                          else RevAmount;
# Zig Zag Specific Data

    plot zzz = zz;
    zzz.EnableApproximation();

    def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
    def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
    def isUp = chg >= 0;

# Bar Count Specific Data

    def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;

# Dom Count Specific Data - Added by mfox
    def zzDomCount = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then 1 else zzDomCount[1] + 1;

    def zzDomTotal = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then zzDomCount[1] else 0;

    def zzCycles = zzCount == 1 and isUp == (if cycleMode == 1 then yes else no);

    def cycleDoms = TotalSum(zzDomTotal);
    def cycleCount = TotalSum(zzCycles);

    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
    dominantCycle.Hide();

    AddLabel(yes, "Dominant Cycle: " + dominantCycle);

Eureka! An average cycle rounded to the nearest 10 (which I will eventually use to perform harmonic reduction on larger values, 40, 80, 120 all go to 40). So I plugged it into my script below, but I ran into a problem. All of my folds now break for some reason. If I read the label from the cycle above I might get exactly 30, in non-decimal form. This goes into a variable CyclicMemory which is domCycle * 2. However, when I started fold'ing, my script compiles, but won't render with the error: "Folding integer 'to' is expected. NaN". I know this has to do with data types and variable lengths, and in a lot of cases I had to break things like Highest() out to a fold to avoid the dreaded "CL constant function parameter 'length'" error. Here's my CyclicRSI v2 script below (assuming domCycle = output of script above), with clutter removed:
Code:
def src = close;
# change 1
# old
# input domcycle = 20; # Works fine
# new
def domcycle = dominantCycle;

def cyclelen = domcycle / 2;
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = domcycle * 2;

def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * (if IsNaN(crsi[1]) then 0 else crsi[1]);

# change 2
# old
# def lm_hist = if crsi > Highest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then crsi
#              else if -crsi < Lowest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then -crsi
#              else 0;
# new
def memHigh = fold hx = 0 to cyclicmemory -1 with lw = double.NEGATIVE_INFINITY do if high > lw then high else lw;
def memLow = fold lx = 0 to cyclicmemory -1 with hw = double.poSITIVE_INFINITY do if low < hw then low else hw;

def lm_hist = if crsi > memHigh and !IsNaN(lm_hist[1])
                then crsi
              else if -crsi < memLow and !IsNaN(lm_hist[1])
                then -crsi
              else 0;

# change 3
# old
#def lmax = -Highest(lm_hist, cyclicmemory -1);
#def lmin = -Lowest(lm_hist, cyclicmemory -1);

def lmax = - (fold lmx = 0 to cyclicmemory -1 with lwx = double.Negative_infinity do if GetValue(lm_hist, lmx) > lwx then GetValue(lm_hist, lmx) else lwx);

def lmin = - (fold lmn = 0 to cyclicmemory -1 with lwn = double.positive_infinity do if GetValue(lm_hist, lmn) < lwn then GetValue(lm_hist, lmn) else lwn);

def mstep = (lmax - lmin) / 100;
def aperc = leveling / 100;

# change 4

# problem: folding to "cyclicmemory - 1" now produces an error: Folding intenger "to" is expected. NaN

# ???

def db = fold dbx = 0 to 100  
            while (fold blx = 0 to cyclicmemory - 1
                     with b
                     do b + if GetValue(crsi, blx) < lmin + mstep * dbx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmin + mstep * dbx;

def ub = fold ubx = 0 to 100  
            while (fold ulx = 0 to cyclicmemory - 1
                     with a
                     do a + if GetValue(crsi, ulx) >= lmax - mstep * ubx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmax - mstep * ubx;

I honestly hope this is a simple mistake, I'll shoulder that shame no problem, I've just always wanted to get this indicator to be truly dynamic. You can see all the folds that go to "cyclicmemory -1" are where this error occurs, but they all seem fine to me. Naturally, if I hard code any integer to the cyclicmemory variable, the code works fine. Is there any possible workaround for this? It's literally the one thing stopping Cyclic RSI v2 from working.
please post a complete code, not a partial, cleaned up version.
 
Complete code:

Code:
# ZigZag High Low Stats
# tomsk
# 11.16.2019

# V1.0 - 11.16.2019 - tomsk - Initial release of ZigZag High Low Stats

# Extracted idea from RDMercer's post #369 of a variant of a massive
# Zig Zag High Low Supply Demand study that comprises many different
# components
#
# https://usethinkscript.com/threads/trend-reversal-indicator-with-signals-for-thinkorswim.183/page-19#post-369
#
# I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High
# Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points
#
# Label for Confirmed/Unconfirmed Status of Current Zigzag
# Price Change between Zigzags
# Price at Zigzag High/Low
# Bar Count between Zigzags
# Volume at Zigzag Reversals

# added by mfox
    input dominantType = {default "Highs", "Lows"};
    def cycleMode;
    switch (dominantType) {
    case "Highs":
        cycleMode = 1;
    case "Lows":
        cycleMode = 2;
    }

    input BubbleOffset = .0005;
    input PercentAmount = .01;
    input RevAmount = .05;
    input ATRreversal = 3.0;
    input ATRlength = 5;

    def zz = ZigZagHighLow("price h" = high, "price l" = low, "percentage reversal" = PercentAmount,
"absolute reversal" = RevAmount, "atr length" = ATRlength, "atr reversal" = ATRreversal);

    def ReversalAmount = if (close * PercentAmount / 100) > Max(RevAmount < ATRreversal * reference ATR(ATRlength), RevAmount)
                     then (close * PercentAmount / 100)
                     else if RevAmount < ATRreversal * reference ATR(ATRlength)
                          then ATRreversal * reference ATR(ATRlength)
                          else RevAmount;
# Zig Zag Specific Data

    plot zzz = zz;
    zzz.EnableApproximation();

    def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
    def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
    def isUp = chg >= 0;

# Bar Count Specific Data

    def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;

# Dom Count Specific Data - Added by mfox
    def zzDomCount = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then 1 else zzDomCount[1] + 1;

    def zzDomTotal = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then zzDomCount[1] else 0;

    def zzCycles = zzCount == 1 and isUp == (if cycleMode == 1 then yes else no);

    def cycleDoms = TotalSum(zzDomTotal);
    def cycleCount = TotalSum(zzCycles);

    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
    dominantCycle.Hide();

# Cyclic RSI
# Origanlly found on Tradingview: https://www.tradingview.com/v/TmqiR1jp/
# Shout out to WentToTrade for the amazing indicator.
# Written in ThinkScript by mfox

# The cyclic smoothed RSI indicator is an enhancement of the classic RSI , adding
# additional smoothing according to the market vibration,
# adaptive upper and lower bands according to the cyclic memory and
# using the current dominant cycle length as input for the indicator.

# The cRSI is used like a standard indicator. The chart highlights trading signals where the signal line # crosses above or below the adaptive lower/upper bands. It is much more responsive to market moves than the basic RSI.

# The indicator uses the dominant cycle as input to optimize signal, smoothing and cyclic memory. To get more in-depth information on the cyclic-smoothed RSI indicator, please read Chapter 4 "Fine tuning technical indicators" of the book "Decoding the Hidden Market Rhythm, Part 1" available at your favorite book store.

declare lower;

def src = close;
# change 1
# old
# input domcycle = 20;
# new
def domcycle = dominantCycle;
def cyclelen = domcycle / 2;
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = domcycle * 2;

input scanlength = 100;

input RSIOversold = 30;
input RSIOverbought = 70;

plot h1 = RSIOversold;
h1.SetDefaultColor(Color.GRAY);
h1.SetPaintingStrategy(PaintingStrategy.DASHES);
h1.SetLineWeight(1);

plot h2 = RSIOverbought;
h2.SetDefaultColor(Color.GRAY);
h2.SetPaintingStrategy(PaintingStrategy.DASHES);
h2.SetLineWeight(1);

def torque = 2.0 / (vibration + 1.0);
def phasingLag = (vibration - 1.0) / 2.0;


def up = (1 / cyclelen) * (Max((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(up[1]) then 0 else up[1]);
def down = (1 / cyclelen) * (-Min((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(down[1]) then 0 else down[1]);

def rsi = if down == 0 then 100 else if up == 0 then 0 else 100 - 100 / (1 + up / down);
def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * (if IsNaN(crsi[1]) then 0 else crsi[1]);

# change 2
# old
# def lm_hist = if crsi > Highest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then crsi
#              else if -crsi < Lowest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then -crsi
#              else 0;
# new
def memHigh = fold hx = 0 to cyclicmemory -1 with lw = double.NEGATIVE_INFINITY do if high > lw then high else lw;
def memLow = fold lx = 0 to cyclicmemory -1 with hw = double.poSITIVE_INFINITY do if low < hw then low else hw;

def lm_hist = if crsi > memHigh and !IsNaN(lm_hist[1])
                then crsi
              else if -crsi < memLow and !IsNaN(lm_hist[1])
                then -crsi
              else 0;

# change 3
# old
#def lmax = -Highest(lm_hist, cyclicmemory -1);
#def lmin = -Lowest(lm_hist, cyclicmemory -1);

def lmax = - (fold lmx = 0 to cyclicmemory -1 with lwx = double.Negative_infinity do if GetValue(lm_hist, lmx) > lwx then GetValue(lm_hist, lmx) else lwx);

def lmin = - (fold lmn = 0 to cyclicmemory -1 with lwn = double.positive_infinity do if GetValue(lm_hist, lmn) < lwn then GetValue(lm_hist, lmn) else lwn);

def mstep = (lmax - lmin) / 100;
def aperc = leveling / 100;

# change 4

# problem: folding to "cyclicmemory - 1" now produces an error: Folding intenger "to" is expected. NaN

# ???

def db = fold dbx = 0 to 100   
            while (fold blx = 0 to cyclicmemory - 1
                     with b
                     do b + if GetValue(crsi, blx) < lmin + mstep * dbx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmin + mstep * dbx;

def ub = fold ubx = 0 to 100   
            while (fold ulx = 0 to cyclicmemory - 1
                     with a
                     do a + if GetValue(crsi, ulx) >= lmax - mstep * ubx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmax - mstep * ubx;

plot lowband = db;
lowband.SetDefaultColor(Color.DARK_GREEN);

plot highband = ub;
highband.SetDefaultColor(Color.DARK_RED);

plot C = crsi;
C.SetDefaultColor(Color.PLUM);

plot Oversold = C < lowband;
Oversold.Hide();

plot Overbought = C > highband;
Overbought.Hide();

plot SuperOversold = lowband < RSIOversold and Oversold;
SuperOversold.Hide();

plot SuperOverbought = highband > RSIOverbought and Overbought;
SuperOverbought.Hide();

plot State = 50;
State.SetPaintingStrategy(PaintingStrategy.POINTS);
State.SetLineWeight(1);
State.AssignValueColor(if SuperOversold then Color.GREEN else
if Oversold then Color.DARK_GREEN else
if SuperOverbought then Color.RED else
if Overbought then Color.DARK_RED else
Color.GRAY);

# AddCloud(db,   ub,   Color.DARK_GRAY,   Color.DARK_GRAY);
# AddCloud(0, if SuperOversold   then Double.POSITIVE_INFINITY else Double.NaN,      Color.GREEN,      Color.GREEN);
# AddCloud(0, if Oversold        then Double.POSITIVE_INFINITY else Double.NaN, Color.DARK_GREEN, Color.DARK_GREEN);
# AddCloud(0, if SuperOverbought then Double.POSITIVE_INFINITY else Double.NaN,        Color.RED,        Color.RED);
# AddCloud(0, if Overbought      then Double.POSITIVE_INFINITY else Double.NaN,   Color.DARK_RED,   Color.DARK_RED);

AddLabel(yes, (if SuperOversold then "Super Oversold" else  if Oversold then "Oversold" else  if SuperOverbought then "Super Overbought" else if Overbought then "Overbought" else  "Neutral"), if SuperOversold then Color.GREEN else
if Oversold then Color.DARK_GREEN else
if SuperOverbought then Color.RED else
if Overbought then Color.DARK_RED else
Color.GRAY);

AddLabel(yes, "Dominant Cycle: " + dominantCycle);
 
It does appear that the value in question, dominantCycle, from the modified Tomsk script, appears to be getting a NaN, causing the fold's to fail, though I cannot determine why. In the lower section, if I change the code:

Code:
# def domCycle = dominantCycle;
def domcycle = if isNaN(dominantCycle) then 20 else if dominantCycle <= 0 then 20 else dominantCycle;

Then it at least renders on the screen, but obviously its incorrect. As to why I'm getting a NaN, could really only mean that when I'm counting the distance between highs (or lows based on settings) that I am getting a NaN when calculating the average (plot dominantCycle etc...). However when I tried to debug this with a chart bubble, no bars seemed to show an example of this NaN.


It does not appear as if the error is consistent. Although the error says as the title, using "cyclicmemory - 1" works on the first two folds, but not the nested folds from my original CyclicRSI script.

Code:
def lmax = - (fold lmx = 0 to cyclicmemory -1 with lwx = double.Negative_infinity do if GetValue(lm_hist, lmx) > lwx then GetValue(lm_hist, lmx) else lwx);

def lmin = - (fold lmn = 0 to cyclicmemory -1 with lwn = double.positive_infinity do if GetValue(lm_hist, lmn) < lwn then GetValue(lm_hist, lmn) else lwn);

# ^^^ cyclicmemory - 1 works fine on these two folds

# as soon as I add these two nested folds from my original script, I get the title error

def db = (fold dbx = 0 to 100   
            while (fold blx = 0 to (cyclicmemory - 1)
                     with b
                     do b + if GetValue(crsi, blx) < lmin + mstep * dbx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmin + mstep * dbx);

def ub = (fold ubx = 0 to 100   
            while (fold ulx = 0 to (cyclicmemory - 1)
                     with a
                     do a + if GetValue(crsi, ulx) >= lmax - mstep * ubx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmax - mstep * ubx);
 
Last edited:
It does appear that the value in question, dominantCycle, from the modified Tomsk script, appears to be getting a NaN, causing the fold's to fail, though I cannot determine why. In the lower section, if I change the code:

Code:
# def domCycle = dominantCycle;
def domcycle = if isNaN(dominantCycle) then 20 else if dominantCycle <= 0 then 20 else dominantCycle;

Then it at least renders on the screen, but obviously its incorrect. As to why I'm getting a NaN, could really only mean that when I'm counting the distance between highs (or lows based on settings) that I am getting a NaN when calculating the average (plot dominantCycle etc...). However when I tried to debug this with a chart bubble, no bars seemed to show an example of this NaN.

i'm at the same place you are, i swapped
def dominantCycle = ...

to be a constant and it plots.
def dominantCycle = 30;

and i don't see any errors in the bubbles...

---------------

maybe the values after the last bar are causing an issue....
nope
i tried this, still nan error
def dominantCycle = if isnan(close) then 0 else (Round(((cycleDoms / cycleCount) / 10), 0) * 10);

----------

zz has nan errors, only a number on a peak or valley, maybe its value is cascading thru causing errors....


Code:
#    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
#    dominantCycle.Hide();

#def dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;

# setting dominantCycle  to a number works
# no errors in bubble vars

def dominantCycle = 30;
    plot zdomcyc = dominantCycle;
    zdomcyc.Hide();

def uu = isnan(cycleDoms) or isnan(cycleDoms);

addchartbubble(1, low, 
 cycleDoms + "\n" +
 cycleCount + "\n" +
 (Round(((cycleDoms / cycleCount) / 10), 0) * 10)
, (if uu then color.yellow else color.gray), no);
 
i'm at the same place you are, i swapped
def dominantCycle = ...

to be a constant and it plots.
def dominantCycle = 30;

and i don't see any errors in the bubbles...

---------------

maybe the values after the last bar are causing an issue....
nope
i tried this, still nan error
def dominantCycle = if isnan(close) then 0 else (Round(((cycleDoms / cycleCount) / 10), 0) * 10);

----------

zz has nan errors, only a number on a peak or valley, maybe its value is cascading thru causing errors....


Code:
#    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
#    dominantCycle.Hide();

#def dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;

# setting dominantCycle  to a number works
# no errors in bubble vars

def dominantCycle = 30;
    plot zdomcyc = dominantCycle;
    zdomcyc.Hide();

def uu = isnan(cycleDoms) or isnan(cycleDoms);

addchartbubble(1, low,
 cycleDoms + "\n" +
 cycleCount + "\n" +
 (Round(((cycleDoms / cycleCount) / 10), 0) * 10)
, (if uu then color.yellow else color.gray), no);
Thanks @halcyonguy and that's what I found too. I edited my previous post because it didn't seem to be the constant causing the issue. It helped, sure, and it renders like you said, but the error is inconsistent between folds, despite [cyclicmemory - 1] not changing. See above post #5 (https://usethinkscript.com/threads/cyclic-rsi-v2-fold-ing-integer-to-is-expected.13170/#post-111390).
 
Thanks @halcyonguy and that's what I found too. I edited my previous post because it didn't seem to be the constant causing the issue. It helped, sure, and it renders like you said, but the error is inconsistent between folds, despite [cyclicmemory - 1] not changing. See above post #5 (https://usethinkscript.com/threads/cyclic-rsi-v2-fold-ing-integer-to-is-expected.13170/#post-111390).
I have apparently been fooled again. Now if I use this exact code:

Code:
# ZigZag High Low Stats
# tomsk
# 11.16.2019

# V1.0 - 11.16.2019 - tomsk - Initial release of ZigZag High Low Stats

# Extracted idea from RDMercer's post #369 of a variant of a massive
# Zig Zag High Low Supply Demand study that comprises many different
# components
#
# https://usethinkscript.com/threads/trend-reversal-indicator-with-signals-for-thinkorswim.183/page-19#post-369
#
# I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High
# Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points
#
# Label for Confirmed/Unconfirmed Status of Current Zigzag
# Price Change between Zigzags
# Price at Zigzag High/Low
# Bar Count between Zigzags
# Volume at Zigzag Reversals

# added by mfox
    input dominantType = {default "Highs", "Lows"};
    def cycleMode;
    switch (dominantType) {
    case "Highs":
        cycleMode = 1;
    case "Lows":
        cycleMode = 2;
    }

    def BubbleOffset = .0005;

    def zz = ZigZagHighLow();

# Zig Zag Specific Data

    def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
    def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
    def isUp = chg >= 0;

# Bar Count Specific Data

    def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;

# Dom Count Specific Data - Added by mfox
    def zzDomCount = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then 1 else if isNaN(zzDomCount[1]) then 1 else zzDomCount[1] + 1;

    def zzDomTotal = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then if isNaN(zzDomCount[1]) then 1 else zzDomCount[1] else 0;

    def zzCycles = zzCount == 1 and isUp == (if cycleMode == 1 then yes else no);

    def cycleDoms = TotalSum(zzDomTotal);
    def cycleCount = TotalSum(zzCycles);

AddLabel(yes, cycleDoms + " | " + cycleCount + " | " + (cycleDoms/cycleCount));

    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
    dominantCycle.Hide();

# Cyclic RSI
# Origanlly found on Tradingview: https://www.tradingview.com/v/TmqiR1jp/
# Shout out to WentToTrade for the amazing indicator.
# Written in ThinkScript by mfox

# The cyclic smoothed RSI indicator is an enhancement of the classic RSI , adding
# additional smoothing according to the market vibration,
# adaptive upper and lower bands according to the cyclic memory and
# using the current dominant cycle length as input for the indicator.

# The cRSI is used like a standard indicator. The chart highlights trading signals where the signal line # crosses above or below the adaptive lower/upper bands. It is much more responsive to market moves than the basic RSI.

# The indicator uses the dominant cycle as input to optimize signal, smoothing and cyclic memory. To get more in-depth information on the cyclic-smoothed RSI indicator, please read Chapter 4 "Fine tuning technical indicators" of the book "Decoding the Hidden Market Rhythm, Part 1" available at your favorite book store.

declare lower;

def src = close;
def domcycle = dominantCycle;
def cyclelen = domcycle / 2;
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = domCycle * 2;

input scanlength = 100;

input RSIOversold = 30;
input RSIOverbought = 70;

plot h1 = RSIOversold;
h1.SetDefaultColor(Color.GRAY);
h1.SetPaintingStrategy(PaintingStrategy.DASHES);
h1.SetLineWeight(1);

plot h2 = RSIOverbought;
h2.SetDefaultColor(Color.GRAY);
h2.SetPaintingStrategy(PaintingStrategy.DASHES);
h2.SetLineWeight(1);

def torque = 2.0 / (vibration + 1.0);
def phasingLag = (vibration - 1.0) / 2.0;

def up =   (1 / cyclelen) * ( Max((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(  up[1]) then 0 else   up[1]);
def down = (1 / cyclelen) * (-Min((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(down[1]) then 0 else down[1]);

def rsi = if down == 0 then 100 else if up == 0 then 0 else 100 - 100 / (1 + up / down);
def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * (if IsNaN(crsi[1]) then 0 else crsi[1]);

def memHigh = fold hx = 0 to cyclicmemory -1 with lw = DOUBLE.NEGATIVE_INFINITY do if high > lw then high else lw;
def memLow =  fold lx = 0 to cyclicmemory -1 with hw = DOUBLE.POSITIVE_INFINITY do if  low < hw then  low else hw;

def lm_hist = if crsi > memHigh and !IsNaN(lm_hist[1])
                then crsi
              else if crsi < memLow and !IsNaN(lm_hist[1])
                then crsi
              else 0;

def lmax = - (fold lmx = 0 to cyclicmemory -1 with lwx = DOUBLE.NEGATIVE_INFINITY do if GetValue(lm_hist, lmx) > lwx then GetValue(lm_hist, lmx) else lwx);

def lmin =   (fold lmn = 0 to cyclicmemory -1 with lwn = DOUBLE.POSITIVE_INFINITY do if GetValue(lm_hist, lmn) < lwn then GetValue(lm_hist, lmn) else lwn);

def mstep = (lmax - lmin) / scanlength;
def aperc = leveling / scanlength;

def db = (fold dbx = 0 to scanlength   
            while (fold blx = 0 to cyclicmemory -1
                     with b
                     do b + if GetValue(crsi, blx) < lmin + mstep * dbx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmin + mstep * dbx);

def ub = (fold ubx = 0 to scanlength   
            while (fold ulx = 0 to cyclicmemory -1
                     with a
                     do a + if GetValue(crsi, ulx) >= lmax - mstep * ubx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmax - mstep * ubx);

AddLabel(yes, "Dominant Cycle: " + dominantCycle);

It works perfectly fine with no errors! But I had to remove the code that plots the CRSI. However... if you add ANY CODE AT ALL before the last AddLabel, it goes back to complaining about Folding integer is NaN. It doesn't make any sense?
 
I have apparently been fooled again. Now if I use this exact code:

Code:
# ZigZag High Low Stats
# tomsk
# 11.16.2019

# V1.0 - 11.16.2019 - tomsk - Initial release of ZigZag High Low Stats

# Extracted idea from RDMercer's post #369 of a variant of a massive
# Zig Zag High Low Supply Demand study that comprises many different
# components
#
# https://usethinkscript.com/threads/trend-reversal-indicator-with-signals-for-thinkorswim.183/page-19#post-369
#
# I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High
# Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points
#
# Label for Confirmed/Unconfirmed Status of Current Zigzag
# Price Change between Zigzags
# Price at Zigzag High/Low
# Bar Count between Zigzags
# Volume at Zigzag Reversals

# added by mfox
    input dominantType = {default "Highs", "Lows"};
    def cycleMode;
    switch (dominantType) {
    case "Highs":
        cycleMode = 1;
    case "Lows":
        cycleMode = 2;
    }

    def BubbleOffset = .0005;

    def zz = ZigZagHighLow();

# Zig Zag Specific Data

    def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
    def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
    def isUp = chg >= 0;

# Bar Count Specific Data

    def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;

# Dom Count Specific Data - Added by mfox
    def zzDomCount = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then 1 else if isNaN(zzDomCount[1]) then 1 else zzDomCount[1] + 1;

    def zzDomTotal = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then if isNaN(zzDomCount[1]) then 1 else zzDomCount[1] else 0;

    def zzCycles = zzCount == 1 and isUp == (if cycleMode == 1 then yes else no);

    def cycleDoms = TotalSum(zzDomTotal);
    def cycleCount = TotalSum(zzCycles);

AddLabel(yes, cycleDoms + " | " + cycleCount + " | " + (cycleDoms/cycleCount));

    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
    dominantCycle.Hide();

# Cyclic RSI
# Origanlly found on Tradingview: https://www.tradingview.com/v/TmqiR1jp/
# Shout out to WentToTrade for the amazing indicator.
# Written in ThinkScript by mfox

# The cyclic smoothed RSI indicator is an enhancement of the classic RSI , adding
# additional smoothing according to the market vibration,
# adaptive upper and lower bands according to the cyclic memory and
# using the current dominant cycle length as input for the indicator.

# The cRSI is used like a standard indicator. The chart highlights trading signals where the signal line # crosses above or below the adaptive lower/upper bands. It is much more responsive to market moves than the basic RSI.

# The indicator uses the dominant cycle as input to optimize signal, smoothing and cyclic memory. To get more in-depth information on the cyclic-smoothed RSI indicator, please read Chapter 4 "Fine tuning technical indicators" of the book "Decoding the Hidden Market Rhythm, Part 1" available at your favorite book store.

declare lower;

def src = close;
def domcycle = dominantCycle;
def cyclelen = domcycle / 2;
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = domCycle * 2;

input scanlength = 100;

input RSIOversold = 30;
input RSIOverbought = 70;

plot h1 = RSIOversold;
h1.SetDefaultColor(Color.GRAY);
h1.SetPaintingStrategy(PaintingStrategy.DASHES);
h1.SetLineWeight(1);

plot h2 = RSIOverbought;
h2.SetDefaultColor(Color.GRAY);
h2.SetPaintingStrategy(PaintingStrategy.DASHES);
h2.SetLineWeight(1);

def torque = 2.0 / (vibration + 1.0);
def phasingLag = (vibration - 1.0) / 2.0;

def up =   (1 / cyclelen) * ( Max((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(  up[1]) then 0 else   up[1]);
def down = (1 / cyclelen) * (-Min((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(down[1]) then 0 else down[1]);

def rsi = if down == 0 then 100 else if up == 0 then 0 else 100 - 100 / (1 + up / down);
def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * (if IsNaN(crsi[1]) then 0 else crsi[1]);

def memHigh = fold hx = 0 to cyclicmemory -1 with lw = DOUBLE.NEGATIVE_INFINITY do if high > lw then high else lw;
def memLow =  fold lx = 0 to cyclicmemory -1 with hw = DOUBLE.POSITIVE_INFINITY do if  low < hw then  low else hw;

def lm_hist = if crsi > memHigh and !IsNaN(lm_hist[1])
                then crsi
              else if crsi < memLow and !IsNaN(lm_hist[1])
                then crsi
              else 0;

def lmax = - (fold lmx = 0 to cyclicmemory -1 with lwx = DOUBLE.NEGATIVE_INFINITY do if GetValue(lm_hist, lmx) > lwx then GetValue(lm_hist, lmx) else lwx);

def lmin =   (fold lmn = 0 to cyclicmemory -1 with lwn = DOUBLE.POSITIVE_INFINITY do if GetValue(lm_hist, lmn) < lwn then GetValue(lm_hist, lmn) else lwn);

def mstep = (lmax - lmin) / scanlength;
def aperc = leveling / scanlength;

def db = (fold dbx = 0 to scanlength  
            while (fold blx = 0 to cyclicmemory -1
                     with b
                     do b + if GetValue(crsi, blx) < lmin + mstep * dbx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmin + mstep * dbx);

def ub = (fold ubx = 0 to scanlength  
            while (fold ulx = 0 to cyclicmemory -1
                     with a
                     do a + if GetValue(crsi, ulx) >= lmax - mstep * ubx then 1 else 0
            ) / cyclicmemory >= aperc
            do lmax - mstep * ubx);

AddLabel(yes, "Dominant Cycle: " + dominantCycle);

It works perfectly fine with no errors! But I had to remove the code that plots the CRSI. However... if you add ANY CODE AT ALL before the last AddLabel, it goes back to complaining about Folding integer is NaN. It doesn't make any sense?



i think this works

this was 0 on 1st bar, causing a divide by 0 error
cycleCount = TotalSum(zzCycles);

i made a if then structure to only process valid data

def cycleDoms;
def cycleCount;
def dominantCycle;
if bn == 1 then {
cycleDoms = 0;
cycleCount = 0;
dominantCycle = 1;
} else if (!isnan(close) and TotalSum(zzCycles) > 0) then {
cycleDoms = TotalSum(zzDomTotal);
cycleCount = TotalSum(zzCycles);
dominantCycle = if (isnan(close) and cycleCount > 0) then 0 else (Round(((cycleDoms / cycleCount) / 10), 0) * 10);
} else {
cycleDoms = 0;
cycleCount = 0;
dominantCycle = 1;
}



i made up numbers for the last condition. 0, 0, 1. they may need to be changed..?

there may need to be some more number checking/altering. the signals on first few dozen bars may be too low and skew the plots.


Code:
# cyclic_RSI_v2_Fold_00


# https://usethinkscript.com/threads/cyclic-rsi-v2-fold-ing-integer-to-is-expected.13170/
# Cyclic RSI v2 - Fold-ing integer "to" is expected
#  mfox  10/28

#sig
#I have been investing for 4 years. I have been programming for 20+. I've been writing scripts on other platforms for years, and TOS is no different. Scalping is primarily my focus. Any insinuated stock or trading information is to be taken lightly, and/or not intended. All code I share is yours to do with as you please but I take no liability for any financial setbacks it may cause you.



#After someone recently commented on Cyclic RSI v1, I mentioned that I don't really trade anymore, and I'm too busy to do much Thinkscript'ing, but it made me start wondering about this script again. I was always disappointed with the fact that I couldn't get the DRO (dominant rhythm oscillator) working to dynamically set the lookback for the Cyclic RSI. So I did some digging...

#I realized that if I was lucky, I could tweak the ZigZagHigh lows to count the bars between highs, and it might have already been out there somewhere, but I didn't find it, so I changed a script from Tomsk and got it working:



#code

#Eureka! An average cycle rounded to the nearest 10 (which I will eventually use to perform harmonic reduction on larger values, 40, 80, 120 all go to 40). So I plugged it into my script below, but I ran into a problem. All of my folds now break for some reason. If I read the label from the cycle above I might get exactly 30, in non-decimal form. This goes into a variable CyclicMemory which is domCycle * 2. However, when I started fold'ing, my script compiles, but won't render with the error: "Folding integer 'to' is expected. NaN". I know this has to do with data types and variable lengths, and in a lot of cases I had to break things like Highest() out to a fold to avoid the dreaded "CL constant function parameter 'length'" error. Here's my CyclicRSI v2 script below (assuming domCycle = output of script above), with clutter removed:

#code

# honestly hope this is a simple mistake, I'll shoulder that shame no problem, I've just always wanted to get this indicator to be truly dynamic. You can see all the folds that go to "cyclicmemory -1" are where this error occurs, but they all seem fine to me. Naturally, if I hard code any integer to the cyclicmemory variable, the code works fine. Is there any possible workaround for this? It's literally the one thing stopping Cyclic RSI v2 from working.


#------------------------------------------------------


# look for vars in folds
#151
#def cyclicmemory = 0;
# 115
#def dominantCycle = 0;




# post4
#Complete code:


# ZigZag High Low Stats
# tomsk
# 11.16.2019

# V1.0 - 11.16.2019 - tomsk - Initial release of ZigZag High Low Stats

# Extracted idea from RDMercer's post #369 of a variant of a massive
# Zig Zag High Low Supply Demand study that comprises many different
# components
#
# https://usethinkscript.com/threads/trend-reversal-indicator-with-signals-for-thinkorswim.183/page-19#post-369
#
# I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High
# Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points
#
# Label for Confirmed/Unconfirmed Status of Current Zigzag
# Price Change between Zigzags
# Price at Zigzag High/Low
# Bar Count between Zigzags
# Volume at Zigzag Reversals


def bn = barnumber();

# added by mfox
    input dominantType = {default "Highs", "Lows"};
    def cycleMode;
    switch (dominantType) {
    case "Highs":
        cycleMode = 1;
    case "Lows":
        cycleMode = 2;
    }

    input BubbleOffset = .0005;
    input PercentAmount = .01;
    input RevAmount = .05;
    input ATRreversal = 3.0;
    input ATRlength = 5;

    def zz = ZigZagHighLow("price h" = high, "price l" = low, "percentage reversal" = PercentAmount,
"absolute reversal" = RevAmount, "atr length" = ATRlength, "atr reversal" = ATRreversal);

    def ReversalAmount = if (close * PercentAmount / 100) > Max(RevAmount < ATRreversal * reference ATR(ATRlength), RevAmount)
                     then (close * PercentAmount / 100)
                     else if RevAmount < ATRreversal * reference ATR(ATRlength)
                          then ATRreversal * reference ATR(ATRlength)
                          else RevAmount;
# Zig Zag Specific Data

    plot zzz = zz;
    zzz.EnableApproximation();

    def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
    def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
    def isUp = chg >= 0;

# Bar Count Specific Data

    def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;

# Dom Count Specific Data - Added by mfox
    def zzDomCount = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then 1 else zzDomCount[1] + 1;

    def zzDomTotal = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then zzDomCount[1] else 0;

    def zzCycles = zzCount == 1 and isUp == (if cycleMode == 1 then yes else no);

#    def cycleDoms = TotalSum(zzDomTotal);
#    def cycleCount = TotalSum(zzCycles);

#    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
#    dominantCycle.Hide();

#def dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;

#def dominantCycle = if isnan(close) then 0 else (Round(((cycleDoms / cycleCount) / 10), 0) * 10);


def cycleDoms;
def cycleCount;
def dominantCycle;
if bn == 1 then {
  cycleDoms = 0;
  cycleCount = 0;
  dominantCycle = 1;
} else if (!isnan(close) and TotalSum(zzCycles) > 0) then {
  cycleDoms = TotalSum(zzDomTotal);
  cycleCount = TotalSum(zzCycles);
  dominantCycle = if (isnan(close) and cycleCount > 0) then 0 else (Round(((cycleDoms / cycleCount) / 10), 0) * 10);
} else {
  cycleDoms = 0;
  cycleCount = 0;
  dominantCycle = 1;
}


# setting dominantCycle  to a number works
# no errors in bubble vars

#def dominantCycle = 30;
    plot zdomcyc = dominantCycle;
    zdomcyc.Hide();

def uu = isnan(cycleDoms) or isnan(cycleDoms);

addchartbubble(0, 20, 
 zz + "\n" +
 zzDomTotal + " zd\n" +
 zzCycles + " zc\n" +

 cycleDoms + "\n" +
 cycleCount + "\n" +
# (Round(((cycleDoms / cycleCount) / 10), 0) * 10) + "\n" +
dominantCycle
, (if uu then color.yellow else color.gray), no);


# Cyclic RSI
# Origanlly found on Tradingview: https://www.tradingview.com/v/TmqiR1jp/
# Shout out to WentToTrade for the amazing indicator.
# Written in ThinkScript by mfox

# The cyclic smoothed RSI indicator is an enhancement of the classic RSI , adding
# additional smoothing according to the market vibration,
# adaptive upper and lower bands according to the cyclic memory and
# using the current dominant cycle length as input for the indicator.

# The cRSI is used like a standard indicator. The chart highlights trading signals where the signal line # crosses above or below the adaptive lower/upper bands. It is much more responsive to market moves than the basic RSI.

# The indicator uses the dominant cycle as input to optimize signal, smoothing and cyclic memory. To get more in-depth information on the cyclic-smoothed RSI indicator, please read Chapter 4 "Fine tuning technical indicators" of the book "Decoding the Hidden Market Rhythm, Part 1" available at your favorite book store.

declare lower;

def src = close;
# change 1
# old
# input domcycle = 20;
# new
def domcycle = dominantCycle;
def cyclelen = domcycle / 2;
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = domcycle * 2;

addchartbubble(0, 70,
  cyclicmemory 
, color.yellow, yes);



input scanlength = 100;

input RSIOversold = 30;
input RSIOverbought = 70;

plot h1 = RSIOversold;
h1.SetDefaultColor(Color.GRAY);
h1.SetPaintingStrategy(PaintingStrategy.DASHES);
h1.SetLineWeight(1);

plot h2 = RSIOverbought;
h2.SetDefaultColor(Color.GRAY);
h2.SetPaintingStrategy(PaintingStrategy.DASHES);
h2.SetLineWeight(1);

def torque = 2.0 / (vibration + 1.0);
def phasingLag = (vibration - 1.0) / 2.0;


def up = (1 / cyclelen) * (Max((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(up[1]) then 0 else up[1]);
def down = (1 / cyclelen) * (-Min((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(down[1]) then 0 else down[1]);

def rsi = if down == 0 then 100 else if up == 0 then 0 else 100 - 100 / (1 + up / down);
def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * (if IsNaN(crsi[1]) then 0 else crsi[1]);

# change 2
# old
# def lm_hist = if crsi > Highest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then crsi
#              else if -crsi < Lowest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then -crsi
#              else 0;
# new


# chg all folds to 60 , it works, no error

def memHigh = fold hx = 0 to cyclicmemory -1 
#def memHigh = fold hx = 0 to 60 -1 
  with lw = double.NEGATIVE_INFINITY
  do if high > lw then high else lw;

def memLow = fold lx = 0 to cyclicmemory -1
#def memLow = fold lx = 0 to 60 -1
  with hw = double.poSITIVE_INFINITY
  do if low < hw then low else hw;

def lm_hist = if crsi > memHigh and !IsNaN(lm_hist[1])
                then crsi
              else if -crsi < memLow and !IsNaN(lm_hist[1])
                then -crsi
              else 0;

# change 3
# old
#def lmax = -Highest(lm_hist, cyclicmemory -1);
#def lmin = -Lowest(lm_hist, cyclicmemory -1);

def lmax = - (fold lmx = 0 to cyclicmemory -1
#def lmax = - (fold lmx = 0 to 60 -1
  with lwx = double.Negative_infinity 
  do if GetValue(lm_hist, lmx) > lwx then GetValue(lm_hist, lmx) else lwx);

def lmin = - (fold lmn = 0 to cyclicmemory -1
#def lmin = - (fold lmn = 0 to 60 -1
  with lwn = double.positive_infinity
  do if GetValue(lm_hist, lmn) < lwn then GetValue(lm_hist, lmn) else lwn);


def mstep = (lmax - lmin) / 100;
def aperc = leveling / 100;

# change 4

# problem: folding to "cyclicmemory - 1" now produces an error: Folding intenger "to" is expected. NaN

# ???

def db = fold dbx = 0 to 100   
            while (fold blx = 0 to cyclicmemory - 1
#            while (fold blx = 0 to 60 - 1
                     with b
                     do b + if GetValue(crsi, blx) < lmin + mstep * dbx then 1 else 0 ) / cyclicmemory >= aperc
            do lmin + mstep * dbx;

def ub = fold ubx = 0 to 100   
            while (fold ulx = 0 to cyclicmemory - 1
#            while (fold ulx = 0 to getvalue(cyclicmemory, 0) - 1
#            while (fold ulx = 0 to 60 - 1
                     with a
                     do a + if GetValue(crsi, ulx) >= lmax - mstep * ubx then 1 else 0 ) / cyclicmemory >= aperc
            do lmax - mstep * ubx;



plot lowband = db;
lowband.SetDefaultColor(Color.DARK_GREEN);

plot highband = ub;
highband.SetDefaultColor(Color.DARK_RED);

plot C = crsi;
C.SetDefaultColor(Color.PLUM);

plot Oversold = C < lowband;
Oversold.Hide();

plot Overbought = C > highband;
Overbought.Hide();

plot SuperOversold = lowband < RSIOversold and Oversold;
SuperOversold.Hide();

plot SuperOverbought = highband > RSIOverbought and Overbought;
SuperOverbought.Hide();

plot State = 50;
State.SetPaintingStrategy(PaintingStrategy.POINTS);
State.SetLineWeight(1);
State.AssignValueColor(if SuperOversold then Color.GREEN else
if Oversold then Color.DARK_GREEN else
if SuperOverbought then Color.RED else
if Overbought then Color.DARK_RED else
Color.GRAY);

# AddCloud(db,   ub,   Color.DARK_GRAY,   Color.DARK_GRAY);
# AddCloud(0, if SuperOversold   then Double.POSITIVE_INFINITY else Double.NaN,      Color.GREEN,      Color.GREEN);
# AddCloud(0, if Oversold        then Double.POSITIVE_INFINITY else Double.NaN, Color.DARK_GREEN, Color.DARK_GREEN);
# AddCloud(0, if SuperOverbought then Double.POSITIVE_INFINITY else Double.NaN,        Color.RED,        Color.RED);
# AddCloud(0, if Overbought      then Double.POSITIVE_INFINITY else Double.NaN,   Color.DARK_RED,   Color.DARK_RED);

AddLabel(yes, (if SuperOversold then "Super Oversold" else  if Oversold then "Oversold" else  if SuperOverbought then "Super Overbought" else if Overbought then "Overbought" else  "Neutral"), if SuperOversold then Color.GREEN else
if Oversold then Color.DARK_GREEN else
if SuperOverbought then Color.RED else
if Overbought then Color.DARK_RED else
Color.GRAY);

AddLabel(yes, "Dominant Cycle: " + dominantCycle);




# post5
#It does appear that the value in question, dominantCycle, from the modified Tomsk script, appears to be getting a NaN, causing the fold's to fail, though I cannot determine why. In the lower section, if I change the code:

#Code:
## def domCycle = dominantCycle;
#def domcycle = if isNaN(dominantCycle) then 20 else if dominantCycle <= 0 then 20 else dominantCycle;

#Then it at least renders on the screen, but obviously its incorrect. As to why I'm getting a NaN, could really only mean that when I'm counting the distance between highs (or lows based on settings) that I am getting a NaN when calculating the average (plot dominantCycle etc...). However when I tried to debug this with a chart bubble, no bars seemed to show an example of this NaN.

#

TJX 5min
PH47KnL.jpg
 
i think this works

this was 0 on 1st bar, causing a divide by 0 error
cycleCount = TotalSum(zzCycles);

i made a if then structure to only process valid data

def cycleDoms;
def cycleCount;
def dominantCycle;
if bn == 1 then {
cycleDoms = 0;
cycleCount = 0;
dominantCycle = 1;
} else if (!isnan(close) and TotalSum(zzCycles) > 0) then {
cycleDoms = TotalSum(zzDomTotal);
cycleCount = TotalSum(zzCycles);
dominantCycle = if (isnan(close) and cycleCount > 0) then 0 else (Round(((cycleDoms / cycleCount) / 10), 0) * 10);
} else {
cycleDoms = 0;
cycleCount = 0;
dominantCycle = 1;
}



i made up numbers for the last condition. 0, 0, 1. they may need to be changed..?

there may need to be some more number checking/altering. the signals on first few dozen bars may be too low and skew the plots.


Code:
# cyclic_RSI_v2_Fold_00


# https://usethinkscript.com/threads/cyclic-rsi-v2-fold-ing-integer-to-is-expected.13170/
# Cyclic RSI v2 - Fold-ing integer "to" is expected
#  mfox  10/28

#sig
#I have been investing for 4 years. I have been programming for 20+. I've been writing scripts on other platforms for years, and TOS is no different. Scalping is primarily my focus. Any insinuated stock or trading information is to be taken lightly, and/or not intended. All code I share is yours to do with as you please but I take no liability for any financial setbacks it may cause you.



#After someone recently commented on Cyclic RSI v1, I mentioned that I don't really trade anymore, and I'm too busy to do much Thinkscript'ing, but it made me start wondering about this script again. I was always disappointed with the fact that I couldn't get the DRO (dominant rhythm oscillator) working to dynamically set the lookback for the Cyclic RSI. So I did some digging...

#I realized that if I was lucky, I could tweak the ZigZagHigh lows to count the bars between highs, and it might have already been out there somewhere, but I didn't find it, so I changed a script from Tomsk and got it working:



#code

#Eureka! An average cycle rounded to the nearest 10 (which I will eventually use to perform harmonic reduction on larger values, 40, 80, 120 all go to 40). So I plugged it into my script below, but I ran into a problem. All of my folds now break for some reason. If I read the label from the cycle above I might get exactly 30, in non-decimal form. This goes into a variable CyclicMemory which is domCycle * 2. However, when I started fold'ing, my script compiles, but won't render with the error: "Folding integer 'to' is expected. NaN". I know this has to do with data types and variable lengths, and in a lot of cases I had to break things like Highest() out to a fold to avoid the dreaded "CL constant function parameter 'length'" error. Here's my CyclicRSI v2 script below (assuming domCycle = output of script above), with clutter removed:

#code

# honestly hope this is a simple mistake, I'll shoulder that shame no problem, I've just always wanted to get this indicator to be truly dynamic. You can see all the folds that go to "cyclicmemory -1" are where this error occurs, but they all seem fine to me. Naturally, if I hard code any integer to the cyclicmemory variable, the code works fine. Is there any possible workaround for this? It's literally the one thing stopping Cyclic RSI v2 from working.


#------------------------------------------------------


# look for vars in folds
#151
#def cyclicmemory = 0;
# 115
#def dominantCycle = 0;




# post4
#Complete code:


# ZigZag High Low Stats
# tomsk
# 11.16.2019

# V1.0 - 11.16.2019 - tomsk - Initial release of ZigZag High Low Stats

# Extracted idea from RDMercer's post #369 of a variant of a massive
# Zig Zag High Low Supply Demand study that comprises many different
# components
#
# https://usethinkscript.com/threads/trend-reversal-indicator-with-signals-for-thinkorswim.183/page-19#post-369
#
# I heavily modified, cleaned up and extracted some interesting Zig Zag statistical information resulting in this study called Zig Zag High
# Low Stats. It displays the following information represented via bubbles at each of the Zig zag turning points
#
# Label for Confirmed/Unconfirmed Status of Current Zigzag
# Price Change between Zigzags
# Price at Zigzag High/Low
# Bar Count between Zigzags
# Volume at Zigzag Reversals


def bn = barnumber();

# added by mfox
    input dominantType = {default "Highs", "Lows"};
    def cycleMode;
    switch (dominantType) {
    case "Highs":
        cycleMode = 1;
    case "Lows":
        cycleMode = 2;
    }

    input BubbleOffset = .0005;
    input PercentAmount = .01;
    input RevAmount = .05;
    input ATRreversal = 3.0;
    input ATRlength = 5;

    def zz = ZigZagHighLow("price h" = high, "price l" = low, "percentage reversal" = PercentAmount,
"absolute reversal" = RevAmount, "atr length" = ATRlength, "atr reversal" = ATRreversal);

    def ReversalAmount = if (close * PercentAmount / 100) > Max(RevAmount < ATRreversal * reference ATR(ATRlength), RevAmount)
                     then (close * PercentAmount / 100)
                     else if RevAmount < ATRreversal * reference ATR(ATRlength)
                          then ATRreversal * reference ATR(ATRlength)
                          else RevAmount;
# Zig Zag Specific Data

    plot zzz = zz;
    zzz.EnableApproximation();

    def zzSave = if !IsNaN(zz) then zz else GetValue(zzSave, 1);
    def chg = (if zzSave == high then high else low) - GetValue(zzSave, 1);
    def isUp = chg >= 0;

# Bar Count Specific Data

    def zzCount = if zzSave[1] != zzSave then 1 else if zzSave[1] == zzSave then zzCount[1] + 1 else 0;

# Dom Count Specific Data - Added by mfox
    def zzDomCount = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then 1 else zzDomCount[1] + 1;

    def zzDomTotal = if zzCount == 1 and isUp == (if cycleMode == 1 then yes else no) then zzDomCount[1] else 0;

    def zzCycles = zzCount == 1 and isUp == (if cycleMode == 1 then yes else no);

#    def cycleDoms = TotalSum(zzDomTotal);
#    def cycleCount = TotalSum(zzCycles);

#    plot dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;
#    dominantCycle.Hide();

#def dominantCycle = Round(((cycleDoms / cycleCount) / 10), 0) * 10;

#def dominantCycle = if isnan(close) then 0 else (Round(((cycleDoms / cycleCount) / 10), 0) * 10);


def cycleDoms;
def cycleCount;
def dominantCycle;
if bn == 1 then {
  cycleDoms = 0;
  cycleCount = 0;
  dominantCycle = 1;
} else if (!isnan(close) and TotalSum(zzCycles) > 0) then {
  cycleDoms = TotalSum(zzDomTotal);
  cycleCount = TotalSum(zzCycles);
  dominantCycle = if (isnan(close) and cycleCount > 0) then 0 else (Round(((cycleDoms / cycleCount) / 10), 0) * 10);
} else {
  cycleDoms = 0;
  cycleCount = 0;
  dominantCycle = 1;
}


# setting dominantCycle  to a number works
# no errors in bubble vars

#def dominantCycle = 30;
    plot zdomcyc = dominantCycle;
    zdomcyc.Hide();

def uu = isnan(cycleDoms) or isnan(cycleDoms);

addchartbubble(0, 20,
 zz + "\n" +
 zzDomTotal + " zd\n" +
 zzCycles + " zc\n" +

 cycleDoms + "\n" +
 cycleCount + "\n" +
# (Round(((cycleDoms / cycleCount) / 10), 0) * 10) + "\n" +
dominantCycle
, (if uu then color.yellow else color.gray), no);


# Cyclic RSI
# Origanlly found on Tradingview: https://www.tradingview.com/v/TmqiR1jp/
# Shout out to WentToTrade for the amazing indicator.
# Written in ThinkScript by mfox

# The cyclic smoothed RSI indicator is an enhancement of the classic RSI , adding
# additional smoothing according to the market vibration,
# adaptive upper and lower bands according to the cyclic memory and
# using the current dominant cycle length as input for the indicator.

# The cRSI is used like a standard indicator. The chart highlights trading signals where the signal line # crosses above or below the adaptive lower/upper bands. It is much more responsive to market moves than the basic RSI.

# The indicator uses the dominant cycle as input to optimize signal, smoothing and cyclic memory. To get more in-depth information on the cyclic-smoothed RSI indicator, please read Chapter 4 "Fine tuning technical indicators" of the book "Decoding the Hidden Market Rhythm, Part 1" available at your favorite book store.

declare lower;

def src = close;
# change 1
# old
# input domcycle = 20;
# new
def domcycle = dominantCycle;
def cyclelen = domcycle / 2;
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = domcycle * 2;

addchartbubble(0, 70,
  cyclicmemory
, color.yellow, yes);



input scanlength = 100;

input RSIOversold = 30;
input RSIOverbought = 70;

plot h1 = RSIOversold;
h1.SetDefaultColor(Color.GRAY);
h1.SetPaintingStrategy(PaintingStrategy.DASHES);
h1.SetLineWeight(1);

plot h2 = RSIOverbought;
h2.SetDefaultColor(Color.GRAY);
h2.SetPaintingStrategy(PaintingStrategy.DASHES);
h2.SetLineWeight(1);

def torque = 2.0 / (vibration + 1.0);
def phasingLag = (vibration - 1.0) / 2.0;


def up = (1 / cyclelen) * (Max((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(up[1]) then 0 else up[1]);
def down = (1 / cyclelen) * (-Min((src - src[1]), 0)) + (1 - (1 / cyclelen)) * (if IsNaN(down[1]) then 0 else down[1]);

def rsi = if down == 0 then 100 else if up == 0 then 0 else 100 - 100 / (1 + up / down);
def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * (if IsNaN(crsi[1]) then 0 else crsi[1]);

# change 2
# old
# def lm_hist = if crsi > Highest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then crsi
#              else if -crsi < Lowest(crsi, cyclicmemory - 1) and !IsNaN(lm_hist[1])
#                then -crsi
#              else 0;
# new


# chg all folds to 60 , it works, no error

def memHigh = fold hx = 0 to cyclicmemory -1
#def memHigh = fold hx = 0 to 60 -1
  with lw = double.NEGATIVE_INFINITY
  do if high > lw then high else lw;

def memLow = fold lx = 0 to cyclicmemory -1
#def memLow = fold lx = 0 to 60 -1
  with hw = double.poSITIVE_INFINITY
  do if low < hw then low else hw;

def lm_hist = if crsi > memHigh and !IsNaN(lm_hist[1])
                then crsi
              else if -crsi < memLow and !IsNaN(lm_hist[1])
                then -crsi
              else 0;

# change 3
# old
#def lmax = -Highest(lm_hist, cyclicmemory -1);
#def lmin = -Lowest(lm_hist, cyclicmemory -1);

def lmax = - (fold lmx = 0 to cyclicmemory -1
#def lmax = - (fold lmx = 0 to 60 -1
  with lwx = double.Negative_infinity
  do if GetValue(lm_hist, lmx) > lwx then GetValue(lm_hist, lmx) else lwx);

def lmin = - (fold lmn = 0 to cyclicmemory -1
#def lmin = - (fold lmn = 0 to 60 -1
  with lwn = double.positive_infinity
  do if GetValue(lm_hist, lmn) < lwn then GetValue(lm_hist, lmn) else lwn);


def mstep = (lmax - lmin) / 100;
def aperc = leveling / 100;

# change 4

# problem: folding to "cyclicmemory - 1" now produces an error: Folding intenger "to" is expected. NaN

# ???

def db = fold dbx = 0 to 100  
            while (fold blx = 0 to cyclicmemory - 1
#            while (fold blx = 0 to 60 - 1
                     with b
                     do b + if GetValue(crsi, blx) < lmin + mstep * dbx then 1 else 0 ) / cyclicmemory >= aperc
            do lmin + mstep * dbx;

def ub = fold ubx = 0 to 100  
            while (fold ulx = 0 to cyclicmemory - 1
#            while (fold ulx = 0 to getvalue(cyclicmemory, 0) - 1
#            while (fold ulx = 0 to 60 - 1
                     with a
                     do a + if GetValue(crsi, ulx) >= lmax - mstep * ubx then 1 else 0 ) / cyclicmemory >= aperc
            do lmax - mstep * ubx;



plot lowband = db;
lowband.SetDefaultColor(Color.DARK_GREEN);

plot highband = ub;
highband.SetDefaultColor(Color.DARK_RED);

plot C = crsi;
C.SetDefaultColor(Color.PLUM);

plot Oversold = C < lowband;
Oversold.Hide();

plot Overbought = C > highband;
Overbought.Hide();

plot SuperOversold = lowband < RSIOversold and Oversold;
SuperOversold.Hide();

plot SuperOverbought = highband > RSIOverbought and Overbought;
SuperOverbought.Hide();

plot State = 50;
State.SetPaintingStrategy(PaintingStrategy.POINTS);
State.SetLineWeight(1);
State.AssignValueColor(if SuperOversold then Color.GREEN else
if Oversold then Color.DARK_GREEN else
if SuperOverbought then Color.RED else
if Overbought then Color.DARK_RED else
Color.GRAY);

# AddCloud(db,   ub,   Color.DARK_GRAY,   Color.DARK_GRAY);
# AddCloud(0, if SuperOversold   then Double.POSITIVE_INFINITY else Double.NaN,      Color.GREEN,      Color.GREEN);
# AddCloud(0, if Oversold        then Double.POSITIVE_INFINITY else Double.NaN, Color.DARK_GREEN, Color.DARK_GREEN);
# AddCloud(0, if SuperOverbought then Double.POSITIVE_INFINITY else Double.NaN,        Color.RED,        Color.RED);
# AddCloud(0, if Overbought      then Double.POSITIVE_INFINITY else Double.NaN,   Color.DARK_RED,   Color.DARK_RED);

AddLabel(yes, (if SuperOversold then "Super Oversold" else  if Oversold then "Oversold" else  if SuperOverbought then "Super Overbought" else if Overbought then "Overbought" else  "Neutral"), if SuperOversold then Color.GREEN else
if Oversold then Color.DARK_GREEN else
if SuperOverbought then Color.RED else
if Overbought then Color.DARK_RED else
Color.GRAY);

AddLabel(yes, "Dominant Cycle: " + dominantCycle);




# post5
#It does appear that the value in question, dominantCycle, from the modified Tomsk script, appears to be getting a NaN, causing the fold's to fail, though I cannot determine why. In the lower section, if I change the code:

#Code:
## def domCycle = dominantCycle;
#def domcycle = if isNaN(dominantCycle) then 20 else if dominantCycle <= 0 then 20 else dominantCycle;

#Then it at least renders on the screen, but obviously its incorrect. As to why I'm getting a NaN, could really only mean that when I'm counting the distance between highs (or lows based on settings) that I am getting a NaN when calculating the average (plot dominantCycle etc...). However when I tried to debug this with a chart bubble, no bars seemed to show an example of this NaN.

#

TJX 5min
PH47KnL.jpg

Good stuff. I do see it compiles, but I will have to deep dive before I consider it resolved since when placed side-by-side with my CyclicRSI v1, ub/db (upper and lower rsi bands), are all way off.

I appreciate your help so far!
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
405 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top