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


diff --git a/CHANGELOG.md b/CHANGELOG.md
index 84d127a..0433c12 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,18 @@
-# next
+# latest
+
+- `breaking change`: Добавлен необязательный параметр `symbolName?: string` для отображения полного названия инструмента в легенде
+- `breaking change`: Добавлен необязательный параметр `symbolTicker?: string` для отображения короткого тикера инструмента в ценовом лейбле
+
+# 0.1.12
 
 - Добавлена поддержка хоткеев на элементы рисования (alt+t, alt+v, alt+h, alt+f, del, esc)
 
+# 0.1.11
+
+- Добавлен необязательный параметр `timeFormat?: TimeFormat` для настройки формата отображения времени
+- Добавлен необязательный параметр `dateFormat?: DateFormat` для настройки формата отображения даты
+- Добавлен необязательный параметр `interval?: Intervals | null` для задания начального интервала при инициализации графика
+
 # 0.1.10
 
 - Добавление логарифмической шкалы
diff --git a/src/core/Chart.ts b/src/core/Chart.ts
index da4f387..6cadc2f 100644
--- a/src/core/Chart.ts
+++ b/src/core/Chart.ts
@@ -361,6 +361,8 @@ export class Chart implements ISerializable<ChartSnapshot> {
       timeFormat,
       interval,
       symbol: this.activeSymbols[0],
+      symbolName: this.eventManager.getSymbolName(),
+      symbolTicker: this.eventManager.getSymbolTicker(),
     };
   }
 
diff --git a/src/core/CompareManager.ts b/src/core/CompareManager.ts
index c450389..5f0761a 100644
--- a/src/core/CompareManager.ts
+++ b/src/core/CompareManager.ts
@@ -10,15 +10,14 @@ import { IndicatorManager } from '@core/IndicatorManager';
 import { PaneManager } from '@core/PaneManager';
 import { PriceScale } from '@core/PriceScale';
 import { COMPARE_COLOR_PALETTE } from '@src/theme';
-import { CompareItem, CompareMode, Direction, IndicatorConfig } from '@src/types';
+import { CompareInstrument, CompareItem, CompareMode, Direction, IndicatorConfig } from '@src/types';
 import { IndicatorSnapshot } from '@src/types/snapshot';
 import { createFallbackColor, normalizeColor, normalizeSymbol } from '@src/utils';
 
-interface CompareEntry {
+interface CompareEntry extends CompareItem {
   key: string;
-  symbol: string;
-  mode: CompareMode;
   symbol$: BehaviorSubject<string>;
+  symbolTicker$: BehaviorSubject<string>;
   entity: Indicator;
 }
 
@@ -88,16 +87,19 @@ export class CompareManager {
 
   public async setSymbolMode(
     seriesType: SeriesType,
-    symbolRaw: string,
+    instrument: CompareInstrument,
     mode: CompareMode,
     paneId?: number,
   ): Promise<void> {
-    const symbol = normalizeSymbol(symbolRaw);
+    const symbol = normalizeSymbol(instrument.symbol);
 
     if (!symbol) {
       return;
     }
 
+    const symbolName = instrument.symbolName.trim() || symbol;
+    const symbolTicker = instrument.symbolTicker.trim() || symbol;
+
     if (mode === CompareMode.NewScale && this.isNewScaleDisabled() && !this.restoringInitialIndicators) {
       return;
     }
@@ -109,6 +111,7 @@ export class CompareManager {
     }
 
     const symbol$ = new BehaviorSubject(symbol);
+    const symbolTicker$ = new BehaviorSubject(symbolTicker);
 
     const entity = this.indicatorManager.addEntity<Indicator>((zIndex, moveUp, moveDown) => {
       const usedColorsByCompare = this.entitiesSubject.value.map(
@@ -127,7 +130,7 @@ export class CompareManager {
 
       const usedColorsByIndicators = flatten(usedColorsByIndicatorsRaw).filter((color) => color !== undefined);
       const usedColors = usedColorsByCompare.concat(usedColorsByIndicators);
-      const config = getDefaultCompareIndicatorConfig(symbol, usedColors);
+      const config = getDefaultCompareIndicatorConfig(seriesType, symbol, symbolName, symbolTicker, usedColors);
 
       const associatedPane =
         mode === CompareMode.NewPane
@@ -140,6 +143,7 @@ export class CompareManager {
         id: key,
         lwcChart: this.chart,
         mainSymbol$: symbol$,
+        mainSymbolTicker$: symbolTicker$,
         dataSource: this.dataSource,
         associatedPane,
         config: {
@@ -170,8 +174,11 @@ export class CompareManager {
     this.entries.set(key, {
       key,
       symbol,
+      symbolName,
+      symbolTicker,
       mode,
       symbol$,
+      symbolTicker$,
       entity,
     });
 
@@ -229,8 +236,10 @@ export class CompareManager {
   }
 
   public getAllEntities() {
-    return Array.from(this.entries.values()).map(({ symbol, entity, mode }) => ({
+    return Array.from(this.entries.values()).map(({ symbol, symbolName, symbolTicker, entity, mode }) => ({
       symbol,
+      symbolName,
+      symbolTicker,
       entity,
       mode,
     }));
@@ -257,6 +266,8 @@ export class CompareManager {
         }
 
         const series = indicator.config.series[0];
+        const symbol = indicator.config.symbol ?? indicator.config.label;
+        const symbolTicker = indicator.config.symbolTicker ?? symbol;
 
         const compareMode =
           series.seriesOptions?.priceScaleId === Direction.Left
@@ -266,7 +277,16 @@ export class CompareManager {
               : CompareMode.Percentage;
 
         // eslint-disable-next-line no-await-in-loop
-        await this.setSymbolMode(series.name, indicator.config.label, compareMode, indicator.paneId);
+        await this.setSymbolMode(
+          series.name,
+          {
+            symbol,
+            symbolName: indicator.config.label,
+            symbolTicker,
+          },
+          compareMode,
+          indicator.paneId,
+        );
       }
     } finally {
       this.restoringInitialIndicators = false;
@@ -284,6 +304,7 @@ export class CompareManager {
     this.indicatorManager.removeEntity(entry.entity);
     entry.entity.destroy();
     entry.symbol$.complete();
+    entry.symbolTicker$.complete();
 
     return true;
   }
@@ -301,6 +322,8 @@ export class CompareManager {
     for (let index = 0; index < values.length; index += 1) {
       items.push({
         symbol: values[index].symbol,
+        symbolName: values[index].symbolName,
+        symbolTicker: values[index].symbolTicker,
         mode: values[index].mode,
       });
 
@@ -392,12 +415,20 @@ function getPaletteColorFromIndex(usedColors: Set<string>, startIndex: number):
   return createFallbackColor(usedColors.size);
 }
 
-const getDefaultCompareIndicatorConfig = (symbol: string, usedColors: string[]): IndicatorConfig => {
+const getDefaultCompareIndicatorConfig = (
+  seriesType: SeriesType,
+  symbol: string,
+  symbolName: string,
+  symbolTicker: string,
+  usedColors: string[],
+): IndicatorConfig => {
   const reservedColors = new Set(usedColors.map(normalizeColor));
 
   return {
+    symbol,
+    symbolTicker,
     newPane: true,
-    label: symbol,
+    label: symbolName,
     series: [
       {
         name: 'Line', // todo: change with enum
diff --git a/src/core/EventManager.ts b/src/core/EventManager.ts
index c99268d..4691d45 100644
--- a/src/core/EventManager.ts
+++ b/src/core/EventManager.ts
@@ -13,6 +13,8 @@ interface EventManagerParams {
   initialTimeframe: Timeframes;
   initialSeries: ChartSeriesType;
   initialSymbol: string;
+  initialSymbolName?: string;
+  initialSymbolTicker?: string;
   initialTimeFormat?: TimeFormat;
   initialDateFormat?: DateFormat;
   initialInterval?: Intervals | null;
@@ -31,6 +33,8 @@ export class EventManager {
   private timeframe$: BehaviorSubject<Timeframes>;
   private seriesSelected$: BehaviorSubject<ChartSeriesType>;
   private symbol$: BehaviorSubject<string>;
+  private symbolName$: BehaviorSubject<string>;
+  private symbolTicker$: BehaviorSubject<string>;
   private timeFormat$: BehaviorSubject<TimeFormat>;
   private dateFormat$: BehaviorSubject<DateFormat>;
   private interval$: BehaviorSubject<Intervals | null>;
@@ -43,21 +47,27 @@ export class EventManager {
     initialTimeframe,
     initialSeries,
     initialSymbol,
+    initialSymbolName,
+    initialSymbolTicker,
     initialTimeFormat,
     initialDateFormat,
     initialInterval = null,
   }: EventManagerParams) {
     this.timeframe$ = new BehaviorSubject<Timeframes>(initialTimeframe);
-    this.interval$ = new BehaviorSubject<Intervals | null>(initialInterval);
     this.seriesSelected$ = new BehaviorSubject<ChartSeriesType>(initialSeries);
     this.symbol$ = new BehaviorSubject<string>(initialSymbol);
+    this.symbolName$ = new BehaviorSubject<string>(initialSymbolName?.trim() || initialSymbol);
+    this.symbolTicker$ = new BehaviorSubject<string>(initialSymbolTicker?.trim() || initialSymbol);
     this.timeFormat$ = new BehaviorSubject<TimeFormat>(initialTimeFormat ?? Defaults.timeFormat);
     this.dateFormat$ = new BehaviorSubject<DateFormat>(initialDateFormat ?? Defaults.dateFormat);
+    this.interval$ = new BehaviorSubject<Intervals | null>(initialInterval);
 
     this.undoRedo = new UndoRedo({
       timeframe: (value) => this.timeframe$.next(value),
       seriesSelected: (value) => this.seriesSelected$.next(value),
       symbol: (value) => this.symbol$.next(value),
+      symbolName: (value) => this.symbolName$.next(value),
+      symbolTicker: (value) => this.symbolTicker$.next(value),
       timeFormat: (value) => this.timeFormat$.next(value),
       dateFormat: (value) => this.dateFormat$.next(value),
       interval: (value) => this.interval$.next(value),
@@ -109,13 +119,46 @@ export class EventManager {
     return this.interval$.asObservable();
   }
 
-  public setSymbol = (next: string, options?: SetWithHistoryOptions) =>
-    this.setWithHistory('symbol', this.symbol$, next, options);
+  public setSymbol = (symbol: string, options?: SetWithHistoryOptions): void => {
+    this.setWithHistory('symbol', this.symbol$, symbol, options);
+  };
 
   public getSymbol(): Observable<string> {
     return this.symbol$.asObservable();
   }
 
+  public setInstrument(
+    symbol: string,
+    symbolName: string,
+    symbolTicker?: string,
+    options?: SetWithHistoryOptions,
+  ): void {
+    const nextSymbolName = symbolName.trim() || symbol;
+    const nextSymbolTicker = symbolTicker?.trim() || symbol;
+
+    this.undoRedo.group(() => {
+      this.setWithHistory('symbolName', this.symbolName$, nextSymbolName, options);
+      this.setWithHistory('symbolTicker', this.symbolTicker$, nextSymbolTicker, options);
+      this.setWithHistory('symbol', this.symbol$, symbol, options);
+    });
+  }
+
+  public symbolName(): Observable<string> {
+    return this.symbolName$.asObservable();
+  }
+
+  public getSymbolName(): string {
+    return this.symbolName$.value;
+  }
+
+  public symbolTicker(): Observable<string> {
+    return this.symbolTicker$.asObservable();
+  }
+
+  public getSymbolTicker(): string {
+    return this.symbolTicker$.value;
+  }
+
   public setTimeFormat = (next: TimeFormat, options?: SetWithHistoryOptions): void =>
     this.setWithHistory('timeFormat', this.timeFormat$, next, options);
 
@@ -207,6 +250,7 @@ export class EventManager {
     }
     if (timeframe) {
       this.setTimeframe(timeframe, setOptions);
+      return;
     }
     if (interval === null) {
       this.resetInterval(setOptions);
@@ -220,6 +264,8 @@ export class EventManager {
     this.controlBarVisible$.complete();
     this.interval$.complete();
     this.symbol$.complete();
+    this.symbolName$.complete();
+    this.symbolTicker$.complete();
     this.seriesSelected$.complete();
   }
 }
diff --git a/src/core/Indicator.ts b/src/core/Indicator.ts
index b0d9ee7..70d8f2a 100644
--- a/src/core/Indicator.ts
+++ b/src/core/Indicator.ts
@@ -14,6 +14,8 @@ type IIndicator = DOMObject;
 
 export interface IndicatorParams extends DOMObjectParams {
   mainSymbol$: Observable<string>;
+  mainSymbolName$?: Observable<string>;
+  mainSymbolTicker$?: Observable<string>;
   lwcChart: IChartApi;
   dataSource: DataSource;
   associatedPane: Pane;
@@ -29,6 +31,8 @@ export class Indicator extends DOMObject implements ISerializable<IndicatorSnaps
   private lwcChart: IChartApi;
   private dataSource: DataSource;
   private mainSymbol$: Observable<string>;
+  private mainSymbolName$: Observable<string>;
+  private mainSymbolTicker$: Observable<string>;
   private associatedPane: Pane;
   private config: IndicatorConfig;
   private settings: SettingsValues = {};
@@ -46,6 +50,8 @@ export class Indicator extends DOMObject implements ISerializable<IndicatorSnaps
     moveUp,
     moveDown,
     mainSymbol$,
+    mainSymbolName$,
+    mainSymbolTicker$,
     associatedPane,
     paneId,
     config,
@@ -54,6 +60,8 @@ export class Indicator extends DOMObject implements ISerializable<IndicatorSnaps
     this.lwcChart = lwcChart;
     this.dataSource = dataSource;
     this.mainSymbol$ = mainSymbol$;
+    this.mainSymbolName$ = mainSymbolName$ ?? mainSymbol$;
+    this.mainSymbolTicker$ = mainSymbolTicker$ ?? mainSymbol$;
     this.indicatorType = type;
     this.config = config;
     this.name = this.getLabel();
@@ -201,6 +209,8 @@ export class Indicator extends DOMObject implements ISerializable<IndicatorSnaps
         seriesOptions,
         priceScaleOptions,
         mainSymbol$: this.mainSymbol$,
+        mainSymbolName$: this.mainSymbolName$,
+        mainSymbolTicker$: this.mainSymbolTicker$,
         mainSerie$: this.associatedPane.getMainSerie(),
         showSymbolLabel: false,
         paneIndex: this.associatedPane.paneIndex(),
diff --git a/src/core/Legend.ts b/src/core/Legend.ts
index b57a6b1..0bf8c93 100644
--- a/src/core/Legend.ts
+++ b/src/core/Legend.ts
@@ -80,7 +80,7 @@ export class Legend {
   private config: OHLCConfig;
 
   private mainSeries!: SeriesStrategies;
-  private mainSymbol = '';
+  private mainSymbolName = '';
   private isChartHovered = false;
   private model$ = new BehaviorSubject<LegendModel>([]);
   private tooltipVisability = new BehaviorSubject<boolean>(false);
@@ -110,10 +110,8 @@ export class Legend {
     this.openIndicatorSettings = openIndicatorSettings;
 
     this.subscriptions.add(
-      this.eventManager.symbol().subscribe((symbol) => {
-        const symbolParts = symbol.split(':');
-
-        this.mainSymbol = symbolParts[symbolParts.length - 1] || symbol;
+      this.eventManager.symbolName().subscribe((symbolName) => {
+        this.mainSymbolName = symbolName;
         this.updateWithLastCandle();
       }),
     );
@@ -189,7 +187,7 @@ export class Legend {
 
       model.push({
         id: `main-series-${this.paneId}`,
-        name: this.mainSymbol,
+        name: this.mainSymbolName,
         values: series as Partial<Record<keyof Ohlc, { value: number | string | Time; color: string; name: string }>>,
         isIndicator: false,
       });
@@ -266,7 +264,7 @@ export class Legend {
 
       model.push({
         id: `main-series-${this.paneId}`,
-        name: this.mainSymbol,
+        name: this.mainSymbolName,
         values: series as Partial<Record<keyof Ohlc, { value: number | string | Time; color: string; name: string }>>,
         isIndicator: false,
       });
diff --git a/src/core/MoexChart.tsx b/src/core/MoexChart.tsx
index 7cf2b96..a222803 100644
--- a/src/core/MoexChart.tsx
+++ b/src/core/MoexChart.tsx
@@ -130,12 +130,15 @@ export class MoexChart implements ISerializable<MoexChartSnapshot> {
 
     setPricePrecision(config.chartCollectionPreset.ohlc.precision);
 
-    const { chartSeriesType, symbol, timeframe, interval, dateFormat, timeFormat } = config.snapshot.charts[0];
+    const { chartSeriesType, symbol, symbolName, symbolTicker, timeframe, interval, dateFormat, timeFormat } =
+      config.snapshot.charts[0];
 
     this.eventManager = new EventManager({
       initialTimeframe: timeframe,
       initialSeries: chartSeriesType,
       initialSymbol: symbol,
+      initialSymbolName: symbolName,
+      initialSymbolTicker: symbolTicker,
       initialTimeFormat: timeFormat,
       initialDateFormat: dateFormat,
       initialInterval: interval,
@@ -272,10 +275,10 @@ export class MoexChart implements ISerializable<MoexChartSnapshot> {
     return res;
   }
 
-  public setSymbol(symbol: string): void {
+  public setSymbol(symbol: string, symbolName?: string, symbolTicker?: string): void {
     if (!symbol) return;
 
-    this.eventManager.setSymbol(symbol);
+    this.eventManager.setInstrument(symbol, symbolName ?? symbol, symbolTicker ?? symbol);
   }
 
   private renderAttachments(config: IMoexChart, toggleToolbar: () => boolean) {
diff --git a/src/core/Pane.tsx b/src/core/Pane.tsx
index 2b228aa..db8d15d 100644
--- a/src/core/Pane.tsx
+++ b/src/core/Pane.tsx
@@ -403,6 +403,8 @@ export class Pane implements ISerializable<PaneSnapshot> {
         lwcChart,
         dataSource,
         mainSymbol$: this.eventManager.getSymbol(),
+        mainSymbolName$: this.eventManager.symbolName(),
+        mainSymbolTicker$: this.eventManager.symbolTicker(),
         mainSerie$: this.mainSeries,
       });
 
diff --git a/src/core/PaneManager.ts b/src/core/PaneManager.ts
index 45a0c0c..633b1a1 100644
--- a/src/core/PaneManager.ts
+++ b/src/core/PaneManager.ts
@@ -95,7 +95,7 @@ export class PaneManager implements ISerializable<PaneSnapshot[]> {
 
     this.priceAxisLabels = new PriceAxisLabels({
       mainSeries$: this.mainPane.getMainSerie().asObservable(),
-      mainSymbol$: this.sharedPaneParams.eventManager.symbol(),
+      mainSymbolTicker$: this.sharedPaneParams.eventManager.symbolTicker(),
       compareEntities$,
       indicatorEntities$,
     });
diff --git a/src/core/PriceAxisLabels/PriceAxisLabels.ts b/src/core/PriceAxisLabels/PriceAxisLabels.ts
index 6a7fdcb..1eaa5f4 100644
--- a/src/core/PriceAxisLabels/PriceAxisLabels.ts
+++ b/src/core/PriceAxisLabels/PriceAxisLabels.ts
@@ -24,7 +24,7 @@ type PriceAxisSide = Direction.Left | Direction.Right;
 
 interface PriceAxisLabelsParams {
   mainSeries$: Observable<SeriesStrategies | null>;
-  mainSymbol$: Observable<string>;
+  mainSymbolTicker$: Observable<string>;
   compareEntities$: Observable<Indicator[]>;
   indicatorEntities$: Observable<Indicator[]>;
 }
@@ -146,16 +146,14 @@ export class PriceAxisLabels {
   private visibleLogicalRange: LogicalRange | null = null;
   private currentPriceLine: IPriceLine | null = null;
   private currentPriceLineHost: SeriesStrategies | null = null;
-  private mainSymbol = '';
+  private mainSymbolTicker = '';
   private isHistoryMode = false;
   private updateFrame: number | null = null;
 
-  constructor({ mainSeries$, mainSymbol$, compareEntities$, indicatorEntities$ }: PriceAxisLabelsParams) {
+  constructor({ mainSeries$, mainSymbolTicker$, compareEntities$, indicatorEntities$ }: PriceAxisLabelsParams) {
     this.subscriptions.add(
-      mainSymbol$.subscribe((symbol) => {
-        const symbolParts = symbol.split(':');
-
-        this.mainSymbol = symbolParts[symbolParts.length - 1] || symbol;
+      mainSymbolTicker$.subscribe((symbolTicker) => {
+        this.mainSymbolTicker = symbolTicker;
 
         this.applyDisplayMode();
         this.scheduleUpdate();
@@ -427,7 +425,7 @@ export class PriceAxisLabels {
         if (source.role === 'main') {
           source.series.applyOptions({
             lastValueVisible: this.isHistoryMode ? false : defaults.lastValueVisible,
-            title: this.isHistoryMode ? '' : this.mainSymbol || defaults.title,
+            title: this.isHistoryMode ? '' : this.mainSymbolTicker || defaults.title,
           });
 
           return;
@@ -673,7 +671,7 @@ export class PriceAxisLabels {
       axisLabelVisible: true,
       axisLabelColor: color,
       axisLabelTextColor: getContrastTextColor(color),
-      title: this.mainSymbol,
+      title: this.mainSymbolTicker,
     });
   }
 
diff --git a/src/core/Series/BaseSeries.ts b/src/core/Series/BaseSeries.ts
index 74e19e0..0742aae 100644
--- a/src/core/Series/BaseSeries.ts
+++ b/src/core/Series/BaseSeries.ts
@@ -69,6 +69,8 @@ export interface BaseSeriesParams<TSeries extends SeriesType = SeriesType> {
   lwcChart: IChartApi;
   dataSource: DataSource;
   mainSymbol$: Observable<string>;
+  mainSymbolName$?: Observable<string>;
+  mainSymbolTicker$?: Observable<string>;
   mainSerie$: BehaviorSubject<SeriesStrategies | null>;
   customFormatter?: (params: IndicatorDataFormatter<TSeries>) => SeriesDataItemTypeMap<Time>[TSeries][];
   seriesOptions?: SeriesPartialOptionsMap[TSeries];
@@ -103,6 +105,8 @@ export abstract class BaseSeries<TSeries extends SeriesType> implements IBaseSer
 
   protected lwcChart: IChartApi;
   protected mainSymbol$: Observable<string>;
+  protected mainSymbolName$: Observable<string>;
+  protected mainSymbolTicker$: Observable<string>;
   protected mainSerie$: BehaviorSubject<SeriesStrategies | null>;
   protected paneIndex: number | null = null;
   protected indicatorReference: Indicator | null = null;
@@ -115,6 +119,8 @@ export abstract class BaseSeries<TSeries extends SeriesType> implements IBaseSer
   constructor({
     lwcChart,
     mainSymbol$,
+    mainSymbolName$,
+    mainSymbolTicker$,
     mainSerie$,
     customFormatter,
     seriesOptions,
@@ -133,6 +139,8 @@ export abstract class BaseSeries<TSeries extends SeriesType> implements IBaseSer
     this.lwcChart = lwcChart;
     this.customFormatter = customFormatter;
     this.mainSymbol$ = mainSymbol$;
+    this.mainSymbolName$ = mainSymbolName$ ?? mainSymbol$;
+    this.mainSymbolTicker$ = mainSymbolTicker$ ?? mainSymbol$;
     this.mainSerie$ = mainSerie$;
     this.showSymbolLabel = showSymbolLabel;
     this.indicatorReference = indicatorReference ?? null;
@@ -383,18 +391,24 @@ export abstract class BaseSeries<TSeries extends SeriesType> implements IBaseSer
   protected subscribeDataSource = (dataSource: DataSource): void => {
     const minMove = getPricePrecisionStep();
 
+    this.lwcSeries.applyOptions({
+      priceFormat: {
+        type: 'custom',
+        minMove,
+        formatter: (price: number) => formatPrice(price) ?? String(price),
+      },
+    });
+
     this.subscriptions.add(
-      this.mainSymbol$.pipe(distinctUntilChanged()).subscribe((symbol) => {
+      this.mainSymbolTicker$.pipe(distinctUntilChanged()).subscribe((symbolTicker) => {
         this.lwcSeries.applyOptions({
-          // todo: на каждый апдейт dataSource сеттим options. Не оптимально
-          title: this.showSymbolLabel ? symbol : '',
-          priceFormat: {
-            type: 'custom',
-            minMove,
-            formatter: (price: number) => formatPrice(price) ?? String(price),
-          },
+          title: this.showSymbolLabel ? symbolTicker : '',
         });
+      }),
+    );
 
+    this.subscriptions.add(
+      this.mainSymbol$.pipe(distinctUntilChanged()).subscribe((symbol) => {
         this.dataSub?.unsubscribe();
         this.realtimeSub?.unsubscribe();
 
diff --git a/src/core/UndoRedo.ts b/src/core/UndoRedo.ts
index 581b616..c39e3c0 100644
--- a/src/core/UndoRedo.ts
+++ b/src/core/UndoRedo.ts
@@ -7,6 +7,8 @@ interface UndoConfig {
   timeframe: (value: Timeframes) => void;
   seriesSelected: (value: ChartSeriesType) => void;
   symbol: (value: string) => void;
+  symbolName: (value: string) => void;
+  symbolTicker: (value: string) => void;
   timeFormat: (value: TimeFormat) => void;
   dateFormat: (value: DateFormat) => void;
   interval: (value: Intervals | null) => void;
diff --git a/src/types/compare.ts b/src/types/compare.ts
index b8ef60f..98657b7 100644
--- a/src/types/compare.ts
+++ b/src/types/compare.ts
@@ -4,7 +4,11 @@ export enum CompareMode {
   NewPane = 'PANE',
 }
 
-export interface CompareItem {
+export interface CompareInstrument {
   symbol: string;
+  symbolName: string;
+  symbolTicker: string;
+}
+export interface CompareItem extends CompareInstrument {
   mode: CompareMode;
 }
diff --git a/src/types/indicator.ts b/src/types/indicator.ts
index ca45dca..e0e3495 100644
--- a/src/types/indicator.ts
+++ b/src/types/indicator.ts
@@ -22,7 +22,7 @@ export type IndicatorType = 'SMA' | 'EMA' | 'RSI' | 'OHLC' | 'VOL';
 
 export type MASource = 'open' | 'high' | 'low' | 'close';
 
-export type IndicatorLabel = (ReturnType<typeof indicatorLabelById>)[IndicatorsIds];
+export type IndicatorLabel = ReturnType<typeof indicatorLabelById>[IndicatorsIds];
 
 export interface IndicatorStateConfig {
   type: IndicatorType;
@@ -48,6 +48,8 @@ export interface IndicatorConfig {
   series: IndicatorSerie[];
   settings?: SettingField[];
   newPane?: boolean;
+  symbol?: string;
+  symbolTicker?: string;
   label?: string;
   seriesLabels?: Record<string, string>;
   paletteStartIndex?: number;
diff --git a/src/types/snapshot.ts b/src/types/snapshot.ts
index 157346b..67b2114 100644
--- a/src/types/snapshot.ts
+++ b/src/types/snapshot.ts
@@ -28,6 +28,8 @@ export interface ChartSnapshot {
   timeframe: Timeframes;
   chartSeriesType: ChartSeriesType;
   symbol: string;
+  symbolName?: string;
+  symbolTicker?: string;
   timeFormat?: TimeFormat;
   dateFormat?: DateFormat;
   interval?: Intervals | null;
diff --git a/stories/MB/MB.stories.tsx b/stories/MB/MB.stories.tsx
index e5b193d..da5142e 100644
--- a/stories/MB/MB.stories.tsx
+++ b/stories/MB/MB.stories.tsx
@@ -5,7 +5,7 @@ import { DateFormat, IMoexChart, Locale, MoexChart, Timeframes } from '@lib';
 import { Portal } from '@lib/components/Portal';
 import { IndicatorsIds } from '@lib/constants';
 import { CompareManager } from '@lib/core/CompareManager';
-import { CompareMode } from '@lib/types';
+import { CompareInstrument, CompareMode } from '@lib/types';
 
 import { dataSourceProvider } from '../common';
 
@@ -183,6 +183,12 @@ export const MB: Story = {
   },
 };
 
+const COMPARE_ITEMS: CompareInstrument[] = [
+  { symbol: 'SBER', symbolName: 'SBER', symbolTicker: 'SBER' },
+  { symbol: 'APAX', symbolName: 'APAX', symbolTicker: 'APAX' },
+  { symbol: 'SOL', symbolName: 'SOL', symbolTicker: 'SOL' },
+];
+
 const Modal = ({ onClose, compareManager }: { onClose: () => void; compareManager: CompareManager | null }) => {
   const [isNewScaleDisabled, setIsNewScaleDisabled] = useState(false);
 
@@ -234,22 +240,22 @@ const Modal = ({ onClose, compareManager }: { onClose: () => void; compareManage
           ...containerStyles,
         }}
       >
-        {['SBER', 'APAX', 'SOL'].map((symbol) => (
+        {COMPARE_ITEMS.map((instrument) => (
           <div
-            key={symbol}
+            key={instrument.symbol}
             style={{ display: 'flex', justifyContent: 'space-between', gap: 16 }}
           >
-            <span>{symbol}</span>
+            <span>{instrument.symbolTicker}</span>
             <div style={{ display: 'flex', gap: 8 }}>
               <button
-                onClick={() => compareManager?.setSymbolMode('Line', symbol, CompareMode.Percentage)}
+                onClick={() => compareManager?.setSymbolMode('Line', instrument, CompareMode.Percentage)}
                 style={buttonStyles}
                 type="button"
               >
                 %
               </button>
               <button
-                onClick={() => compareManager?.setSymbolMode('Line', symbol, CompareMode.NewScale)}
+                onClick={() => compareManager?.setSymbolMode('Line', instrument, CompareMode.NewScale)}
                 style={{
                   backgroundColor: isNewScaleDisabled ? 'darkgray' : 'lightgray',
                   padding: '2px 8px',
@@ -261,7 +267,7 @@ const Modal = ({ onClose, compareManager }: { onClose: () => void; compareManage
                 Новая шкала
               </button>
               <button
-                onClick={() => compareManager?.setSymbolMode('Line', symbol, CompareMode.NewPane)}
+                onClick={() => compareManager?.setSymbolMode('Line', instrument, CompareMode.NewPane)}
                 style={buttonStyles}
                 type="button"
               >
diff --git a/stories/TradeRadar/TradeRadar.stories.tsx b/stories/TradeRadar/TradeRadar.stories.tsx
index 99f3b84..962916d 100644
--- a/stories/TradeRadar/TradeRadar.stories.tsx
+++ b/stories/TradeRadar/TradeRadar.stories.tsx
@@ -5,7 +5,7 @@ import { createPortal } from 'react-dom';
 import { CompareManager } from '@core/CompareManager';
 import { DateFormat, IMoexChart, Locale, MoexChart, Timeframes } from '@lib';
 import { IndicatorsIds } from '@lib/constants';
-import { CompareMode } from '@lib/types';
+import { CompareInstrument, CompareMode } from '@lib/types';
 
 // import { argTypes } from '../argTypes';
 
@@ -219,6 +219,12 @@ export const TradeRadar: Story = {
   },
 };
 
+const COMPARE_ITEMS: CompareInstrument[] = [
+  { symbol: 'SBER', symbolName: 'SBER', symbolTicker: 'SBER' },
+  { symbol: 'APAX', symbolName: 'APAX', symbolTicker: 'APAX' },
+  { symbol: 'SOL', symbolName: 'SOL', symbolTicker: 'SOL' },
+];
+
 const Modal = ({ onClose, compareManager }: { onClose: () => void; compareManager: CompareManager | null }) => {
   const [isNewScaleDisabled, setIsNewScaleDisabled] = useState(false);
 
@@ -262,22 +268,22 @@ const Modal = ({ onClose, compareManager }: { onClose: () => void; compareManage
           backgroundColor: 'white',
         }}
       >
-        {['SBER', 'APAX', 'SOL'].map((symbol) => (
+        {COMPARE_ITEMS.map((instrument) => (
           <div
-            key={symbol}
+            key={instrument.symbol}
             style={{ display: 'flex', justifyContent: 'space-between', gap: 16 }}
           >
-            <span>{symbol}</span>
+            <span>{instrument.symbolTicker}</span>
             <div style={{ display: 'flex', gap: 8 }}>
               <button
-                onClick={() => compareManager?.setSymbolMode('Line', symbol, CompareMode.Percentage)}
+                onClick={() => compareManager?.setSymbolMode('Line', instrument, CompareMode.Percentage)}
                 style={{ backgroundColor: 'lightgray', padding: '2px 8px' }}
                 type="button"
               >
                 %
               </button>
               <button
-                onClick={() => compareManager?.setSymbolMode('Line', symbol, CompareMode.NewScale)}
+                onClick={() => compareManager?.setSymbolMode('Line', instrument, CompareMode.NewScale)}
                 style={{
                   backgroundColor: isNewScaleDisabled ? 'darkgray' : 'lightgray',
                   padding: '2px 8px',
@@ -289,7 +295,7 @@ const Modal = ({ onClose, compareManager }: { onClose: () => void; compareManage
                 Новая шкала
               </button>
               <button
-                onClick={() => compareManager?.setSymbolMode('Line', symbol, CompareMode.NewPane)}
+                onClick={() => compareManager?.setSymbolMode('Line', instrument, CompareMode.NewPane)}
                 style={{ backgroundColor: 'lightgray', padding: '2px 8px' }}
                 type="button"
               >