В окно параметров OsEngine можно выводить не только параметры, но и другие элементы, включая таблицы и чарты.
Данный пример робота служит демонстрацией реализации кастомного чарта в окне параметров.
В нем показано:
- Динамический график: График обновляется в реальном времени по мере поступления новых данных.
- Взаимодействие с пользователем: Пользователь может изменять масштаб графика и получать значения в конкретных точках.
- Настраиваемые параметры: Возможность выбора метода расчета спреда и максимальное количество точек на графике.
1. Как это выглядит.
Заходим в тестер и запускаем нашего робота, открываем окно параметров.
1. Вкладка настроек «Prime»:
В ней находятся настройка режима вычисления спреда и параметр, отвечающий за количество отображаемых данных на чарте.
2. Вкладка настроек «Chart Spread»:
Здесь у нас находится сам чарт.
2. Где найти робота в проекте?
Ссылка на робота GitHub: https://github.com/AlexWan/OsEngine/blob/master/project/OsEngine
3. Разбор робота.
Строки 1-12:
Импортируются необходимые пространства имен:
Строки 24-27:
Определяется пространство имен OsEngine.Robots.TechSamples для организации кода и класс CustomChartInParamWindowSample наследует от BotPanel:
Строки 29-41:
Этот блок отвечает за набор переменных робота:
Строки 45-49:
Инициализируется панель бота:
Cоздаются две простые вкладки, сохраняется ссылка на вкладку в _tab0 и _tab1 для дальнейшего использования.
Строка 51-53:
Создание параметров робота:
Строки 55-64:
Создание вкладки и самого чарта для нее:
Создание вкладки и настройка ее размеров.
Строки73-81:
Переопределение методов GetNameStrategyType и ShowIndividualSettingsDialog.
Первый метод возвращает имя стратегии, второй — пустой, предназначен для отображения индивидуальных настроек.
Строки 86-118:
Запускаем фоновый поток для периодической проверки и обновления графика:
Метод StartPaintChart.
Периодически обновляет график на основе данных из двух источников (tab0 и tab1).
1. Инициализирует счетчики countCandlesTab0 и countCandlesTab1 для отслеживания количества обработанных свечей для каждого источника данных.
2. В бесконечном цикле выполняет следующие действия:
- Ожидает одну секунду (Thread.Sleep(1000)).
- Проверяет доступность данных для обоих источников (_tab0.Securiti != null и _tab1.Securiti != null).
- Проверяет наличие новых свечей в обоих источниках (_tab0.CandlesFinishedOnly.Count и _tab1.CandlesFinishedOnly.Count).
- Если количество свечей увеличилось для обоих источников, обновляет счетчики и вызывает метод LoadValueOnChart().
3. Обработка ошибок:
- Метод заключен в блок try-catch для обработки исключений, возникающих во время выполнения. В случае ошибки выводится сообщение пользователю.
Строки 123-172:
Создаем чарт и подписываемся на все необходимые события:
Метод CreateChart:
1. Проверка потока:
- Метод проверяет, вызывается ли он в правильном потоке (UI-потоке). Если нет, то вызывает себя рекурсивно из UI-потока, чтобы обеспечить правильную работу графического интерфейса.
2. Создание контейнера и графика:
- Создается элемент WindowsFormsHost, который позволяет размещать элементы Windows Forms в приложениях WPF.
- Создается объект Chart — это основной элемент для построения графиков в .NET.
- График добавляется в качестве дочернего элемента к WindowsFormsHost.
3. Очистка существующих элементов:
- Очищаются коллекции серий и областей графика, чтобы избежать дублирования элементов.
4. Создание области графика:
- Создается новая область графика ChartArea с именем «ChartAreaSpread».
- Настраиваются различные свойства области, такие как:
- Включение возможности выделения области по оси X.
- Установка типа оси Y на вторичную.
- Настройка размеров и положения области.
- Установка цвета фона и меток осей.
5. Добавление области графика:
- Созданная область добавляется в коллекцию областей графика.
6. Настройка внешнего вида графика:
- Настраивается цвет и толщина курсора по оси X.
- Устанавливается прозрачный фон для графика и областей.
- Настраивается цвет меток осей X и Y.
7. Подписка на события:
- Подписываются события изменения масштаба, изменения положения курсора и клика по графику. Эти события позволяют отслеживать пользовательские взаимодействия с графиком и выполнять необходимые действия.
8. Обработка ошибок:
- Метод заключен в блок try-catch для обработки исключений, возникающих во время выполнения. В случае ошибки выводится сообщение пользователю.
Строки 174-178:
Создаем хранилище для нашего спреда и переменную, чтобы запоминать последнее значение метода вычисления спреда:
Строки 183-234:
Формируем серии данных для чарта:
Метод LoadValueOnChart:
- Проверяет изменился ли режим расчета спреда (regimeSpread.ValueString) и очищает данные спреда (spreadData) при необходимости.
- Ограничивает количество точек на графике (maxCountDotInLine.ValueInt), удаляя старые значения из spreadData.
- Проверяет наличие данных из обоих источников (tab0 и tab1).
- Вычисляет значение спреда в зависимости от выбранного режима расчета и добавляет его в список spreadData.
- Создает серию данных (lineSeries) для графика.
- Заполняет серию данными из списка spreadData.
- Обновляет график с помощью метода SetSeries.
Строки 239-266:
Подгружаем серии данных на наш чарт:
Метод SetSeries:
1. Проверка потока:
- Метод проверяет, вызывается ли он из UI-потока. Если нет, то вызывает себя рекурсивно из UI-потока, чтобы обеспечить безопасное обновление графического интерфейса.
2. Очистка графика:
- Удаляет все существующие серии данных с графика, чтобы избежать дублирования и обеспечить отображение только актуальных данных.
3. Добавление новой серии:
- Добавляет переданную серию данных lineSeries на график.
4. Проверка и настройка области графика:
- Ищет область графика с именем «ChartAreaSpread».
- Если область найдена и полоса прокрутки по оси X видна, то сдвигает представление графика вправо, чтобы отобразить новые данные.
5. Обновление размера и перерисовка графика:
- Вызывает метод ChartResize() для обновления размера графика (подробности этого метода неизвестны).
- Вызывает метод Refresh() для перерисовки графика и отображения изменений.
6. Обработка ошибок:
- Метод заключен в блок try-catch для обработки исключений, возникающих во время выполнения. В случае ошибки выводится сообщение пользователю.
Строки 270-283:
События, отвечающие за изменение масштаба графика:
Строки 285-332:
Метод, вызываемый при каждом нажатии на график, с помощью него выводим значение Y в месте клика:
Метод Chart_MouseClick:
1. Получение координат клика:
- Получает координаты x точки клика относительно левого верхнего угла графика.
2. Преобразование координат:
- Преобразует координату x пикселя в значение по оси X графика, используя метод PixelPositionToValue.
3. Округление и проверка:
- Округляет полученное значение X вверх, чтобы найти ближайший индекс в массиве данных.
- Проверяет, чтобы полученный индекс не выходил за пределы массива.
4. Удаление предыдущей аннотации:
- Если уже существует аннотация, удаляет ее с графика.
5. Создание новой аннотации:
- Создает новый объект TextAnnotation и задает его свойства:
- Текст аннотации: строка, содержащая индекс и значение ближайшей точки.
- Положение аннотации: привязывается к координате ближайшей точки на графике.
- Форматирование текста: шрифт, цвет и выравнивание текста.
6. Добавление аннотации на график:
- Добавляет созданную аннотацию на график.
7. Обработка ошибок:
- Метод заключен в блок try-catch для обработки исключений, возникающих во время выполнения. В случае ошибки выводится сообщение пользователю.
Строки 337-384:
Метод, который устанавливает границы графика по оси Y:
Метод ChartResize:
1. Проверка наличия данных:
- Если список данных spreadData пуст, метод завершается.
2. Поиск объектов серии данных и области графика:
- Ищет серию данных с именем «SeriesLine» и область графика с именем «ChartAreaSpread».
- Если не найдена серия или область, метод завершается.
3. Определение видимой области по оси X:
- start и end определяют индексы первого и последнего отображаемых элементов серии данных.
- Если полоса прокрутки по оси X не видна, значения start и end равны 0 и количеству элементов в серии соответственно.
- Если полоса прокрутки видна, то значения start и end рассчитываются на основе текущего положения и размера видимой области.
4. Определение минимального и максимального значений для отображения:
- Вызывает методы GetMaxValueOnChart и GetMinValueOnChart для определения минимального и максимального значений в списке spreadData в пределах видимой области (start и end).
5. Обработка одинаковых минимального и максимального значений:
- Если минимальное и максимальное значения совпадают:
- Если значение равно 0, устанавливает максимум равным 1.
- Иначе, устанавливает минимум равным 0.
6. Установка границ отображения по оси Y:
- Устанавливает для оси Y2 области графика «ChartAreaSpread» полученные минимальное и максимальное значения.
7. Обработка ошибок:
- Метод заключен в блок try-catch для обработки исключений, возникающих во время выполнения. В случае ошибки выводится сообщение пользователю.
Строки 389-420:
Методы для нахождения максимального и минимального значения из массива данных:
Этот пример робота будет полезен для демонстрации, как создавать и настраивать кастомные элементы в окне параметров робота. Он показывает, как создавать чарт для вывода значений спреда, что может служить готовым шаблоном для реализации подобных задач.
Удачных алгоритмов!
Комментарии открыты для друзей!
OsEngine: https://github.com/AlexWan/OsEngine
Поддержка OsEngine: https://t.me/osengine_official_support
Регистрируйся в АЛОР и получай бонусы: https://www.alorbroker.ru/open
Сайт АЛОР БРОКЕР: https://www.alorbroker.ru
Раздел «Для клиентов»: https://www.alorbroker.ru/openinfo/for-clients
Программа лояльности от АЛОР БРОКЕР и OsEngine: https://smart-lab.ru/company/os_engine/blog/972745.php