Нужна помощь со встречным закрытием в советнике

 

Приветствую.

Закрываю и удаляю все ордера и позы в советнике этим кодом:

void CloseAll(){
   for (int i=OrdersTotal()-1;i>=0;i--){
      if (!OrderSelect(i,SELECT_BY_POS))  continue;
      if (OrderSymbol()!=Symbol())        continue;
      ordertype=OrderType();
      Ticket  =OrderTicket();
      ORLot   =OrderLots();
      if(ordertype==0){//bay
            ES=OrderClose(Ticket,ORLot,MarketInfo(OrderSymbol(),MODE_BID),3,0);
            continue;
      }
      if(ordertype==1){//sell
            ES=OrderClose(Ticket,ORLot,MarketInfo(OrderSymbol(),MODE_ASK),3,0);
            continue;
      }
      if((ordertype==4)||(ordertype==5)){
            ES=OrderDelete(Ticket);
            continue;
      }
      }
}

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

Есть у кого-нибудь готовая функция для этого?  Заранее спасибо.

 
ALex2008:

Приветствую.

Закрываю и удаляю все ордера и позы в советнике этим кодом:

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

Наоборот: финансовый результат будет лучше (на величину спреда с одного закрытия), а стейт останется практически тем же самым (немножко пила уйдет)

 Есть у кого-нибудь готовая функция для этого?  Заранее спасибо.

К сожалению, одной функцией тут не обойтись, если, конечно, делать нормально, а не для тестера.

Алгоритм такой:

1. Собираем нужные ордера в массив. Использую для этого массив структур:

struct OrderInfo
{
   int      type;
   int      ticket;
   uint     seriesIndex;
   double   volume;
   double   openPrice;
};

 2. Вычисляем доминирующий объем:

double GetDominanceVolumeAndType(int &dominanceType)
{
   // Вычисление совокупных объемов Buy и Sell-ордеров
   double buyVolume = 0, sellVolume = 0;
   for (uint i = 0; i < m_ordersCnt; i++)
      if (m_orders[i].type == OP_BUY)
         buyVolume += m_orders[i].volume;
      else
         sellVolume += m_orders[i].volume;
         
   // Определение доминирующего объема
   // Доминирует Buy
   if (buyVolume > sellVolume)
   {
      dominanceType = OP_BUY;
      return buyVolume - sellVolume;
   }
   
   // Доминирует Sell
   if (sellVolume > buyVolume)
   {
      dominanceType = OP_SELL;
      return sellVolume - buyVolume;
   }
   
   // Нет доминанты
   return 0;
}

3. Если объемы встречных ордеров совокупно равны, то находим в списке ордеров два противоположных и закрываем их при помощи OrderCloseBy. Продолжаем до тех пор, пока не закроем все ордера.

4. Если объемы не равны, то сначала закрывается доминирующий объем, а потом только выполняется п. 3.

 

Последний (четвертый) пункт разбивается на несколько подзадач:

1. Найти в списке ордеров ордер, который точно равен доминирующему объему.

2. Если такой ордер есть, то закрываем его.

3. Если нет такого ордера, то ищем ордер с наибольшим объемом, но не большим, чем доминирующая величина, и закрываем его.

4. Повторяем закрытие доминирующего объема, пока он не исчезнет.

void CloseDominanceVolume(int dominanceType, double dominanceVolume)
{
   // Поиск ордера с точно таким же объемом
   int orderTicket = GetOrderTheSameVolume(dominanceType, dominanceVolume);
   if (orderTicket > 0)
      return <закрыть ордер orderTicket>;
      
   // Поиск ордера с наибольшим объемом
   orderTicket = GetOrderMaxVolume(dominanceType);
   return <закрыть ордер orderTicket>;
}
int GetOrderTheSameVolume(int dominanceType, double dominanceVolume)
{
   for (uint i = 0; i < m_ordersCnt; i++)
      if (m_orders[i].type == dominanceType && IsValuesEquals(m_orders[i].volume, dominanceVolume, SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP) / 10))
         return m_orders[i].ticket;
         
   return -1;
}
int GetOrderMaxVolume(int dominanceType)
{
   double maxVolume = 0;
   int orderTicket = -1;
   for (uint i = 0; i < m_ordersCnt; i++)
      if (m_orders[i].type == dominanceType && m_orders[i].volume > maxVolume)
      {
         maxVolume = m_orders[i].volume;
         orderTicket = m_orders[i].ticket;
      }
         
   return orderTicket;
}
bool IsValuesEquals(double first, double second, double delta)
{
   return (MathAbs(first - second) < delta);
}
Причина обращения: