Не простой вопрос .....

 

Идет серия закрытых ордеров прибыльный, прибыльный, убыточный, убыточный, убыточный, прибыльный.

Как найти последние 2 убыточных ордера ...

То есть определится ... если последние два закрылись в минус то ........

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

если последние два в прибыль то ничего не делаем ...

Ломаю голову уже месяц над этой арифметикой ....

Прошу помощи у спецов .

 
  datetime or1      =  0;
   int      orTic1   =  -1,orTic2=  -1;
   int      profit   =  0;
   for(int i=OrdersHistoryTotal()-1;i>=0;i--)
      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
      {
         if(NormalizeDouble(OrderProfit(),Digits)==0)continue;         
         if(OrderType()>OP_SELL)continue;

         if(OrderCloseTime()!=0)
         {
            if(or1==0)
            {
               or1      =  OrderCloseTime();
               orTic1   =  OrderTicket();            
               if(OrderProfit()>0)profit= profit+1;else profit=profit -1;
            }else{
               orTic2   =  OrderTicket();            
               if(OrderProfit()>0)profit= profit+1;else profit=profit -1;
               break;
            }
         }
      }     

   if(orTic1!=-1 && orTic2!=-1)      
   {
      if(OrderSelect(orTic1,SELECT_BY_TICKET))
         OrderPrint();
      if(OrderSelect(orTic2,SELECT_BY_TICKET))
         OrderPrint();
      if(profit>1)
         Print("Оба +");
      if(profit<-1)
         Print("Оба -");
      if(profit==0)
         Print(" закрыты в разный профит");
   }else{
      Print("Нет в истории.");
   }
   
 
   int hist = OrdersHistoryTotal();
   if (hist == 0) return (MinLot);
   
   double fr = NormalizeDouble(AccountFreeMargin()*RiskFree/1000,1);
   double ls = MathMin(OrderLots() + Risk, MaxLot);
   double pr = MathMin(OrderLots() - Risk, MaxLot);
   double db = MathMin(OrderLots() * 2, MaxLot);  

   for (int i = 0; i < hist; i++) {
      OrderSelect(i, SELECT_BY_POS, MODE_HISTORY);
      if (OrderSymbol() == Symbol() && OrderMagicNumber() == magic) 
      {
         if (OrderProfit() > 0 ) { losses = 0; profit++;} 
         if (OrderProfit() < 0 ) { profit = 0; losses++;}
      } 
         if ( LotSizeF == true  && ((losses < StepLosses) || (profit < StepProfit)) )    { lot = fr;}  
         if ( LotSizeF == false && ((losses < StepLosses) || (profit < StepProfit)) )    { lot = MinLot;} 
         if ( LotSizeP == true  &&  profit >= StepProfit )                               { lot = pr;}
         if ( LotSizeL == true  &&  losses >= StepLosses )                               { lot = ls;}
         if ( LotSizeD == true  &&  losses >= StepLosses )                               { lot = db;} 
      }
         if(lot<MinLot) lot=MinLot;
         if(lot>MaxLot) lot=MaxLot;  
....я так делал...
 

Зачем же месяц тратить? Спросили бы. Вам просто не понятен алгоритм, как найти эти 2 убыточных ордера.

Организуем цикл, перебирающий ордера. Причём нужно чтоб он их перебирал от конца в начало вот так:

for(int i=OrdersHistoryTotal()-1;i>=0;i--){
  if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)){
    Print("Ошибка № ",GetLastError()," при выборе ордера истории № ",i);
  }
  else{
  }

В else пишем условие, мол если профит ордера менее нуля, то запоминаем его профит (или тикет) и увеличиваем обнулённый перед циклом счётчик ордеров на 1. На следующей итерации цикла советник возьмёт предшествующий этому ордер (предпоследний в списке). Тут мы смотрим, если он тоже имеет профит менее нуля, то объявленную заранее, скажем, булеву переменную ставим в положение истина. Иначе в положение ложь. Этого вполне достаточно чтоб вычислить были ли последние два ордера убыточными, или нет.

