Секреты TSLab | Торговые роботы | События
31 Май

Торговый робот “Бегемот”. Апгрейд.

Недавно была статья в которой описывался торговый робот “Бегемот” и детали реализации. В процессе эксплуатации данного бота, появились дополнительные моменты, которые было необходимо доработать для обеспечения высокой надежности функционирования. Каждая ошибка стоила больших денег, так как объемы торговли обозначены как вполне весомые. Рассмотрим проблемы и решения.

Торговый робот “Бегемот” против брокера. Кто кого?

Через пару недель эксплуатации вылезла одна серьезная проблема, которая требовала экстренного решения. Торговался алгоритм через брокера ВТБ и следовательно через Quick и следовательно с использованием DDE. Неожиданно часто, данные от терминала переставали приходить в TSLab и, в итоге, мы не могли узнать о новых сделках, совершенных алгоритмом. В результате, наблюдался многократный вход в одну и ту же позицию. При этом, только ручная остановка спасала от набора позиции на все депо. Проблема очень серьезная. Нам доступны были 2 адекватных варианта решения:

  1. Отказаться от Quick совсем и переключиться полностью на Plaza 2. При текущем депозите, это небольшая плата за надежность и безглючность работы.
  2. Доработать скрипт, чтобы он мог детектировать проблемы связки TSLab – Quick и сигнализировать о проблемах. Как вариант, чтобы останавливал торговлю.

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

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

Самая опасная и серьезная проблема, с которой можно столкнуться, это отсутствие ответа о приеме или отмене заявки. Это легко приводит к тому, что вы думаете что заявки нет, но заявка на самом деле есть. Или вы думаете что заявку сняли, но заявка не снята, а висит на бирже. Об этом была наша статья на smart-lab.ru про брокера IT-Invest и потерянные 4000000 рублей, но она чудным образом испарилась. Видимо администрация smart-lab.ru за деньги готова на все и не брезгует переписывать историю задним числом. Все что может противопоставить этой проблеме TSLab – сообщение об ошибке. Если нет ответа от брокера, то мы можем только гадать что в реале произошло и максимум что можем сделать, уведомить пользователя о проблеме. Но внутрь скрипта не попадают сообщения об ошибках, и видеть их мы можем только визуально. Таким образом, нам нужно техническое решение, позволяющее понизить опасность проблемы до минимально возможно уровня. И мы его нашли.

Маркировка торговых приказов

Если разложить суть проблемы на запчасти (это зовется декомпозицией), то проблема выглядит следующим образом:

  • мы должны видеть ситуацию когда ордер отправлен, но ответ не получен.
  • мы должны видеть ситуацию когда ордер отменялся, но не отменился в реале.
  • мы должны видеть ситуацию когда ордер совершает запрещенный переход. Например, active -> cancelled.

Последний пункт, уже был реализован ранее, но первые 2 не были. И это создавало почву для больших проблем с DDE. Если отслеживать ордер, видимый в TSLab-е, можно легко по его номеру, то еще не существующий ордер нельзя. Еще одна проблема TSLab в том, что любой приказ, отработанный с ошибкой, сразу попадает в список отмененных. Как пример, отмена ордера завершившаяся ошибкой приводит к тому, что ордер попадает в список отменных независимо от того был ли он в реале отменен или нет. Подача ордера завершившаяся с ошибкой, вообще может завершиться БЕЗ появления ордер в TSLab, хотя в реале ордер может встать в ранок.

Проблема с ошибкой отмены ордера, совершенно типовой глюк серверов Транзак у Финама. Если поставить и тут же попытаться отменить, то высока вероятность получить сообщение о том, что такого ордера вообще нет. Про отпадание DDE, на подключениях через Quick, вообще  молчу. То есть, бороться с проблемой нужно.

Решение проблемы 1.

Как забороть проблему? Через комментарий ордера. Совершенно штатное и типовое решение. При подаче приказа, в поле комментария будем записывать сигнал и некий уникальный ключ приказа. И если на следующем пересчете мы не наблюдаем активного или исполненного ордера с нашим комментарием, значит дело труба и надо сигнализировать. Главное условие, чтобы ключ был уникален на всем времени торговли, по меньшей мере в пределах одного агента, иначе мы рискуем найти какой то старый ордер, в то время как для нашего нового ордера ответ не будет получен от брокера. Выбран был совсем простой способ, а именно число тиков в текущем локальном времени. Это гарантирует уникальность ключа и простой способ генерации. Полностью комментарий выглядит следующим образом “LE$2343453452345“. В качестве разделителя выбран знак $ как это сделали создатели TSLab. В процессе доработки торгового робота, была использована примитивная реализация генерации ключа, но чуть позже был разработан простой класс для этих целей в соответствии с парадигмой программирования SOLID.

    public interface IUniqueGenerator
    {
        long Next();
        long Current { get; }
    }

    public class TickUniqueGen : IUniqueGenerator
    {
        private static long _current = DateTime.UtcNow.Ticks;

        public long Current
        {
            get { return _current; }
        }

        public long Next()
        {
            _current++;
            return Current;
        }
    }

Вероятность коллизий у данного генератора практически равна нулю. А в пределах одного торгового алгоритма и совершенно ничтожна. Чтобы добиться коллизий нужно создавать очень много ордеров в секунду, при этом перевести время назад в процессе работы и перезапустить TSLab после этого.

Отлично, с ключами мы разобрались, но тут встает проблема работы с этими страшными комментариями. Как обрабатывать их и выделять имя сигнала? Как формировать эти комментарии удобным способом? В идеале написать такой класс, который бы знал как склеить из сигнала и ключа комментарий, а так же мог бы потом вычленить элементы из полного комментария. В процессе разработки я сразу же мыслил глобально и уже обдумывал как это пристраивать в другие алгоритмы, поэтому все так серьезно получается. Такой вот, получился интерфейс и класс.

    public interface ICommentFormatter
    {
        // формирует полный комментарий по заданным параметрам
        string Comment { get; }

        // Выделяет из строки комментария часть, которая является сигналом и возвращает ее.
        string ExtractSignal(string comment);
    }

    public class SigKeyCommentFormatter : ICommentFormatter
    {
        private string _signal;
        private long _key;

        public string Signal
        {
            get { return _signal; }
            set
            {
                if (value == string.Empty)
                    throw new ArgumentException("Сигнал не должен быть пустым", "value");

                _signal = value;
            }
        }
        public long Key
        {
            get { return _key; }
            set
            {
                if (value <= 0)
                    throw new ArgumentException("Ключ должен быть положительным", "value");

                _key = value;
            }
        }
        public char Delimeter { get; set; }

        public string Comment
        {
            get { return string.Format("{0}{1}{2}", Signal, Delimeter, Key); }
        }

        public string ExtractSignal(string comment)
        {
            var items = comment.Split(new[] { Delimeter }, StringSplitOptions.RemoveEmptyEntries);
            return items.Length == 2 ? items[0] : string.Empty;
        }

        public SigKeyCommentFormatter(string signal, long key, char delimeter = '$')
        {
            Signal = signal;
            Key = key;
            Delimeter = delimeter;
        }

        public SigKeyCommentFormatter()
        {
            Signal = "Signal";
            Key = 1234567890;
            Delimeter = '$';
        }
    }

Интерфейс, естественно написан минимально функциональным и является базовым для будущих возможных более комплексных решения. Например, видится в будущем такой вариант Сигнал$Уник.Ключ.Позиции$Но.Ордера. Что позволит нам легко компоновать большую позицию из множества сделок и вести ее одним целым (такая возможность, собственно, и стала одним из важнейших плюсов в TSLab 2.0). В общем, фантазия богатая и бурная, но пока, у нас задача конкретная и мы ее решаем.

Полученный класс можно передавать в методы обработки ордеров, и он позволит методу, вычленять СИГНАЛ из общего комментария без кодирования логики парсинга непосредственно в теле метода. Красивенько выходит.

