В нескольких предыдущих постах серии мы разговаривали про IServer, свойства и методы, которые в нём есть. Их много и довольно разных. При этом каждое отдельно взятое API что-то поддерживает, а что-то нет. О том, что конкретно коннектор поддерживает, OsEngine должен знать ДО того, как начнёт запрашивать неработающий функционал. Для этого ServerPermission и существует.
Например, данные могут быть только свечные, или может не быть 15 минутных свечек. Или API может вообще не поддерживать скачку глубоких исторических данных. Или API не поддерживает какие-то торговые операции: нет Market ордеров, не работает перестановка цены ордера.
Cлой автотестов для коннекторов переживает в OsEngine уже ВТОРОЕ пришествие. Увеличившись с первой версии в 10 раз. Про что и будет данная мини-серия статей внутри серии «Коннекторы к OsEngine». АЖ НА 20 Постов. Так надо…
А данный пост о том, зачем такой большой слой тестирования и введение в тему.
Так вышло, что ядро OsEngine тестируется почти без остановки с разных сторон одновременно. И тестером, и оптимизатором и роботами в реальных боях. В какой-то момент дошло до того, что команда в офисе узнаёт о багах, если таковые есть, после их пуша в ядро через 10 – 20 минут.
Выглядит это так:
Рис. 1. Модули, тестирующие слои, поддерживающие работу роботов.
Поэтому само ядро OsEngine стабильно.
Проблемы в другом месте… В коннекторах. Чем мы с Вами и будем весь 2024 год заниматься.
Это самая важная часть создания коннекторов. «Наговнить немного кода, чтобы как-то что-то заработало» — дело нехитрое. Однако при таком подходе пользователи будут не довольны, т.к. коннектор будет работать плохо. Поэтому надо делать хорошо, чтобы коннектор начал проходить автоматические тесты. И для этого придётся попотеть.
Сегодня рассмотрим интерфейс с названием IServer, через который осуществляется доступ к коннекторам в OsEngine. Посмотрим, что у него там есть внутри.
IServer – интерфейс для доступа к реализациям серверов почти во всём проекте. Нужен для того, чтобы унифицировать методы и свойства, нужные для роботов и OsData.
Вероятно, для каких-то молодых камрадов это будет откровением, ибо каждая книжка по Шарпам уже с первых глав нас знакомит с тем, что в C# за сборкой мусора следить не надо. Однако это маркетинговая выдумка. В высоко нагруженных проектах вроде OsEngine, как только ты не проследил за удалением объектов и выкинул это из головы, началась утечка памяти.
Я и сам, как программист-самоучка, очень много лет проживал в этой парадигме, от чего было много проблем как у меня, так и у пользователей OsEngine.
И в этом посте поговорим о том, какие штуки надо обязательно подчищать за собой при удалении коннектора. А вернее при вызове его обязательного к перегрузке метода DISPOSE();
Очень часто коннектор нуждается в перезапуске. Это обусловлено свойствами работы сети интернет. В этот момент у ServerRealization вызывается метод Dispose. Все манипуляции по очищению памяти и переменных нужно делать из этого метода. И ни из какого другого…
Надеюсь, все отдохнули! С прошедшими! Поговорим о том, что нас ждёт в этом году.
От Динского социально-реабилитационного центра для несовершеннолетних. Сегодня отвёз им стиральную машину и четыре огромных коробки конфет. Спасибо всем, кто помогал!
Напоминаю, 9 декабря 2023 года мы собирались на митап алготрейдеров из сообществ OsEngine и Смартлаб: https://smart-lab.ru/company/os_engine/blog/965467.php
Мне показалось хорошей идеей предложить тем, кто встречается, немного помочь ребятам из Динской. И в качестве входного билета можно было купить «благотворительный билет» и задонатить на это дело без покупки чего-то.
Внезапно, нашлись люди (спасибо Вам!), которые идею поддержали. В итоге собрали 36 т.р.
Я ничего выдумывать не стал, позвонил директору заведения и спросил, что им нужно купить.
У них недавно сломались две стиральные машины из четырёх. И чтобы дети были отстираны, нужна была срочно замена.
Во время создания коннектора для OsEngine рекомендуется использовать версию C# не выше шестой. Новый синтаксический сахар ОЧЕНЬ интересен начинающим программистам, а они при этом нихрена в этом не понимают, от чего неизбежно будут проблемы. Поэтому мы просто всё это дело запретим.
Далее, очень короткое описание истории шарпов по версиям:
Многие API не разрешают избыточно частое (по их мнению) обращение к некоторым данным. Почти всегда на разные типы запросов есть те или иные ограничения. И в случае их превышения происходит какой-то вид отключения клиента от API, либо даже денежные штрафы!
Нам конечно же доводить до отключения коннектора от API нельзя. И коннектор, который не умеет соблюдать дистанцию между запросами, не работающий.
В связи с этим в коннекторах необходимо устанавливать ограничение на запросы определённых методов. Вроде подписки на инструменты или даже выставление ордеров. Как это делать? Поговорим в этой статье.
Объект, который отвечает за задержки между запросами, называется RateGate и находится у нас в проекте вот здесь:
Большинство коннекторов в OsEngine так или иначе используют данную технологию. Особенно это касается бирж криптовалют. Потоковые данные идут именно через данный протокол.
Библиотек для подключения данного протокола великое множество. В этой статье поговорим о библиотеке, которую надо использовать и на что обратить внимание.
WebSocket4Net.
Данная библиотека и реализация вёбсокетов хорошо себя показывают в работе. Её и нужно использовать.
Http (в контексте написания коннектора для OsEngine) – важнейший способ получения данных через АПИ соответствующих бирж/брокеров. На ровне с WebSocket, Http, как протокол связи, используется в нашем фреймворке в подавляющем кол-ве коннекторов.
Естественно, с годами у нас накопился определённый опыт по тому, как надо и как не надо его использовать. Поговорим об этом…
Во всех API крипто-бирж данный протокол в том или ином виде присутствует. Он позволяет отправлять различные запросы на сервер биржи и получать в ответ какие-то данные.
Обычно это:
Делать эти запросы можно совершенно по-разному. За десятилетия жизни протокола появились сотни библиотек для этого. Однако, я рекомендую использовать следующие.
Клиент для отправки Http запросов может и должен быть использован в запросах, в которых нет динамически меняющихся заголовков. Т.е. для public запросов.