Close By. мт5

 

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

 

//функция ищет всречные ордера и закрывает только их. Одиночные не трогает
void fnCloseBy()
   {
      ulong tkt1=0,tkt2=0;
      string smb1="",smb2="";
      bool flag=false;
      ENUM_POSITION_TYPE type1=POSITION_TYPE_BUY,type2=POSITION_TYPE_BUY;
      
      while(!IsStopped()){
         tkt1=0;tkt2=0;
         smb1="";smb2="";
         flag=true;
         type1=POSITION_TYPE_BUY;type2=POSITION_TYPE_BUY;
         
         //Берём первый попавшийся ордер         
         for(int i=PositionsTotal()-1;i>=0;i--){
            smb1=PositionGetSymbol(i);
            //if (!lcSymbolChekLite(smb1)) continue; - здесь у меня идёт функция для проверка доступности торговли и т.д.
            tkt1=PositionGetTicket(i);
            type1=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
            
            //Берём второй символ
            for(int j=i-1;j>=0;j--){
               smb2=PositionGetSymbol(j);
               //if (!lcSymbolChekLite(smb2)) continue; - здесь у меня идёт функция для проверка доступности торговли и т.д.
               tkt2=PositionGetTicket(j);
               type2=(ENUM_POSITION_TYPE)PositionGetInteger(POSITION_TYPE);
               if (tkt1!=0 && tkt2!=0 && tkt1!=tkt2 && smb1==smb2 && type1!=type2)               
                  if (Ctrd.PositionCloseBy(tkt1,tkt2)){
                     Print("Закрываем:" +smb1+" тикет: "+(string)tkt1);
                     Print("Встречный:" +smb2+" тикет: "+(string)tkt2);                     
                     Print("Успешно");
                     flag=false;
                     break; 
                  }                       
                  else Print("Закрыть не получилось");
               
               tkt2=0;
               smb2="";
               type2=POSITION_TYPE_BUY;
            }             
            if (!flag) break;
         }     
         if (flag){
            Print("Встречных больше нет");
            break;
         }
      }
   }

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

 
Alexey Oreshkin:

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

 

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

Мне вот это не нравится, выделил жирным. А если встретится отложенник?

if (tkt1!=0 && tkt2!=0 && tkt1!=tkt2 && smb1==smb2 && type1!=type2) 

Я делал по другому, правда, для других целей, но и тут сгодится. Один раз пройтись по всем ордерам, данные по каждому ордеру писать в структуру, там нужно немного: тикет, прибыль (посчитанная со свопами и комиссией). Эти данные писать в два массива, на бай и на селл.

Потом массивы отсортировать по величине прибыли, так будет выгоднее закрывать.

Честно говоря, не мерял время выполнения ордерных функций, но такой подход явно будет быстрее и гибче. 

 
Alexey Volchanskiy:

Мне вот это не нравится, выделил жирным. А если встретится отложенник?

При чём тут отложенник ? для отложки встречка не нужна, её можно и так закрыть, на ней же никаких финансовых затрат нет всё равно. Это актуально только для маркетов.
Создать структуру тоже можно и потом закрыть всё по ней, но на глаз мне показалось что разница в скорости не такая большая чтобы создавать структуру, а код вырастет значительно., а соотвественно и баги.
 

Alexey Volchanskiy:

Честно говоря, не мерял время выполнения ордерных функций, но такой подход явно будет быстрее и гибче. 

Конечно будет быстрей, ведь контрагента не надо искать. А что касается спреда, так я очень сомневаюсь в экономии.
 
Alexey Oreshkin:

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

 

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

У вас не анализируется объем встречных. Логичнее сначала закрывать пары с одинаковыми объемами, чтобы не плодить "остатки", потом из оставшихся пары с максимальными объемами, чтобы количество остатков было минимально.
 
Alexey Viktorov:
Конечно будет быстрей, ведь контрагента не надо искать. А что касается спреда, так я очень сомневаюсь в экономии.
В нормальных ДЦ спред экономится на 50%, встречал одно западное ДЦ, где спред вообще обнулялся при закрытии 2-х встречных с одинаковыми лотами. 
 
Andrey Barinov:
У вас не анализируется объем встречных. Логичнее сначала закрывать пары с одинаковыми объемами, чтобы не плодить "остатки", потом из оставшихся пары с максимальными объемами, чтобы остатки были минимальны.
И я об этом, но пдля этого удобнее и быстрее заранее считать данные по всем ордерам и потом их анализировать. И никакого раздутия кода тут не будет, 5-6 дополнительных строчек максимум.
 
Alexey Volchanskiy:
И я об этом, но пдля этого удобнее и быстрее заранее считать данные по всем ордерам и потом их анализировать. И никакого раздутия кода тут не будет, 5-6 дополнительных строчек максимум.
В случае с остатками структуры надо будет перезаполнять, т.к в результате закрытия пары будет появляться новый ордер. В МТ4 он будет иметь новый тикет, в МТ5 тикет не меняется.
 
Alexey Viktorov:
Конечно будет быстрей, ведь контрагента не надо искать. А что касается спреда, так я очень сомневаюсь в экономии.

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

Andrey Barinov:
У вас не анализируется объем встречных. Логичнее сначала закрывать пары с одинаковыми объемами, чтобы не плодить "остатки", потом из оставшихся пары с максимальными объемами, чтобы остатки были минимальны.
Вот это грамотная мысль, сначала большие закрыть, чтобы не было остатков. Формирование остатков и последующее их закрытие наверняка даст значительную потерю скорости. 
Как изменю функцию так выложу новый вариант.
 
Andrey Barinov:
В случае с остатками структуры надо будет перезаполнять, т.к в результате закрытия пары будет появляться новый ордер. В МТ4 он будет иметь новый тикет, в МТ5 тикет не меняется.
Вот этого еще не знал, надо проверить
 
Alexey Volchanskiy:
Вот этого еще не знал, надо проверить
Я уже проверил :)