Cyclic Smoothed RSI with Divergence For ThinkOrSwim

petergluis

Active member
Here is cRSI + Waves Indicator with VWMA overlay. It provides an effective way find the stock bottoms.

// Hints
// - The most common parameter to change is the [CRSI Top/Bottom Detector Lookback]. Different stocks will have different levels of strength in their peaks. A setting of 2 may generate too many corrective waves.
// - Different times scales will give you different wave counts. This is to be expected. A conunter impulse wave inside a corrective wave may actually go above the cRSI WMA on a smaller time frame. You may need to increase it one or two levels to see large waves.
// - Just because you see divergence (bear or hidden bear) does not mean a price is going to go down. Often price continues to rise through bears, so take note and that is normal. Bulls are usually pretty good indicators especially if you see them on C,E,G waves.

P84Z1qO.png


Here is the link of the strategy. But I would like to have the indicator based on ThinkScript. Thank you very much for your help.
https://www.tradingview.com/script/Wa7IfacA-Cyclic-Smoothed-RSI-with-Divergence-Indicator/
 
Last edited by a moderator:

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

I would like to know whether there is ThinkOrSwim version of cRSI + Waves Indicator with VWMA overlay. It provides an effective way find the stock bottoms.

Here is the link of the strategy. But I would like to have the indicator based on ThinkScript. Thank you very much for your help.

https://www.tradingview.com/script/Wa7IfacA-Cyclic-Smoothed-RSI-with-Divergence-Indicator/



// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Dr_Roboto
//
//@version=4
//
// This indicator uses the cyclic smoothed Relative Strength Index (cRSI) instead of the traditional Relative Strength Index (RSI). See below for more info on the benefits to the cRSI.
//
// My key contributions
// 1) A Weighted Moving Average (WMA) to track the general trend of the cRSI signal. This is very helpful in determining when the equity switches from bullish to bearish, which can be used to determine buy/sell points.
// This is then is used to color the region between the upper and lower cRSI bands (green above, red below).
// 2) An attempt to detect the motive (impulse) and corrective and waves. Corrective waves are indicated A, B, C, D, E, F, G. F and G waves are not technically Elliot Waves, but the way I detect waves it is really hard
// to always get it right. Once and a while you could actually see G and F a second time. Motive waves are identified as s (strong) and w (weak). Strong waves have a peak above the cRSI upper band and weak waves have a peak below the upper band.
// 3) My own divergence indicator for bull, hidden bull, bear, and hidden bear. I was not able to replicate the TradingView style of drawing a line from peak to peak, but for this indicator I think in the end it makes the chart cleaner.
// 4) I have also added "alert conditions" for most of the key events. Select the equity you want (such as: SPX) and the desired timeframe (such as: D).
// Go to the TradingView "Alerts" tab (click the alarm clock icon) --> Create Alert (alarm clock with a +) --> Change the first condition drop down to "Cyclic Smoothed RSI with Motive-Corrective Wave Indicator" --> in the
// drop down below that select the alert that you want (such as: Bull - cRSI Above WMA). You will want to give the alert a good name that includes the ticker name and time frame, for example "SPX 1D: Bull - cRSI above WMA"
//
// There is a latency issue with an indicator like this that is based on moving averages. That means they tend to trigger right after key events. Perfect timing is not possible strictly with these indicators, but they do work
// very well "on average." However, my implementation has minimal latency as peaks (tops/bottoms) only require one bar to detect.
//
// As a bit of an Easter Egg, this code can be tweaked and run as a strategy to get buy/sell signals. I use this code for both my indicator and for trading strategy. Just copy and past it into a new strategy script and just
// change it from study to something like.
// strategy("cRSI + Waves Strategy with VWMA overlay", overlay=overlay)
// The buy/sell code is at the end and just needs to be uncommented. I make no promises or guarantees about how good it is as a strategy, but it gives you some code and ideas to work with.
//
// Tuning
// 1) Volume Weighted Moving Average (VWMA): This is a “hidden strategy” feature implemented that will display the high-low bands of the VWMA on the price chart if run the code using “overlay = true”.
// - [Use Volume for VWMA] If the equity does not have volume, then the VWMA will not show up. Uncheck this box and it will use the regular WMA (no volume).
// - [VWMA Length] defines how far back the WMA averages price.
//
// 2) cRSI (Black line in the indicator)
// - [CRSI Dominate Cycle Length] Increase to length that amount of time a band (upper/lower) stays high/low after a peak. Reduce the value to shorten the time. Just increment it up/down to see the effect.
// - [CRSI Moving Average Length] defines how far back the SMA averages the cRSI. This affects the purple line in the indicator.
// - [CRSI Top/Bottom Detector Lookback] defines how many bars back the peak detector looks to determine if a peak has occurred. For example, a top is detected like this: current-bar down relative to the 1-bar-back,
// 1-bar-back up relative to 2-bars-back (look back = 1), c) 2-bars-back up relative to 3-bars-back (lookback = 2), and d) 3-bars-back up relative to 4-bars-back (lookback = 3). I hope that makes sense. There are
// only 2 options for this setting: 2 or 3 bars. 2 bars will be able to detect small peaks but create more “false” peaks that may not be meaningful. 3 bars will be more robust but can miss short duration peaks.
//
// 3) Waves
// - The check boxes are self explanatory for which labels they turn on and off on the plot.
//
// 4) Divergence Indicators
// - The check boxes are self explanatory for which labels they turn on and off on the plot.
//
// Hints
// - The most common parameter to change is the [CRSI Top/Bottom Detector Lookback]. Different stocks will have different levels of strength in their peaks. A setting of 2 may generate too many corrective waves.
// - Different times scales will give you different wave counts. This is to be expected. A conunter impulse wave inside a corrective wave may actually go above the cRSI WMA on a smaller time frame. You may need to increase it one or two levels to see large waves.
// - Just because you see divergence (bear or hidden bear) does not mean a price is going to go down. Often price continues to rise through bears, so take note and that is normal. Bulls are usually pretty good indicators especially if you see them on C,E,G waves.
//
//
// ---------------------------------------
// cyclic smoothed RSI (cRSI) indicator
// ---------------------------------------
// The “core” code for the cyclic smoothed RSI (cRSI) indicator was written by Lars von Theinen and is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/. Copyright (C) 2017 CC BY,
// whentotrade / Lars von Thienen. For more details on the cRSI Indicator: https://www.tradingview.com/script/TmqiR1jp-RSI-cyclic-smoothed-v2/
//
// The cyclic smoothed RSI indicator is an enhancement of the classic RSI, adding
// 1) additional smoothing according to the market vibration,
// 2) adaptive upper and lower bands according to the cyclic memory and
// 3) using the current dominant cycle length as input for the indicator.
// 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 Decoding The Hidden Market Rhythm - Part 1: Dynamic Cycles (2017), Chapter 4: "Fine-tuning technical indicators." You need to derive the dominant cycle as input parameter for the cycle length as described in chapter 4.
Code:
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Dr_Roboto
//
//@version=4
//
// This indicator uses the cyclic smoothed Relative Strength Index (cRSI) instead of the traditional Relative Strength Index (RSI). See below for more info on the benefits to the cRSI.
//
// My key contributions
// 1) A Weighted Moving Average (WMA) to track the general trend of the cRSI signal. This is very helpful in determining when the equity switches from bullish to bearish, which can be used to determine buy/sell points.
// This is then is used to color the region between the upper and lower cRSI bands (green above, red below).
// 2) An attempt to detect the motive (impulse) and corrective and waves. Corrective waves are indicated A, B, C, D, E, F, G. F and G waves are not technically Elliot Waves, but the way I detect waves it is really hard
// to always get it right. Once and a while you could actually see G and F a second time. Motive waves are identified as s (strong) and w (weak). Strong waves have a peak above the cRSI upper band and weak waves have a peak below the upper band.
// 3) My own divergence indicator for bull, hidden bull, bear, and hidden bear. I was not able to replicate the TradingView style of drawing a line from peak to peak, but for this indicator I think in the end it makes the chart cleaner.
// 4) I have also added "alert conditions" for most of the key events. Select the equity you want (such as: SPX) and the desired timeframe (such as: D).
// Go to the TradingView "Alerts" tab (click the alarm clock icon) --> Create Alert (alarm clock with a +) --> Change the first condition drop down to "Cyclic Smoothed RSI with Motive-Corrective Wave Indicator" --> in the
// drop down below that select the alert that you want (such as: Bull - cRSI Above WMA). You will want to give the alert a good name that includes the ticker name and time frame, for example "SPX 1D: Bull - cRSI above WMA"
//
// There is a latency issue with an indicator like this that is based on moving averages. That means they tend to trigger right after key events. Perfect timing is not possible strictly with these indicators, but they do work
// very well "on average." However, my implementation has minimal latency as peaks (tops/bottoms) only require one bar to detect.
//
// As a bit of an Easter Egg, this code can be tweaked and run as a strategy to get buy/sell signals. I use this code for both my indicator and for trading strategy. Just copy and past it into a new strategy script and just
// change it from study to something like.
// strategy("cRSI + Waves Strategy with VWMA overlay", overlay=overlay)
// The buy/sell code is at the end and just needs to be uncommented. I make no promises or guarantees about how good it is as a strategy, but it gives you some code and ideas to work with.
//
// Tuning
// 1) Volume Weighted Moving Average (VWMA): This is a “hidden strategy” feature implemented that will display the high-low bands of the VWMA on the price chart if run the code using “overlay = true”.
// - [Use Volume for VWMA] If the equity does not have volume, then the VWMA will not show up. Uncheck this box and it will use the regular WMA (no volume).
// - [VWMA Length] defines how far back the WMA averages price.
//
// 2) cRSI (Black line in the indicator)
// - [CRSI Dominate Cycle Length] Increase to length that amount of time a band (upper/lower) stays high/low after a peak. Reduce the value to shorten the time. Just increment it up/down to see the effect.
// - [CRSI Moving Average Length] defines how far back the SMA averages the cRSI. This affects the purple line in the indicator.
// - [CRSI Top/Bottom Detector Lookback] defines how many bars back the peak detector looks to determine if a peak has occurred. For example, a top is detected like this: current-bar down relative to the 1-bar-back,
// 1-bar-back up relative to 2-bars-back (look back = 1), c) 2-bars-back up relative to 3-bars-back (lookback = 2), and d) 3-bars-back up relative to 4-bars-back (lookback = 3). I hope that makes sense. There are
// only 2 options for this setting: 2 or 3 bars. 2 bars will be able to detect small peaks but create more “false” peaks that may not be meaningful. 3 bars will be more robust but can miss short duration peaks.
//
// 3) Waves
// - The check boxes are self explanatory for which labels they turn on and off on the plot.
//
// 4) Divergence Indicators
// - The check boxes are self explanatory for which labels they turn on and off on the plot.
//
// Hints
// - The most common parameter to change is the [CRSI Top/Bottom Detector Lookback]. Different stocks will have different levels of strength in their peaks. A setting of 2 may generate too many corrective waves.
// - Different times scales will give you different wave counts. This is to be expected. A conunter impulse wave inside a corrective wave may actually go above the cRSI WMA on a smaller time frame. You may need to increase it one or two levels to see large waves.
// - Just because you see divergence (bear or hidden bear) does not mean a price is going to go down. Often price continues to rise through bears, so take note and that is normal. Bulls are usually pretty good indicators especially if you see them on C,E,G waves.
//
//
// ---------------------------------------
// cyclic smoothed RSI (cRSI) indicator
// ---------------------------------------
// The “core” code for the cyclic smoothed RSI (cRSI) indicator was written by Lars von Theinen and is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/. Copyright (C) 2017 CC BY,
// whentotrade / Lars von Thienen. For more details on the cRSI Indicator: https://www.tradingview.com/script/TmqiR1jp-RSI-cyclic-smoothed-v2/
//
// The cyclic smoothed RSI indicator is an enhancement of the classic RSI, adding
// 1) additional smoothing according to the market vibration,
// 2) adaptive upper and lower bands according to the cyclic memory and
// 3) using the current dominant cycle length as input for the indicator.
// 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 Decoding The Hidden Market Rhythm - Part 1: Dynamic Cycles (2017), Chapter 4: "Fine-tuning technical indicators." You need to derive the dominant cycle as input parameter for the cycle length as described in chapter 4.



//=================================================================================================================================
//=================================================================================================================================
overlay = true // plots VWMA (need to close and re-added)
// overlay = false // plots cRSI (need to close and re-added)
strategy("cRSI + Waves Strategy with VWMA overlay", overlay=overlay, max_bars_back=300)


//=================================================================================================================================
//=================================================================================================================================
// Disables cRSI and VWMA plotting so debug data can be plotted
// DEBUG = true
DEBUG = false


//=================================================================================================================================
//=================================================================================================================================
// Helper Functions
//=================================================================================================================================
//=================================================================================================================================
// function to convert bool to int
b2i(bval) =>
ival = bval ? 1 : 0

// function to look for a price in the lookback that is recently above the current price
recentAbove(in, thresh, lookback) =>
found = false
for i=0 to lookback
if in >= thresh
found := true
break
if found
res = true
else
res = false

// is value rising or falling based on history
isRisingFalling(in, lookback) =>
cntThresh = round(lookback*0.6) // majority = greater than 50%
cntUp = 0
cntDown = 0
rising = false
falling = false
// count up the times it is above or below the current value
for i=1 to lookback
if in[0] > in
cntUp := cntUp + 1
else if in[0] < in
cntDown := cntDown + 1
// rising
if cntUp > cntThresh
rising := true
else
rising := false
// falling
if cntDown > cntThresh
falling := true
else
falling := false
// flat
flat = not(rising) and not(falling)
// if flat, then select preivous value for rising and falling
if flat
rising := rising[1]
falling := falling[1]
// return tuple
[rising,falling,flat]

// Do the last several prices form a top
isTop(price, lookback) =>
if lookback == 3
// 3 prices back -> 3rd check helps ensure there was a down trend, but can miss some small reversals
// up->up->down
if (price[2] > price[3]) and (price[1] > price[2]) and (price[0] < price[1])
top = true
else
top = false
else
// 2 places back
// up->down
if (price[1] > price[2]) and (price[0] < price[1])
top = true
else
top = false

// Do the last several prices form a bottom
isBottom(price, lookback) =>
if lookback == 3
// 3 prices back -> 3rd check helps ensure there was a down trend, but can miss some small reversals
// down->down->up
if (price[2] < price[3]) and (price[1] < price[2]) and (price[0] > price[1])
bottom = true
else
bottom = false
else
// 2 prices back
// down->up
if (price[1] < price[2]) and (price[0] > price[1])
bottom = true
else
bottom = false

// function to filter multiple signals in a row
filterSignal(signalFlag, lookback) =>
signalFlagFilt = signalFlag
for i = 1 to lookback
signalFlagFilt := signalFlagFilt[0] == true and signalFlagFilt == true ? false : signalFlagFilt



//=================================================================================================================================
//=================================================================================================================================
// Price Movement
//=================================================================================================================================
//=================================================================================================================================
priceRising = close[0] >= close[1] and close[1] >= close[2]
priceFalling = close[0] <= close[1] and close[1] <= close[2]

// plot(priceRising?1.0:0,color=color.green)
// plot(priceFalling?1.0:0,color=color.red)

//=================================================================================================================================
//=================================================================================================================================
// Volume Weighted Moving Average (VWMA)
//=================================================================================================================================
//=================================================================================================================================
plotVWMA = overlay and not(DEBUG)

// check if volume is available for this equity
useVolume = input(title="Use Volume for VWMA (uncheck if equity does not have volume)", defval=true)

vwmaLen = input(defval=21, title="VWMA Length", type=input.integer, minval=1, maxval=200)
vwma = vwma(close, vwmaLen)
vwma_high = vwma(high, vwmaLen)
vwma_low = vwma(low, vwmaLen)

if not(useVolume)
vwma := wma(close, vwmaLen)
vwma_high := wma(high, vwmaLen)
vwma_low := wma(low, vwmaLen)

// +1 when above, -1 when below, 0 when inside
vwmaSignal(priceOpen, priceClose, vwmaHigh, vwmaLow) =>
sig = 0
color = color.gray
if priceClose > vwmaHigh
sig := 1
color := color.green
else if priceClose < vwmaLow
sig := -1
color := color.red
else
sig := 0
color := color.gray
[sig,color]

[vwma_sig, vwma_color] = vwmaSignal(open, close, vwma_high, vwma_low)

priceAboveVWMA = vwma_sig == 1 ? true : false
priceBelowVWMA = vwma_sig == -1 ? true : false
// plot(priceAboveVWMA?2.0:0,color=color.blue)
// plot(priceBelowVWMA?2.0:0,color=color.maroon)

// bandTrans = input(defval=70, title="VWMA Band Transparancy (100 invisible)", type=input.integer, minval=0, maxval=100)
// fillTrans = input(defval=70, title="VWMA Fill Transparancy (100 invisible)", type=input.integer, minval=0, maxval=100)
bandTrans = 70
fillTrans = 70

// ***** Plot VWMA *****
highband = plot(plotVWMA?fixnan(vwma_high):na, title='VWMA High band', color = vwma_color, linewidth=1, transp=bandTrans)
lowband = plot(plotVWMA?fixnan(vwma_low):na, title='VWMA Low band', color = vwma_color, linewidth=1, transp=bandTrans)
fill(lowband, highband, title='VWMA Band fill', color=vwma_color, transp=fillTrans)
plot(plotVWMA?vwma:na, title='VWMA', color = vwma_color, linewidth=3, transp=0)


//=================================================================================================================================
//=================================================================================================================================
// Moving Average (VWMA)
//=================================================================================================================================
//=================================================================================================================================
smaLineWidth = 8
smaLen1 = input(defval=50, title="SMA #1 Length", type=input.integer, minval=1, maxval=200)
plot(sma(close,smaLen1), title='SMA', color = color.blue, linewidth=smaLineWidth)


smaLen2 = input(defval=100, title="SMA #2 Length", type=input.integer, minval=1, maxval=200)
plot(sma(close,smaLen2), title='SMA', color = color.black, linewidth=smaLineWidth)



