Загрузка данных
import { SeriesDataItemTypeMap, Time } from 'lightweight-charts';
import { IndicatorDataFormatter } from '@core/Indicators/index';
import { getThemeStore } from '@src/theme';
export function volume({
mainSeriesData,
candle,
}: IndicatorDataFormatter<'Histogram'>): SeriesDataItemTypeMap<Time>['Histogram'][] {
const { colors } = getThemeStore();
if (!candle) {
return mainSeriesData.map((d) => {
const cv = d.customValues;
return {
time: d.time as Time,
value: cv.volume,
color: cv.close && cv.open && cv.close >= cv.open ? colors.chartCandleWickUp : colors.chartCandleWickDown,
};
});
}
const cv = candle.customValues;
return [
{
time: candle.time as Time,
value: cv.volume,
color: cv.close && cv.open && cv.close >= cv.open ? colors.chartCandleWickUp : colors.chartCandleWickDown,
},
];
}
import {
DeepPartial,
PriceScaleMode,
PriceScaleOptions,
SeriesDataItemTypeMap,
SeriesPartialOptionsMap,
SeriesType,
Time,
} from 'lightweight-charts';
import { Indicator } from '@core/Indicator';
import { emaIndicator } from '@core/Indicators/ema';
import { macdHist, macdLine, macdSignal } from '@core/Indicators/macd';
import { smaIndicator } from '@core/Indicators/sma';
import { volume } from '@core/Indicators/volume';
import { SerieData } from '@core/Series/BaseSeries';
import { Candle, ChartSeriesType } from '@lib';
import { getThemeStore } from '@src/theme';
import { Direction, LineCandle } from '@src/types';
export interface IndicatorConfig {
series: {
id: string;
name: ChartSeriesType;
legendVisible?: boolean;
legendColor?: string;
seriesOptions?: SeriesPartialOptionsMap[ChartSeriesType];
priceScaleOptions?: DeepPartial<PriceScaleOptions>;
priceScaleId?: string;
dataFormatter<T extends SeriesType>(params: IndicatorDataFormatter<T>): SeriesDataItemTypeMap<Time>[T][];
}[];
paneIndex?: number;
}
export enum IndicatorsIds {
'vol' = 'vol',
'sma' = 'sma',
'ema' = 'ema',
'macd' = 'macd',
}
export const labelByIndicatorId: Record<IndicatorsIds, string> = {
[IndicatorsIds.vol]: 'Объём',
[IndicatorsIds.sma]: 'SMA',
[IndicatorsIds.ema]: 'EMA',
[IndicatorsIds.macd]: 'MACD',
};
export type ChartTypeToCandleData = {
['Bar']: Candle;
['Candlestick']: Candle;
['Area']: LineCandle;
['Baseline']: LineCandle;
['Line']: LineCandle;
['Histogram']: LineCandle;
['Custom']: Candle;
};
export interface IndicatorDataFormatter<T extends SeriesType> {
mainSeriesData: SerieData[];
selfData: ChartTypeToCandleData[T][];
candle?: SerieData;
indicatorReference?: Indicator;
}
export const indicatorsMap: Partial<Record<IndicatorsIds, IndicatorConfig>> = {
[IndicatorsIds.vol]: {
series: [
{
name: 'Histogram',
id: 'volume',
priceScaleOptions: {
scaleMargins: { top: 0.7, bottom: 0 },
},
seriesOptions: {
priceScaleId: 'vol',
priceFormat: {
type: 'volume',
},
},
dataFormatter: (params) => volume(params as IndicatorDataFormatter<'Histogram'>),
},
],
},
[IndicatorsIds.sma]: {
series: [
{
name: 'Line', // todo: change with enum
id: 'sma',
seriesOptions: {
color: getThemeStore().colors.indicatorLineSma,
},
dataFormatter: (params) => smaIndicator(params as IndicatorDataFormatter<'Line'>, 10),
},
],
},
[IndicatorsIds.ema]: {
series: [
{
name: 'Line', // todo: change with enum
id: 'ema',
seriesOptions: {
color: getThemeStore().colors.indicatorLineEma,
},
dataFormatter: (params) => {
return emaIndicator(params as IndicatorDataFormatter<'Line'>, 25);
},
},
],
},
[IndicatorsIds.macd]: {
paneIndex: 1, // todo: временное решение , пока нет поддержки пейнов
series: [
{
name: 'Line', // todo: change with enum
id: 'longEma',
legendVisible: false,
dataFormatter: (params) => {
return emaIndicator(params as IndicatorDataFormatter<'Line'>, 26);
},
seriesOptions: {
priceScaleId: 'macd_emas',
visible: false,
lastValueVisible: false,
color: getThemeStore().colors.chartPriceLineText,
},
},
{
name: 'Line', // todo: change with enum
id: 'shortEma',
legendVisible: false,
dataFormatter: (params) => {
return emaIndicator(params as IndicatorDataFormatter<'Line'>, 12);
},
seriesOptions: {
priceScaleId: 'macd_emas',
visible: false,
lastValueVisible: false,
color: getThemeStore().colors.chartPriceLineText,
},
},
{
name: 'Line', // todo: change with enum
id: 'macd',
legendVisible: true,
priceScaleOptions: {
mode: PriceScaleMode.Normal,
},
dataFormatter: (params) => macdLine(params as IndicatorDataFormatter<'Line'>),
seriesOptions: {
priceScaleId: Direction.Right,
lastValueVisible: false,
color: getThemeStore().colors.indicatorLineSma,
},
},
{
name: 'Line', // todo: change with enum
id: 'macd_signal',
legendVisible: true,
priceScaleOptions: {
mode: PriceScaleMode.Normal,
},
dataFormatter: (params) => macdSignal(params as IndicatorDataFormatter<'Line'>),
seriesOptions: {
priceScaleId: Direction.Right,
lastValueVisible: false,
color: getThemeStore().colors.chartCandleUp,
},
},
{
name: 'Histogram', // todo: change with enum
id: 'hist',
legendVisible: true,
priceScaleOptions: {
autoScale: true,
},
seriesOptions: {
priceScaleId: Direction.Right,
lastValueVisible: false,
},
dataFormatter: (params) => macdHist(params as IndicatorDataFormatter<'Histogram'>),
},
],
},
};