sclass BollingerBands { replace Candle with TradingCandle. new Welford welford; settable int length = 20; // Bollinger length (how many candles to look at) settable double deviation = 2; // result settable DoubleRange range; simplyCached CircularFifoBuffer candles() { ret new CircularFifoBuffer(length); } gettable AverageAndStandardDeviation as; Candle lastCandle() { ret candles().last(); } void feed(TradingCandleMaker candleMaker) { if (candleMaker != null) for (candle : candleMaker.candles()) add(candle); } void add(TradingCandle candle) { if (candle.ongoing()) ret; if (lastCandle() != null && lessOrEq(candle.startTime, lastCandle().startTime)) ret; candles().removeToSize(length-1); candles().add(candle); if (l(candles()) >= length) { var bCandles = candles().asList(); var prices = mapToDoubleArray(bCandles, ->.endPrice()); as = averageAndStandardDeviation(prices); range = bollingerRange(as, deviation); } } }