Загрузка данных
import { PriceScaleMode, SeriesType } from 'lightweight-charts';
import { Indicator } from '@core/Indicator';
import { emaIndicator } from '@core/Indicators/ema';
import { macdHist, macdLine, macdOscillatorFastMa, macdOscillatorSlowMa, 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 } from '@lib';
import { IndicatorsIds } from '@src/constants';
import { INDICATOR_COLOR_PALETTE_MIDDLE_INDEX } from '@src/theme';
import { t } from '@src/translations';
import { Direction, IndicatorConfig, LineCandle, SettingsValues } from '@src/types';
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;
settings?: SettingsValues;
}
export const indicatorsMap = (): Partial<Record<IndicatorsIds, IndicatorConfig>> => ({
[IndicatorsIds.Volume]: {
series: [
{
name: 'Histogram',
id: 'volume',
priceScaleOptions: {
scaleMargins: { top: 0.7, bottom: 0 },
},
seriesOptions: {
priceScaleId: 'vol',
lastValueVisible: false,
priceLineVisible: false,
priceFormat: {
type: 'volume',
},
},
dataFormatter: (params) => volume(params as IndicatorDataFormatter<'Histogram'>),
},
],
},
[IndicatorsIds.SMA]: {
series: [
{
name: 'Line', // todo: change with enum
id: 'sma',
seriesOptions: {},
dataFormatter: (params) => smaIndicator(params as IndicatorDataFormatter<'Line'>),
},
],
settings: [
{ type: 'number', key: 'length', label: t('Length'), defaultValue: 10, min: 1, max: 500 },
{
type: 'select',
key: 'source',
label: t('Data'),
defaultValue: 'close',
options: [
{ label: t('Open price'), value: 'open' },
{ label: t('Max'), value: 'high' },
{ label: t('Min'), value: 'low' },
{ label: t('Close price'), value: 'close' },
],
},
{ type: 'number', key: 'offset', label: t('Offset'), defaultValue: 0, min: -100, max: 100 },
],
},
[IndicatorsIds.EMA]: {
paletteStartIndex: INDICATOR_COLOR_PALETTE_MIDDLE_INDEX,
series: [
{
name: 'Line', // todo: change with enum
id: 'ema',
seriesOptions: {},
dataFormatter: (params) => {
return emaIndicator(params as IndicatorDataFormatter<'Line'>);
},
},
],
settings: [
{ type: 'number', key: 'length', label: t('Length'), defaultValue: 10, min: 1, max: 500 },
{
type: 'select',
key: 'source',
label: t('Data'),
defaultValue: 'close',
options: [
{ label: t('Open price'), value: 'open' },
{ label: t('Max'), value: 'high' },
{ label: t('Min'), value: 'low' },
{ label: t('Close price'), value: 'close' },
],
},
{ type: 'number', key: 'offset', label: t('Offset'), defaultValue: 0, min: -100, max: 100 },
],
},
[IndicatorsIds.MACD]: {
newPane: true,
series: [
{
name: 'Line', // todo: change with enum
id: 'oscillatorSlowMa',
dataFormatter: (params) => macdOscillatorSlowMa(params as IndicatorDataFormatter<'Line'>),
seriesOptions: {
priceScaleId: 'macd_oscillator_ma',
visible: false,
lastValueVisible: false,
},
},
{
name: 'Line', // todo: change with enum
id: 'oscillatorFastMa',
dataFormatter: (params) => macdOscillatorFastMa(params as IndicatorDataFormatter<'Line'>),
seriesOptions: {
priceScaleId: 'macd_oscillator_ma',
visible: false,
lastValueVisible: false,
},
},
{
name: 'Line', // todo: change with enum
id: 'macdLine',
actLikeMainSerie: true,
priceScaleOptions: {
mode: PriceScaleMode.Normal,
},
dataFormatter: (params) => macdLine(params as IndicatorDataFormatter<'Line'>),
seriesOptions: {
priceScaleId: Direction.Right,
lastValueVisible: false,
},
},
{
name: 'Line', // todo: change with enum
actLikeMainSerie: true,
id: 'signalLine',
priceScaleOptions: {
mode: PriceScaleMode.Normal,
},
dataFormatter: (params) => macdSignal(params as IndicatorDataFormatter<'Line'>),
seriesOptions: {
priceScaleId: Direction.Right,
lastValueVisible: false,
},
},
{
name: 'Histogram', // todo: change with enum
actLikeMainSerie: true,
id: 'histogram',
priceScaleOptions: {
autoScale: true,
},
seriesOptions: {
priceScaleId: Direction.Right,
lastValueVisible: false,
},
dataFormatter: (params) => macdHist(params as IndicatorDataFormatter<'Histogram'>),
},
],
settings: [
{
type: 'select',
key: 'source',
label: t('Data'),
defaultValue: 'close',
options: [
{ label: t('Open price'), value: 'open' },
{ label: t('Max'), value: 'high' },
{ label: t('Min'), value: 'low' },
{ label: t('Close price'), value: 'close' },
],
},
{ type: 'number', key: 'fastLength', label: t('Fast length'), defaultValue: 12, min: 1, max: 500 },
{ type: 'number', key: 'slowLength', label: t('Slow length'), defaultValue: 26, min: 1, max: 500 },
{ type: 'number', key: 'signalLength', label: t('Signal length'), defaultValue: 9, min: 1, max: 500 },
{
type: 'select',
key: 'oscillatorMaType',
label: t('Oscillator MA type'),
defaultValue: 'ema',
options: [
{ label: 'EMA', value: 'ema' },
{ label: 'SMA', value: 'sma' },
],
},
{
type: 'select',
key: 'signalMaType',
label: t('Signal MA type'),
defaultValue: 'ema',
options: [
{ label: 'EMA', value: 'ema' },
{ label: 'SMA', value: 'sma' },
],
},
],
},
});
import { DrawingsManagerSnapshot } from '@core/DrawingsManager';
import { ChartSeriesType, DateFormat, IndicatorsIds, Intervals, Timeframes } from '@lib';
import { Direction } from '@src/types/chart';
import { SymbolInfo, SymbolInfoInput } from '@src/types/symbol';
import { TimeFormat } from '@src/types/timeScale';
import { SettingsValues } from './settings';
import type { PriceScaleMode } from 'lightweight-charts';
export type PriceScaleSide = Direction.Left | Direction.Right;
export interface ISerializable<T extends object> {
getSnapshot: () => T;
}
export interface InitialSnapshot extends SymbolInfoInput {
timeframe: Timeframes; // todo: move to snap
chartSeriesType: ChartSeriesType; // todo: move to snap
}
export interface MoexChartSnapshotInput {
// settings: ChartSettingsSnapshot;
charts: ChartSnapshotInput[];
}
export interface MoexChartSnapshot {
// settings: ChartSettingsSnapshot;
charts: ChartSnapshot[];
}
interface ChartSnapshotBase {
timeframe: Timeframes;
chartSeriesType: ChartSeriesType;
timeFormat?: TimeFormat;
dateFormat?: DateFormat;
interval?: Intervals | null;
panes: PaneSnapshot[];
}
export interface ChartSnapshotInput extends ChartSnapshotBase, SymbolInfoInput {}
export interface ChartSnapshot extends ChartSnapshotBase, SymbolInfo {}
export interface PriceScaleSnapshot {
side: PriceScaleSide;
mode: PriceScaleMode;
}
export interface PaneSnapshot {
isMain: boolean;
id: number;
indicators: (IndicatorSnapshot | CompareSnapshot)[];
drawings: DrawingsManagerSnapshot;
priceScales?: PriceScaleSnapshot[];
}
export interface CompareSnapshot extends Partial<DOMObjectSnapshot> {
symbolInfo: SymbolInfoInput;
seriesName: ChartSeriesType;
scale: Direction;
}
export interface IndicatorSnapshot extends Partial<DOMObjectSnapshot> {
indicatorType: IndicatorsIds;
settings?: SettingsValues;
}
// todo: move DrawingsManagerSnapshot here
export interface DOMObjectSnapshot {
id: string;
name: string;
zIndex: number;
hidden: boolean;
paneId: number;
}