//=================================================================================================================================
//=================================================================================================================================
// Moving Average Convergence Divergence (MACD)
//=================================================================================================================================
//=================================================================================================================================
[macdLine, signalLine, histLine] = macd(close, 12, 26, 9)

// Is the histogram rising or falling
histLineRising = histLine[0] >= histLine[1] and histLine[1] >= histLine[2]
histLineFalling = histLine[0] <= histLine[1] and histLine[1] <= histLine[2]

// Did the histogram cross over zero
histLineCrossNeg2Pos = histLine[0] >= 0.0 and histLine[1] < 0.0
histLineCrossPos2Neg = histLine[0] <= 0.0 and histLine[1] > 0.0

// plot(histLineRising?1.0:0,color=color.green)
// plot(histLineFalling?1.0:0,color=color.red)
// plot(histLineCrossNeg2Pos?1.0:0,color=color.green)
// plot(histLineCrossPos2Neg?1.0:0,color=color.red)




//=================================================================================================================================
//=================================================================================================================================
// Cyclic Smoothed Relative Strength Index (cRSI)
//=================================================================================================================================
//=================================================================================================================================
plotCRSI = not(overlay) and not(DEBUG)

//src = input(title="cRSI Source", defval=close)
src = close
domcycle = input(10, minval=5, title="cRSI Dominant Cycle Length (persist after high/low)") //12

crsi = 0.0
cyclelen = domcycle / 2
vibration = 10
leveling = 10.0
cyclicmemory = domcycle * 2
//set min/max ranges?

torque = 2.0 / (vibration + 1)
phasingLag = (vibration - 1) / 2.0

up = rma(max(change(src), 0), cyclelen)
down = rma(-min(change(src), 0), cyclelen)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - 100 / (1 + up / down)
crsi := torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * nz(crsi[1])

// there is a bug that can cause the lower bound to be bigger than the upper bound with a value of 999999.0
// lmax = -999999.0
// lmin = 999999.0
lmax = 0.0 // don't konw why, but this fixes the bug
lmin = 0.0
for i = 0 to cyclicmemory - 1 by 1
if nz(crsi, -999999.0) > lmax
lmax := nz(crsi)
lmax
else
if nz(crsi, 999999.0) < lmin
lmin := nz(crsi)
lmin

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

crsiLowband = 0.0
for steps = 0 to 100 by 1
testvalue = lmin + mstep * steps
above = 0
below = 0
for m = 0 to cyclicmemory - 1 by 1
below := below + iff(crsi[m] < testvalue, 1, 0)
below

ratio = below / cyclicmemory
if ratio >= aperc
crsiLowband := testvalue
break
else
continue

crsiHighband = 0.0
for steps = 0 to 100 by 1
testvalue = lmax - mstep * steps
above = 0
for m = 0 to cyclicmemory - 1 by 1
above := above + iff(crsi[m] >= testvalue, 1, 0)
above

ratio = above / cyclicmemory
if ratio >= aperc
crsiHighband := testvalue
break
else
continue




//=================================================================================================================================
//=================================================================================================================================
// cRSI moving average
//=================================================================================================================================
//=================================================================================================================================
crsiMaLen = input(title="cRSI Moving Average Length", defval=50, minval=0, step=5, type=input.integer)
// crsiSMA = sma(crsi,crsiMaLen)
// crsiEMA = ema(crsi,crsiMaLen)
crsiWMA = wma(crsi,crsiMaLen)

// plot(crsiSMA, "CRSI SMA", color.red, linewidth=2)
// plot(crsiEMA, "CRSI EMA", color.green, linewidth=2)
// plot(crsiWMA, "CRSI WMA", color.fuchsia, linewidth=2)




//=================================================================================================================================
//=================================================================================================================================
// cRSI Feature Analysis
//=================================================================================================================================
//=================================================================================================================================
// Crossing of upper band
crsiAboveHighband = crsi >= crsiHighband
crsiBelowHighband = not(crsiAboveHighband)
crsiCrossAboveHighband = crsiAboveHighband[0] and crsiBelowHighband[1] ? true : false
crsiCrossBelowHighband = crsiBelowHighband[0] and crsiAboveHighband[1] ? true : false

// plot(crsiAboveHighband?2.0:0,color=color.black)
// plot(crsiBelowHighband?2.25:0,color=color.red)
// plot(crsiCrossAboveHighband?2.5:0,color=color.green)
// plot(crsiCrossBelowHighband?2.75:0,color=color.blue)


//-----------------------------------------------------------------------------
// Crossing of lower band
crsiAboveLowband = crsi >= crsiLowband
crsiBelowLowband = not(crsiAboveLowband)
crsiCrossAboveLowband = crsiAboveLowband[0] and crsiBelowLowband[1] ? true : false
crsiCrossBelowLowband = crsiBelowLowband[0] and crsiAboveLowband[1] ? true : false

// plot(crsiAboveLowband?1.0:0,color=color.black)
// plot(crsiBelowLowband?1.25:0,color=color.red)
// plot(crsiCrossAboveLowband?1.5:0,color=color.green)
// plot(crsiCrossBelowLowband?1.75:0,color=color.blue)


//-----------------------------------------------------------------------------
// Crossing of WMA
crsiAboveWMA = crsi >= crsiWMA
crsiBelowWMA = not(crsiAboveWMA)
crsiCrossAboveWMA = crsiAboveWMA[0] and crsiBelowWMA[1] ? true : false
crsiCrossBelowWMA = crsiBelowWMA[0] and crsiAboveWMA[1] ? true : false

// plot(crsiAboveWMA?1.0:0,color=color.black)
// plot(crsiBelowWMA?1.25:0,color=color.red)
// plot(crsiCrossAboveWMA?1.5:0,color=color.blue)
// plot(crsiCrossBelowWMA?1.75:0,color=color.maroon)


//-----------------------------------------------------------------------------
// Crossing of 50 level
crsiAbove50 = crsi >= 50
crsiBelow50 = not(crsiAbove50)
crsiCrossAbove50 = crsiAbove50[0] and crsiBelow50[1] ? true : false
crsiCrossBelow50 = crsiBelow50[0] and crsiAbove50[1] ? true : false


//-----------------------------------------------------------------------------
// CRSI falling or rising
crsiRising = crsi[0] >= crsi[1]
crsiFalling = crsi[0] < crsi[1]

// plot(crsiRising?3.0:0,color=color.green)
// plot(crsiFalling?3.0:0,color=color.red)


//-----------------------------------------------------------------------------
// Compare cRSI to crsiWMA to determine if equity is bullish (motive) or bearish (corrective)
bull = crsiAboveWMA
bear = not(bull)
bullBearColor = bull ? color.green : color.red

bullStart = bull[0] and bear[1] ? true : false
bearStart = bear[0] and bull[1] ? true : false


alertcondition(bullStart, title='Bull - cRSI above WMA', message='Bull - cRSI above WMA')
alertcondition(bearStart, title='Bear - cRSI below WMA', message='Bear - cRSI below WMA')


//=================================================================================================================================
//=================================================================================================================================
// Plot cRSI colored by Bull or Bear
//=================================================================================================================================
//=================================================================================================================================
// Basic RSI
hline(plotCRSI?50:na, title="Middle Line", linestyle=hline.style_dashed, linewidth=2)
h2 = hline(plotCRSI?70:na, title="Overbought", linestyle=hline.style_dashed, linewidth=2)
h1 = hline(plotCRSI?30:na, title="Oversold", linestyle=hline.style_dashed, linewidth=2)
fill(h1, h2, color=color.silver, transp=80)

// cRSI
crsiLB2 = plot(plotCRSI?crsiLowband:na, "cRSI LowBand", bullBearColor)
crsiHB2 = plot(plotCRSI?crsiHighband:na, "cRSI HighBand", bullBearColor)
fill(crsiLB2, crsiHB2, bullBearColor, transp=75)
plot(plotCRSI?crsiWMA:na, "CRSI WMA", color.fuchsia, linewidth=2)
plot(plotCRSI?crsi:na, "CRSI", color.black, linewidth=4)




//=================================================================================================================================
//=================================================================================================================================
// Moitve (impulse) and Corrective Waves
//=================================================================================================================================
//=================================================================================================================================
// THIS IS A MAJOR ASSUMPTION TO THIS APPROACH!!!
motiveWave = bull
correctiveWave = bear

// TOP AND BOTTOM ARE DETECTED ONE BAR LATE!!!
topBottomLookback = input(title="cRSI Top/Bottom Detector Lookback (3 is more robust but misses smaller)", defval=2, minval=2, maxval=3, step=1, type=input.integer)
crsiTop = isTop(crsi, topBottomLookback)
crsiBottom = isBottom(crsi,topBottomLookback)

// Top above high band
crsiTopAboveHighband = crsiTop and crsiAboveHighband[1]
waveStrongImpulse = crsiTopAboveHighband

// Top that does not break high band but is above WMA
crsiTopBelowHighband = (crsiTop and crsiBelowHighband[1]) and (crsi > crsiWMA)
waveWeakImpulse = crsiTopBelowHighband


//-----------------------------------------------------------------------------
// Determine the ABC, ABCDE, ABCDEFG sequence
// Note that ABCDEFG is not a true Elliott corrective wave sequence, but for this approach is shows up once in a blue moon
possibleWaveA = crsiBottom and crsiBelowLowband[1]
possibleWaveB = (crsiTop and crsiBelowWMA[1]) or (crsiTop and crsiBelow50[1]) // Also catch the tops that are above wma but stay under RSI 50 (rare)
possibleWaveC = possibleWaveA or (crsiBottom and crsiBelowWMA[1]) // sometimes wave C is above the lower band but below the WMA

// Wave AB
findWaveAB(possibleWaveA, possibleWaveB, correctiveWave) =>
isWaveAB = false
foundMatch = false
// start with Wave B
if possibleWaveB
// search backwards and look for wave A
for i=1 to 50
// Equity must be in correction else invalidated
if correctiveWave
if possibleWaveA
foundMatch := true
break
//else
// keep looping
else
// motive wave invalidates search
foundMatch := false
break
// Did we match an A and B wave?
if foundMatch
isWaveAB := true
else
isWaveAB := false
else
isWaveAB := false

waveAB = findWaveAB(possibleWaveA, possibleWaveB, correctiveWave)

// Wave ABC
findWaveABC(possibleWaveC, waveAB, correctiveWave) =>
isWaveABC = false
foundMatch = false
if possibleWaveC
// search backwards and look for wave AB
for i=1 to 50
// Equity must be in correction else invalidated
if correctiveWave
if waveAB
foundMatch := true
break
//else
// keep looping
else
// motive wave invalidates search
foundMatch := false
break
// Did we match a waveAB with C?
if foundMatch
isWaveABC := true
else
isWaveABC := false
else
isWaveABC := false

waveABC = findWaveABC(possibleWaveC, waveAB, correctiveWave)

// Wave ABCD
findWaveABCD(possibleWaveB, waveABC, correctiveWave) =>
isWaveABCD = false
foundMatch = false
if possibleWaveB
// search backwards and look for wave ABC
for i=1 to 50
// Equity must be in correction else invalidated
if correctiveWave
if waveABC
foundMatch := true
break
//else
// keep looping
else
// motive wave invalidates search
foundMatch := false
break
// Did we match a waveABC with D?
if foundMatch
isWaveABCD := true
else
isWaveABCD := false
else
isWaveABCD := false

waveABCD = findWaveABCD(possibleWaveB, waveABC, correctiveWave)

// Wave ABCDE
findWaveABCDE(possibleWaveC, waveABCD, correctiveWave) =>
isWaveABCDE = false
foundMatch = false
if possibleWaveC
// search backwards and look for another wave ABC in this correction
for i=1 to 50
// Equity must be in correction else invalidated
if correctiveWave
if waveABCD
foundMatch := true
break
//else
// keep looping
else
// motive wave invalidates search
foundMatch := false
break
// Did we match a waveABC with another waveABC?
if foundMatch
isWaveABCDE := true
else
isWaveABCDE := false
else
isWaveABCDE := false

waveABCDE = findWaveABCDE(possibleWaveC, waveABCD, correctiveWave)

// Wave ABCDEF
findWaveABCDEF(possibleWaveB, waveABCDE, correctiveWave) =>
isWaveABCDEF = false
foundMatch = false
if possibleWaveB
// search backwards and look for another wave ABC in this correction
for i=1 to 50
// Equity must be in correction else invalidated
if correctiveWave
if waveABCDE
foundMatch := true
break
//else
// keep looping
else
// motive wave invalidates search
foundMatch := false
break
// Did we match a waveABC with another waveABC?
if foundMatch
isWaveABCDEF := true
else
isWaveABCDEF := false
else
isWaveABCDEF := false

waveABCDEF = findWaveABCDEF(possibleWaveB, waveABCDE, correctiveWave)

// Wave ABCDEFG
findWaveABCDEFG(possibleWaveC, waveABCDEF, correctiveWave) =>
isWaveABCDEFG = false
foundMatch = false
if possibleWaveC
// search backwards and look for another wave ABC in this correction
for i=1 to 50
// Equity must be in correction else invalidated
if correctiveWave
if waveABCDEF
foundMatch := true
break
//else
// keep looping
else
// motive wave invalidates search
foundMatch := false
break
// Did we match a waveABC with another waveABC?
if foundMatch
isWaveABCDEFG := true
else
isWaveABCDEFG := false
else
isWaveABCDEFG := false

waveABCDEFG = findWaveABCDEFG(possibleWaveC, waveABCDEF, correctiveWave)


// Determine individual corrective waves
waveA = possibleWaveA and not(waveABC) and not(waveABCDE)
waveB = waveAB and not(waveABCD)
waveC = waveABC
waveD = waveABCD
waveE = waveABCDE
waveF = waveABCDEF
waveG = waveABCDEFG



//-----------------------------------------------------------------------------
// Plot key cRSI points
// plot(crsiCrossBelowHighband?crsi:na, title='cRSI cross below high band', color=color.red, linewidth=7, style=plot.style_circles)
// plot(crsiCrossAboveLowband?crsi:na, title='cRSI cross above low band', color=color.green, linewidth=7, style=plot.style_circles)

// plot(crsiCrossBelowWMA?crsi:na, title='cRSI cross below WMA', color=color.red, linewidth=5, style=plot.style_cross)
// plot(crsiCrossAboveWMA?crsi:na, title='cRSI cross above WMA', color=color.green, linewidth=5, style=plot.style_cross)

// plot(crsiCrossAbove50?crsi:na, title='cRSI cross above 50', color=color.black, linewidth=7, style=plot.style_circles)
// plot(crsiCrossBelow50?crsi:na, title='cRSI cross below 50', color=color.black, linewidth=7, style=plot.style_circles)

// plot(crsiTop?crsi[1]:na, title='cRSI Top', color=color.blue, linewidth=4, style=plot.style_cross, offset=-1)
// plot(crsiBottom?crsi[1]:na, title='cRSI Top', color=color.purple, linewidth=4, style=plot.style_cross, offset=-1)


//--------------------
// Impulse waves
plotStrong = input(title="Plot Strong Impulse Waves (above upper band)", defval=true) and plotCRSI
plotWeak = input(title="Plot Weak Impulse Waves (below upper band)", defval=true) and plotCRSI
impWaveSz = size.tiny
plotshape(plotStrong and waveStrongImpulse?crsi[1]:na, text="s", title='Strong Impulse', style=shape.labeldown, location=location.absolute, color=color.navy, transp=0, offset=-1, textcolor=color.white, size=impWaveSz)
plotshape(plotWeak and waveWeakImpulse?crsi[1]:na, text="w", title='Weak Impulse', style=shape.labeldown, location=location.absolute, color=color.purple, transp=0, offset=-1, textcolor=color.white, size=impWaveSz)

//---------------------
// Corrective waves
// plot(possibleWaveC?crsi[1]:na, title='Possible Wave C', color=color.green, linewidth=6, style=plot.style_circles, offset=-1)
// plot(possibleWaveB?crsi[1]:na, title='Possible Wave B', color=color.blue, linewidth=6, style=plot.style_circles, offset=-1)
// plot(possibleWaveA?crsi[1]:na, title='Possible Wave A', color=color.purple, linewidth=6, style=plot.style_circles, offset=-1)

// plot(waveAB?crsi[1]:na, title='Wave AB', color=color.black, linewidth=5, style=plot.style_cross, offset=-1)
// plot(waveABC?crsi[1]:na, title='Wave ABC', color=color.black, linewidth=7, style=plot.style_cross, offset=-1)
// plot(waveABCDE?crsi[1]:na, title='Wave ABCDE', color=color.black, linewidth=9, style=plot.style_cross, offset=-1)

// plotshape(waveAB?crsi[1]:na, title='Wave AB', style=shape.triangledown, location=location.absolute, color=color.orange, transp=0, offset=-1, text="AB", textcolor=color.orange, size=size.small)
// plotshape(waveABC?crsi[1]:na, title='Wave ABC', style=shape.triangleup, location=location.absolute, color=color.blue, transp=0, offset=-1, text="ABC", textcolor=color.blue, size=size.small)
// plotshape(waveABCD?crsi[1]:na, title='Wave ABCD', style=shape.triangledown, location=location.absolute, color=color.red, transp=0, offset=-1, text="ABCD", textcolor=color.red, size=size.small)
// plotshape(waveABCDE?crsi[1]:na, title='Wave ABCDE', style=shape.triangleup, location=location.absolute, color=color.green, transp=0, offset=-1, text="ABCDE", textcolor=color.green, size=size.small)

plotWaves = input(title="Plot Corrective Waves (ABC,ABCDE)", defval=true) and plotCRSI
corWaveSz = size.small
plotshape(plotWaves and waveA?crsi[1]:na, text="A", title='Wave A', style=shape.labelup, location=location.absolute, color=color.blue, transp=0, offset=-1, textcolor=color.white, size=corWaveSz)
plotshape(plotWaves and waveB?crsi[1]:na, text="B", title='Wave B', style=shape.labeldown, location=location.absolute, color=color.red, transp=0, offset=-1, textcolor=color.white, size=corWaveSz)
plotshape(plotWaves and waveC?crsi[1]:na, text="C", title='Wave C', style=shape.labelup, location=location.absolute, color=color.green, transp=0, offset=-1, textcolor=color.white, size=corWaveSz)
plotshape(plotWaves and waveD?crsi[1]:na, text="D", title='Wave D', style=shape.labeldown, location=location.absolute, color=color.maroon, transp=0, offset=-1, textcolor=color.white, size=corWaveSz)
plotshape(plotWaves and waveE?crsi[1]:na, text="E", title='Wave E', style=shape.labelup, location=location.absolute, color=color.lime, transp=0, offset=-1, textcolor=color.white, size=corWaveSz)
plotshape(plotWaves and waveF?crsi[1]:na, text="F", title='Wave F', style=shape.labeldown, location=location.absolute, color=color.fuchsia, transp=0, offset=-1, textcolor=color.white, size=corWaveSz)
plotshape(plotWaves and waveG?crsi[1]:na, text="G", title='Wave G', style=shape.labelup, location=location.absolute, color=color.aqua, transp=0, offset=-1, textcolor=color.white, size=corWaveSz)



//---------------------
// PRICE CHANGE BETWEEN IMPULSE AND WAVE A





//=================================================================================================================================
//=================================================================================================================================
// Divergence Indicator Using cRSI
//=================================================================================================================================
//=================================================================================================================================
plotBull = input(title="Plot Bullish (cRSI Higher-Low : Price Lower-Low)", defval=true) and plotCRSI
plotHiddenBull = input(title="Plot Hidden Bullish (cRSI Lower-Low : Price Higher-Low)", defval=true) and plotCRSI
plotBear = input(title="Plot Bearish (cRSI Lower-High : Price Higher-High", defval=true) and plotCRSI
plotHiddenBear = input(title="Plot Hidden Bearish (cRSI Higher-High : Price Lower-High)", defval=true) and plotCRSI


//------------------------------------------------------------------------------
crsiHighs = waveStrongImpulse or waveWeakImpulse
crsiLows = possibleWaveA or possibleWaveC


//------------------------------------------------------------------------------
// Regular Bullish --> cRSI makes a Higher-Low, but price makes a Lower-Low
// Hidden Bullish --> cRSI makes a Lower-Low, but price makes a Higher-Low
bullish(crsiLows, crsi, price) =>
foundLow = false
crsiHigherLow = false
priceHigher = false
regularBullish = false
hiddenBullish = false
if crsiLows[0] == true
for i=1 to 50
if crsiLows == true
foundLow := true
// crsi higher or lower?
if crsi[0] > crsi
crsiHigherLow := true
else
crsiHigherLow := false
// price higher or lower
if price[0] > price
priceHigher := true
else
priceHigher := false
// found low, stop looking
break
else
continue
if foundLow
// Regular Bullish --> cRSI makes a Higher-Low, but price makes a Lower-Low
if (crsiHigherLow==true) and (priceHigher==false)
regularBullish := true
hiddenBullish := false
// Hidden Bullish --> cRSI makes a Lower-Low, but price makes a Higher-Low
else if (crsiHigherLow==false) and (priceHigher==true)
regularBullish := false
hiddenBullish := true
else
regularBullish := false
hiddenBullish := false
else
regularBullish := false
hiddenBullish := false
else
// this is not a low
regularBullish := false
hiddenBullish := false
// return tuple
[regularBullish,hiddenBullish]

[regularBullish,hiddenBullish] = bullish(crsiLows, crsi, close)

plotshape(plotBull and regularBullish?crsi[1]-12:na, text="Bull", title='Bull', style=shape.labelup, location=location.absolute, color=color.green, transp=0, offset=-1, textcolor=color.white, size=corWaveSz)
plotshape(plotHiddenBull and hiddenBullish?crsi[1]-12:na, text="H Bull", title='Hidden Bull', style=shape.labelup, location=location.absolute, color=color.green, transp=20, offset=-1, textcolor=color.white, size=corWaveSz)





//------------------------------------------------------------------------------
// Regular Bearish --> cRSI makes a Lower-High, but price makes a Higher-High
// Hidden Bearish --> cRSI makes a Higher-High, but price makes a Lower-High
bearish(crsiHighs, crsi, price) =>
foundHigh = false
crsiHigherHigh = false
priceHigher = false
regularBearish = false
hiddenBearish = false
if crsiHighs[0] == true
for i=1 to 50
if crsiHighs == true
foundHigh := true
// crsi higher or lower?
if crsi[0] > crsi
crsiHigherHigh := true
else
crsiHigherHigh := false
// price higher or lower
if price[0] > price
priceHigher := true
else
priceHigher := false
// found high, stop looking
break
else
continue
if foundHigh
// Regular Bearish --> cRSI makes a Lower-High, but price makes a Higher-High
if (crsiHigherHigh==false) and (priceHigher==true)
regularBearish := true
hiddenBearish := false
// Hidden Bearish --> cRSI makes a Higher-High, but price makes a Lower-High
else if (crsiHigherHigh==true) and (priceHigher==false)
regularBearish := false
hiddenBearish := true
else
regularBearish := false
hiddenBearish := false
else
regularBearish := false
hiddenBearish := false
else
// this is not a low
regularBearish := false
hiddenBearish := false
// return tuple
[regularBearish,hiddenBearish]

[regularBearish,hiddenBearish] = bearish(crsiHighs, crsi, close)

plotshape(plotBear and regularBearish?crsi[1]+10:na, text="Bear", title='Bear', style=shape.labeldown, location=location.absolute, color=color.red, transp=0, offset=-1, textcolor=color.white, size=corWaveSz)
plotshape(plotHiddenBear and hiddenBearish?crsi[1]+10:na, text="H Bear", title='Hidden Bear', style=shape.labeldown, location=location.absolute, color=color.red, transp=20, offset=-1, textcolor=color.white, size=corWaveSz)





//==================================================================================================================================================================================================================================================================
//==================================================================================================================================================================================================================================================================
//==================================================================================================================================================================================================================================================================
// Buy/Sell Strategy
//==================================================================================================================================================================================================================================================================
//==================================================================================================================================================================================================================================================================
//==================================================================================================================================================================================================================================================================
// Remove duplicate buy/sells if one was already executed recently
filterLookback = 5

// normalize a value in a range between min and max
normalize(val, valMin, valMax) =>
valNorm = val
valNorm := valNorm < valMin ? valMin : valNorm
valNorm := valNorm > valMax ? valMax : valNorm
valNorm := (valNorm-valMin) / (valMax-valMin)

recentWave(wave, lookback) =>
ret = false
found = false
for i=0 to lookback
if wave == true
found := true
break
if found
ret := true
else
ret := false


//-----------------------------------------------------------------------------
// Levels for upper band - High
crsiHighband_extremeHighLevel = 90
crsiHighband_highLevel = 70
crsiHighband_highWeight = normalize(crsiHighband, crsiHighband_highLevel, crsiHighband_extremeHighLevel)

// Levels for upper band - Low
crsiHighband_extremeLowLevel = 45
crsiHighband_lowLevel = 55
crsiHighband_lowWeight = 1.0 - normalize(crsiHighband, crsiHighband_extremeLowLevel, crsiHighband_lowLevel)

// plot(crsiHighband_highWeight,color=color.blue)
// plot(crsiHighband_lowWeight,color=color.red)


//-----------------------------------------------------------------------------
// // Levels for lower band - High
crsiLowband_extremeHighLevel = 80
crsiLowband_highLevel = 60
crsiLowband_higheight = normalize(crsiLowband, crsiLowband_highLevel, crsiLowband_extremeHighLevel)

// Levels for lower band - Low
crsiLowband_extremeLowLevel = 20
crsiLowband_lowLevel = 45
crsiLowband_lowWeight = 1.0 - normalize(crsiLowband, crsiLowband_extremeLowLevel, crsiLowband_lowLevel)

// plot(crsiLowband_highWeight,color=color.blue)
// plot(crsiLowband_lowWeight,color=color.red)


//--------------------------------------------------------------------------------------------
// SELL
//--------------------------------------------------------------------------------------------
maxSellOrderSize = 10

crsiHighband_above_crsiHighband_highLevel = crsiHighband > crsiHighband_highLevel ? true : false

Sell1 = waveStrongImpulse
Sell2 = crsiAboveHighband and crsiFalling ? true : false // Above high band and now falling
Sell3 = crsiAboveHighband[1] and crsiFalling ? true : false // 1x previous was above high band and now falling (sometimes it can be off by a bar)
Sell4 = crsiAboveHighband[2] and crsiFalling ? true : false // 2x previous was above high band and now falling (sometimes it can be off by a bar)

//Sell = Sell1 //and crsiHighband_above_crsiHighband_highLevel
// Sell = Sell1 //and crsiHighband_above_crsiHighband_highLevel
// Sell = (Sell1 or Sell2) //and crsiHighband_above_crsiHighband_highLevel
// Sell = (Sell1 or Sell2 or Sell3) //and crsiHighband_above_crsiHighband_highLevel
Sell = (Sell1 or Sell2 or Sell3 or Sell4) and crsiHighband_above_crsiHighband_highLevel
Sell := filterSignal(Sell, filterLookback)

// Base sell size on how high the Highband is
sellSize = crsiHighband_highWeight *maxSellOrderSize // When in doubt, DON'T SELL! Stonks only go up ;)


// extreme cRSI
sellSize := crsi > crsiHighband_extremeHighLevel ? 1.5*maxSellOrderSize : sellSize


// if the sell size is small, just make min sell
sellSize := sellSize < maxSellOrderSize/3 ? 0 : sellSize

sellSize := round(sellSize)

if Sell
strategy.order("Sell", false, sellSize)




//--------------------------------------------------------------------------------------------
// BUY - Price can continue to fall even when cRSI is rising!!!
//--------------------------------------------------------------------------------------------
maxBuyOrderSize = 10


// Wait until it crosses back above WMA so it is clear that motive wave is clear.
// Buying at the bottom is really hard because RSI can start to rise yet price will continue to fall
Buy1 = bullStart

// Using waves can help do a better job timing the bottom, but big corrections can go much deeper than just Wave C (Zig Zag)
Buy2 = waveA and regularBullish
Buy3 = waveC and regularBullish
Buy4 = waveE and (topBottomLookback == 3) // usullay max is a wave E with topBottomLookback == 3
Buy5 = waveG and (topBottomLookback == 2) // can see a G wave when topBottomLookback == 2

Buy = Buy1 or Buy2 or Buy3 or Buy4 or Buy5
Buy := filterSignal(Buy, filterLookback)


// Base buy size on how low the Lowband is
buySize = crsiLowband_lowWeight*maxBuyOrderSize
// buySize := buySize < 1 ? 1 : buySize // When in doubt, BUY! Stonks only go up ;)

// Look for recent wave endings that can increase our guess of buying at a low
recentWaveC = recentWave(waveC, 10)
recentWaveE = recentWave(waveE, 10)
recentWaveG = recentWave(waveG, 10)
// buySize := recentWaveE ? 1.5*maxBuyOrderSize : buySize
// buySize := recentWaveG ? 1.5*maxBuyOrderSize : buySize
buySize := recentWaveE ? maxBuyOrderSize : buySize
buySize := recentWaveG ? maxBuyOrderSize : buySize

// if the buy size is small, just make min buy
buySize := buySize < maxSellOrderSize/3 ? 0 : buySize

buySize := round(buySize)

if Buy
strategy.order("Buy", true, buySize)
check the below:

CSS:
#// This indicator was created by merging the cyclic smoothed RSI indicator by Lars von Theinen and the tradingview.com built in divergence indicator.
#// © Dr_Roboto
#// Copyright (C) 2017 CC BY, whentotrade / Lars von Thienen
#// Source:
#// Book: Decoding The Hidden Market Rhythm - Part 1: Dynamic Cycles (2017)
#// Chapter 4: "Fine-tuning technical indicators for more details on the cRSI Indicator
#// https://www.tradingview.com/script/TmqiR1jp-RSI-cyclic-smoothed-v2/
#// The cyclic smoothed RSI indicator is an enhancement of the classic RSI, adding
#//      1) additional smoothing according to the market vibration,
#//      2) adaptive upper and lower bands according to the cyclic memory and
#//      3) 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.
#study(title="Cyclic Smoothed RSI with Divergence Indicator", format=format.price, shorttitle="cRSI + Divergence")

# Converted by Sam4Cok@Samer800    - 03/2024
Declare lower;

input crsiSource = close; #(title="cRSI Source", defval=close)
input crsiDominantCycleLength = 12; #, minval=5, title="cRSI Dominant Cycle Length (persist after high/low)")
input crsiMovAvgLength = 40; #(title="cRSI Moving Average Length", defval=40, minval=0, step=5, type=input.integer)

def na = Double.NaN;
def last = isNaN(close);

def cyclelen = Round(crsiDominantCycleLength / 2, 0);
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = crsiDominantCycleLength * 2;
def torque = 2.0 / (vibration + 1);
def phasingLag = Round((vibration - 1) / 2.0, 0);
#//set min/max ranges?
def rsi = rsi(Price = crsiSource, Length = cyclelen);
def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * if(isNaN(crsi[1]), 0, crsi[1]);
def lmax = fold i0 = 0 to cyclicmemory with p=-999999.0 do
           Max(p, crsi[i0]);
def lmin = fold i1 = 0 to cyclicmemory with q=999999.0 do
           Min(q, crsi[i1]);
def mstep = (lmax - lmin) / 100;
def aperc = leveling / 100;

def crsiLowband = fold j0 = 0 to 100 with p0 while p0 < aperc do
            if ((fold m0 = 0 to cyclicmemory with q0 do
            q0 + if(crsi[m0] < (lmin + mstep * j0), 1, 0)) / cyclicmemory) >= aperc then lmin + mstep * j0 else p0;
def crsiHighband = fold j1 = 0 to 100 with p1 while p1 < aperc do
            if ((fold m1 = 0 to cyclicmemory with q1 do
            q1 + if(crsi[m1] >= (lmax - mstep * j1), 1, 0)) / cyclicmemory) >= aperc then lmax - mstep * j1 else p1;

#// cRSI moving average
def crsiWMA = wma(crsi,crsiMovAvgLength);
def bull = crsi > crsiWMA;
def bear = !bull;
def col = if bull then 1 else if bear then -1 else 0;
def gr = col>0 or col[-1]>0;
def rd = col<0 or col[-1]<0;

plot CRSILine = CRSI;
plot CRSIWM = crsiWMA; #, "CRSI WMA", color.fuchsia, linewidth=2)
plot crsiLB2 = crsiLowband; #, "cRSI LowBand", bullBearColor)
plot crsiHB2 = crsiHighband; #, "cRSI HighBand", bullBearColor)
CRSILine.SetLineWeight(2);
CRSILine.SetDefaultColor(Color.VIOLET);
CRSIWM.SetDefaultColor(Color.MAGENTA);
crsiLB2.AssignValueColor(if col>0 then Color.DARK_GREEN else if col<0 then COlor.DARK_RED else COlor.GRAY);
crsiHB2.AssignValueColor(if col>0 then Color.DARK_GREEN else if col<0 then COlor.DARK_RED else COlor.GRAY);

AddCloud(if gr then crsiLB2 else na, crsiHB2, Color.DARK_GREEN, Color.DARK_GREEN, yes);
AddCloud(if rd then crsiLB2 else na, crsiHB2, Color.DARK_RED, Color.DARK_RED, yes);

#// cRSI Analysis
#// Crossing of upper band
def crsiAboveHighband = crsi >= crsiHighband;
def crsiBelowHighband = !crsiAboveHighband;
def crsiCrossAboveHighband = crsiAboveHighband[0] and crsiBelowHighband[1];
def crsiCrossBelowHighband = crsiBelowHighband[0] and crsiAboveHighband[1];
#// Crossing of lower band
def crsiAboveLowband = crsi >= crsiLowband;
def crsiBelowLowband = !crsiAboveLowband;
def crsiCrossAboveLowband = crsiAboveLowband[0] and crsiBelowLowband[1];
def crsiCrossBelowLowband = crsiBelowLowband[0] and crsiAboveLowband[1];
#// Crossing of WMA
def crsiAboveWMA = crsi >= crsiWMA;
def crsiBelowWMA = !crsiAboveWMA;
def crsiCrossAboveWMA = crsiAboveWMA[0] and crsiBelowWMA[1];
def crsiCrossBelowWMA = crsiBelowWMA[0] and crsiAboveWMA[1];
#// CRSI falling or rising
def crsiRising = crsi[0] >= crsi[1];
def crsiFalling = crsi[0] < crsi[1];
#// Plot key points
plot CrossHiBand = if crsiCrossBelowHighband then crsi else na; #, title='cRSI cross above high band'
plot CrossLoBand = if crsiCrossAboveLowband then crsi else na; #, title='cRSI cross below high band'
CrossHiBand.SetPaintingStrategy(PaintingStrategy.POINTS);
CrossLoBand.SetPaintingStrategy(PaintingStrategy.POINTS);
CrossHiBand.SetDefaultColor(Color.RED);
CrossLoBand.SetDefaultColor(Color.GREEN);


#----Div-----------
input ShowLastDivLines = yes;
input ShowLastHiddenDivLines = no;
input DivBull = yes;      # "Plot Bullish"
input DivBear = yes;      # "Plot Bearish"
input DivHiddenBull = no; # "Plot Hidden Bullish"
input DivHiddenBear = no; # "Plot Hidden Bearish"
input LookBackRight  = 5; # "Pivot Lookback Right"
input LookBackLeft  = 5;  # "Pivot Lookback Left"
input MaxLookback = 60;   # "Max of Lookback Range"
input MinLookback = 5;    # "Min of Lookback Range"

def divSrc = crsi;

def h = high;
def l = low;

