Загрузка данных
import { SymbolInfo } from '@src/types/symbol';
export enum CompareMode {
Absolute = 'ABS',
Percentage = 'PCT',
NewScale = 'SCALE',
NewPane = 'PANE',
}
export interface CompareItem extends SymbolInfo {
mode: CompareMode;
}
import { MenuList, type MenuOption } from '@src/components/Menu/MenuList';
import { t } from '@src/translations';
import type { ChartView } from '@src/core/Seasonality/types';
interface ChartViewMenuProps {
selectedView: ChartView;
onClick: (view: ChartView) => void;
}
export function ChartViewMenu({ selectedView, onClick }: ChartViewMenuProps) {
const options: MenuOption<ChartView>[] = [
{ value: 'chart', label: t('Chart') },
{ value: 'seasonality', label: t('Seasonality') },
];
return (
<MenuList
mode="single"
value={selectedView}
options={options}
onClick={onClick}
/>
);
}
import { MenuList, type MenuOption } from '@src/components/Menu/MenuList';
import { t } from '@src/translations';
import type { SeasonalityScale } from '@src/core/Seasonality/types';
interface SeasonalityScaleMenuProps {
selectedScale: SeasonalityScale;
onClick: (scale: SeasonalityScale) => void;
}
export function SeasonalityScaleMenu({ selectedScale, onClick }: SeasonalityScaleMenuProps) {
const options: MenuOption<SeasonalityScale>[] = [
{ value: 'absolute', label: t('Price') },
{ value: 'percentage', label: t('Percent') },
];
return (
<MenuList
mode="single"
value={selectedScale}
options={options}
onClick={onClick}
/>
);
}
import { Dropdown } from '@src/components/Dropdown';
import { RangeField } from '@src/components/FormFields';
import { SeasonalityScaleMenu } from '@src/components/Menu/SeasonalityScaleMenu';
import { t } from '@src/translations';
import { useObservable } from '@src/utils';
import styles from './index.module.scss';
import type { SeasonalityRange, SeasonalityScale, SeasonalityState } from '@src/core/Seasonality/types';
import type { Observable } from 'rxjs';
interface SeasonalityControlsProps {
stateObs: Observable<SeasonalityState>;
setScale: (scale: SeasonalityScale) => void;
setRange: (range: SeasonalityRange) => void;
}
export function SeasonalityControls({ stateObs, setScale, setRange }: SeasonalityControlsProps) {
const state = useObservable(stateObs);
if (!state || state.view !== 'seasonality') {
return null;
}
const handleRangeChange = ([fromYear, toYear]: [number, number]) => {
setRange({ fromYear, toYear });
};
return (
<div className={styles.controls}>
<div className={styles.controls_header}>
<Dropdown selectedValue={state.scale === 'absolute' ? t('Price') : t('Percent')}>
<SeasonalityScaleMenu
selectedScale={state.scale}
onClick={setScale}
/>
</Dropdown>
</div>
<div className={styles.controls_range}>
<RangeField
mode="range"
value={[state.fromYear, state.toYear]}
min={state.minYear}
max={state.maxYear}
step={1}
suffix=""
size="sm"
disabled={state.status === 'loading' || state.status === 'error'}
onRangeChange={handleRangeChange}
/>
</div>
</div>
);
}
import type { Candle } from '@src/types';
import type { Timeframes } from '@src/types/timeframes';
export type ChartView = 'chart' | 'seasonality';
export type SeasonalityScale = 'absolute' | 'percentage';
export interface SeasonalityRange {
fromYear: number;
toYear: number;
}
export interface SeasonalityState extends SeasonalityRange {
view: ChartView;
status: 'idle' | 'loading' | 'ready' | 'empty' | 'error';
scale: SeasonalityScale;
symbolId: string;
minYear: number;
maxYear: number;
error: string | null;
}
export function createInitialSeasonalityState(): SeasonalityState {
const year = new Date().getUTCFullYear();
return {
view: 'chart',
status: 'idle',
scale: 'absolute',
symbolId: '',
error: null,
minYear: year - 4,
maxYear: year,
fromYear: year - 4,
toYear: year,
};
}
export interface SeasonalityPoint {
date: string;
chartDate: string;
price: number;
percentage: number | null;
}
export interface SeasonalityYear {
year: number;
baselineDate: string;
baselinePrice: number;
points: SeasonalityPoint[];
}
export interface DailyClose {
date: string;
close: number;
}
export type SeasonalityGetData = (timeframe: Timeframes, symbolId: string, until?: Candle) => Promise<Candle[] | null>;
import { SeriesType, Time } from 'lightweight-charts';
import { DateFormat } from '@src/utils/formatter';
import { TimeFormat } from './timeScale';
/**
* Типы графиков, поддерживаемые библиотекой
*/
export type ChartSeriesType = SeriesType;
/**
* Универсальный формат данных для всех типов графиков
*/
export interface ChartDataPoint {
time?: Time;
value?: number;
open?: number;
high?: number;
low?: number;
close?: number;
volume?: number;
}
interface CandlestickChartOptions {
upColor?: string;
downColor?: string;
wickUpColor?: string;
wickDownColor?: string;
borderVisible?: boolean;
}
interface LineChartOptions {
lineStyle?: 'solid' | 'dotted' | 'dashed';
}
interface AreaChartOptions {
topColor?: string;
bottomColor?: string;
}
interface BaselineChartOptions {
baseValue?: number;
topLineColor?: string;
bottomLineColor?: string;
topFillColor1?: string;
topFillColor2?: string;
bottomFillColor1?: string;
bottomFillColor2?: string;
}
interface TimescaleOptions {
timeVisible?: boolean;
secondsVisible?: boolean;
timeFormat?: TimeFormat;
dateFormat?: DateFormat;
}
interface CrosshairOptions {
crosshairLineXColor?: string;
crosshairLineYColor?: string;
crosshairLabelXBgColor?: string;
crosshairLabelYBgColor?: string;
}
interface HistogramOptions {
scaleMargins?: {
top: number;
bottom: number;
};
}
/**
* @deprecated
* Опции для разных типов графиков
*/
export interface ChartTypeOptions // todo: неверный интерфейс
extends HistogramOptions,
CrosshairOptions,
TimescaleOptions,
BaselineChartOptions,
AreaChartOptions,
LineChartOptions,
CandlestickChartOptions {
// Общие опции
color?: string;
lineWidth?: number;
}
export interface LineCandle {
time: number;
value: number;
volume?: number;
}
export interface Candle {
time: number;
open: number;
high: number;
low: number;
close: number;
volume?: number; // todo: volume & future metaData to customFields
}
export type Destroyable = {
destroy(): void;
};
export enum Direction {
Top = 'top',
Bottom = 'bottom',
Left = 'left',
Right = 'right',
}
// Настройки графика, которые могут изменяться в рантайме
export interface ChartOptionsModel {
dateFormat: DateFormat;
timeFormat: TimeFormat;
showTime: boolean;
}