Блог им. empenoso

Отслеживание позиций торгового робота Московской биржи через CSV файл

Нахожусь в процессе написания механизма торгового робота, работающего на Московской бирже через API одного из брокеров. Брокеров имеющих своё АПИ для МосБиржи катастрофически мало — мне известно только о трёх. При этом, когда я стал публиковать модули робота (и полностью выложу готовый механизм робота на GitHub), то стал получать непонимание — например, мне писали в комментариях — зачем придумывать велосипед, когда уже есть QUIK — популярная российская платформа для биржевых торгов. В Квике уже есть готовый функционал «импорт транзакций из файла» или таблица «карман транзакций». В тех же комментариях предлагали даже рассмотреть использование платформы 1С для робота, но оказалось, что торговля все равно будет осуществляться через импорт .tri-файла в Квик.

Лично мне Квик не очень нравится тем, что это программа для Windows. Хочется иметь механизм торгового робота, который был бы кроссплатформенным и легким — это позволит использовать его даже на «слабом» сервере. К тому же, много лет назад, когда Квик был единственной альтернативой для частного лица, невозможно было внутри одной Windows без использования виртуальной машины запустить несколько копий программы технического анализа с разными системами — для того, чтобы каждая из этих копий отправляла свои сигналы на покупку и продажу в соответствующий Квик. Это было нужно для разных торговых стратегий.

По субъективным причинам я стал писать торгового робота в среде исполнения JavaScript Node.js, но для тестирования на истории пришлось использовать Python и его библиотеки.

Модуль, считывающий позиции из файла

Проблемы с записью позиций в Node.js

Вообще именно этот модуль пришлось пару раз переписывать, потому что не смог сразу отладить его. Проблема была в том, что вызов модуля записи и обновления позиций осуществлялся сразу из нескольких мест и одни результаты перезаписывали другие. Но удалось разобраться и теперь всё протестировано и работает.

Дополнительно использую библиотеки csv-parser и json2csv — это популярные инструменты Node.js для обработки данных CSV, каждая из которых служит различным целям:

  • csv-parser, это легкая и быстрая библиотека для анализа файлов CSV. Она основана на потоках, что делает ее очень эффективной для обработки больших наборов данных.
  • json2csv, это утилита для преобразования данных JSON в формат CSV. Идеально подходит для экспорта данных из приложений в структуру, удобную для CSV, может работать как синхронно, так и асинхронно.

Установка этих библиотек:

Отслеживание позиций торгового робота Московской биржи через CSV файл

Мой модуль csvHandler.js

Этот код определяет модуль для взаимодействия с CSV-файлом для управления финансовыми торговыми позициями. Служит для загрузки, сохранения, обновления и удаления финансовых позиций, хранящихся в CSV-файле.

Ключевые библиотеки:

  • fs: для операций файловой системы, таких как чтение и запись файлов.
  • csv-parser: для анализа CSV-файлов в объекты JavaScript.
  • json2csv: для преобразования объектов JavaScript в формат CSV для сохранения.
  • path: для управления путями к файлам.
  • Интеграция: включает пользовательские модули для ведения журнала (logService) и получения имен функций для лучшей отладки.

Функциональность

  1. Обработка пути к файлу: использует модуль path для поиска CSV-файла, хранящего данные о позиции: ../../data/+positions.csv.
  1. Функции управления позицией:

loadPositions():

  1. Считывает CSV-файл и анализирует его в массив объектов позиции.
  2. Преобразует числовые поля (quantity, purchasePrice, maxPrice, profitLoss) в числа с плавающей точкой для вычислений.
  3. Возвращает обещание, которое разрешается с проанализированными данными или отклоняется в случае ошибки.

savePositions(positions):

  1. Преобразует массив объектов позиции обратно в формат CSV с помощью json2csv.
  2. Перезаписывает CSV-файл обновленными данными.

removePosition(figi):

  1. Удаляет позицию из CSV-файла на основе ее figi (уникального идентификатора).
  2. Загружает все позиции, отфильтровывает указанную и перезаписывает файл.

