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


diff --git a/src/constants/indicator.ts b/src/constants/indicator.ts
index f5a575bcc4af1402ead95cab273b49e705470ae9..4dbfeab8ad167cd71a1d696f482757c7c67d7a87 100644
--- a/src/constants/indicator.ts
+++ b/src/constants/indicator.ts
@@ -1,4 +1,4 @@
-export enum IndicatorsIds {
+export enum IndicatorsIds { // todo: rename to IndicatorsTypes
   Volume = 'vol',
   SMA = 'sma',
   EMA = 'ema',
diff --git a/src/core/Chart.ts b/src/core/Chart.ts
index 3daa904e9d90e4b5a25de9eb231b083233abcbb0..2b1a6d1048846d508fa6d7e17b67d17a03e0ebbf 100644
--- a/src/core/Chart.ts
+++ b/src/core/Chart.ts
@@ -1,3 +1,4 @@
+import { ChartSnapshot, ISerializable, PaneSnapshot } from '@src/types/snapshot';
 import dayjs from 'dayjs';
 
 import {
@@ -24,7 +25,6 @@ import { EventManager } from '@core/EventManager';
 import { IndicatorManager } from '@core/IndicatorManager';
 import { ModalRenderer } from '@core/ModalRenderer';
 import { PaneManager } from '@core/PaneManager';
-import { IndicatorsIds } from '@src/constants';
 import { CompareManager } from '@src/core/CompareManager';
 import { SeriesStrategies } from '@src/modules/series-strategies/SeriesFactory';
 import { getThemeStore } from '@src/theme/store';
@@ -42,6 +42,7 @@ import { Defaults } from '@src/types/defaults';
 import { DayjsOffset, Intervals, intervalsToDayjs } from '@src/types/intervals';
 
 import { createTickMarkFormatter, formatDate } from '@src/utils/formatter';
+import flatten from 'lodash-es/flatten';
 
 export interface ChartConfig extends Partial<ChartOptionsModel> {
   container: HTMLElement;
@@ -59,19 +60,22 @@ export enum Resize {
 
 const HISTORY_LOAD_THRESHOLD = 50;
 
-interface ChartParams extends ChartConfig {
-  dataSource: DataSource;
-  eventManager: EventManager;
-  modalRenderer: ModalRenderer;
-  ohlcConfig: OHLCConfig;
-  tooltipConfig: TooltipConfig;
-  initialIndicators?: IndicatorsIds[];
+interface ChartParams {
+  params: {
+    dataSource: DataSource;
+    eventManager: EventManager;
+    modalRenderer: ModalRenderer;
+    ohlcConfig: OHLCConfig;
+    tooltipConfig: TooltipConfig;
+    panes: PaneSnapshot[];
+  },
+  lwcChartConfig: ChartConfig
 }
 
 /**
  * Абстракция над библиотекой для построения графиков
  */
-export class Chart {
+export class Chart implements ISerializable<ChartSnapshot>{
   private lwcChart!: IChartApi;
   private container: HTMLElement;
   private eventManager: EventManager;
@@ -97,25 +101,30 @@ export class Chart {
   private historyBatchRunning = false;
 
   constructor({
-    eventManager,
-    dataSource,
-    modalRenderer,
-    ohlcConfig,
-    tooltipConfig,
-    initialIndicators,
-    ...lwcConfig
+    params,
+    lwcChartConfig
   }: ChartParams) {
+
+    const {
+      eventManager,
+      dataSource,
+      modalRenderer,
+      ohlcConfig,
+      tooltipConfig,
+      panes: panesSnapshot,
+    } = params
+
     this.eventManager = eventManager;
     this.dataSource = dataSource;
-    this.container = lwcConfig.container;
-    this.chartConfig = lwcConfig;
+    this.container = lwcChartConfig.container;
+    this.chartConfig = lwcChartConfig;
 
-    this.lwcChart = createChart(this.container, getOptions(lwcConfig));
+    this.lwcChart = createChart(this.container, getOptions(lwcChartConfig));
 
     this.optionsSubscription = this.eventManager
       .getChartOptionsModel()
       .subscribe(({ dateFormat, timeFormat, showTime }) => {
-        const configToApply = { ...lwcConfig, dateFormat, timeFormat, showTime };
+        const configToApply = { ...lwcChartConfig, dateFormat, timeFormat, showTime };
 
         this.lwcChart.applyOptions({
           ...getOptions(configToApply),
@@ -139,6 +148,7 @@ export class Chart {
 
     this.paneManager = new PaneManager({
       eventManager: this.eventManager,
+      panesSnapshot,
       lwcChart: this.lwcChart,
       dataSource,
       DOM: this.DOM,
@@ -151,16 +161,17 @@ export class Chart {
 
     this.indicatorManager = new IndicatorManager({
       eventManager,
-      initialIndicators,
+      initialIndicators: flatten(panesSnapshot.map((pane) => pane.indicators.map((ind) => ({...ind, paneId: pane.id})) )),
       DOM: this.DOM,
       dataSource: this.dataSource,
       lwcChart: this.lwcChart,
       paneManager: this.paneManager,
-      chartOptions: lwcConfig.chartOptions,
+      chartOptions: lwcChartConfig.chartOptions,
     });
 
     this.compareManager = new CompareManager({
       chart: this.lwcChart,
+      initialIndicators: flatten(panesSnapshot.map((pane) => pane.indicators.map((ind) => ({...ind, paneId: pane.id})) )),
       eventManager: this.eventManager,
       dataSource: this.dataSource,
       indicatorManager: this.indicatorManager,
@@ -284,6 +295,15 @@ export class Chart {
     };
   }
 
+  public getSnapshot(): ChartSnapshot {
+    return {
+      panes: this.paneManager.getSnapshot(),
+      chartSeriesType: this.eventManager.exportChartSettings().seriesSelected,
+      timeframe: this.eventManager.exportChartSettings().timeframe,
+      symbol: this.activeSymbols[0]
+    }
+  }
+
   private scheduleHistoryBatch = () => {
     if (this.historyBatchRunning) return;
 
diff --git a/src/core/CompareManager.ts b/src/core/CompareManager.ts
index 1fee19eacd6f0afab165f962a58e2256c53434a4..b2ad48d4390bfe3c1b4b6764d035e1e950d574f8 100644
--- a/src/core/CompareManager.ts
+++ b/src/core/CompareManager.ts
@@ -1,3 +1,4 @@
+import { IndicatorSnapshot } from '@src/types/snapshot';
 import { IChartApi, PriceScaleMode, SeriesType } from 'lightweight-charts';
 import { BehaviorSubject, distinctUntilChanged, map, Observable } from 'rxjs';
 
@@ -31,6 +32,7 @@ interface CompareManagerParams {
   dataSource: DataSource;
   indicatorManager: IndicatorManager;
   paneManager: PaneManager;
+  initialIndicators?: IndicatorSnapshot[];
 }
 
 const getDefaultCompareIndicatorConfig = (symbol: string): IndicatorConfig => {
@@ -61,7 +63,7 @@ export class CompareManager {
   private readonly itemsSubject = new BehaviorSubject<CompareItem[]>([]);
   private readonly entitiesSubject = new BehaviorSubject<Indicator[]>([]);
 
-  constructor({ chart, eventManager, dataSource, indicatorManager, paneManager }: CompareManagerParams) {
+  constructor({ chart, eventManager, dataSource, indicatorManager, paneManager, initialIndicators = []}: CompareManagerParams) {
     this.chart = chart;
     this.eventManager = eventManager;
     this.dataSource = dataSource;
@@ -71,18 +73,31 @@ export class CompareManager {
     this.eventManager.timeframe().subscribe(() => {
       this.applyPolicy();
     });
-  }
 
-  public itemsObs(): Observable<CompareItem[]> {
-    return this.itemsSubject.asObservable();
+    if(!initialIndicators){
+      return
+    }
+
+    this.setup(initialIndicators)
   }
 
-  public entitiesObs(): Observable<Indicator[]> {
-    return this.entitiesSubject.asObservable();
+  private async setup(initialIndicators: IndicatorSnapshot[]) {
+    for(const indicator of initialIndicators){
+      if(indicator.config && indicator.config.label){ // условие проверки compare ли это
+        const serie = indicator.config.series[0]
+
+        const compareMode = serie.seriesOptions?.priceScaleId === Direction.Left
+          ? CompareMode.NewScale
+          : indicator.config.newPane ? CompareMode.NewPane : CompareMode.Percentage
+
+        // eslint-disable-next-line no-await-in-loop
+        await this.setSymbolMode(serie.name, indicator.config.label, compareMode, indicator.paneId)
+      }
+    }
   }
 
-  public snapshot(): CompareItem[] {
-    return this.itemsSubject.value;
+  public itemsObs(): Observable<CompareItem[]> {
+    return this.itemsSubject.asObservable();
   }
 
   public clear(): void {
@@ -94,7 +109,7 @@ export class CompareManager {
     this.publish();
   }
 
-  public async setSymbolMode(seriesType: SeriesType, symbolRaw: string, mode: CompareMode): Promise<void> {
+  public async setSymbolMode(seriesType: SeriesType, symbolRaw: string, mode: CompareMode, paneId?: number): Promise<void> {
     const symbol = normalizeSymbol(symbolRaw);
     if (!symbol) return;
 
@@ -110,16 +125,16 @@ export class CompareManager {
     const entity = this.indicatorManager.addEntity<Indicator>((zIndex, moveUp, moveDown) => {
       const config = getDefaultCompareIndicatorConfig(symbol);
 
+      const associatedPane = mode === CompareMode.NewPane
+        ? paneId !== undefined ? this.paneManager.getPaneById(paneId) : this.paneManager.addPane()
+        : this.paneManager.getMainPane()
+
       return new Indicator({
         id: key,
         lwcChart: this.chart,
         mainSymbol$: symbol$,
         dataSource: this.dataSource,
-        zIndex,
-        onDelete: () => this.removeByKey(key),
-        moveUp,
-        moveDown,
-        paneManager: this.paneManager,
+        associatedPane,
         config: {
           ...config,
           series: [
@@ -133,6 +148,11 @@ export class CompareManager {
           ],
           newPane: mode === CompareMode.NewPane,
         },
+        zIndex,
+        onDelete: () => this.removeByKey(key),
+        moveUp,
+        moveDown,
+        paneId: associatedPane.getId()
       });
     });
 
diff --git a/src/core/DOMObject.ts b/src/core/DOMObject.ts
index b9b66cfdd0e54464bcdf4b8c6b71820f075c00c7..53ad642ed5bcbaadbdda5f9343a8539dc05ee981 100644
--- a/src/core/DOMObject.ts
+++ b/src/core/DOMObject.ts
@@ -1,3 +1,4 @@
+import { DOMObjectSnapshot, IndicatorSnapshot, ISerializable } from '@src/types/snapshot';
 import { BehaviorSubject } from 'rxjs';
 
 enum DOMObjectType {
@@ -23,30 +24,33 @@ export interface IDOMObject {
 
 export interface DOMObjectParams {
   id: string;
-  name?: string;
+  paneId: number; // todo: implement for drawings
   zIndex: number;
   onDelete: (id: string) => void;
   moveUp: (id: string) => void;
   moveDown: (id: string) => void;
+  name?: string;
 }
 
-export class DOMObject implements IDOMObject {
+export class DOMObject implements IDOMObject, ISerializable<DOMObjectSnapshot> {
   public readonly id: string;
   public name: string;
   public zIndex: number;
   public hidden = new BehaviorSubject(false);
   public moveUp: () => void;
   public moveDown: () => void;
+  public paneId: number;
   protected onDelete: (id: string) => void;
 
   // eslint-disable-next-line @typescript-eslint/ban-ts-comment
   // @ts-ignore
   type: DOMObjectType;
 
-  constructor({ id, name, zIndex, onDelete, moveUp, moveDown }: DOMObjectParams) {
+  constructor({ id, name, zIndex, onDelete, moveUp, moveDown, paneId }: DOMObjectParams) {
     this.id = id;
     this.name = name ?? id;
     this.zIndex = zIndex;
+    this.paneId = paneId;
     this.onDelete = onDelete;
     this.moveUp = () => moveUp(this.id);
     this.moveDown = () => moveDown(this.id);
@@ -73,4 +77,14 @@ export class DOMObject implements IDOMObject {
   shouldShowInObjectTree(): boolean {
     return true;
   }
+
+  public getSnapshot(): DOMObjectSnapshot {
+    return {
+      id: this.id,
+      name: this.name,
+      zIndex: this.zIndex,
+      hidden: this.hidden.value,
+      paneId: this.paneId
+    }
+  }
 }
diff --git a/src/core/Indicator.ts b/src/core/Indicator.ts
index 58106e4b78ba09e9c19a7f195ec7c077ea1c9624..0fa9351614f3da4f2244ef73293c1380e8b4ec98 100644
--- a/src/core/Indicator.ts
+++ b/src/core/Indicator.ts
@@ -1,3 +1,4 @@
+import { DOMObjectSnapshot, IndicatorSnapshot, ISerializable } from '@src/types/snapshot';
 import { IChartApi } from 'lightweight-charts';
 import { Observable, Subscription } from 'rxjs';
 
@@ -15,16 +16,16 @@ import { ensureDefined } from '@src/utils';
 type IIndicator = DOMObject;
 
 export interface IndicatorParams extends DOMObjectParams {
-  type?: IndicatorsIds;
   mainSymbol$: Observable<string>;
   lwcChart: IChartApi;
   dataSource: DataSource;
-  paneManager: PaneManager;
+  associatedPane: Pane;
+  config: IndicatorConfig;
+  type?: IndicatorsIds;
   chartOptions?: ChartTypeOptions;
-  config?: IndicatorConfig;
 }
 
-export class Indicator extends DOMObject implements IIndicator {
+export class Indicator extends DOMObject implements ISerializable<IndicatorSnapshot> {
   private indicatorType?: IndicatorsIds;
   private series: SeriesStrategies[] = [];
   private seriesMap: Map<string, SeriesStrategies> = new Map();
@@ -48,20 +49,21 @@ export class Indicator extends DOMObject implements IIndicator {
     moveUp,
     moveDown,
     mainSymbol$,
-    paneManager,
+    associatedPane,
+    paneId,
     config,
   }: IndicatorParams) {
-    super({ id, name: config?.label ?? id, zIndex, onDelete, moveUp, moveDown });
+    super({ id, name: config?.label ?? id, zIndex, onDelete, moveUp, moveDown, paneId });
     this.lwcChart = lwcChart;
     this.dataSource = dataSource;
     this.mainSymbol$ = mainSymbol$;
     this.indicatorType = type;
-    this.config = ensureDefined(type ? indicatorsMap[type] : config);
+    this.config = config;
     this.name = this.getLabel();
 
     this.settings = this.getDefaultSettings();
 
-    this.associatedPane = this.config.newPane ? paneManager.addPane() : paneManager.getMainPane();
+    this.associatedPane = associatedPane;
 
     this.createSeries();
 
@@ -76,7 +78,7 @@ export class Indicator extends DOMObject implements IIndicator {
     });
   }
 
-  public getLabel(): string {
+  public getLabel = () => {
     if (this.config.label) {
       return this.config.label;
     }
@@ -152,6 +154,21 @@ export class Indicator extends DOMObject implements IIndicator {
     super.hide();
   }
 
+  public override getSnapshot(): DOMObjectSnapshot & IndicatorSnapshot {
+    const domSnap = super.getSnapshot()
+
+    return {
+      ...domSnap,
+      dataSource: this.dataSource,
+      indicatorType: this.indicatorType,
+      config: this.config,
+    }
+  }
+
+  public setSnapshot(snap: IndicatorSnapshot): void {
+
+  }
+
   // destroy и delete принципиально отличаются!
   // delete вызовет destroy в конце концов. По сути - это destroy с сайд-эффектом в eventManager
   public delete() {
diff --git a/src/core/IndicatorManager.ts b/src/core/IndicatorManager.ts
index b4b1fd0b9a8b10e9e9f248c7a5c8c231e83d6bce..4f6a52733f059a14041efd37b78951be7ed3cb65 100644
--- a/src/core/IndicatorManager.ts
+++ b/src/core/IndicatorManager.ts
@@ -1,14 +1,15 @@
+import { IndicatorSnapshot } from '@src/types/snapshot';
 import { IChartApi } from 'lightweight-charts';
 import { BehaviorSubject, map, Observable } from 'rxjs';
+import { indicatorsMap as indicatorsConfigMap } from '@src/core/Indicators';
 
 import { DataSource } from '@core/DataSource';
 import { DOMModel } from '@core/DOMModel';
 import { EventManager } from '@core/EventManager';
 import { Indicator } from '@core/Indicator';
 import { PaneManager } from '@core/PaneManager';
-import { IndicatorsIds } from '@src/constants';
 import { DOMObject } from '@src/core/DOMObject';
-import { ChartTypeOptions } from '@src/types';
+import { ChartTypeOptions, IndicatorConfig } from '@src/types';
 
 interface SeriesParams {
   eventManager: EventManager;
@@ -16,7 +17,7 @@ interface SeriesParams {
   lwcChart: IChartApi;
   paneManager: PaneManager;
   DOM: DOMModel;
-  initialIndicators?: IndicatorsIds[];
+  initialIndicators?: IndicatorSnapshot[];
   chartOptions?: ChartTypeOptions;
 }
 
@@ -52,25 +53,38 @@ export class IndicatorManager {
     return this.DOM.setEntity(factory);
   }
 
-  public addIndicator(indicatorType: IndicatorsIds): void {
+  public addIndicator(snap: Partial<IndicatorSnapshot>): void {
+    if(!snap.indicatorType) {
+      console.error('[IndicatorManager] Не был получен тип индиктора');
+      return
+    }
     const indicatorsMap = new Map(this.indicatorsMap$.value);
 
-    const id = `${indicatorType}-${crypto.randomUUID()}`;
+    const id = snap.id ?? `${snap.indicatorType}-${crypto.randomUUID()}`;
+
+    const config = indicatorsConfigMap[snap.indicatorType] as IndicatorConfig;
+
+    const associatedPane = snap.paneId !== undefined
+      ? this.paneManager.getPaneById(snap.paneId)
+      : config?.newPane ? this.paneManager.addPane() : this.paneManager.getMainPane();
 
     const indicatorToSet = this.addEntity<Indicator>(
       (zIndex: number, moveUp: (id: string) => void, moveDown: (id: string) => void) =>
         new Indicator({
           id,
-          type: indicatorType,
-          lwcChart: this.lwcChart,
-          mainSymbol$: this.eventManager.getSymbol(),
-          dataSource: this.dataSource,
-          chartOptions: this.chartOptions,
+          paneId: associatedPane.getId(),
           zIndex,
           onDelete: this.deleteIndicator,
           moveUp,
           moveDown,
-          paneManager: this.paneManager,
+
+          mainSymbol$: this.eventManager.getSymbol(),
+          lwcChart: this.lwcChart,
+          dataSource: this.dataSource,
+          associatedPane,
+          config,
+          type: snap.indicatorType,
+          chartOptions: this.chartOptions,
         }),
     );
 
diff --git a/src/core/MoexChart.tsx b/src/core/MoexChart.tsx
index d11fc031a25ed0791f590eb685d73d063f5eeffe..b56c338fb25f6122b3f63489b4f281051c79e7dc 100644
--- a/src/core/MoexChart.tsx
+++ b/src/core/MoexChart.tsx
@@ -1,3 +1,5 @@
+import { Pane } from '@core/Pane';
+import { InitialSnapshot, ISerializable, MoexChartSnapshot } from '@src/types/snapshot';
 import { combineLatest, Subscription } from 'rxjs';
 
 import { ControlBar } from '@components/ControlBar';
@@ -33,24 +35,7 @@ import 'exchange-elements/dist/style.css';
 import 'exchange-elements/dist/tokens/moex.css';
 
 // todo: forbid @lib in /src
-export interface IMoexChart {
-  container: HTMLElement;
-  supportedTimeframes: Timeframes[];
-  initialTimeframe: Timeframes;
-  supportedChartSeriesTypes: ChartSeriesType[];
-  initialChartSeriesTypes: ChartSeriesType;
-  initialSymbol: string;
-  getDataSource: DataSourceParams['getData'];
-  theme: ThemeKey; // 'mb' | 'mxt' | 'tr'
-  ohlc: OHLCConfig;
-  initialIndicators?: IndicatorsIds[];
-  size?:
-    | {
-        width: number;
-        height: number;
-      }
-    | false;
-  mode?: ThemeMode; // 'light' | 'dark'
+export interface ChartCollectionPreset {
   undoRedoEnabled?: boolean;
   showMenuButton?: boolean;
   showBottomPanel?: boolean;
@@ -77,13 +62,32 @@ export interface IMoexChart {
    *    }
    *```
    */
-  chartSettings?: ChartSettingsSource;
-  chartOptions?: ChartTypeOptions; // todo: разнести по разным полям в соответствии с тиами графика
-  tooltipConfig?: TooltipConfig;
+  tooltipConfig?: TooltipConfig; // todo: wrap into ChartCollectionSettings
+
+  size?:
+    | {
+    width: number;
+    height: number;
+  }
+    | false;
+  supportedTimeframes: Timeframes[];
+  supportedChartSeriesTypes: ChartSeriesType[];
+  getDataSource: DataSourceParams['getData'];
+  theme: ThemeKey; // 'mb' | 'mxt' | 'tr'
+  ohlc: OHLCConfig;
+  mode?: ThemeMode; // 'light' | 'dark'
   openCompareModal?: () => void;
 }
 
-export class MoexChart {
+export interface IMoexChart {
+  snapshot: MoexChartSnapshot;  // todo: combine with snapshot
+  chartCollectionPreset: ChartCollectionPreset;
+
+  container: HTMLElement;
+  lwcInheritedChartOptions?: ChartTypeOptions;
+}
+
+export class MoexChart implements ISerializable<MoexChartSnapshot> {
   private chart: Chart;
   private resizeObserver?: ResizeObserver;
   private eventManager: EventManager;
@@ -102,22 +106,30 @@ export class MoexChart {
 
   private fullscreen: FullscreenController;
 
+  private chartCollectionPresetSettings: ChartCollectionPreset;
+
   constructor(config: IMoexChart) {
-    setPricePrecision(config.ohlc.precision);
+    this.setup(config)
+  }
+
+  private setup = (config: IMoexChart) => {
+    this.chartCollectionPresetSettings = config.chartCollectionPreset
+    setPricePrecision(config.chartCollectionPreset.ohlc.precision);
 
     this.eventManager = new EventManager({
-      initialTimeframe: config.initialTimeframe,
-      initialSeries: config.initialChartSeriesTypes,
-      initialSymbol: config.initialSymbol,
-      initialChartOptions: config.chartOptions,
+      initialTimeframe: config.snapshot.charts[0].timeframe,
+      initialSeries: config.snapshot.charts[0].chartSeriesType,
+      initialSymbol: config.snapshot.charts[0].symbol,
+      initialChartOptions: config.lwcInheritedChartOptions,
     });
 
-    if (config.chartSettings) {
-      this.setSettings(config.chartSettings);
-    }
+    // todo: сюда прокидывается не подходящий под сигнатуру интерфейс. Функция не работает
+    // if (config.lwcInheritedChartOptions) {
+    //   this.setSettings(config.lwcInheritedChartOptions);
+    // }
 
     this.dataSource = new DataSource({
-      getData: config.getDataSource,
+      getData: config.chartCollectionPreset.getDataSource,
       eventManager: this.eventManager,
     });
 
@@ -125,7 +137,7 @@ export class MoexChart {
 
     this.fullscreen = new FullscreenController(this.rootContainer);
 
-    const store = configureThemeStore(config);
+    const store = configureThemeStore(config.chartCollectionPreset);
 
     const {
       chartAreaContainer,
@@ -134,27 +146,31 @@ export class MoexChart {
       modalContainer,
       controlBarContainer,
       footerContainer,
-      toggleToolbar, // todo: move this function to toolbarRenderer
+      toggleToolbar, // todo: move this function to toolbarModel
     } = ContainerManager.createContainers({
       parentContainer: this.rootContainer,
-      showBottomPanel: config.showBottomPanel, // todo: apply config.showBottomPanel in FullscreenController
-      showMenuButton: config.showMenuButton,
+      showBottomPanel: config.chartCollectionPreset.showBottomPanel, // todo: apply config.showBottomPanel in FullscreenController
+      showMenuButton: config.chartCollectionPreset.showMenuButton,
     });
 
     this.modalRenderer = new ModalRenderer(modalContainer);
 
     this.chart = new Chart({
-      eventManager: this.eventManager,
-      modalRenderer: this.modalRenderer,
-      container: chartAreaContainer,
-      theme: store.theme,
-      mode: store.mode,
-      seriesTypes: config.supportedChartSeriesTypes,
-      dataSource: this.dataSource,
-      chartOptions: config.chartOptions, // todo: remove, use only model from eventManager
-      ohlcConfig: config.ohlc, // todo: omptimize
-      tooltipConfig: config.tooltipConfig ?? {},
-      initialIndicators: config.initialIndicators,
+      params: {
+        dataSource: this.dataSource,
+        eventManager: this.eventManager,
+        modalRenderer: this.modalRenderer,
+        ohlcConfig: config.chartCollectionPreset.ohlc, // todo: omptimize
+        tooltipConfig: config.chartCollectionPreset.tooltipConfig ?? {},
+        panes: config.snapshot.charts[0].panes
+      },
+      lwcChartConfig:{
+        container: chartAreaContainer,
+        seriesTypes: config.chartCollectionPreset.supportedChartSeriesTypes,
+        theme: store.theme,
+        mode: store.mode,
+        chartOptions: config.lwcInheritedChartOptions, // todo: remove, use only model from eventManager
+      }
     });
 
     this.subscriptions.add(
@@ -169,61 +185,110 @@ export class MoexChart {
     this.headerRenderer = new ReactRenderer(headerContainer);
     this.toolbarRenderer = new ReactRenderer(toolBarContainer);
 
-    if (config.showControlBar) {
+    if (config.chartCollectionPreset.showControlBar) {
       this.controlBarRenderer = new ReactRenderer(controlBarContainer);
     }
 
-    if (config.showBottomPanel) {
+    if (config.chartCollectionPreset.showBottomPanel) {
       this.footerRenderer = new ReactRenderer(footerContainer);
     }
 
+    this.timeScaleHoverController = new TimeScaleHoverController({
+      eventManager: this.eventManager,
+      controlBarContainer,
+      chartContainer: chartAreaContainer,
+    });
+
+    this.renderAttachments(config, toggleToolbar)
+  }
+
+  public setSettings(settings: ChartSettingsSource): void {
+    this.eventManager.importChartSettings(settings);
+  }
+
+  public getSettings(): ChartSettings {
+    return this.eventManager.exportChartSettings();
+  }
+
+  public getRealtimeApi() {
+    return this.chart.getRealtimeApi();
+  }
+
+  // todo: описать в доке
+  public getCompareManager(): CompareManager {
+    return this.chart.getCompareManager();
+  }
+
+  // todo: описать в доке
+  public setSnapshot(snap: MoexChartSnapshot) {
+    const configConstructorLike: IMoexChart = {
+      snapshot: snap,
+      chartCollectionPreset: this.chartCollectionPresetSettings,
+      container: this.rootContainer,
+    }
+    this.destroy()
+
+    this.setup(configConstructorLike)
+  }
+
+  // todo: описать в доке
+  public getSnapshot(): MoexChartSnapshot {
+    const res = {
+      settings: this.getSettings(),
+      charts: [this.chart.getSnapshot()], // todo: в будущем может быть несколько инстансов чартов
+    }
+
+    return res
+  }
+
+  public setSymbol(symbol: string): void {
+    if (!symbol) return;
+
+    this.eventManager.setSymbol(symbol);
+  }
+
+  private renderAttachments(config: IMoexChart, toggleToolbar: () => boolean) {
     this.headerRenderer.renderComponent(
       <Header
-        timeframes={config.supportedTimeframes}
+        timeframes={config.chartCollectionPreset.supportedTimeframes}
         selectedTimeframeObs={this.eventManager.getTimeframeObs()}
         setTimeframe={(value) => {
           this.eventManager.setTimeframe(value);
         }}
-        seriesTypes={config.supportedChartSeriesTypes}
+        seriesTypes={config.chartCollectionPreset.supportedChartSeriesTypes}
         selectedSeriesObs={this.eventManager.getSelectedSeries()}
         setSelectedSeries={(value) => {
           this.eventManager.setSeriesSelected(value);
         }}
         showSettingsModal={
-          config.showSettingsButton
+          config.chartCollectionPreset.showSettingsButton
             ? () =>
-                this.modalRenderer.renderComponent(
-                  <SettingsModal
-                    // todo: deal with onSave
-                    changeTimeFormat={(format) => this.eventManager.setTimeFormat(format)}
-                    changeDateFormat={(format) => this.eventManager.setDateFormat(format)}
-                    chartDateTimeFormatObs={this.eventManager.getChartOptionsModel()}
-                  />,
-                  { title: 'Настройки' },
-                )
+              this.modalRenderer.renderComponent(
+                <SettingsModal
+                  // todo: deal with onSave
+                  changeTimeFormat={(format) => this.eventManager.setTimeFormat(format)}
+                  changeDateFormat={(format) => this.eventManager.setDateFormat(format)}
+                  chartDateTimeFormatObs={this.eventManager.getChartOptionsModel()}
+                />,
+                { title: 'Настройки' },
+              )
             : undefined
         }
-        addIndicatorToChart={(indicatorsType: IndicatorsIds) =>
-          this.chart.getIndicatorManager().addIndicator(indicatorsType)
+        addIndicatorToChart={(indicatorType: IndicatorsIds) =>
+          this.chart.getIndicatorManager().addIndicator({ indicatorType })
         }
-        showMenuButton={config.showMenuButton}
-        showFullscreenButton={config.showFullscreenButton}
+        showMenuButton={!!config.chartCollectionPreset.showMenuButton}
+        showFullscreenButton={!!config.chartCollectionPreset.showFullscreenButton}
         fullscreen={this.fullscreen}
-        undoRedo={config.undoRedoEnabled ? this.eventManager.getUndoRedo() : undefined}
+        undoRedo={config.chartCollectionPreset.undoRedoEnabled ? this.eventManager.getUndoRedo() : undefined}
         toggleToolbarVisible={toggleToolbar}
-        showCompareButton={!!config.showCompareButton}
-        openCompareModal={config.openCompareModal ? config.openCompareModal : undefined}
-        isMXT={config.theme === 'mxt'}
+        showCompareButton={!!config.chartCollectionPreset.showCompareButton}
+        openCompareModal={config.chartCollectionPreset.openCompareModal ? config.chartCollectionPreset.openCompareModal : undefined}
+        isMXT={config.chartCollectionPreset.theme === 'mxt'}
       />,
     );
 
-    this.timeScaleHoverController = new TimeScaleHoverController({
-      eventManager: this.eventManager,
-      controlBarContainer,
-      chartContainer: chartAreaContainer,
-    });
-
-    if (config.showMenuButton) {
+    if (this.toolbarRenderer && config.chartCollectionPreset.showMenuButton) {
       this.toolbarRenderer.renderComponent(
         <Toolbar
           toggleDOM={this.chart.getDom().toggleDOM}
@@ -239,7 +304,7 @@ export class MoexChart {
       );
     }
 
-    if (this.controlBarRenderer && config.showControlBar) {
+    if (this.controlBarRenderer && config.chartCollectionPreset.showControlBar) {
       this.controlBarRenderer.renderComponent(
         <ControlBar
           scroll={this.chart.scrollTimeScale}
@@ -250,10 +315,10 @@ export class MoexChart {
       );
     }
 
-    if (this.footerRenderer && config.showBottomPanel) {
+    if (this.footerRenderer && config.chartCollectionPreset.showBottomPanel) {
       this.footerRenderer.renderComponent(
         <Footer
-          supportedTimeframes={config.supportedTimeframes}
+          supportedTimeframes={config.chartCollectionPreset.supportedTimeframes}
           setInterval={this.eventManager.setInterval}
           intervalObs={this.eventManager.getInterval()}
         />,
@@ -261,29 +326,6 @@ export class MoexChart {
     }
   }
 
-  public setSettings(settings: ChartSettingsSource): void {
-    this.eventManager.importChartSettings(settings);
-  }
-
-  public getSettings(): ChartSettings {
-    return this.eventManager.exportChartSettings();
-  }
-
-  public getRealtimeApi() {
-    return this.chart.getRealtimeApi();
-  }
-
-  // todo: описать в доке
-  public getCompareManager(): CompareManager {
-    return this.chart.getCompareManager();
-  }
-
-  public setSymbol(symbol: string): void {
-    if (!symbol) return;
-
-    this.eventManager.setSymbol(symbol);
-  }
-
   /**
    * Уничтожение графика и очистка ресурсов
    * @returns void
diff --git a/src/core/Pane.tsx b/src/core/Pane.tsx
index 75a0fb608b816edcfaa0f7f36436cf37519716ea..3eb3a91aff04accb3b7d08b54a580527b643ca42 100644
--- a/src/core/Pane.tsx
+++ b/src/core/Pane.tsx
@@ -1,3 +1,4 @@
+import { ISerializable, PaneSnapshot } from '@src/types/snapshot';
 import { IChartApi, IPaneApi, Time } from 'lightweight-charts';
 
 import { BehaviorSubject, Subscription } from 'rxjs';
@@ -44,7 +45,7 @@ export interface PaneParams {
 // todo: на каждый символ свой DataSource (учитывать что есть MainPane и "главный" DataSource, который инициализиурется во время старта moexChart)
 // todo: сделать два разных представления для compare, в зависимости от отображения на главном пейне или на второстепенном
 
-export class Pane {
+export class Pane implements ISerializable<PaneSnapshot>{
   private readonly id: number;
   private isMain: boolean;
   private mainSeries: BehaviorSubject<SeriesStrategies | null> = new BehaviorSubject<SeriesStrategies | null>(null); // Main Series. Exists in a single copy
@@ -141,7 +142,6 @@ export class Pane {
     });
 
     this.subscriptions.add(
-      // todo: переедет в пейн
       this.drawingsManager.entities().subscribe((drawings) => {
         const hasRuler = drawings.some((drawing) => drawing.getDrawingName() === DrawingsNames.ruler);
         this.legendContainer.style.display = hasRuler ? 'none' : '';
@@ -294,6 +294,23 @@ export class Pane {
     });
   }
 
+  public getSnapshot(): PaneSnapshot {
+    const indicators = []
+
+    this.indicatorsMap.value.forEach((ind) => {
+      indicators.push(ind.getSnapshot())
+    })
+
+    const snap = {
+      isMain: this.isMain,
+      id: this.id,
+      indicators,
+      drawings: this.getDrawingsSnapshot()
+    }
+
+    return snap
+  }
+
   public destroy() {
     this.subscriptions.unsubscribe();
     this.tooltip?.destroy();
@@ -303,6 +320,8 @@ export class Pane {
     this.tooltipRenderer?.destroy();
     this.indicatorsMap.complete();
 
+    this.mainSeries.value?.destroy();
+    this.mainSeries?.complete();
     this.mainSerieSub?.unsubscribe();
     try {
       this.lwcChart.removePane(this.id);
diff --git a/src/core/PaneManager.ts b/src/core/PaneManager.ts
index 5bbbc00d5717f42aabeb9535b7a7fb46c633407b..d97d6b60b0b96e25da5b9122936df918a6187912 100644
--- a/src/core/PaneManager.ts
+++ b/src/core/PaneManager.ts
@@ -1,8 +1,11 @@
 import { DataSource } from '@core/DataSource';
 import { DrawingsManager, DrawingsManagerSnapshot } from '@core/DrawingsManager';
 import { Pane, PaneParams } from '@core/Pane';
+import { ISerializable, PaneSnapshot } from '@src/types/snapshot';
 
-type PaneManagerParams = Omit<PaneParams, 'isMainPane' | 'id' | 'basedOn' | 'onDelete'>;
+interface PaneManagerParams extends Omit<PaneParams, 'isMainPane' | 'id' | 'basedOn' | 'onDelete'> {
+  panesSnapshot: PaneSnapshot[]
+};
 
 // todo: PaneManager, регулирует порядок пейнов. Знает про MainPane.
 // todo: Также перекинуть соответствующие/необходимые свойства из чарта, и из чарта удалить
@@ -10,7 +13,8 @@ type PaneManagerParams = Omit<PaneParams, 'isMainPane' | 'id' | 'basedOn' | 'onD
 // todo: на каждый символ свой DataSource (учитывать что есть MainPane и "главный" DataSource, который инициализиурется во время старта moexChart)
 // todo: сделать два разных представления для compare, в зависимости от отображения на главном пейне или на второстепенном
 
-export class PaneManager {
+
+export class PaneManager implements ISerializable<PanesSnapshot> {
   private mainPane: Pane;
   private paneChartInheritedParams: PaneManagerParams & { isMainPane: boolean };
   private panesMap: Map<number, Pane> = new Map<number, Pane>();
@@ -22,6 +26,39 @@ export class PaneManager {
     this.mainPane = new Pane({ ...params, isMainPane: true, id: 0, onDelete: () => {} });
 
     this.panesMap.set(this.panesIdIterator++, this.mainPane);
+    this.setup(params.panesSnapshot)
+
+  }
+
+  private setup(panesSnapshot: PaneSnapshot[]) {
+    panesSnapshot.forEach((paneSnap: PaneSnapshot) => {
+      const {
+        isMain,
+        id,
+        indicators,
+        drawings
+      } = paneSnap
+
+
+      if(this.panesMap.has(id)){
+        this.panesMap.get(id).destroy()
+      }
+
+      if(isMain){
+        this.mainPane = new Pane({ ...this.paneChartInheritedParams, isMainPane: true, id: 0, onDelete: () => {} });
+
+        this.panesMap.set(id, this.mainPane);
+
+        this.mainPane.setDrawingsSnapshot(drawings)
+      } else {
+        const pane = this.addPane()
+        pane.setDrawingsSnapshot(drawings)
+      }
+    })
+  }
+
+  public getPaneById(id: number): Pane {
+    return this.panesMap.get(id);
   }
 
   public getDrawingsSnapshot(): DrawingsManagerSnapshot {
@@ -63,4 +100,13 @@ export class PaneManager {
     // todo: temp
     return this.mainPane.getDrawingManager();
   }
+
+  public getSnapshot(): PaneSnapshot[] {
+    const res: PaneSnapshot[] = []
+    this.panesMap.forEach((pane) => {
+      res.push(pane.getSnapshot())
+    })
+
+    return res
+  }
 }
diff --git a/src/types/snapshot.ts b/src/types/snapshot.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1a18c1be36a0fcb15f3ebf240d9a83f00454d6b4
--- /dev/null
+++ b/src/types/snapshot.ts
@@ -0,0 +1,50 @@
+import { ChartSettings as ChartSettingsSnapshot, ChartSettingsSource } from '@core/ChartSettings';
+import { DataSource } from '@core/DataSource';
+import { DrawingsManagerSnapshot } from '@core/DrawingsManager';
+import { ChartSeriesType, IndicatorsIds, Timeframes } from '@lib';
+import { IndicatorConfig } from '@src/types/indicator';
+
+export interface ISerializable<T extends object> {
+  getSnapshot: () => T;
+}
+
+export type InitialSnapshot = {
+  timeframe: Timeframes; // todo: move to snap
+  chartSeriesType: ChartSeriesType; // todo: move to snap
+  symbol: string; // todo: move to snap
+}
+
+export type MoexChartSnapshot = {
+  // settings: ChartSettingsSnapshot;
+  charts: ChartSnapshot[];
+}
+
+export type ChartSnapshot = {
+  timeframe: Timeframes;
+  chartSeriesType: ChartSeriesType;
+  symbol: string;
+  panes: PaneSnapshot[];
+}
+
+export type PaneSnapshot = {
+  isMain: boolean,
+  id: number,
+  indicators: IndicatorSnapshot[]
+  drawings: DrawingsManagerSnapshot
+}
+
+export type IndicatorSnapshot = Partial<DOMObjectSnapshot> & {
+  dataSource?: DataSource,
+  indicatorType: IndicatorsIds | undefined, // if indicatorType is undefined, then its compareIndicator
+  config?: IndicatorConfig,
+}
+
+// todo: move DrawingsManagerSnapshot here
+
+export type DOMObjectSnapshot = {
+  id: string;
+  name: string;
+  zIndex: number;
+  hidden: boolean;
+  paneId: number;
+}
\ No newline at end of file
diff --git a/stories/MB/MB.stories.tsx b/stories/MB/MB.stories.tsx
index 54add23fc11a3d2db82dc9c7e28d0fb07e6d27f1..b2ce1a017c63c11e076794e0a50c494519eb4fc1 100644
--- a/stories/MB/MB.stories.tsx
+++ b/stories/MB/MB.stories.tsx
@@ -23,6 +23,7 @@ import 'moex-chart/dist/styles.css';
 
 type MBProps = Omit<IMoexChart, 'container'>;
 
+// todo: переписат ьпод новую сигнатуру
 const MBEntry = (props: MBProps) => {
   const [isCompareOpen, setIsCompareOpen] = useState(false);
   const [moexChart, setMoexChart] = useState<MoexChart | undefined>(undefined);
@@ -91,53 +92,72 @@ export default meta;
 type Story = StoryObj<typeof meta>;
 
 const args: MBProps = {
-  supportedTimeframes: [
-    Timeframes['1s'],
-    Timeframes['5s'],
-    Timeframes['10s'],
-    Timeframes['1m'],
-    Timeframes['2m'],
-    Timeframes['30m'],
-    Timeframes['1h'],
-    Timeframes['2h'],
-    Timeframes['1d'],
-    Timeframes['1w'],
-  ],
-  initialTimeframe: Timeframes['10s'],
-  supportedChartSeriesTypes: ['Candlestick', 'Line', 'Bar'],
-  initialChartSeriesTypes: 'Candlestick',
-  initialSymbol: 'APPL',
-  initialIndicators: [IndicatorsIds.Volume],
-  getDataSource: dataSourceProvider.generateCandles.bind(dataSourceProvider),
-  theme: 'mb',
-  ohlc: {
-    show: true,
-    precision: 4,
+  snapshot:{
+    charts: [{
+      timeframe: Timeframes['10s'],
+      chartSeriesType: 'Candlestick',
+      symbol: 'APPL',
+      panes: [
+        { // empty panes deletes automatically
+          isMain: true, // Be careful. There is only one main pane can be present
+          id: 0,
+          indicators: [
+            {
+              indicatorType: IndicatorsIds.Volume,
+            },
+          ],
+          drawings: []
+        }
+      ],
+    }],
   },
-  mode: 'dark',
-  chartOptions: {
+  chartCollectionPreset: {
+    undoRedoEnabled: true,
+    showMenuButton: true,
+    showBottomPanel: true,
+    showControlBar: true,
+    showFullscreenButton: true,
+    showSettingsButton: true,
+    showCompareButton: false,
+    tooltipConfig: {
+      showTooltip: false,
+      time: { visible: true, label: 'Время' },
+      close: { visible: true, label: 'Закр.' },
+      change: { visible: true, label: 'Изм.' },
+      volume: { visible: true, label: 'Объем' },
+      open: { visible: true, label: 'Откр.' },
+      high: { visible: true, label: 'Макс.' },
+      low: { visible: true, label: 'Мин.' },
+    },
+
+    supportedTimeframes: [
+      Timeframes['1s'],
+      Timeframes['5s'],
+      Timeframes['10s'],
+      Timeframes['1m'],
+      Timeframes['2m'],
+      Timeframes['30m'],
+      Timeframes['1h'],
+      Timeframes['2h'],
+      Timeframes['1d'],
+      Timeframes['1w'],
+    ],
+    supportedChartSeriesTypes: ['Candlestick', 'Line', 'Bar'],
+    getDataSource: dataSourceProvider.generateCandles.bind(dataSourceProvider),
+    theme: 'mb',
+    ohlc: {
+      show: true,
+      precision: 4,
+    },
+    mode: 'dark',
+  },
+
+  lwcInheritedChartOptions: {
     timeVisible: true,
     secondsVisible: false,
     timeFormat: '24h',
     dateFormat: DateFormat.DD_MM_YYYY_HH_mm_ss,
   },
-  showMenuButton: true,
-  showBottomPanel: true,
-  showFullscreenButton: true,
-  showCompareButton: false,
-  showSettingsButton: true,
-  showControlBar: true,
-  tooltipConfig: {
-    showTooltip: false,
-    time: { visible: true, label: 'Время' },
-    close: { visible: true, label: 'Закр.' },
-    change: { visible: true, label: 'Изм.' },
-    volume: { visible: true, label: 'Объем' },
-    open: { visible: true, label: 'Откр.' },
-    high: { visible: true, label: 'Макс.' },
-    low: { visible: true, label: 'Мин.' },
-  },
-  undoRedoEnabled: true,
 };
 
 export const MB: Story = {
diff --git a/stories/MXT/MXT.stories.tsx b/stories/MXT/MXT.stories.tsx
index 97708742b37df00786bd5d01eee704895af3892a..2a905d06db023345725bdbbbbcbcab9c46fe2b4b 100644
--- a/stories/MXT/MXT.stories.tsx
+++ b/stories/MXT/MXT.stories.tsx
@@ -18,7 +18,7 @@ import 'moex-chart/dist/styles.css';
  */
 
 export type MXTProps = Omit<IMoexChart, 'container'>;
-
+// todo: переписат ьпод новую сигнатуру
 const MXTEntry = (props: MXTProps) => {
   const containerRef = useRef<HTMLDivElement | null>(null);
 
@@ -71,49 +71,70 @@ export default meta;
 
 type Story = StoryObj<typeof meta>;
 const args: MXTProps = {
-  supportedTimeframes: [
-    Timeframes['1m'],
-    Timeframes['10m'],
-    Timeframes['1h'],
-    Timeframes['1d'],
-    Timeframes['1w'],
-    Timeframes['1М'],
-    Timeframes['3М'],
-  ],
-  initialTimeframe: Timeframes['1m'],
-  supportedChartSeriesTypes: ['Candlestick', 'Line', 'Bar'],
-  initialChartSeriesTypes: 'Candlestick',
-  initialSymbol: 'APPL',
-  initialIndicators: [IndicatorsIds.Volume],
-  getDataSource: dataSourceProvider.generateCandles.bind(dataSourceProvider),
-  theme: 'mxt',
-  ohlc: {
-    show: false,
-    precision: 6,
+  snapshot:{
+    charts: [{
+      timeframe: Timeframes['1m'],
+      chartSeriesType: 'Candlestick',
+      symbol: 'APPL',
+      panes: [
+        { // empty panes deletes automatically
+          isMain: true, // Be careful. There is only one main pane can be present
+          id: 0,
+          indicators: [
+            {
+              indicatorType: IndicatorsIds.Volume,
+            },
+          ],
+          drawings: []
+        }
+      ],
+    }],
   },
-  mode: 'light',
-  chartOptions: {
+  chartCollectionPreset: {
+    undoRedoEnabled: false,
+    showMenuButton: false,
+    showBottomPanel: false,
+    showControlBar: false,
+    showFullscreenButton: false,
+    showSettingsButton: false,
+    showCompareButton: false,
+
+    tooltipConfig: {
+      showTooltip: true,
+      time: { visible: true, label: 'Время' },
+      close: { visible: true, label: 'Закр.' },
+      change: { visible: true, label: 'Изм.' },
+      volume: { visible: true, label: 'Объем' },
+      open: { visible: true, label: 'Откр.' },
+      high: { visible: true, label: 'Макс.' },
+      low: { visible: true, label: 'Мин.' },
+    },
+
+    supportedTimeframes: [
+      Timeframes['1m'],
+      Timeframes['10m'],
+      Timeframes['1h'],
+      Timeframes['1d'],
+      Timeframes['1w'],
+      Timeframes['1М'],
+      Timeframes['3М'],
+    ],
+    supportedChartSeriesTypes: ['Candlestick', 'Line', 'Bar'],
+    getDataSource: dataSourceProvider.generateCandles.bind(dataSourceProvider),
+    theme: 'mxt',
+    ohlc: {
+      show: false,
+      precision: 6,
+    },
+    mode: 'light',
+  },
+
+  lwcInheritedChartOptions: {
     timeVisible: true,
     secondsVisible: false,
     timeFormat: '24h',
     dateFormat: DateFormat.DD_MM_YYYY_HH_mm_ss,
   },
-  showMenuButton: false,
-  showBottomPanel: false,
-  showFullscreenButton: false,
-  showCompareButton: false,
-  showSettingsButton: false,
-  showControlBar: false,
-  tooltipConfig: {
-    showTooltip: true,
-    time: { visible: true, label: 'Время' },
-    close: { visible: true, label: 'Закр.' },
-    change: { visible: true, label: 'Изм.' },
-    volume: { visible: true, label: 'Объем' },
-    open: { visible: true, label: 'Откр.' },
-    high: { visible: true, label: 'Макс.' },
-    low: { visible: true, label: 'Мин.' },
-  },
 };
 
 export const MXT: Story = {
diff --git a/stories/TradeRadar/TradeRadar.stories.tsx b/stories/TradeRadar/TradeRadar.stories.tsx
index 10e2e9a4787dedec575df335bd6ce3e436bd49bb..c4b07ce9d7d20a199e0b8c5e8a32a7bcf34bfe58 100644
--- a/stories/TradeRadar/TradeRadar.stories.tsx
+++ b/stories/TradeRadar/TradeRadar.stories.tsx
@@ -1,11 +1,13 @@
+import { DataSource } from '@core/DataSource';
+import { DrawingsSnapshot, IndicatorSnapshot } from '@src/types/snapshot';
 import { useEffect, useRef, useState } from 'react';
 
 import { createPortal } from 'react-dom';
 
 import { CompareManager } from '@core/CompareManager';
-import { DateFormat, IMoexChart, MoexChart, Timeframes } from '@lib';
+import { ChartSeriesType, DateFormat, IMoexChart, Intervals, MoexChart, Timeframes } from '@lib';
 import { IndicatorsIds } from '@lib/constants';
-import { CompareMode } from '@lib/types';
+import { CompareMode, IndicatorConfig, TimeFormat } from '@lib/types';
 
 import { argTypes } from '../argTypes';
 
@@ -25,6 +27,7 @@ type TRProps = Omit<IMoexChart, 'container'>;
 const TREntry = (props: TRProps) => {
   const [isCompareOpen, setIsCompareOpen] = useState(false);
   const [moexChart, setMoexChart] = useState<MoexChart | undefined>(undefined);
+  const [snap, setSnap] = useState<any | undefined>(undefined);
 
   const containerRef = useRef<HTMLDivElement | null>(null);
 
@@ -38,7 +41,10 @@ const TREntry = (props: TRProps) => {
     const chart = new MoexChart({
       ...props,
       container,
-      openCompareModal: () => setIsCompareOpen(true),
+      chartCollectionPreset: {
+        ...props.chartCollectionPreset,
+        openCompareModal: () => setIsCompareOpen(true),
+      }
     });
 
     setMoexChart(chart);
@@ -54,6 +60,18 @@ const TREntry = (props: TRProps) => {
   return (
     <div style={{ padding: '20px' }}>
       <h3>TradeRadar usage</h3>
+      <button
+        type={'button'}
+        onClick={() => {
+          setSnap(moexChart?.getSnapshot())
+        }}
+      >Сохранить стейт</button>
+      <button
+        type={'button'}
+        onClick={() => {
+          moexChart?.setSnapshot(snap)
+        }}
+      >Применить стейт</button>
       <div style={{ height: 'calc(100vh - 64px)', width: '100%' }}>
         <div ref={containerRef} />
         {isCompareOpen &&
@@ -89,53 +107,82 @@ export default meta;
 type Story = StoryObj<typeof meta>;
 
 const args: TRProps = {
-  supportedTimeframes: [
-    Timeframes['1s'],
-    Timeframes['5s'],
-    Timeframes['10s'],
-    Timeframes['1m'],
-    Timeframes['2m'],
-    Timeframes['30m'],
-    Timeframes['1h'],
-    Timeframes['2h'],
-    Timeframes['1d'],
-    Timeframes['1w'],
-  ],
-  initialTimeframe: Timeframes['10s'],
-  supportedChartSeriesTypes: ['Candlestick', 'Line', 'Bar'],
-  initialChartSeriesTypes: 'Candlestick',
-  initialSymbol: 'APPL',
-  initialIndicators: [IndicatorsIds.Volume],
-  getDataSource: dataSourceProvider.generateCandles.bind(dataSourceProvider),
-  theme: 'tr',
-  ohlc: {
-    show: true,
-    precision: 4,
+  snapshot:{
+    charts: [{
+      timeframe: Timeframes['10s'],
+      chartSeriesType: 'Candlestick',
+      symbol: 'APPL',
+      panes: [
+        { // empty panes deletes automatically
+          isMain: true, // Be careful. There is only one main pane can be present
+          id: 0,
+          indicators: [
+            {
+              indicatorType: IndicatorsIds.Volume,
+            },
+          ],
+          drawings: []
+        },
+        {
+          isMain: false,
+          id: 1,
+          indicators: [
+            {
+              indicatorType: IndicatorsIds.MACD,
+            },
+          ],
+          drawings: []
+        },
+      ],
+    }],
+  },
+  chartCollectionPreset: {
+    undoRedoEnabled: true,
+    showMenuButton: true,
+    showBottomPanel: true,
+    showControlBar: true,
+    showFullscreenButton: true,
+    showSettingsButton: true,
+    showCompareButton: true,
+    tooltipConfig: {
+      showTooltip: false,
+      time: { visible: true, label: 'Время' },
+      close: { visible: true, label: 'Закр.' },
+      change: { visible: true, label: 'Изм.' },
+      volume: { visible: true, label: 'Объем' },
+      open: { visible: true, label: 'Откр.' },
+      high: { visible: true, label: 'Макс.' },
+      low: { visible: true, label: 'Мин.' },
+    },
+
+    supportedTimeframes: [
+      Timeframes['1s'],
+      Timeframes['5s'],
+      Timeframes['10s'],
+      Timeframes['1m'],
+      Timeframes['2m'],
+      Timeframes['30m'],
+      Timeframes['1h'],
+      Timeframes['2h'],
+      Timeframes['1d'],
+      Timeframes['1w'],
+    ],
+    supportedChartSeriesTypes: ['Candlestick', 'Line', 'Bar'],
+    getDataSource: dataSourceProvider.generateCandles.bind(dataSourceProvider),
+    theme: 'tr',
+    ohlc: {
+      show: true,
+      precision: 4,
+    },
+    mode: 'dark',
   },
-  mode: 'dark',
-  chartOptions: {
+
+  lwcInheritedChartOptions: {
     timeVisible: true,
     secondsVisible: false,
     timeFormat: '24h',
     dateFormat: DateFormat.DD_MM_YYYY_HH_mm_ss,
   },
-  showMenuButton: true,
-  showBottomPanel: true,
-  showFullscreenButton: true,
-  showCompareButton: true,
-  showSettingsButton: true,
-  showControlBar: true,
-  tooltipConfig: {
-    showTooltip: false,
-    time: { visible: true, label: 'Время' },
-    close: { visible: true, label: 'Закр.' },
-    change: { visible: true, label: 'Изм.' },
-    volume: { visible: true, label: 'Объем' },
-    open: { visible: true, label: 'Откр.' },
-    high: { visible: true, label: 'Макс.' },
-    low: { visible: true, label: 'Мин.' },
-  },
-  undoRedoEnabled: true,
 };
 
 export const TradeRadar: Story = {