Чередование открытия ордеров

 

Всем привет!

кто знает – можно ли задать жесткое чередование открытия ордеров по типам?
Пример:
По условиям открытия - открылся ордер бай, закрылся как положено. Следующий ордер может быть только селл, а после его закрытия - только бай и т.д. Если после закрытия ордера бай возникают условия для повторного открытия бай, то ордер не открывается, а система ждет до тех пор, пока не появиться условия селл. И так далее в режиме чередования. (Вариант с зеркальными условиями открытия-закрытия не подходит)

 
waitra >>:

Всем привет!

кто знает – можно ли задать жесткое чередование открытия ордеров по типам?

Можно, конечно. Ищем последний закрытый _свой_ ордер в истории и смотрим его тип.
 
TheXpert писал(а) >>
Можно, конечно. Ищем последний закрытый _свой_ ордер в истории и смотрим его тип.

Спасибо! А как будет код выглядеть? Есть где-то образец подобного обращения?

Может за деньги мне кто напишет?

 
waitra >>:

Спасибо! А как будет код выглядеть? Может, есть где-то образец подобного обращения?

Например, так:

int LastType(int MN = -1)
{
   datetime max = 0;
   int ticket = -1;
   
   for(int i = 0; i < OrdersHistoryTotal(); i++)
   {
      // already closed
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY) == false) continue;
      // not current symbol
      if(OrderSymbol() != Symbol()) continue;
      // order was opened in another way
      if(OrderMagicNumber() != MN && MN != -1) continue;

      if(OrderType() != OP_BUY && OrderType() != OP_SELL) continue;
      
      datetime current = OrderCloseTime();
      
      if (current > max) 
      {
         max = current;
         ticket = OrderTicket();
      }
   }
   
   if (!OrderSelect(ticket, SELECT_BY_TICKET, MODE_HISTORY)) return (-1);
   
   return (OrderType());
}

И пользуем:

{
   if (/*sell condition*/)
   {
      //close buys
      
      int lastType = LastType(MyMagic);
      if (lastType == OP_BUY || lastType == -1)
      {
         //sell
      }
   }
   
   if (/*buy condition*/)
   {
      //close sells
      
      lastType = LastType(MyMagic);
      if (lastType == OP_SELL || lastType == -1)
      {
         //buy
      }
   }
}
 
TheXpert писал(а) >>

Например, так:

И пользуем:

- Спасибо большое! Поробую :-)
 
waitra >>:
- Спасибо большое! Поробую :-)

Ааа, забыл одну вещь. Код может возвращать -1, это надо адекватно обрабатывать.

 
TheXpert:

Ааа, забыл одну вещь. Код может возвращать -1, это надо адекватно обрабатывать.

Помогите адекватно обработать в этом коде

// ---
void OnTick()
{
    // ---
    // закрытие сделки
    if(find_orders(_MagicNumber))
    {
        if(cl_buy_sig())
        {
            cbm(_MagicNumber, _Slippage, OP_BUY);
        }
        if(cl_sell_sig())
        {
            cbm(_MagicNumber, _Slippage, OP_SELL);
        }
    }
   
    // открытие сделки
    // ---
    get_lots_by_percent(Ask, Ask-_SL*K_DIG*Point);
    // ---
    if(!find_orders(_MagicNumber, (_OnlyOneOpenedPos ? -1 : OP_BUY)))
    {
        if(op_buy_sig() && LAST_BUY_BARTIME != iTime(Symbol(), Period(), 0))
        {
            LAST_BUY_BARTIME = iTime(Symbol(), Period(), 0);
            open_positions(OP_BUY, OP_LOTS);   
        }
    }
    // ---
    if(!find_orders(_MagicNumber, (_OnlyOneOpenedPos ? -1 : OP_SELL)))
    {
        if(op_sell_sig() && LAST_SELL_BARTIME != iTime(Symbol(), Period(), 0))
        {
            LAST_SELL_BARTIME = iTime(Symbol(), Period(), 0);
            open_positions(OP_SELL, OP_LOTS);   
        }
    }
    // ---
    T_SL();
    // ---
    nonLoss();
}