double ProfitLastOrdera=0;  bool Oba_V_Minuse=false; int CountOrders=0;
for(int i=OrdersHistoryTotal()-1;i>=0;i--){
  if(!OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)){
    Print("Ошибка № ",GetLastError()," при выборе ордера истории № ",i);
  }
  else{
    CountOrders++;// увеличиваем счётчик на 1
    if(CountOrders>2){
      break;// это уже третий из последних ордеров - прерываем цикл
    }    
    if(CountOrders==1){
      ProfitLastOrdera=OrderProfit();
    }
    else{// иначе это второй ордер
      if(OrderProfit()<0 && ProfitLastOrdera<0{
        Oba_V_Minuse=true;
      }
     else{
       Oba_V_Minuse=false;
    }
  }
}
 
drknn:

Зачем же месяц тратить? Спросили бы. Вам просто не понятен алгоритм, как найти эти 2 убыточных ордера.

Организуем цикл, перебирающий ордера. Причём нужно чтоб он их перебирал от конца в начало вот так:

В else пишем условие, мол если профит ордера менее нуля, то запоминаем его профит (или тикет) и увеличиваем обнулённый перед циклом счётчик ордеров на 1. На следующей итерации цикла советник возьмёт предшествующий этому ордер (предпоследний в списке). Тут мы смотрим, если он тоже имеет профит менее нуля, то объявленную заранее, скажем, булеву переменную ставим в положение истина. Иначе в положение ложь. Этого вполне достаточно чтоб вычислить были ли последние два ордера убыточными, или нет.

а если количество убыточных ордеров больше 2 или задается в ручную в водимых параметрах ??? Как тут быть ???

Можно ли использовать такой код ???

  int      totalh=OrdersHistoryTotal();
  int      z=0;
  int      min = 0 ;
 for (int is=totalh-1; is>=0; is--)
   {
    if(OrderSelect(is, SELECT_BY_POS,MODE_HISTORY))
     {
      if(OrderSymbol()==Symbol()&&OrderMagicNumber()==Magic)
       {  z++;
        if ( OrderProfit() < 0 && z<Perevorot )// если профит меньше 0 и количество переборов меньше заданного количества убытков
        {
         min++; // увеличить на 1
        }
        if ( min == Perevorot ) если колличество убытков равно заданному изменить флаг остановить цикл 
        {
         flag = 1 ;        
         break;
        }
        if ( OrderProfit() > 0 ) //если из колличества ордеров перебора было убытков меньше заданного и появился прибыльный обнулить счетчик
        {
         min=0;
        }        
       }
     }
   }
 
VOLDEMAR:

а если количество убыточных ордеров больше 2 или задается в ручную в водимых параметрах ??? Как тут быть ???

Можно ли использовать такой код ???

 


Самое лучшее, что тут можно сделать - это детально продумать код. Продумать самостоятельно!
 
Мне бы знать, которые из них последние:) В авиации обычно о крайних говорят ... 
 
VOLDEMAR:

а если количество убыточных ордеров больше 2 или задается в ручную в водимых параметрах ??? Как тут быть ???

Можно ли использовать такой код ??? 

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

bool fCheck_IsLoss (int fi_Perevorot)
{
    int totalh = OrdersHistoryTotal(), z = 0;
//----
    for (int is = totalh - 1; is >= 0; is--)
    {
        if (!OrderSelect (is, SELECT_BY_POS, MODE_HISTORY)) continue;
        if (OrderSymbol() != Symbol()) continue;
        if (OrderMagicNumber() != Magic) continue;
        if (OrderType() > 1) continue;
        //--- Если профит меньше 0 (убыточный)
        if (OrderProfit() < 0.0)
        {
            z++; // увеличить на 1
            //---- Если количество убытков равно заданному - выход
            if (z == fi_Perevorot) return (true);
            continue;
        }
        return (false);
    }
//----
    return (false);
}
Причина обращения: