Индикаторы
Каталог примерно из 160 технических индикаторов живёт в отдельном пакете @stocksharp/indicators. Он приезжает вместе с графиком как зависимость, но импортировать определения нужно именно из него. Любое определение вычисляется публичным IndicatorRuntime по вашим свечам, а результат вы рисуете сами обычными сериями — наложением на ценовую панель или осциллятором в отдельной подпанели.
Живая демонстрация
Полосы Боллинджера поверх свечей, а RSI и MACD — в отдельных панелях ниже.
Настройка
Импортируйте среду выполнения и нужные определения, прогоните каждое по свечам и постройте выводы. На вход среде подаются пары { time, value }, где value — это свеча:
import { createChart, CandlestickSeries, LineSeries, HistogramSeries, BandSeries } from '@stocksharp/chart';
import {
IndicatorRuntime,
BollingerBandsIndicator,
RelativeStrengthIndexIndicator,
MacdHistogramIndicator,
} from '@stocksharp/indicators';
// Вычисляет один индикатор по свечам; возвращает его точки, сгруппированные по id вывода.
function compute(definition, parameters, candles) {
const runtime = new IndicatorRuntime({ definition, parameters });
runtime.resetStreaming(candles.map(c => ({ time: c.time, value: c })));
const out = {};
for (const p of runtime.points()) {
if (p.time == null || p.value == null) continue; // прогревочные бары ничего не выдают
(out[p.outputId] ||= []).push({ time: p.time, value: p.value });
}
return out;
}
const chart = createChart(document.getElementById('chart'), {});
const price = chart.addSeries(CandlestickSeries, { upColor: '#26a69a', downColor: '#ef5350' });
price.setData(candles);
// Полосы Боллинджера (20, 2) как огибающая-наложение на ценовой панели.
const bb = compute(BollingerBandsIndicator, { length: 20, width: 2 }, candles); // выводы: upper, middle, lower
chart.addSeries(BandSeries, { upperColor: '#42a5f5', lowerColor: '#42a5f5' })
.setData(bb.upper.map((u, i) => ({ time: u.time, value: bb.middle[i].value, upper: u.value, lower: bb.lower[i].value })));
// RSI (14) в собственной подпанели.
const rsiPane = chart.addPane();
const rsi = compute(RelativeStrengthIndexIndicator, { length: 14 }, candles); // вывод: oscillator
chart.addSeries(LineSeries, { color: '#4a9eff', lineWidth: 2 }, rsiPane).setData(rsi.oscillator);
// MACD (12, 26, 9) во второй подпанели.
const macdPane = chart.addPane();
const macd = compute(
MacdHistogramIndicator,
{ shortMaLength: 12, longMaLength: 26, signalMaLength: 9 }, // выводы: macd, signal, histogram
candles);
chart.addSeries(HistogramSeries, {}, macdPane).setData(macd.histogram);
chart.addSeries(LineSeries, { color: '#4a9eff' }, macdPane).setData(macd.macd);
chart.addSeries(LineSeries, { color: '#f5c542' }, macdPane).setData(macd.signal);
chart.timeScale().fitContent();
Параметры и выводы
Каждое определение объявляет собственные параметры и идентификаторы выводов, и обращаться к ним нужно по этим идентификаторам, а не по описательным именам:
| Определение | Параметры | Выводы | Панель |
|---|---|---|---|
BollingerBandsIndicator |
length (20), width (2), upBandWidth, lowBandWidth |
upper, middle, lower |
наложение |
RelativeStrengthIndexIndicator |
length (15) |
oscillator |
отдельная |
MacdHistogramIndicator |
shortMaLength (12), longMaLength (26), signalMaLength (9) |
macd, signal, histogram |
отдельная |
Caution
Незнакомый идентификатор параметра молча отбрасывается, и индикатор считается на значении по умолчанию. Ошибки не будет — будет неправильная линия. По этой же причине у полос Боллинджера отклонение задаётся ключом width, а не stdDev, а у RSI по умолчанию длина 15, а не 14: если нужен привычный период, его надо передать явно, как в примере выше.
Полный список определений с их параметрами отдаёт каталог:
import { getClientCatalog } from '@stocksharp/indicators';
for (const item of getClientCatalog()) {
console.log(item.id, item.name, item.parameters.map(p => p.id));
}
Данные в реальном времени
Полный пересчёт на каждый бар не нужен. Сохраните IndicatorRuntime и вызывайте update — он возвращает патч с тем, что изменилось:
const runtime = new IndicatorRuntime({ definition: RelativeStrengthIndexIndicator, parameters: { length: 14 } });
runtime.resetStreaming(history.map(c => ({ time: c.time, value: c })));
// Незакрытый бар: false означает предварительное значение, которое заменится следующим вызовом.
runtime.update({ time: bar.time, value: bar }, false);
// Бар закрылся — значение становится окончательным.
const patch = runtime.update({ time: bar.time, value: bar }, true);
Пока бар не закрыт, среда держит предварительную точку и заменяет её при каждом вызове, поэтому история не растёт от обновлений внутри одного бара. discardPreview() убирает предварительную точку, correct(index, input) пересчитывает исторический бар, приехавший с исправлением.