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: