Volatility Calibrated ATR for ThinkOrSwim

samer800

Moderator - Expert
VIP
Lifetime
DahYWwl.png

Author Message:
https://www.tradingview.com/script/PHWhs8pW-Volatility-Calibrated-ATR/
Description:
An indicator based on ATR adjusted for volatility of the market. It uses Heikin Ashi data to find short and long opportunities and displays a dynamic stop loss level. Additionally, it has alerts for when the trend changes (which is an entry signal).

How it works:
It works by dynamically calculating the Period for ATR which depends on current volatility level that is calculated by a function that uses Standard Deviation of price. ATR is then smoothed by Weighted Moving Average and multiplied by ATR Factor, resulting in a plot that changes its colour to red when we're in a downtrend and green when in an uptrend. This plot should be used as a dynamic Stop Loss level. Trend change is determined by price crossing the dynamic Stop Loss level. The squared red and green labels appear when the trend changes, and should be used as Entry signals.

Parameters:
  • Source -> data used for calculations
  • ATR Factor -> higher values produce less noise and longer trends, lower values give more signals

CODE:

CSS:
# VCATR Volatility Calibrated ATR For ThinkOrSwim
# [URL]https://www.tradingview.com/script/PHWhs8pW-Volatility-Calibrated-ATR/[/URL]
# Converted and mod by Sam4Cok@Samer800 - 12/2022
input PaintBars = no;
input ShowCloud = yes;
input CalcMethod = {Default Calibrated, Normal};
input src = hl2;           # "Source"
#input Len = 20;
input atr_factor = 4.01;    # "ATR Factor"
input indicatorStyle = {Default Trend, Lines, Both};
input useHeikinAshiSmoother = yes;
input ShowBubbles = no;

def na = Double.NaN;
def method = if CalcMethod==CalcMethod.Calibrated then 1 else 0;
def Style1 = if indicatorStyle==indicatorStyle.Trend then 1 else
             if indicatorStyle==indicatorStyle.Lines then -1 else
             if indicatorStyle==indicatorStyle.Both  then 0 else Style1[1];
def Style = Style1;
script nz {
    input data  = close;
    input repl  = 0;
    def ret_val = if isNaN(data) then repl else data;
    plot return = ret_val;
}
# stoch(source, high, low, length) =>
script stoch {
   input src = close;
   input h = high;
   input l = low;
   input len = 100;
    def stoch = 100 * (src - Lowest(l, len)) / (Highest(h, len) - Lowest(l, len));
    plot return = stoch;
}
#atr_f(length) =>
script atr_f {
    input length = 20;
    def sum;
    def tr = TrueRange(high, close, low);
    sum = (tr + (length - 1) * nz(sum[1])) / length;
    plot return = nz(sum,tr);
}
#volStop(src, atrlen, atrfactor) =>
script volStop2 {
input src = close;
input atrfactor = 3;
    def atrlen = 20;
    def max;#     = src
    def min;#     = src
    def uptrend;# = true
    def stop;#    = 0.0
    def tr = TrueRange(High,Close,Low);
    def atrM      = atr(LENGTH=atrlen) * atrfactor;
        uptrend = src - stop[1] >= 0.0;
    if uptrend != nz(uptrend[1], yes) {
        max    = src;
        min    = src;
        stop   = if uptrend then max - atrM else min + atrM;
    } else {
        max    = nz(max(max[1], src), src);
        min    = nz(min(min[1], src), src);
        stop   = if uptrend then max(stop[1], max - atrM) else min(stop[1], min + atrM);
}
    plot dir = nz(stop, src);
    plot trend = nz(uptrend, yes);
  }
#// Calibrator function
#main_f(source, atr_factor) =>
script volStop1 {
    input source = close;
    input atr_factor = 10;
#// Volatility function
    def agg = GetAggregationPeriod();
    def stdLen = if agg < AggregationPeriod.FOUR_HOURS then 45 else
                 if agg < AggregationPeriod.WEEK then 21 else 1;
    def Len = 20;
    def src = source;
    def x = Exp(StDev(Log(src / src[1]), Len) * Len);
    def y = src * Power(x, 2);
    def z = src / Power(x, 2);
    def vol_f = stoch(src, y, z, Len);
    def uptrend;
    def max;
    def min;
    def stop;
    def vol = nz(vol_f, 1);
    def len2 = AbsValue(106 *  vol / 100);
    def len1 = Floor(Min(2000, len2));
    def nATR = atr_f(len1);
    def atrM = WMA(nATR, stdLen) * atr_factor - StDev(nATR, stdLen);
    uptrend = if isNaN(uptrend[1]) then yes else
              src >= if(isNaN(stop[1]) or stop[1]<=0, src, stop[1]);
    if uptrend != uptrend[1] {
        max  = src;
        min  = src;
        stop = if uptrend then max - atrM else min + atrM;
    } else {
        max  = if (isNaN(max[1]) or max[1]<=0) then src else Max(max[1], src);
        min  = if (isNaN(min[1]) or min[1]<=0) then src else Min(min[1], src);
        stop = if (isNaN(stop[1]) or stop[1]<=0) then src else
               if uptrend then Max(stop[1], max - atrM) else Min(stop[1], min + atrM);
    }
    plot dir = nz(stop, src);
    plot trend = nz(uptrend, yes);
}
script f_HeikinAshi {
  input _highIn = high;
  input _lowIn = low;
  input _closeIn = close;
    def _closeOsc = _closeIn;
    def _openOsc  = nz(_closeOsc[1], _closeOsc);
    def _highOsc_raw = _highIn;
    def _lowOsc_raw  = _lowIn;
    def _highOsc  = Max( _highOsc_raw, _lowOsc_raw);
    def _lowOsc   = Min( _highOsc_raw, _lowOsc_raw);
    def _close    = ( _openOsc + _highOsc + _lowOsc + _closeOsc ) / 4;
  plot close = _close;
}
def VCh     = if method then volStop1(high, atr_factor).dir else volStop2(high, atr_factor).dir;
def VCl     = if method then volStop1(low , atr_factor).dir else volStop2(low , atr_factor).dir;
def VCsrc   = if method then volStop1(src , atr_factor).dir else volStop2(src , atr_factor).dir;
def uptrend = if method then volStop1(src , atr_factor).trend else volStop2(src, atr_factor).trend;
def HAvcATR = f_HeikinAshi(VCh, VCl, VCsrc);
def vcATR = if useHeikinAshiSmoother then HAvcATR else VCsrc;


plot Long  = if Style>=0 and uptrend then vcATR else na;
Long.AssignValueColor(Color.CYAN);
plot Short = if Style>=0 and !uptrend then vcATR else na;
Short.AssignValueColor(Color.MAGENTA);

def up = uptrend != uptrend[1] and uptrend;
def dn = uptrend != uptrend[1] and !uptrend;

plot LongDot = if up and Style>=0 then vcATR else na;
LongDot.SetPaintingStrategy(PaintingStrategy.POINTS);
LongDot.AssignValueColor(Color.CYAN);
LongDot.SetLineWeight(2);
plot ShortDot = if dn and Style>=0 then vcATR else na;
ShortDot.SetPaintingStrategy(PaintingStrategy.POINTS);
ShortDot.AssignValueColor(Color.MAGENTA);
ShortDot.SetLineWeight(2);


####################
def barBull = BarNumber();
def barBear = BarNumber();

def transBull = uptrend and !uptrend[1];
def transBear = !uptrend and uptrend[1];

def transitionBarBull = if transBull then barBull else transitionBarBull[1];
def transitionBarBear = if transBear then barBear else transitionBarBear[1];

def transPriceBull = if isNaN(transPriceBull[1]) or transPriceBull[1]==0 then src else
                     if barBull == transitionBarBull then vcATR[1] else transPriceBull[1];
def transPriceBear = if isNaN(transPriceBear[1]) or transPriceBear[1]==0 then src else
                     if barBear == transitionBarBear then vcATR[1] else transPriceBear[1];

def hlineBull1 = transPriceBull;
def hlineBear1 = transPriceBear;

#--------------------------------------------------------------
def hlineBull = CompoundValue(1, nz(hlineBull1, hlineBull[1]), hlineBull1);
def hlineBear = CompoundValue(1, nz(hlineBear1, hlineBear[1]), hlineBear1);
#--------------------------------------------------------------
plot horizLineBull = if Style>0 or isNaN(close) then na else hlineBull;
horizLineBull.SetDefaultColor(Color.MAGENTA);
horizLineBull.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
plot horizLineBear = if Style>0 or isNaN(close) then na else hlineBear;
horizLineBear.SetDefaultColor(Color.CYAN);
horizLineBear.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
#----- Signals
def UpSig = if src > hlineBull and uptrend then UpSig[1] + 1 else 0;
def DnSig = if src < hlineBear and !uptrend then DnSig[1] + 1 else 0;

AddCloud(if !ShowCloud or Style<0 then na else
  if dn then ohlc4 else vcATR, if up then vcATR else ohlc4, CreateColor(99,0,99), CreateColor(0,99,99));

AddCloud(if !ShowCloud or Style>=0 or horizLineBear!=horizLineBear[1] or horizLineBull!=horizLineBull[1] then na else if up then horizLineBear else horizLineBull,if up then horizLineBull else horizLineBear, CreateColor(99,0,99), CreateColor(0,99,99));

AddChartBubble(ShowBubbles and uptrend and UpSig==1, low, "Up", Color.CYAN, no);
AddChartBubble(ShowBubbles and !uptrend and DnSig==1,high, "Dn", Color.MAGENTA, yes);

AssignPriceColor(if PaintBars then if uptrend and src>hlineBull then Color.GREEN else
                                   if uptrend then Color.DARK_GREEN else
                                   if !uptrend and src<hlineBear then Color.RED else
                                   if !uptrend then Color.DARK_RED else
                                     Color.GRAY else Color.CURRENT);

#--- END CODE
 
Last edited by a moderator:

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

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