input signalType = {default "Cloud Break", "Trend Continues"}; input confirmationRequired = yes; input tradeSize = 100; input tenkan_period = 9; input kijun_period = 26; input lookBack = 5; input breakOutBars = 3; def Tenkan = (Highest(high, tenkan_period) + Lowest(low, tenkan_period)) / 2; def Kijun = (Highest(high, kijun_period) + Lowest(low, kijun_period)) / 2; def "Span A" = (Tenkan[kijun_period] + Kijun[kijun_period]) / 2; def "Span B" = (Highest(high[kijun_period], 2 * kijun_period) + Lowest(low[kijun_period], 2 * kijun_period)) / 2; def Chikou = close[-kijun_period]; def bullishCloud = "Span A" >= "Span B"; def bearishCloud = "Span B" > "Span A"; def closeCloudDiff = close - "Span B"; def closeCloudDiffLong = if bullishCloud then close - "Span A" else close - "Span B"; def closeCloudDiffShort = if bearishCloud then close - "Span A" else close - "Span B"; def slowDiff = MovingAverage(AverageType.SIMPLE, closeCloudDiff, lookBack); def underCloud = highest(slowDiff[1], lookBack) < 0; def overCloud = lowest(slowDiff[1], lookBack) > 0; def cloudBreakOutLong = lowest(closeCloudDiffLong, breakOutBars) > 0; def cloudBreakOutShort = highest(closeCloudDiffShort, breakOutBars) < 0; def laggingLineOverCloud = (Chikou > "Span A" and bullishCloud) or (Chikou > "Span B" and bearishCloud); def laggingLineUnderCloud = (Chikou < "Span A" and bearishCloud) or (Chikou < "Span B" and bullishCloud); # this signal finds the long side break outs of price action above the cloud def signalBreakAboveCloud = (close > "Span A" and bullishCloud and underCloud[breakOutBars] and cloudBreakOutLong and cloudBreakOutLong[1] == 0) or (close > "Span B" and bearishCloud and underCloud[breakOutBars] and cloudBreakOutLong and cloudBreakOutLong[1] == 0); # this signal finds the short side break downs of price action below the cloud def signalBreakBelowCloud = (close < "Span A" and bearishCloud and overCloud[breakOutBars] and cloudBreakOutShort and cloudBreakOutShort[1] == 0) or (close < "Span B" and bullishCloud and overCloud[breakOutBars] and cloudBreakOutShort and cloudBreakOutShort[1] == 0); # this signal tells if the Lagging line (Chikou) is above the cloud def signalBullishConfirmation = laggingLineOverCloud[kijun_period]; # this signal tells if the Lagging line (Chikou) is below the cloud def signalBearishConfirmation = laggingLineUnderCloud[kijun_period]; # this signal finds the bullish crossovers of the turning line back above the standard line def trendContinuationLong = bullishCloud and close > "Span B" and (Tenkan > Kijun and Tenkan[1] < Kijun[1]); # this signal finds the bearish crossover of the turning line back below the standard line def trendContinuationShort = bearishCloud and close < "Span B" and (Tenkan < Kijun and Tenkan[1] > Kijun[1]); # use this scan plot to find bullish break out signals without confirmation def longBreak = signalBreakAboveCloud; # use this scan plot to find bullish break out signals with confirmation def longBreakConfirmed = signalBreakAboveCloud and signalBullishConfirmation; # use this scan plot to find bearish break down signals without confirmation def shortBreak = signalBreakBelowCloud; #use this scan plot to find bearish break down signals with confirmation def shortBreakConfirmed = signalBreakBelowCloud and signalBearishConfirmation; # use this scan plot to find bullish trend continuation signals without confirmation def longTrend = trendContinuationLong; # use this scan plot to find bullish trend continuation signals with confirmation def longTrendConfirmed = trendContinuationLong and signalBullishConfirmation; # use this scan plot to find bearish trend continuation signals without confirmation def shortTrend = trendContinuationShort; # use this scan plot to find bearish trend continuation signals with confirmation def shortTrendConfirmed = trendContinuationShort and signalBearishConfirmation; # here we setup the long and short entry signals according to user selection def longEntry; def shortEntry; switch (signalType) { case "Cloud Break": longEntry = if confirmationRequired then longBreakConfirmed else longBreak; shortEntry = if confirmationRequired then shortBreakConfirmed else shortBreak; case "Trend Continues": longEntry = if confirmationRequired then longTrendConfirmed else longTrend; shortEntry = if confirmationRequired then shortTrendConfirmed else shortTrend; } #---------- ATR Trailing Stop used in place of the PSAR used in original version input trailType = {default modified, unmodified}; input ATRPeriod = 5; input ATRFactor = 3.5; input firstTrade = {default long, short}; input averageType = AverageType.WILDERS; Assert(ATRFactor > 0, "'atr factor' must be positive: " + ATRFactor); def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod)); def HRef = if low <= high[1] then high - close[1] else (high - close[1]) - 0.5 * (low - high[1]); def LRef = if high >= low[1] then close[1] - low else (close[1] - low) - 0.5 * (low[1] - high); def trueRange; switch (trailType) { case modified: trueRange = Max(HiLo, Max(HRef, LRef)); case unmodified: trueRange = TrueRange(high, close, low); } def loss = ATRFactor * MovingAverage(averageType, trueRange, ATRPeriod); def state = {default init, long, short}; def trail; switch (state[1]) { case init: if (!IsNaN(loss)) { switch (firstTrade) { case long: state = state.long; trail = close - loss; case short: state = state.short; trail = close + loss; } } else { state = state.init; trail = Double.NaN; } case long: if (close > trail[1]) { state = state.long; trail = Max(trail[1], close - loss); } else { state = state.short; trail = close + loss; } case short: if (close < trail[1]) { state = state.short; trail = Min(trail[1], close + loss); } else { state = state.long; trail = close - loss; } } plot TrailingStop = trail; TrailingStop.SetPaintingStrategy(PaintingStrategy.POINTS); TrailingStop.DefineColor("Buy", GetColor(0)); TrailingStop.DefineColor("Sell", GetColor(1)); TrailingStop.AssignValueColor(if state == state.long then TrailingStop.Color("Sell") else TrailingStop.Color("Buy")); def longExit = low < TrailingStop[1]; #low[1] > TrailingStop[1] and def shortExit = high > TrailingStop[1]; #high[1] < TrailingStop[1] and # now that all the signals have been established, let's add some orders AddOrder(OrderType.BUY_AUTO, longEntry and low > TrailingStop and open[-1] > TrailingStop, open[-1], tradeSize, Color.BLUE, Color.LIGHT_GREEN, signalType +" Long @ " +open[-1]); #and open[-1] > TrailingStop AddOrder(OrderType.SELL_TO_CLOSE, longExit[-1], min(open, TrailingStop[0]), tradeSize, Color.PINK, Color.PINK, "ATR TrailStop @ " + min(open, TrailingStop[0])); AddOrder(OrderType.SELL_AUTO, shortEntry and high < TrailingStop[0], open[-1], tradeSize, Color.PINK, Color.PINK, signalType +" Short @ " + open[-1]); AddOrder(OrderType.BUY_TO_CLOSE, shortExit[-1], max(open, TrailingStop[0]), tradeSize, Color.BLUE, Color.LIGHT_GREEN, "ATR TrailStop @ " +max(open, TrailingStop[0])); AddLabel(yes, "Entry Type: " + signalType, Color.LIGHT_GREEN); AddLabel(yes, "Confirmation Required: " + if confirmationRequired then "Yes" else "No", Color.WHITE);