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


# Виджет «График»

## Назначение

Виджет предназначен для отображения ценовых графиков финансовых инструментов с использованием библиотеки `moex-chart`. Позволяет анализировать динамику цен различных инструментов, включая акции, фьючерсы, валютные инструменты и индикативные котировки, с использованием доступных таймфреймов и типов отображения графика.

## UI

Интерфейс состоит из:

* шапки виджета с названием инструмента и элементами управления;
* области графика `MoexChart`.

### Шапка виджета

Состоит из:

* названия выбранного инструмента;
* названия инструмента, даты расчёта и фирмы при отображении индикативных котировок;
* иконки поиска инструментов;
* контекстного меню виджета.

### График

Используется:

* библиотека `moex-chart`;
* `DataSourceProvider` для передачи исторических и realtime-данных;
* поддержка типов отображения графика, заданных конфигурацией библиотеки;
* поддержка изменения таймфрейма;
* поддержка сравнения инструментов;
* поддержка индикаторов;
* поддержка инструментов рисования;
* сохранение и восстановление состояния графика.

## Функции и возможности

* отображение ценовых графиков для различных типов финансовых инструментов;
* загрузка исторических свечей;
* получение обновлений свечей в режиме реального времени;
* поддержка таймфреймов, заданных в конфигурации `MOEX_CHART_CONFIG`;
* выбор и изменение основного инструмента;
* поддержка индикативных котировок;
* сравнение нескольких инструментов на одном графике;
* добавление и настройка индикаторов;
* использование и настройка инструментов рисования;
* сохранение текущего состояния графика;
* восстановление ранее сохранённого состояния;
* поддержка Drag & Drop для смены инструмента;
* интеграция с другими виджетами через механизм привязок;
* поддержка полноэкранного режима.

## Интеграции

* Используется совместно с виджетом «Индикативные котировки» для отображения индикативных данных.
* Поддерживает привязку к другим виджетам через механизм `publicContext`.
* Может получать инструмент от виджета, используемого в качестве мастера.
* Уведомляет связанные виджеты об изменении текущего инструмента.
* Обрабатывает внешние события открытия инструмента.
* Поддерживает визуальное выделение виджета через событие `HIGHLIGHT_WIDGET_EVENT`.

## Бизнес требования

* Для обычных инструментов данные загружаются через основной API котировок.
* Для индикативных инструментов данные загружаются через `indicativeQuotesController`.
* При смене инструмента через механизм привязок сохраняется связь с мастер-виджетом.
* При ручной смене инструмента существующая привязка разрывается.
* При ручной смене инструмента очищаются индикативные данные, ранее переданные в свойства виджета.
* Выбранный инструмент сохраняется в свойствах виджета.
* Состояние графика, включая таймфрейм, индикаторы, инструменты рисования и настройки, должно сохраняться и восстанавливаться после повторного открытия виджета.
* Изменение основного инструмента должно происходить без полного пересоздания экземпляра графика.

## Особенности кода

* Используется кастомный хук `useChartComponentFacade` для управления текущим инструментом, Drag & Drop, привязками, состоянием меню и внешними событиями.
* Используется кастомный хук `useMoexChart` для создания и уничтожения экземпляра `MoexChart`, смены основного символа, сохранения snapshot и управления realtime-подпиской.
* Используется хук `useChartPublicContext` для интеграции с механизмом привязок.
* Для адаптации данных к API `moex-chart` используется класс `DataSourceProvider`.
* Исторические данные загружаются через функцию `requestBars`.
* Realtime-данные загружаются через функцию `requestRealtimeBars`.
* Для индикативных котировок используется отдельный API `indicativeQuotesController`.
* Серверные свечи преобразуются в формат `moex-chart` с помощью функции `candleToBar`.
* Для таймфреймов, которые напрямую не поддерживаются источником данных, выполняется свёртка свечей.
* Для определения индикативных инструментов используется функция `isIndicativeTicker`.
* Модальное окно поиска основного инструмента реализовано на стороне приложения через компонент `SymbolSearchModal`.
* Модальное окно сравнения инструментов реализовано на стороне приложения через компонент `CompareModal`.
* Для управления сравниваемыми инструментами используется `CompareManager`, предоставляемый библиотекой `moex-chart`.
* Для `currentInstrument` одновременно используются `useState` и `useRef`: состояние обеспечивает перерисовку компонента, а ref хранит актуальное значение и используется для защиты от повторных и циклических обновлений.
* Для обновления всех отображаемых инструментов используется один realtime-таймер экземпляра `DataSourceProvider`.

## Проблемы

* Функция `isIndicativeTicker` требует отдельного рефакторинга.
* Комбинированное использование `useState` и `useRef` для `currentInstrument` необходимо повторно оценить после стабилизации механизма привязок.
* Логика свёртки исторических и realtime-свечей для нестандартных таймфреймов требует дополнительного тестового покрытия.
* Экспорт данных графика в Excel после перехода на `moex-chart` в текущей реализации недоступен. Новый механизм экспорта необходимо согласовать отдельно.

## Примечания

* Виджет использует библиотеку `moex-chart`.
* Основной инструмент изменяется через публичный метод `setSymbol` без пересоздания экземпляра графика.
* Поиск инструментов и модальные окна реализуются на стороне приложения.
* Для исторических и realtime-данных используется единый `DataSourceProvider`.
* При остановке realtime-подписки созданный таймер очищается.
* Состояние графика хранится в `moexChartState`.
* Перед сохранением snapshot из конфигураций индикаторов исключаются несериализуемые источники данных и функции.
* Набор доступных таймфреймов, типов серий и элементов управления определяется конфигурацией `MOEX_CHART_CONFIG`.
* Отображение нескольких инструментов на одном графике реализуется через механизм сравнения.
* При повторном выборе уже активного инструмента обновление состояния не выполняется.

## TODO

* Отрефакторить функцию `isIndicativeTicker` в `src/widgets/Chart/utils/isIndicativeTicker.ts`.
* Добавить тесты для свёртки исторических свечей.
* Добавить тесты для свёртки realtime-свечей.
* Проанализировать возможность упрощения хранения `currentInstrument` после стабилизации механизма привязок.
* Согласовать необходимость сохранения экспорта в Excel и определить подходящий механизм его реализации.