sclass Supertrend extends CandleBasedIndicator { replace Candle with TradingCandle. // length parameter is in base class // We need ATR for the calculation gettable ATR atr; settable double multiplier = 3; settable DoubleRange bands; // The final value settable double supertrend = Double.NaN; // The buy/sell signal (-1/0/1) settable int signal; // Final bands collected as tickers gettable TickerSequence upperBandHistory = new TickerSequence("Final upper band"); gettable TickerSequence lowerBandHistory = new TickerSequence("Final lower band"); gettable TickerSequence basicUpperBandHistory = new TickerSequence("Basic upper band"); gettable TickerSequence basicLowerBandHistory = new TickerSequence("Basic lower band"); gettable TickerSequence supertrendHistory = new TickerSequence("Supertrend"); gettable TickerSequence signalHistory = new TickerSequence("Signal"); int candlesNeeded() { ret 2; } { length = 10; onCandleAdded(candle -> { if (atr == null) atr = new ATR(length); atr().add(candle); var atrValue = atr!; if (isNaN(atrValue)) ret; Candle prev = candles().nextToLast(); double hl2 = candle.hl2(); double basicUpperBand = hl2+multiplier*atrValue; double basicLowerBand = hl2-multiplier*atrValue; var previousBands = bands; double finalUpperBand = previousBands == null || basicUpperBand < previousBands.end || prev.close() > previousBands.end ? basicUpperBand : previousBands.end; double finalLowerBand = previousBands == null || basicLowerBand > previousBands.start || prev.close() < previousBands.start ? basicLowerBand : previousBands.start; if (previousBands == null || supertrend == previousBands.end) supertrend(candle.close() < finalUpperBand ? finalUpperBand : finalLowerBand); else supertrend(candle.close() > finalLowerBand ? finalLowerBand : finalUpperBand); // Literature suggests candle.close() instead of hl2 signal(sign(candle.close()-supertrend)); //signal(sign(hl2-supertrend)); bands(doubleRange(finalLowerBand, finalUpperBand)); upperBandHistory?.addIfPriceChanged(finalUpperBand, candle.endTime().toLong()); lowerBandHistory?.addIfPriceChanged(finalLowerBand, candle.endTime().toLong()); basicUpperBandHistory?.addIfPriceChanged(basicUpperBand, candle.endTime().toLong()); basicLowerBandHistory?.addIfPriceChanged(basicLowerBand, candle.endTime().toLong()); supertrendHistory?.add(supertrend, candle.endTime().toLong()); signalHistory?.add(signal, candle.endTime().toLong()); change(); }); } L bandsAsTickers(L candles) { feed(candles); ret ll(upperBandHistory, lowerBandHistory); } Double value() { ret supertrend(); } void reset :: after { resetFields(this, "previousBands bands upperBandHistory lowerBandHistory basicUpperBandHistory basicLowerBandHistory supertrendHistory supertrend atr signal"); } }