calculate method
Pure computation function that produces an IndicatorResult from candles.
Implementation
@override
IndicatorResult calculate(List<Candle> candles) {
final values = List<double?>.filled(candles.length, null);
if (candles.length < period) {
return IndicatorResult(
indicatorId: id,
name: name,
isOverlay: false,
series: [
IndicatorSeries(
id: 'cci',
label: name,
color: color,
strokeWidth: strokeWidth,
values: values,
),
],
horizontalLevels: const [-100.0, 0.0, 100.0],
);
}
// 1. Calculate Typical Price (TP) for all candles
final tp = List<double>.generate(
candles.length,
(i) => (candles[i].high + candles[i].low + candles[i].close) / 3.0,
);
// 2. Compute CCI for each window
for (int i = period - 1; i < candles.length; i++) {
double sumTp = 0.0;
for (int j = i - period + 1; j <= i; j++) {
sumTp += tp[j];
}
final smaTp = sumTp / period;
double sumDev = 0.0;
for (int j = i - period + 1; j <= i; j++) {
sumDev += (tp[j] - smaTp).abs();
}
final meanDev = sumDev / period;
if (meanDev == 0.0) {
values[i] = 0.0;
} else {
values[i] = (tp[i] - smaTp) / (0.015 * meanDev);
}
}
return IndicatorResult(
indicatorId: id,
name: name,
isOverlay: false,
series: [
IndicatorSeries(
id: 'cci',
label: name,
color: color,
strokeWidth: strokeWidth,
values: values,
),
],
horizontalLevels: const [-100.0, 0.0, 100.0],
);
}