// ---

// ---
void get_lots_by_percent(double op_price, double sl_price)
{
    // MQL4 | объём сделки рассчитывается по значению SL и допустимому проценту потерь
    RefreshRates();
    if(_SL == 0)
    {
        OP_LOTS = MarketInfo(Symbol(), MODE_MINLOT);
        return;
    }
    // ---
    int pp;
    if (op_price < sl_price)
        pp = int((sl_price - op_price) / Point);
    else
        pp = int((op_price - sl_price) / Point);
    OP_LOTS = (((AccountBalance() * _LosPercent) / 100) / MarketInfo(Symbol(), MODE_TICKVALUE)) / (pp);
    OP_LOTS = MathRound(OP_LOTS / MarketInfo(Symbol(), MODE_LOTSTEP)) * MarketInfo(Symbol(), MODE_LOTSTEP);
    OP_LOTS = MathMax(OP_LOTS, MarketInfo(Symbol(), MODE_MINLOT));
    OP_LOTS = MathMin(OP_LOTS, MarketInfo(Symbol(), MODE_MAXLOT));
}

// ---
// ---
bool find_orders(int magic = -1, int type = -1, int time = -1, string symb = "NULL", double price = -1, double lot = -1)
{
    // MQL4 | функция поиска открытых ордеров
    // возвращает истину, если найден хотя бы один ордер с подходящими параметрами
    for (int i = OrdersTotal() - 1; i >= _OR; i--)
    {
        if (!OrderSelect(i, SELECT_BY_POS, MODE_TRADES))
            break;
        if (((OrderType() == type) || (type == -1))
            && ((OrderMagicNumber() == magic) || (magic == -1))
            && ((OrderSymbol() == symb) || (symb == "NULL" && OrderSymbol() == Symbol()))
            && ((OrderOpenTime() >= time) || (time == -1))
            && ((OrderLots() == lot) || (lot == -1))
            && ((NormalizeDouble(OrderOpenPrice(), Digits) == NormalizeDouble(price, Digits)) || (price == -1)))
        {
            return (true);
            break;
        }
    }
    return (false);
}

// ---
 

Не надо для этого километровых кодов написать.

Достаточно держать один признак, который принимает значения 1 и 2 (допустим для селл-1, для бай-2) и при открытии ордера проверить этот признак и поменять значение.

Это всего несколько строк.

 
Petros Shatakhtsyan:

Не надо для этого километровых кодов написать.

Достаточно держать один признак, который принимает значения 1 и 2 (допустим для селл-1, для бай-2) и при открытии ордера проверить этот признак и поменять значение.

Это всего несколько строк.

Это всё более чем понятно )

Просто у меня не хочет работать, вот и обратился за помощью.

Если несколько строк, то не смогли бы Вы дополнить код выше этими строками? )

 
Vadim Zhuravlev:

Это всё более чем понятно )

Просто у меня не хочет работать, вот и обратился за помощью.

Если несколько строк, то не смогли бы Вы дополнить код выше этими строками? )

// открытие сделки 
// --- 
   get_lots_by_percent(Ask,Ask-_SL*K_DIG*Point);
// --- 
   if(!find_orders() && GlobalVariableGet("oper")==1)
     {
      if(op_buy_sig() && LAST_BUY_BARTIME!=iTime(Symbol(),Period(),0))
        {
         LAST_BUY_BARTIME=iTime(Symbol(),Period(),0);
         open_positions(OP_BUY,OP_LOTS);
         GlobalVariableSet("oper",0);
        }
     }
// --- 
   if(!find_orders() && GlobalVariableGet("oper")==0)
     {
      if(op_sell_sig() && LAST_SELL_BARTIME!=iTime(Symbol(),Period(),0))
        {
         LAST_SELL_BARTIME=iTime(Symbol(),Period(),0);
         open_positions(OP_SELL,OP_LOTS);
         GlobalVariableSet("oper",1);
        }
     }
Помогли на другом форуме
Причина обращения: