ФОРТС. Вопросы по исполнению - страница 163

 
911@open.ru   или 911@open-broker.ru ?
 
md110 #:
911@open.ru   или 911@open-broker.ru ?

Я точно не помню (сейчас за городом)

Добавлено

911@open.ru

 
Спасибо. Попытался через личный кабинет в чат, просто не работает у них. Попробую сегодня 911
 
JRandomTrader #:

С задержками не всё так просто.

Задержки ответа от промежуточных узлов могут быль больше, чем от конечного, задержка ответа на icmp8 (ping) может отличаться от задержки ответа на tcp_syn.

Кинул в личку номера и ip серверов - у меня так. Кстати, на пинги они не отвечают, даже icmp11 не шлют. А на tcp_syn - шлют.

У меня через основного провайдера 10-11 мс, а через резервного - 45-50 мс и маршрут через Амстердам.

Вот что получилось


 
prostotrader #:

Вот что получилось

Я и говорю - на пинги не отвечают. А виндовый tracert трассирует именно пингами (icmp8).

Надо трассировать TCP SYN'ами на 443 порт. Не знаю, как это сделать под виндой.

 
А какой IP?
 
Dmitriy Skub #:
А какой IP?

Кинул в личку.

1-й и 9-й - внутренние адреса, они не ответят.

 

Печальные новости для тех, кто торгует на ФОРТС.

Похоже, что Биржа (или Открывашка) занялась фронтраннингом (Биржу уже наказывали за это)

Пример

Отсылаю асинхронный ордер

Терминал
2023.05.04 16:32:23.686 Trades  'xxxxx': sell limit 1 TRNF-9.23 at 112353                                                       //Терминал отдал приказ об установке ордера 
2023.05.04 16:32:23.696 Trades  'xxxxx': accepted sell limit 1 TRNF-9.23 at 112353                                        //Сервер проверил параметры ордера
2023.05.04 16:32:23.697 Trades  'xxxxx': sell limit 1 TRNF-9.23 at 112353 placed for execution in 10.588 ms   //Сервер отправил ордер на биржу

Далее советник ждет подтверждение об установке ордера.

В советнике есть механизм слежения за ордерами (функция ProcessOrders)

К сожалению, терминал не логирует ответ биржи при асинхронной отправке ордеров!

Советник
2023.05.04 16:32:25.165 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:26.665 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:28.165 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:29.664 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:31.164 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:32.664 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:34.163 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:35.163 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:36.663 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:38.162 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:39.662 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866
2023.05.04 16:32:41.162 FCS_Trader (TRNF-9.23,M1)       ProcessOrders: Sell Ордер в переходном состоянии. Билет = 233884866

Считаем время от момента отправки ордера (2023.05.04 16:32:23.686)

до последней проверки (2023.05.04 16:32:41.162)

И видим, что ордер устанавливался аж ~8,5 СЕКУНДЫ !!!!!

Никакими задержками сети это объяснить невозможно.

Часть кода из функции OrderRealSelect(), где получаем SELECT_BUSY

