## START STUDY
## linus, 2014-07-18, v0.2
#hint: thinkScript adaptation of Chandelier stops.
#hint n: lookback length for highest highs, lowest lows.
input n = 15;
#hint atrLength: Period length of avg. true range.
input atrLength = 5;
#hint atrMult: Multiplier of avg. true range.
input atrMult = 3.0;
#hint atrType: Moving average type of ATR.
input atrType = AverageType.SIMPLE;
#hint shift: Offsets the data this many bars.
input shift = 1;
#hint hideOppositeStop: Set to No to see the inactive stop.
input hideOppositeStop = Yes;
#hint label: Toggles P/L label.
input label = Yes;
#hint bubbles: Toggles P/L bubbles.
input bubbles = Yes;
def atr = MovingAverage(atrType, TrueRange(high, close, low)) * atrMult;
def smax = Lowest(low, n)[shift] + atr[shift];
def smin = Highest(high, n)[shift] - atr[shift];
def dir = compoundValue(1, if close > smax then 1 else if close < smin then -1 else dir, 0);
def rUB = compoundValue(1, if dir > 0 then if smax > rUB then smax else rUB else if dir < 0 then if smax < rUB then smax else rUB else rUB, high);
def rLB = compoundValue(1, if dir < 0 then if smin < rLB then smin else rLB else if dir > 0 then if smin > rLB then smin else rLB else rLB, low);
plot UB = if !hideOppositeStop or dir < 0 then rUB else Double.NaN;
plot LB = if !hideOppositeStop or dir > 0 then rLB else Double.NaN;
def orderDir = dir;
def isOrder = orderDir crosses 0;
def orderCount = compoundValue(1, if isNaN(isOrder) then 0 else if isOrder then orderCount + 1 else orderCount, 0);
def noBar = isNaN(open[-1]);
def orderPrice = if isOrder then if noBar then close else open[-1] else orderPrice;
def profitLoss = if !isOrder or orderCount == 1 then 0 else if orderDir > 0 then orderPrice - orderPrice else if orderDir < 0 then orderPrice - orderPrice else 0;
def profitLossSum = compoundValue(1, if isNaN(isOrder) then 0 else if isOrder then profitLossSum + profitLoss else profitLossSum, 0);
AddLabel(label, orderCount + " orders | P/L " + AsDollars((profitLossSum / tickSize()) * tickValue()), if profitLossSum > 0 then Color.GREEN else if profitLossSum < 0 then Color.RED else Color.GRAY);
AddChartBubble(bubbles and isOrder and orderDir > 0, low, profitLoss, if noBar then Color.LIGHT_GRAY else Color.GREEN, 0);
AddChartBubble(bubbles and isOrder and orderDir < 0, high, profitLoss, if noBar then Color.GRAY else Color.RED, 1);
## END STUDY
It's a pretty simple one. Basically, buy when the line turns blue. Sell or go short when the line turns magenta. The change over is based on the average true range and is basically the exact same as ATRtrailingstop already in TOS.
@john3 It's not accurate. I saw the price go below the band but the the color didn't change. I think I gave it a good shot and came up with one. Somehow these darn volatility trailing stops are hard to find and done right that aren't supertrend, and even that is sometimes done wrong. I found one on tradingview that that looks pretty solid that liked, or atleast the code looks solid I think. I gave it a whirl, can't be worse than what's mostly out there anyway. I then compared it to Wilder's original volatility trailing stop and noticed that the ATR length is much higher on the Chandelier version. I might be wrong but I'll assume this was a mistake because it looks way off when plotted on the chart so I changed it from 22 to a 7 because 22 seems way off. The highest high and lowest low used for the bands can supposedly be changed to just closing price. If you change the ATR length to be the same as the lookback length and the highest and lowest, from high and low, to close and close then it becomes Wilder's volatility stop. Hope yall like it.
#Chandelier Volatility Trailing Stop
#Code taken and re-edited to thinkorswim from pipCharlie, who got it from LazyBear
input AtrMult = 3.0;
input ATRlength = 7;
input lookbackLength = 22;
input highestHigh = high;
input lowestLow = low;
input AvgType = AverageType.WILDERS;
input PaintBars = no;
def ATR = MovingAverage(AvgType, TrueRange(high, close, low), ATRlength);
def longstop = Highest(highestHigh,lookbackLength)-AtrMult*atr;
def shortstop = Lowest(lowestLow,lookbackLength)+AtrMult*atr;
def shortvs = if isNaN(shortvs) then shortstop else if close>shortvs then shortstop else min(shortstop,shortvs);
def longvs = if isNaN(longvs) then longstop else if close<longvs then longstop else max(longstop,longvs);
def longswitch= if close>=shortvs and close<shortvs then 1 else 0;
def shortswitch = if close<=longvs and close>longvs then 1 else 0;
def direction = if isNaN(direction) then 0 else if direction<=0 and longswitch then 1 else if direction>=0 and shortswitch then -1 else direction;
def pc = if direction>0 then longvs else shortvs;
plot VolatilityStop = pc;
VolatilityStop.AssignValueColor(if direction < 0 then Color.RED else Color.GREEN);
AssignPriceColor(if PaintBars and direction < 0
else if PaintBars and direction > 0