script FindPivots {
    input dat = close; # default data or study being evaluated
    input HL  = 0;    # default high or low pivot designation, -1 low, +1 high
    input lbL  = 5;    # default Pivot Lookback Left
    input lbR  = 1;    # default Pivot Lookback Right
    ##############
    def _nan;    # used for non-number returns
    def _BN;     # the current barnumber
    def _VStop;  # confirms that the lookforward period continues the pivot trend
    def _V;      # the Value at the actual pivot point
    ##############
    _BN  = BarNumber();
    _nan = Double.NaN;
    _VStop = if !isNaN(dat) and lbr > 0 and lbl > 0 then
                fold a = 1 to lbR + 1 with b=1 while b do
                    if HL > 0 then dat > GetValue(dat,-a) else dat < GetValue(dat,-a) else _nan;
   if (HL > 0) {
        _V = if _BN > lbL + 1 and dat == Highest(dat, lbL + 1) and _VStop
            then dat else _nan;
    } else {
        _V = if _BN > lbL + 1 and dat == Lowest(dat, lbL + 1) and _VStop
            then dat else _nan;
    }
    plot result = if !IsNaN(_V) and _VStop then _V else _nan;
}
#_inRange(cond) =>
script _inRange {
    input cond = yes;
    input rangeUpper = 60;
    input rangeLower = 5;
        def bars = if cond then 0 else bars[1] + 1;
        def inrange =  (rangeLower <= bars) and (bars <= rangeUpper);
plot retrun = inRange;
}
def pl_ = findpivots(divSrc,-1, LookBackLeft, LookBackRight);
def ph_ = findpivots(divSrc, 1, LookBackLeft, LookBackRight);
def pl = !isNaN(pl_);
def ph = !isNaN(ph_);
def pll = lowest(divSrc,LookBackLeft);
def phh = highest(divSrc,LookBackLeft);
def sll = lowest(l, LookBackLeft);
def shh = highest(h, LookBackLeft);
#-- Pvt Low
def plStart  = if pl then yes else plStart[1];
def plFound  = if (plStart and pl) then 1 else 0;
def vlFound1 = if plFound then divSrc else vlFound1[1];
def vlFound_ = if vlFound1!=vlFound1[1] then vlFound1[1] else vlFound_[1];
def vlFound  = if !vlFound_ then pll else vlFound_;
def plPrice1 = if plFound then l else plPrice1[1];
def plPrice_ = if plPrice1!=plPrice1[1] then plPrice1[1] else plPrice_[1];
def plPrice  = if !plPrice_ then sll else plPrice_;
#-- Pvt High
def phStart = if ph then yes else phStart[1];
def phFound = if (phStart and ph) then 1 else 0;
def vhFound1 = if phFound then divSrc else vhFound1[1];
def vhFound_ = if vhFound1!=vhFound1[1] then vhFound1[1] else vhFound_[1];
def vhFound = if !vhFound_ then phh else vhFound_;
def phPrice1 = if phFound then h else phPrice1[1];
def phPrice_ = if phPrice1!=phPrice1[1] then phPrice1[1] else phPrice_[1];
def phPrice = if !phPrice_ then sll else phPrice_;
#// Regular Bullish
def inRangePl = _inRange(plFound[1],MaxLookback,MinLookback);
def oscHL = divSrc > vlFound and inRangePl;
def priceLL = l < plPrice and divSrc <= 50;
def bullCond = plFound and oscHL and priceLL;
#// Hidden Bullish
def oscLL = divSrc < vlFound and inRangePl;
def priceHL = l > plPrice and divSrc <= 50;
def hiddenBullCond = plFound and oscLL and priceHL;
#// Regular Bearish
def inRangePh = _inRange(phFound[1],MaxLookback,MinLookback);
def oscLH   = divSrc < vhFound and inRangePh;
def priceHH = h > phPrice and divSrc >= 50;
def bearCond = phFound and oscLH and priceHH;
#// Hidden Bearish
def oscHH = divSrc > vhFound and inRangePh;
def priceLH = h < phPrice and divSrc >= 50;
def hiddenBearCond = phFound and oscHH and priceLH;

#------ Bubbles
def bullBub  = DivBull and bullCond;
def HbullBub = DivHiddenBull and hiddenBullCond;
def bearBub  = DivBear and bearCond;
def HbearBub = DivHiddenBear and hiddenBearCond;

addchartbubble(bullBub, divSrc, "R", color.GREEN, no);
addchartbubble(bearBub, divSrc, "R", CreateColor(156,39,176), yes);
addchartbubble(HbullBub, divSrc, "H", color.DARK_green, no);
addchartbubble(HbearBub, divSrc, "H", color.DARK_red, yes);

##### Lines
def bar = BarNumber();
#-- Bear Line
def lastPhBar = if ph then bar else lastPhBar[1];
def prePhBar = if lastPhBar!=lastPhBar[1] then lastPhBar[1] else prePhBar[1];
def priorPHBar = if bearCond then prePhBar else priorPHBar[1];
#-- Bull Line
def lastPlBar = if pl then bar else lastPlBar[1];
def prePlBar = if lastPlBar!=lastPlBar[1] then lastPlBar[1] else prePlBar[1];
def priorPLBar = if bullCond then prePlBar else priorPLBar[1];

def lastBullBar = if bullCond then bar else lastBullBar[1];
def lastBearBar = if bearCond then bar else lastBearBar[1];

def HighPivots = ph and bar >= HighestAll(priorPHBar) and bar <= HighestAll(lastBearBar);
def LowPivots  = pl and bar >= HighestAll(priorPLBar) and bar <= HighestAll(lastBullBar);

def pivotHigh = if HighPivots then divSrc else na;
def pivotLow  = if LowPivots  then divSrc else na;

plot PlotHline = if ShowLastDivLines then pivotHigh else na;
PlotHline.EnableApproximation();
PlotHline.SetDefaultColor(Color.RED);

plot PlotLline = if ShowLastDivLines then pivotLow else na;
PlotLline.EnableApproximation();
PlotLline.SetDefaultColor(Color.GREEN);

#--- Hidden Lines
#-- Bear Line
def priorHPHBar = if hiddenBearCond then prePhBar else priorHPHBar[1];
#-- Bull Line
def priorHPLBar = if hiddenBullCond then prePlBar else priorHPLBar[1];

def lastHBullBar = if hiddenBullCond then bar else lastHBullBar[1];
def lastHBearBar = if hiddenBearCond then bar else lastHBearBar[1];

def HighHPivots = ph and bar >= HighestAll(priorHPHBar) and bar <= HighestAll(lastHBearBar);
def LowHPivots  = pl and bar >= HighestAll(priorHPLBar) and bar <= HighestAll(lastHBullBar);

def pivotHidHigh = if HighHPivots then divSrc else na;
def pivotHidLow  = if LowHPivots  then divSrc else na;

plot PlotHBearline = if ShowLastHiddenDivLines then pivotHidHigh else na;
PlotHBearline.EnableApproximation();
PlotHBearline.SetDefaultColor(Color.DARK_RED);

plot PlotHBullline = if ShowLastHiddenDivLines then pivotHidLow else na;
PlotHBullline.EnableApproximation();
PlotHBullline.SetDefaultColor(Color.DARK_GREEN);

plot mid = if last then na else 50; # "Middle Line"
plot h2 = if last then na else 70;  # "Overbought"
plot h1 = if last then na else 30;  # "Oversold"

mid.SetDefaultColor(Color.DARK_GRAY);
h2.SetDefaultColor(Color.DARK_GRAY);
h1.SetDefaultColor(Color.DARK_GRAY);
mid.SetStyle(Curve.SHORT_DASH);
h2.SetStyle(Curve.SHORT_DASH);
h1.SetStyle(Curve.SHORT_DASH);

#-- END of CODE
 
Warning: this script is probably too complex for scan hacker so do NOT scan the universe of stocks.
May work on a small subset, so use the "scan in" field to feed in stocks that meet your other criteria or to limit the scan to smaller subsets like S&P500.

1. save the below script as a separate study
2. to create scan: https://usethinkscript.com/threads/how-to-use-thinkorswim-stock-hacker-scans.284/
3. in your scan filter choose one of the following:
#green R bubble:
bullBub is true
#purple R bubble:
bearBub is true
#green H bubble:
HbullBub is true
#red H bubble:
HbearBub is true

SCAN ONLY script: Cyclic Smoothed RSI with Divergence SCAN ONLY
Ruby:
#study Cyclic Smoothed RSI with Divergence  SCAN ONLY
# Converted by Sam4Cok@Samer800    - 03/2024

input crsiSource = close; #(title="cRSI Source", defval=close)
input crsiDominantCycleLength = 12; #, minval=5, title="cRSI Dominant Cycle Length (persist after high/low)")
input crsiMovAvgLength = 40; #(title="cRSI Moving Average Length", defval=40, minval=0, step=5, type=input.integer)

def na = Double.NaN;
def last = isNaN(close);

def cyclelen = Round(crsiDominantCycleLength / 2, 0);
def vibration = 10;
def leveling = 10.0;
def cyclicmemory = crsiDominantCycleLength * 2;
def torque = 2.0 / (vibration + 1);
def phasingLag = Round((vibration - 1) / 2.0, 0);
#//set min/max ranges?
def rsi = rsi(Price = crsiSource, Length = cyclelen);
def crsi = torque * (2 * rsi - rsi[phasingLag]) + (1 - torque) * if(isNaN(crsi[1]), 0, crsi[1]);
def lmax = fold i0 = 0 to cyclicmemory with p=-999999.0 do
           Max(p, crsi[i0]);
def lmin = fold i1 = 0 to cyclicmemory with q=999999.0 do
           Min(q, crsi[i1]);
def mstep = (lmax - lmin) / 100;
def aperc = leveling / 100;

def crsiLowband = fold j0 = 0 to 100 with p0 while p0 < aperc do
            if ((fold m0 = 0 to cyclicmemory with q0 do
            q0 + if(crsi[m0] < (lmin + mstep * j0), 1, 0)) / cyclicmemory) >= aperc then lmin + mstep * j0 else p0;
def crsiHighband = fold j1 = 0 to 100 with p1 while p1 < aperc do
            if ((fold m1 = 0 to cyclicmemory with q1 do
            q1 + if(crsi[m1] >= (lmax - mstep * j1), 1, 0)) / cyclicmemory) >= aperc then lmax - mstep * j1 else p1;

#// cRSI moving average
def crsiWMA = wma(crsi,crsiMovAvgLength);
def bull = crsi > crsiWMA;
def bear = !bull;
def col = if bull then 1 else if bear then -1 else 0;
def gr = col>0 or col[-1]>0;
def rd = col<0 or col[-1]<0;

plot CRSILine = CRSI;
plot CRSIWM = crsiWMA; #, "CRSI WMA", color.fuchsia, linewidth=2)
plot crsiLB2 = crsiLowband; #, "cRSI LowBand", bullBearColor)
plot crsiHB2 = crsiHighband; #, "cRSI HighBand", bullBearColor)
CRSILine.SetLineWeight(2);
CRSILine.SetDefaultColor(Color.VIOLET);
CRSIWM.SetDefaultColor(Color.MAGENTA);
crsiLB2.AssignValueColor(if col>0 then Color.DARK_GREEN else if col<0 then COlor.DARK_RED else COlor.GRAY);
crsiHB2.AssignValueColor(if col>0 then Color.DARK_GREEN else if col<0 then COlor.DARK_RED else COlor.GRAY);

AddCloud(if gr then crsiLB2 else na, crsiHB2, Color.DARK_GREEN, Color.DARK_GREEN, yes);
AddCloud(if rd then crsiLB2 else na, crsiHB2, Color.DARK_RED, Color.DARK_RED, yes);

#// cRSI Analysis
#// Crossing of upper band
def crsiAboveHighband = crsi >= crsiHighband;
def crsiBelowHighband = !crsiAboveHighband;
def crsiCrossAboveHighband = crsiAboveHighband[0] and crsiBelowHighband[1];
def crsiCrossBelowHighband = crsiBelowHighband[0] and crsiAboveHighband[1];
#// Crossing of lower band
def crsiAboveLowband = crsi >= crsiLowband;
def crsiBelowLowband = !crsiAboveLowband;
def crsiCrossAboveLowband = crsiAboveLowband[0] and crsiBelowLowband[1];
def crsiCrossBelowLowband = crsiBelowLowband[0] and crsiAboveLowband[1];
#// Crossing of WMA
def crsiAboveWMA = crsi >= crsiWMA;
def crsiBelowWMA = !crsiAboveWMA;
def crsiCrossAboveWMA = crsiAboveWMA[0] and crsiBelowWMA[1];
def crsiCrossBelowWMA = crsiBelowWMA[0] and crsiAboveWMA[1];
#// CRSI falling or rising
def crsiRising = crsi[0] >= crsi[1];
def crsiFalling = crsi[0] < crsi[1];
#// Plot key points
plot CrossHiBand = if crsiCrossBelowHighband then crsi else na; #, title='cRSI cross above high band'
plot CrossLoBand = if crsiCrossAboveLowband then crsi else na; #, title='cRSI cross below high band'
CrossHiBand.SetPaintingStrategy(PaintingStrategy.POINTS);
CrossLoBand.SetPaintingStrategy(PaintingStrategy.POINTS);
CrossHiBand.SetDefaultColor(Color.RED);
CrossLoBand.SetDefaultColor(Color.GREEN);


#----Div-----------
input ShowLastDivLines = yes;
input ShowLastHiddenDivLines = no;
input DivBull = yes;      # "Plot Bullish"
input DivBear = yes;      # "Plot Bearish"
input DivHiddenBull = no; # "Plot Hidden Bullish"
input DivHiddenBear = no; # "Plot Hidden Bearish"
input LookBackRight  = 5; # "Pivot Lookback Right"
input LookBackLeft  = 5;  # "Pivot Lookback Left"
input MaxLookback = 60;   # "Max of Lookback Range"
input MinLookback = 5;    # "Min of Lookback Range"

def divSrc = crsi;

def h = high;
def l = low;

script FindPivots {
    input dat = close; # default data or study being evaluated
    input HL  = 0;    # default high or low pivot designation, -1 low, +1 high
    input lbL  = 5;    # default Pivot Lookback Left
    input lbR  = 1;    # default Pivot Lookback Right
    ##############
    def _nan;    # used for non-number returns
    def _BN;     # the current barnumber
    def _VStop;  # confirms that the lookforward period continues the pivot trend
    def _V;      # the Value at the actual pivot point
    ##############
    _BN  = BarNumber();
    _nan = Double.NaN;
    _VStop = if !isNaN(dat) and lbr > 0 and lbl > 0 then
                fold a = 1 to lbR + 1 with b=1 while b do
                    if HL > 0 then dat > GetValue(dat,-a) else dat < GetValue(dat,-a) else _nan;
   if (HL > 0) {
        _V = if _BN > lbL + 1 and dat == Highest(dat, lbL + 1) and _VStop
            then dat else _nan;
    } else {
        _V = if _BN > lbL + 1 and dat == Lowest(dat, lbL + 1) and _VStop
            then dat else _nan;
    }
    plot result = if !IsNaN(_V) and _VStop then _V else _nan;
}
#_inRange(cond) =>
script _inRange {
    input cond = yes;
    input rangeUpper = 60;
    input rangeLower = 5;
        def bars = if cond then 0 else bars[1] + 1;
        def inrange =  (rangeLower <= bars) and (bars <= rangeUpper);
plot retrun = inRange;
}
def pl_ = findpivots(divSrc,-1, LookBackLeft, LookBackRight);
def ph_ = findpivots(divSrc, 1, LookBackLeft, LookBackRight);
def pl = !isNaN(pl_);
def ph = !isNaN(ph_);
def pll = lowest(divSrc,LookBackLeft);
def phh = highest(divSrc,LookBackLeft);
def sll = lowest(l, LookBackLeft);
def shh = highest(h, LookBackLeft);
#-- Pvt Low
def plStart  = if pl then yes else plStart[1];
def plFound  = if (plStart and pl) then 1 else 0;
def vlFound1 = if plFound then divSrc else vlFound1[1];
def vlFound_ = if vlFound1!=vlFound1[1] then vlFound1[1] else vlFound_[1];
def vlFound  = if !vlFound_ then pll else vlFound_;
def plPrice1 = if plFound then l else plPrice1[1];
def plPrice_ = if plPrice1!=plPrice1[1] then plPrice1[1] else plPrice_[1];
def plPrice  = if !plPrice_ then sll else plPrice_;
#-- Pvt High
def phStart = if ph then yes else phStart[1];
def phFound = if (phStart and ph) then 1 else 0;
def vhFound1 = if phFound then divSrc else vhFound1[1];
def vhFound_ = if vhFound1!=vhFound1[1] then vhFound1[1] else vhFound_[1];
def vhFound = if !vhFound_ then phh else vhFound_;
def phPrice1 = if phFound then h else phPrice1[1];
def phPrice_ = if phPrice1!=phPrice1[1] then phPrice1[1] else phPrice_[1];
def phPrice = if !phPrice_ then sll else phPrice_;
#// Regular Bullish
def inRangePl = _inRange(plFound[1],MaxLookback,MinLookback);
def oscHL = divSrc > vlFound and inRangePl;
def priceLL = l < plPrice and divSrc <= 50;
def bullCond = plFound and oscHL and priceLL;
#// Hidden Bullish
def oscLL = divSrc < vlFound and inRangePl;
def priceHL = l > plPrice and divSrc <= 50;
def hiddenBullCond = plFound and oscLL and priceHL;
#// Regular Bearish
def inRangePh = _inRange(phFound[1],MaxLookback,MinLookback);
def oscLH   = divSrc < vhFound and inRangePh;
def priceHH = h > phPrice and divSrc >= 50;
def bearCond = phFound and oscLH and priceHH;
#// Hidden Bearish
def oscHH = divSrc > vhFound and inRangePh;
def priceLH = h < phPrice and divSrc >= 50;
def hiddenBearCond = phFound and oscHH and priceLH;

#------ Bubbles
plot bullBub  = DivBull and bullCond;
plot HbullBub = DivHiddenBull and hiddenBullCond;
plot bearBub  = DivBear and bearCond;
plot HbearBub = DivHiddenBear and hiddenBearCond;
@LearningStock2018
 
Last edited:

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
407 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