В конце концов, при подаче ордера вписываем в поле комментария полученный Комментарий и ждем чего будет :). Естественно, в кэшэ скрипта запоминаем о том что ордер подали и его комментарий тоже. Если на следующем пересчете мы не обнаружили ордер активным, или не обнаружили его исполненным, или он найден отмененным, или другая нештатная ситуация, то мы можем реагировать на нее разными способами, включая остановку торговли.

Проблема номер 1, решена. Осталась проблема номер 2.

Решение проблемы 2.

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

Модуль управления рисками

Кто-то может сейчас сказать: “Да зачем весь этот сыр бор? Есть же модуль управления рисками и он все может сделать!”. А вот и нет. Это хорошая штука, сделана профессиональным риск менеджером, НО модуль не сможет вам ничего сделать если нет ответа от брокера, или отмена приказа прошла с ошибкой и по факту приказ не отменился. Таким образом, самые опасные проблемы брокеров этот модуль не может контролировать и предотвращать. Поэтому весь сыр бор. И потому, что наши брокеры не предоставляют сервис даже примитивного риск менеджмента и не могут поставить для вашего портфеля банальный максимальный размер убытка за день. Такие дела. Живем как в каменном веке.

Реальные торги

Раньше не было картинки процесса торговли данного бота, теперь прилагаю. Видно как выглядят входы и выходы с нашими новыми комментариями. Снизу, добавлена панель отображающая полный доход скрипта за все время торгов. Штука полезная, особенно при работе через ISecurityRt потому, что на вкладке Доход ничего не отображается и других способов узнать доход нет.

Торговый робот БегемотРисунок 1. Первые результаты в режиме агента

 


comments powered by HyperComments

DenCommander
2015-06-04 22:35:01
Подскажите. Когда подсчитываем текущую позицию через iSecurityRT.Orders мы же все время получаем список ордеров с начала жизни скрипта. Не отнимает ли это много лишнего времени? А если скрипт совершает много сделок и работает уже несколько месяцев?
ra81
2015-06-05 18:54:26
Да, это может стать проблемой. Но вам никто не мешает обработать только сделки за последний день или за последнюю неделю и оставить в покое все остальные :). В одном из скриптов где сделки были только интрадей, я как раз только за текущий день обрабатывал. В конце концов, нужно проявить хитрость и смекалку :).
Дмитрий Высоцкий
2015-12-01 16:46:33
Как купить у вас робота? Был раньше магазин, но к сожалению закрыли, а я так и не успел там ничего купить :( Можно с кем-то переговорить индивидуально может?
ra81
2015-12-01 17:05:40
Пока продажа закрыта. Ничего не продается из роботов. Если что то изменится, те кто подписан на рассылку об этом узнают. подпишитесь на рассылку, мы очень мало шлем писем, поэтому ваш ящик не пострадает.
Павел Дуков
2015-12-02 18:18:57
спасибо
Елена
2017-01-01 14:52:46
Секс знакомства http://bit.ly/2hkF2s9
14
Июл
2017

Доверительное управление. Результаты в июне 2017 года.

Доверительное управление. Результаты в июне 2017 года. Июнь индекс РТС вновь провел преимущественно в боковых движениях, а… »

11
Июн
2017

Доверительное управление. Результаты в мае 2017 года.

Доверительное управление. Результаты в мае 2017 года. В мае “болтанка” индекса РТС продолжилась, на паре… »

7
Май
2017

Доверительное управление. Результаты в апреле 2017 года.

Доверительное управление. Результаты в апреле 2017 года. В апреле мы наблюдали очередной месяц “боковика” по… »

2
Апр
2017

Доверительное управление. Результаты в марте 2017 года.

Доверительное управление. Результаты в марте 2017 года. В марте волатильность на рынке несущественно выросла. Все… »

7
Мар
2017

Доверительное управление. Результаты в феврале 2017 года.

Доверительное управление. Результаты в феврале 2017 года. Февраль был самым коротким торговым месяцем, к тому же… »