if(OrderSelect(ticket) == true)
    {
      ord_data.is_hystory = HYST_FALSE;
      if(get_data == true)
      {
//--- long      
        ord_data.ticket = ulong(OrderGetInteger(ORDER_TICKET));
        ord_data.time_setup = datetime(OrderGetInteger(ORDER_TIME_SETUP));
        ord_data.type = ENUM_ORDER_TYPE(OrderGetInteger(ORDER_TYPE));
        ord_data.state = ENUM_ORDER_STATE(OrderGetInteger(ORDER_STATE));
        ord_data.expiration = datetime(OrderGetInteger(ORDER_TIME_EXPIRATION));
        ord_data.time_done = datetime(OrderGetInteger(ORDER_TIME_DONE));
        ord_data.t_set_msc = datetime(OrderGetInteger(ORDER_TIME_SETUP_MSC));
        ord_data.t_done_msc = datetime(OrderGetInteger(ORDER_TIME_DONE_MSC));
        ord_data.type_filling = ENUM_ORDER_TYPE_FILLING(OrderGetInteger(ORDER_TYPE_FILLING));
        ord_data.type_time = ENUM_ORDER_TYPE_TIME(OrderGetInteger(ORDER_TYPE_TIME));
        ord_data.magic = OrderGetInteger(ORDER_MAGIC);
        ord_data.reason = ENUM_ORDER_REASON(OrderGetInteger(ORDER_REASON));
        ord_data.pos_id = OrderGetInteger(ORDER_POSITION_ID);
        ord_data.pos_by_id = OrderGetInteger(ORDER_POSITION_BY_ID);
//--- double        
        ord_data.vol_init = OrderGetDouble(ORDER_VOLUME_INITIAL);
        ord_data.vol_cur = OrderGetDouble(ORDER_VOLUME_CURRENT);
        ord_data.price_open = OrderGetDouble(ORDER_PRICE_OPEN);
        ord_data.sl = OrderGetDouble(ORDER_SL);
        ord_data.tp = OrderGetDouble(ORDER_TP);
        ord_data.price_cur = OrderGetDouble(ORDER_PRICE_CURRENT);
        ord_data.price_stlim = OrderGetDouble(ORDER_PRICE_STOPLIMIT);
//--- string        
        ord_data.symbol = OrderGetString(ORDER_SYMBOL);
        ord_data.comment = OrderGetString(ORDER_COMMENT);
        ord_data.ext_id = OrderGetString(ORDER_EXTERNAL_ID);      
      }
      else ord_data.state = ENUM_ORDER_STATE(OrderGetInteger(ORDER_STATE));
      switch(ord_data.state)
      { 
        case ORDER_STATE_STARTED:
        case ORDER_STATE_REQUEST_ADD:
        case ORDER_STATE_REQUEST_MODIFY:
        case ORDER_STATE_REQUEST_CANCEL:
          ord_data.real_state = ORDER_BUSY;
        break; 
        case ORDER_STATE_PARTIAL:
          ord_data.real_state = ORDER_EXIST_PARTIAL;
        break;
        case ORDER_STATE_PLACED:
          ord_data.real_state = ORDER_EXIST;
        break;
      }
    }
    else ord_data.error_code = GetLastError();
switch(ord_data.real_state)
      {
        case ORDER_BUSY:
          return(SELECT_BUSY);
        break;
        case ORDER_EXIST:   
        case ORDER_EXIST_PARTIAL:
          return(SELECT_TRUE);
        break;
        default:   
          return(SELECT_FALSE);
        break;                                             
      }

Функция ProcessOrders

