#
#
8. Примечания к алгоритму

На данной странице собраны подробные описания неочевидных моментов работы алгоритма робота.

#
#
8.1. Особенности использования торговых стаканов

В роботе для получения цен используются таблицы/потоки торговых стаканов по финансовым инструментам. Особенность работы со стаканами такова, что стакан не приходит с биржи в готовом виде. Чтобы минимизировать объём пересылаемой информации биржа присылает сначала снимок/слепок стакана по финансовому инструменту на какой-то момент времени, а потом приходят только обновления, сообщающие об изменениях в стакане. Робот НЕ строит стакан сразу по всем финансовым инструментам, стакан строится только по используемым в портфелях финансовым инструментам. Поэтому, для добавления нового финансового инструмента в список финансовых инструментов, по которым строится стакан, необходимо переоткрыть поток с текущим слепком, а потом применять к нему обновления из потока инкрементальных обновлений. В момент получения потока со слепком, стакан в роботе временно перестает обновляться по всем используемым финансовым инструментам. Он начнет обновляться только после того как будет закрыт поток со слепком (это может занять некоторое время, зависящее от общего количества финансовых инструментов, приходящих в данном потоке, и размера стаканов) и начнут применяться инкрементальные обновления. Соответственно, в момент переоткрытия стакана вы можете наблюдать отсутствие цен по финансовым инструментам. Переоткрытие требуется в большинстве подключений, потому что стаканы по всем финансовым инструментам или полный лог заявок приходят, как правило, в одном потоке, т.е. нельзя получать данные по конкретным финансовым инструментам, получать вы всегда будете все данные, а использовать можете только для нужных финансовых инструментов.

Стакан в роботе может переоткрываться в следующих случаях:

  • создание нового портфеля;
  • добавление финансового инструмента в портфель;
  • снятие флага Disabled с портфеля;
  • пропуски в номерах сообщений инкрементального потока обновлений стакана в UDP подключениях к биржам (чем больше у вас портфелей и финансовых инструментов, тем выше вероятность возникновения этих пропусков).

Т.е. произойдёт приостановка торговли по всем портфелям, использующим финансовые инструменты данной биржи. Это не является ошибочным поведением робота.

#
#
8.2. Использование приказа переместить заявку

На некоторых подключениях реализована отправка приказа переместить заявку (иногда эта команда также называется изменением заявки). Использование данного приказа позволяет сократить количество транзакций и увеличить отношение количества сделок к количеству транзакций, особенно при котировании, а так же увеличить время нахождения заявок в рынке. Так как особенности использования данной команды отличаются на разных рынках и типах подключений, то, в зависимости от подключения, данный приказ может применяться только для первой ноги портфеля или же для финансовых инструментов обеих ног. На данный момент отправка такой команды реализована для FIX-подключений фондового и валютного рынков Московской биржи, а так же TWIME-подключения срочного рынка Московской биржи.

Использование приказа переместить заявку для поддерживаемых подключений не является обязательным. Эта возможность может быть отключена при создании нового транзакционного подключения.

#
#
8.3. Правила перемещения Lim_Sell и Lim_Buy

Сигнальные цены Lim_Sell и Lim_Buy перемещаются только при прохождении сделок по Is first финансовому инструменту портфеля кроме случая использования Always timer.

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

Введем следующие обозначения: diffpos - знаковое количество лотов в сделке по Is first финансовому инструменту, V - это v_in_left × Count или v_out_left × Count в зависимости от того открываем мы позицию или закрываем данной заявкой, Count - это Count Is first финансового инструмента, Curpos - текущая позиция по Is first финансового инструмента портфеля (т.е. прошедшая только что сделка еще НЕ учтена), нижний индекс 0 - предыдущее значение параметра, 1 - новое значение параметра. В данных обозначениях алгоритм перемещения сигнальных цен примет вид:

  • если прошла продажа(соответственно в количестве diffpos):

    • если текущая позиция до момента совершения сделки была curpos0curpos\neq 0, то:

      k3=(Lim_Sell0Lim_Buy0TPK)×Vcurpos,k3=\left(|{Lim\_Sell_0- Lim\_Buy_0}|-TP-K\right)\times\frac{V}{curpos},

      k4={k3+K2,ifLim_Sell0Lim_Buy00k3+K2,ifLim_Sell0Lim_Buy0<0,k4= \begin{cases}k3+K2, &\text{if}\enspace Lim\_Sell_0-Lim\_Buy_0\geq 0\\ -k3+K2, &\text{if}\enspace Lim\_Sell_0-Lim\_Buy_0<0 \end{cases},

      Lim_Buy1=Lim_Buy0+diffposV×{k4,ifcurpos>0K1,ifcurpos<0,Lim\_Buy_1= Lim\_Buy_0+\frac{|{diffpos}|}{V}\times \begin{cases} k4, &\text{if}\enspace curpos>0\\ K1, &\text{if}\enspace curpos<0 \end{cases},

      Lim_Sell1=Lim_Sell0+diffposV×{K2,ifcurpos>0K,ifcurpos<0,Lim\_Sell_1=Lim\_Sell_0+\frac{|{diffpos}|}{V}\times \begin{cases} K2, &\text{if}\enspace curpos>0\\ K, &\text{if}\enspace curpos<0 \end{cases},

    • если текущая позиция до момента совершения сделки была curpos=0curpos=0, то:

      Lim_Sell1=Lim_Sell0+diffposV×K,Lim\_Sell_1=Lim\_Sell_0+\frac{|{diffpos}|}{V}\times K,

      Lim_Buy1=Lim_Sell0TP,Lim\_Buy_1=Lim\_Sell_0-TP,

  • если прошла покупка (соответственно в количестве diffpos):

    • если текущая позиция до момента совершения сделки была curpos0curpos\neq 0, то:

      k3=(Lim_Sell0Lim_Buy0TPK)×Vcurpos,k3=\left(|Lim\_Sell_0-Lim\_Buy_0|-TP-K\right)\times\frac{V}{curpos},

      k4={k3+K2,ifLim_Sell0Lim_Buy00k3+K2,ifLim_Sell0Lim_Buy0<0,k4= \begin{cases} -k3+K2, &\text{if}\enspace Lim\_Sell_0-Lim\_Buy_0\geq 0\\ k3+K2, &\text{if}\enspace Lim\_Sell_0-Lim\_Buy_0<0 \end{cases},

      Lim_Sell1=Lim_Sell0diffposV×{k4,ifcurpos<0K1,ifcurpos>0,Lim\_Sell_1=Lim\_Sell_0-\frac{|{diffpos}|}{V}\times \begin{cases} k4, &\text{if}\enspace curpos<0\\ K1, &\text{if}\enspace curpos>0 \end{cases},

      Lim_Buy1=Lim_Buy0diffposV×{K2,ifcurpos<0K,ifcurpos>0,Lim\_Buy_1=Lim\_Buy_0-\frac{|{diffpos}|}{V}\times \begin{cases} K2, &\text{if}\enspace curpos<0\\ K, &\text{if}\enspace curpos>0 \end{cases},

    • если текущая позиция до момента совершения сделки была curpos=0curpos=0, то:

      Lim_Sell1=Lim_Buy0+TP,Lim\_Sell_1=Lim\_Buy_0+TP,

      Lim_Buy1=Lim_Buy0diffposV×K.Lim\_Buy_1=Lim\_Buy_0-\frac{|{diffpos}|}{V}\times K.

Также перемещение сигнальных цен происходит когда заявка не может быть выставлена из-за ограничений по v_min, v_max, To0. Если робот не может купить из-за ограничений по v_max, то в соответствии с параметрами портфеля Limits timer и Percent цены Lim_Sell и Lim_Buy уменьшаются на величину параметра портфеля K, если же робот не может продать из-за ограничений по v_min, то в соответствии с параметрами портфеля Limits timer и Percent значения Lim_Sell и Lim_Buy увеличиваются на величину параметра портфеля K.

#
#
8.4. Особенности поведения заявок, переставленных по SL или Timer

При нулевом или положительном значении параметра k_sl заявки, выставленные по следующим событиям: переставление заявки из-за срабатывания условия на SL, переставление заявки из-за срабатывания условия на Timer, закрытие или выравнивание позиции в соответствии с настройками в расписании или по нажатию на "кликер" To market, будут переставляться раз в секунду до момента сведения в сделку, до выключения торговли с помощью Hard stop или до получения ошибки выставления. Переставление заявок будет осуществляться на цену bid - k_sl для продажи и offer + k_sl для покупки.

Это дополнительное переставление, оно не меняет существующие настройки параметра Timer и параметра TE и не зависит от них, т.е. оно выполняется даже при снятом флаге TE.

#
#
8.5. Подсчёт финансового результата

Финансовый результат (в смысле просто число) считается по сделкам и никаких "экзотических" случаев, связанных с его подсчетом нет. НО есть случаи когда не будет раздвижки в таблицах виджетов финансовых результатов (Finres for today и Finres history). Нужно запомнить главное правило, чтобы была раздвижка, должна быть сделка по главному финансовому инструменту, если ее нет, то и раздвижки нет. То есть, если у вас по какой-то причине "кривая" позиция и вы ее "подровняли", нажав на кнопку To market, то вы не получите нормальной раздвижки в данных виджетах. У вас будет только одна "кривая" раздвижка, в которой фигурирует только главный финансовый инструмент (как пример, флуд контроль, проходят сделки по первой ноге, а по второй не дают выставиться, у вас будут одноногие "кривые" раздвижки с первой ногой, а после нажатия To market, когда пройдут сделки, т.к. они были только по второй ноге, то раздвижки в таблице не будет, но с финансовым результатом все будет в порядке).

И еще один вариант, когда значение параметра Count первой ноги больше значения параметра Count второй. Пусть вы торгуете долларом валюты против доллара на срочном рынке, и валюта первая нога. Т.е. Count у валюты 100, а у срочки 1, и вы перекрываете на срочке каждые 100 контрактов валютки. Вы выставили 100 контрактов на валютке. Предположим, у вас взяли 60. Раздвижки в таблице не будет, т.к. она получится заведомо "кривой", вторую ногу же не кидали. Потом прошло еще 50, и вы снова не увидите раздвижки. Да, вы кинете один финансовый инструмент на срочку, он пройдет (в финансовом результате все нормально учтется). Но опять же не совсем ясно к каким сделкам его привязывать, если привязать как обычно к последней (т.е. к 50), то будет заведомо кривая раздвижка, а искать какие-то предыдущие сделки уже не вариант, т.к. все могло быть не так просто, как в описанном примере.

#
#
8.6. О ценах выставления заявок второй ноги

Заявки по инструментам второй ноги выставляются по следующим ценам: заявка на покупку выставляется по лучшей цене на продажу, к которой прибавляется отступ k или отступ k_sl в случае переставления заявки по стоп лоссу и другим аналогичным событиям, заявка на продажу выставляется по лучшей цене на покупку, из которой вычитается отступ k или отступ k_sl в случае переставления заявки по стоп лоссу и другим аналогичным событиям. При этом лучшие цены на покупку и продажу по финансовым инструментам второй ноги фиксируются в момент выставления заявки по Is first финансовому инструменту. Таким образом, в момент совершения сделки по Is first финансовому инструменту все остальные финансовые инструменты в портфеле выставятся с отступами не от текущих лучших цен, а от лучших цен, которые были во время выставления заявки по Is first финансовому инструменту. Исключение составляет использование параметра Equal price.

Других вариантов вариантов формирования цен заявок второй ноги, кроме описанных выше, не предусмотрено.

#
#
8.7. Об объёмах выставления заявок

Для некоторых бирж (к примеру Deribit) если объём в заявке не кратен лоту, то объем выставляемой заявки принудительно округляется до целого количества лотов(например лот равен 10, объём выставляемой заявки 25, то в действительности на бирже выставится заявка объемом 20 (округление всегда происходит в меньшую сторону)). Если при подобном округлении объём выставляемой заявки станет равным нулю, то вы получите ошибку выставления REASON_ZERO_AMOUNT_TO_MULTIPLE.