Загрузка данных


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'>),
      },
    ],
  },
};