updatePosition(newPosition):

  1. Добавляет новую позицию или обновляет существующую в CSV-файле:
  2. Если figi существует, обновляет соответствующую позицию.
  3. В противном случае добавляет новую позицию.
  4. Сохраняет обновленный список обратно в CSV-файл.
  1. Экспортированные модули: функции loadPositions, updatePosition и removePosition для использования в других частях робота.

Полный код csvHandler.js:

Отслеживание позиций торгового робота Московской биржи через CSV файл

Мой модуль checkCSVpositions.js

Этот модуль важен для обеспечения согласованности данных между локальным CSV-файлом и текущими позициями, полученными из T‑Bank Invest API. Он проверяет наличие несоответствий, которые могут привести к ошибкам в торговых операциях, и останавливает робота, если обнаруживаются несоответствия.

Основные функции

  1. Интеграция с внешними системами
  • T‑Bank Invest API: взаимодействует с API для извлечения торговых позиций в реальном времени.
  • CSV File Management: использует локальный CSV-файл для хранения и управления представлением бота о торговых позициях.
  1. Проверка согласованности
  • Сравнивает позиции из CSV-файла с позициями с сервера T‑Bank Invest API.
  • Проверяет как количество, так и наличие позиций для обнаружения несоответствий.
  1. Обработка ошибок
  • Регистрирует подробные ошибки при обнаружении несоответствий.
  • Останавливает торговые операции для предотвращения дальнейших действий на основе неверных данных.

Основные функции:

1. getServerPositions()

  • Извлекает все открытые позиции из T‑Bank Invest API.
  • Извлекает позиции с ценными бумагами и преобразует баланс в float для сравнения.
  • Регистрирует ответ сервера для отладки и аудита.

2. checkForDiscrepancies()

  • Загружает данные CSV: считывает локальную запись позиций бота с помощью csvHandler.Сравнивает позиции:
  • Для каждой позиции CSV ищет соответствующую позицию на сервере с помощью FIGI (уникальный идентификатор).
  • Извлекает размер лота для точного сравнения количества.
  • Если обнаружены расхождения в количестве или отсутствующие позиции, регистрирует ошибки и останавливает торговлю.
  • Статус журнала: подтверждает, когда все позиции совпадают, и позволяет продолжить торговлю.

Рабочий процесс

  1. Извлечение позиций:
  • Локальные позиции загружаются из CSV-файла.
  • Позиции сервера извлекаются через API Tinkoff.
  1. Обнаружение расхождений: Для каждой позиции в CSV-файле:
  2. Код вычисляет общее количество в лотах (csvPosition.quantity * lotSize).
  3. Сравнивает с балансом на сервере.Ошибки регистрируются, если:
  4. Количества не совпадают.
  5. Позиция в CSV-файле отсутствует на сервере.
  1. Безопасность робота:
  • Любые обнаруженные расхождения вызывают ошибку, останавливающую торговые операции.
  • Не позволяет роботу совершать сделки на основе устаревших или неверных данных.

Полный код checkCSVpositions.js:

Отслеживание позиций торгового робота Московской биржи через CSV файл

Итоги

Проект полностью представлен на Гитхабе: https://github.com/empenoso/SilverFir-TradingBot. Новые модули будут загружаться по мере написания и тестирования.

Автор:Михаил Шардин

27 ноября 2024 г.

Данная публикация является личным мнением автора. Мнение владельца сайта может не совпадать с мнением автора.
6.8К | ★11
12 комментариев
В Квике можно не только через текстовые *.tri файлы работать, но и через Trans2Quik.dll
А вообще, удачи в вашем начинании.
По мере усложнения логики код будет сложно поддерживать. Надо разделять на независимые модули. Отделять работу с апи брокером от логики, логику от конфигурирования. Модель данных выносить. Как минимум попробуйте паттерн Model-View-Controller. Но я бы добавил Interface к брокеру в этот паттерн — там часто нужно контроль кол-ва запросов делать, чтобы лимиты не привысить.

Сохранение не потокобезопасное — будут ошибки при синхронной записи и считать. Очередь поможет.

И новые функции лучше разрабатывать через тесты — тестирование позволит делать менее связанный код, его потом легче поддерживать и модифицировать. Ну а тесты позволят прогонять функционал и быть более уверенным, что работает.

Из простых решений еще можно ESLint добавить в проект — он будет помогать ошибки находить и стиль поддерживать.

Сам JS для бота сложный выбор. Проще питон подучить и на нем делать. Там хотя бы pandas и numba с Jit копиляцией есть и мультипроцессорность понятная.

PS логи и данные в проекте — зло.
avatar
QUIK конечно поразительная программа, в эпоху санкций, работающая на Windows. За 20 лет, могли бы и кроссплатформенность добавить. А вам удачи.
avatar
У квика всегда были конкуренты, которые так и не распространились. 
У гуты-банка, у Цериха, у Атона, у Альфы, у Айти-инвеста, был еще  нет-трейдер и это неполный список. И, насколько я знаю, из под линукса на квике торгуют. 
Что касается авторского проекта, если рассматривать его как рабочий макет, то все здорово. Осталось понять косяки, учесть принципиальные недостатки и написать заново. 
Автор, как я понимаю, пишет быстро, так что все в его руках.

avatar
SergeyJu, линукса на квике скорее всего через эмулятор. Тот же Wine например
avatar
Михаил Шардин, т-банк плохой брокер. 
По хорошему бы надо для надежности получать данные от двух разных брокеров. Ну и деньги по счетам разложить.  Например, на одном создать пассивный портфель. А торговать на втором активно. 
Да, и учтите, данные об транзакциях могут иногда теряться. Систем должна быть устойчива к максимально большому спектру искажений в данных. Не  в смысле частоты появления, а в смысле критичности дла портфеля. 
Быстрый робот моего знакомого как-то, теряя подтверждения о сделках, считал, что сделка не проведена и долбал снова и снова, пока не вышел на максимально возможное плечо. 
avatar
Михаил Шардин, Wine не эмулятор, а имплементация подмножества Win API для запуска под X. Для маков тоже должен быть. 
Гораздо проще использовать нативный Офис/Excel, да и Квик от них ничем не отличается. Просто рисуется все не в винде, а в Линуксе.
avatar

Тебя T-bank дурит и на самом деле об заявки обрабатывает у себя
для выходя на прямую лучше использовать github.com/kmlebedev/txmlconnector

Да он немного легаcи, но это прямо прямой доступ, там есть пример как данные выгрузить в клик, а дальше можно с ними вертеть как захочешь.

что мешает в json формате хранить данные? их и получать обратно проще нативными методами. зачем эта компиляция в csv туда-сюда? Ну и раз предполагается хранение — не имеет ли смысл использовать базу данных?
avatar
Slan, конечно, данные должны быть в базе. И структура базы не самое последнее дело при проектировании.
avatar
Slan, база -  это сразу сложность на ступень выше, а выгоды сомнительные, csv достаточно, если масштаб не тиковый, конечно, без стакана и ордерлога
avatar
Для Backtrader есть готовы коннектор для Тинька, смысл писать велосипед на JS
github.com/cia76/TinkoffPy
avatar

Читайте на SMART-LAB:
Фото
РУСАЛ: прибыль иксанула в рамках прогноза, но осадочек остался. Минорам плохо когда мажору все равно на акции и нет отдачи в виде дивидендов/байбека
РУСАЛ отчитался за 1-е полугодие, компания была бенефициаром «Ормузского кризиса» т.к. все помнят высокие цены на алюминий с марта 2026 года...
Фото
Как закрытие Ормузского пролива влияет на стоимость нефти
Ормузский пролив закрыт шестой месяц, конфликт на Ближнем Востоке не урегулирован, но нефть Brent не обновляет годовые максимумы. Разбираемся,...
Как работают синергии внутри Группы Займер
Два месяца назад в состав Группы Займер вошла платежная система «БЭСТ». Данное приобретение усилило синергетический потенциал группы, который...
Фото
Портовый срез #8: НМТП отгружает нефть, разворот в контейнерах и ставках
Порты России вместо привычной сверхмаржи и дохода для инвесторов стали мишенью для БПЛА противника. Перестали ли из-за этого они быть...

теги блога Михаил Шардин

....все тэги



UPDONW
Новый дизайн