void ProcessOrders(const ulong a_ticket, ENUM_ORD_STATUS o_status)
{
  ORDER_DATA order_data;
  ENUM_ORD_SELECT order_select = OrderRealSelect(a_ticket, order_data, true);
  switch(order_select)
  {
    case SELECT_ERROR:
      if(order_data.error_code == ERR_ZERO_TICKET)
      {
        switch(o_status)
        {
          case BUY_ORDER:
            BuyOrder.Canceled(true);
            Print(__FUNCTION__, ": Билет Buy ордера = 0");
          break;
          case SELL_ORDER:
            SellOrder.Canceled(true);
            Print(__FUNCTION__, ": Билет Sell ордера = 0");
          break;
        }
      }
      else
      {
        switch(o_status)
        {
          case BUY_ORDER:
            BuyOrder.mem_time = GetMicrosecondCount();
            Print(__FUNCTION__, ": Ошибка определения состояния Buy ордера! Билет = ", a_ticket, " Код ошибки: ", order_data.error_code,
                                " История: ", EnumToString(order_data.is_hystory));
          break;
          case SELL_ORDER:
            SellOrder.mem_time = GetMicrosecondCount();
            Print(__FUNCTION__, ": Ошибка определения состояния Sell ордера! Билет = ", a_ticket, " Код ошибки: ", order_data.error_code,
                                " История: ", EnumToString(order_data.is_hystory));
          break;
        }
      }
    break;
    case SELECT_BUSY:
      switch(o_status)
      {
        case BUY_ORDER:
          BuyOrder.mem_time = GetMicrosecondCount();
          Print(__FUNCTION__, ": Buy Ордер в переходном состоянии. Билет = ", a_ticket);
        break;
        case SELL_ORDER:
          SellOrder.mem_time = GetMicrosecondCount();
          Print(__FUNCTION__, ": Sell Ордер в переходном состоянии. Билет = ", a_ticket);
        break;
      }
    break;
    case SELECT_FALSE:
      switch(order_data.real_state)
      {
        case ORDER_NONE_CANCELED:
          switch(o_status)
          {
            case BUY_ORDER:
              BuyOrder.Canceled(true);
              Print(__FUNCTION__, ": Buy ордер отменён пользователем. Билет = ", a_ticket);
            break;
            case SELL_ORDER:
              SellOrder.Canceled(true);
              Print(__FUNCTION__, ": Sell ордер отменён пользователем. Билет = ", a_ticket);
            break;
          }
        break;
        case ORDER_NONE_EXPIRED:
          switch(o_status)
          {
            case BUY_ORDER:
              BuyOrder.Canceled(true);
              Print(__FUNCTION__, ": Buy ордер отменён по сроку. Билет = ", a_ticket);
            break;
            case SELL_ORDER:
              SellOrder.Canceled(true);
              Print(__FUNCTION__, ": Sell ордер отменён по сроку. Билет = ", a_ticket);
            break;
          }
        break;
        case ORDER_NONE_FILLED:
        case ORDER_NONE_PARTIAL:
        case ORDER_NONE_PARTIAL_CANCELED:
          PositionState();
          if((exp_state.prim_volume != exp_state.sec_volume) && (main_request_id == 0))
          {
            FastBuySell();
          }
          switch(o_status)
          {
            case BUY_ORDER:
              Print(__FUNCTION__, ": Сделка соверщена. Buy ордер. Билет = ", a_ticket);
              BuyOrder.Deal(true);
            break;
            case SELL_ORDER:
              Print(__FUNCTION__, ": Сделка соверщена. Sell ордер. Билет = ", a_ticket);
              SellOrder.Deal(true);
            break;
          }
        break;
        case ORDER_NONE_REJECTED:
          switch(o_status)
          {
            case BUY_ORDER:
              BuyOrder.Canceled(true);
              Print(__FUNCTION__, ": Buy ордер отменён Биржей(брокером). Билет = ", a_ticket);
            break;
            case SELL_ORDER:
              SellOrder.Canceled(true);
              Print(__FUNCTION__, ": Sell ордер отменён Биржей(брокером). Билет = ", a_ticket);
            break;
          }
        break;
      }
    break;
    case SELECT_TRUE:
      switch(order_data.real_state)
      {
        case ORDER_EXIST:
          switch(o_status)
          {
            case BUY_ORDER:
              BuyOrder.mem_time = GetMicrosecondCount();
              switch(BuyOrder.state)
              {
                case ORD_DO_SET:
                  BuyOrder.state = ORD_WORK;
                  Print(__FUNCTION__, ": Buy ордер установлен. Билет = ", a_ticket);
                break;
                case ORD_DO_MODIFY:
                  if(NormalizeDouble(BuyOrder.modify_price, Digits()) == NormalizeDouble(order_data.price_open, Digits()))
                  {
                    BuyOrder.state = ORD_WORK;
                    Print(__FUNCTION__, ": Buy ордер модифицирован. ", "Новая цена = ", order_data.price_open, " Билет = ", a_ticket);
                  }
                  else Print(__FUNCTION__, ": Buy ордер в процессе модификации. Билет = ", a_ticket);
                break;
                case ORD_DO_CANCEL:
                  Print(__FUNCTION__, ": Buy ордер в процессе удаления. Билет = ", a_ticket);
                break;
              }
            break;
            case SELL_ORDER:
              SellOrder.mem_time = GetMicrosecondCount();
              switch(SellOrder.state)
              {
                case ORD_DO_SET:
                  SellOrder.state = ORD_WORK;
                  Print(__FUNCTION__, ": Sell ордер установлен. Билет = ", a_ticket);
                break;
                case ORD_DO_MODIFY:
                  if(NormalizeDouble(SellOrder.modify_price, Digits()) == NormalizeDouble(order_data.price_open, Digits()))
                  {
                    SellOrder.state = ORD_WORK;
                    Print(__FUNCTION__, ": Sell ордер модифицирован. ", "Новая цена = ", order_data.price_open, " Билет = ", a_ticket);
                  }
                  else Print(__FUNCTION__, ": Sell ордер в процессе модификации. Билет = ", a_ticket);
                break;
                case ORD_DO_CANCEL:
                  Print(__FUNCTION__, ": Sell ордер в процессе удаления. Билет = ", a_ticket);
                break;
              } 
            break;
          }
        break;
        case ORDER_EXIST_PARTIAL:
          PositionState();
          if((exp_state.prim_volume != exp_state.sec_volume) && (main_request_id == 0))
          {
            FastBuySell();
            switch(o_status)
            {
              case BUY_ORDER:
                BuyOrder.mem_time = GetMicrosecondCount();
                BuyOrder.state = ORD_WORK;
                Print(__FUNCTION__, ": Сделка совершена. Buy ордер. Билет = ", BuyOrder.ticket);
              break;
              case SELL_ORDER:
                SellOrder.mem_time = GetMicrosecondCount();
                SellOrder.state = ORD_WORK;
                Print(__FUNCTION__, ": Сделка совершена. Sell ордер. Билет = ", SellOrder.ticket);
              break;
            }
          }
          else
          {
            switch(o_status)
            {
              case BUY_ORDER:
                BuyOrder.mem_time = GetMicrosecondCount();
                switch(BuyOrder.state)
                {
                  case ORD_DO_MODIFY:
                    Print(__FUNCTION__, ": Buy ордер в процессе модификации. Билет = ", a_ticket);
                  break;
                  case ORD_DO_CANCEL:
                    Print(__FUNCTION__, ": Buy ордер в процессе удаления. Билет = ", a_ticket);
                  break;
                }
              break;
              case SELL_ORDER:
                SellOrder.mem_time = GetMicrosecondCount();
                switch(SellOrder.state)
                {
                  case ORD_DO_MODIFY:
                    Print(__FUNCTION__, ": Sell ордер в процессе модификации. Билет = ", a_ticket);
                  break;
                  case ORD_DO_CANCEL:
                    Print(__FUNCTION__, ": Sell ордер в процессе удаления. Билет = ", a_ticket);
                  break;
                }
              break;
            }
          }
        break;
      }
    break;
  }
}

Вопрос:

Как выяснить, кто занялся фронтраннингом (Биржа (опять) или брокер)?

Добавлено

Если есть кто-то, кто торгует на ФОРТС в БКС или Финаме, то отзовитесь, есть ли такие задержки у них?

 
prostotrader #:

Печальные новости для тех, кто торгует на ФОРТС.

Похоже, что Биржа (или Открывашка) занялась фронтраннингом (Биржу уже наказывали за это)

Пример

Отсылаю асинхронный ордер

Далее советник ждет подтверждение об установке ордера.

В советнике есть механизм слежения за ордерами (функция ProcessOrders)

К сожалению, терминал не логирует ответ биржи при асинхронной отправке ордеров!

Считаем время от момента отправки ордера (2023.05.04 16:32:23.686)

до последней проверки (2023.05.04 16:32:41.162)

И видим, что ордер устанавливался аж ~8,5 СЕКУНДЫ !!!!!

Никакими задержками сети это объяснить невозможно.

Часть кода, где получаем SELECT_BUSY

Функция ProcessOrders

Вопрос:

Как выяснить, кто занялся фронтраннингом (Биржа (опять) или брокер)?

Добавлено

Если есть кто-то, кто торгует на ФОРТС в БКС или Финаме, то отзовитесь, есть ли такие задержки у них?

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

 
Aleksey Vyazmikin #:

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

Это уже не претензия а прототип обвинения!

Причина обращения: