Проблема с удвоением лота

 
Здравствуйте, уважаемые форумчане. Делаю советника, который будет удваивать лот после каждой убыточной сделки, но столкнулся с такой проблемой - почему-то лот удваивается с запозданием через одну сделку.

пример:
сделка 1. лот - 0,1   профит - +10
сделка 2. лот - 0,1   профит - -10 (отрицательная сделка, после нее следующий лот должен быть удвоенным)
сделка 3. лот - 0,1   профит - +10 (в этой сделке лот должен был удвоиться)
сделка 4. лот - 0,2   профит - +10 (но удвоился он почему-то здесь)


Помогите пожалуйста разобраться. За ранее огромное спасибо!


//+------------------------------------------------------------------+
//|                                                      Begemot.mq4 |
//|                                                        Begemot32 |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Begemot32"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict


extern double Lot; 
double OrPrice;         
double OrLots;         
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {



   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//---
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert start function                                             |
//+------------------------------------------------------------------+
int start()
{
  
  



 
  for(int i=0;i<OrdersTotal();i++)
   {
   if (OrderSelect(OrdersHistoryTotal()-1, SELECT_BY_POS, MODE_HISTORY)) // Выбираем последний ордер из истории.
     {
      OrPrice=OrderProfit(); //узнаем профит закрытого ордера
      OrLots=OrderLots();  //узнаем объем(лот)закрытого ордера
     }
   }
if(OrPrice<0) {           //если профит меньше нуля (отрицательный показатель) то..
 Lot=OrLots*2;       // ...умножаем лот на 2
         
 
 

                 if(OrdersTotal() == 0 && Open[0]<Close[0] && Close[0]==High[0]) // если нет ордеров и восходящая свеча то..
                   {
                   OrderSend(Symbol(), OP_BUY, Lot, Ask, 3, Ask-50*Point, Ask+50*Point); // открываем ордер на БАЙ с удвоенным лотом
                   }
                 else

                 
                 
                 
                if(OrdersTotal() == 0 && Open[0]>Close[0] && Close[0]==Low[0]) // если нет ордеров и нисходящая свеча то..
                  {
                  OrderSend(Symbol(), OP_SELL, Lot, Bid, 3, Bid+50*Point, Bid-50*Point); // открываем ордер на СЕЛЛ с удвоенным лотом
                  }
                else
                Print("ORDER NE USTANOVLEN!!!");
 
 }
 else // если последний ордер закрылся с положительным результатом (цена больше или равна нулю)то..




                 //ОТКРЫТИЕ ОРДЕРА НА ПОКУПКУ
                 if(OrdersTotal() == 0 && Open[0]<Close[0] && Close[0]==High[0]) // если нет ордеров и восходящая свеча то..
                   {
                   OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Ask-50*Point, Ask+50*Point); // открываем ордер на БАЙ
                   }
                 else
                 Print("BUY - ORDER NE USTANOVLEN!!!");
                                      




                //ОТКРЫТИЕ ОРДЕРА НА ПРОДАЖУ                      
                if(OrdersTotal() == 0 && Open[0]>Close[0] && Close[0]==Low[0]) // если нет ордеров и нисходящая свеча то..
                  {
                  OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, Bid+50*Point, Bid-50*Point); // открываем ордер на СЕЛЛ
                  }
                else
                Print("ORDER NE USTANOVLEN!!!");












  
  
   return(0);
}
 
BEGEMOT33:
Здравствуйте, уважаемые форумчане. Делаю советника, который будет удваивать лот после каждой убыточной сделки, но столкнулся с такой проблемой - почему-то лот удваивается с запозданием через одну сделку.

пример:
сделка 1. лот - 0,1   профит - +10
сделка 2. лот - 0,1   профит - -10 (отрицательная сделка, после нее следующий лот должен быть удвоенным)
сделка 3. лот - 0,1   профит - +10 (в этой сделке лот должен был удвоиться)
сделка 4. лот - 0,2   профит - +10 (но удвоился он почему-то здесь)


Помогите пожалуйста разобраться. За ранее огромное спасибо!


for(int i = OrdersHistoryTotal()-1; i>=0; i--)
     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))

дальше по времени закрытия 

 
pako:
for(int i = OrdersHistoryTotal()-1; i>=0; i--)
     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))

дальше по времени закрытия 

большое вам спасибо за ответ! уже все сделал
 
pako:
for(int i = OrdersHistoryTotal()-1; i>=0; i--)
     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))

дальше по времени закрытия 

попробовал ваш код подставить, но теперь почему-то вообще перестал удваивать лот


//+------------------------------------------------------------------+
//|                                                      Begemot.mq4 |
//|                                                        Begemot32 |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Begemot32"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict


extern double Lot; 
double OrPrice;         
double OrLots;         
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {



   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//---
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert start function                                             |
//+------------------------------------------------------------------+
int start()
{
  
  

for(int i = OrdersHistoryTotal()-1; i>=0; i--)
     {

      if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY)) // Выбираем последний ордер из истории.
     {
      OrPrice=OrderProfit(); //узнаем профит закрытого ордера
      OrLots=OrderLots();  //узнаем объем(лот)закрытого ордера
     }
   }
if(OrPrice<0) {           //если профит меньше нуля (отрицательный показатель) то..
 Lot=OrLots*2;       // ...умножаем лот на 2
         
 
 

                 if(OrdersTotal() == 0 && Open[0]<Close[0] && Close[0]==High[0]) // если нет ордеров и восходящая свеча то..
                   {
                   OrderSend(Symbol(), OP_BUY, Lot, Ask, 3, Ask-100*Point, Ask+100*Point); // открываем ордер на БАЙ с удвоенным лотом
                   }
                 else

                 
                 
                 
                if(OrdersTotal() == 0 && Open[0]>Close[0] && Close[0]==Low[0]) // если нет ордеров и нисходящая свеча то..
                  {
                  OrderSend(Symbol(), OP_SELL, Lot, Bid, 3, Bid+100*Point, Bid-100*Point); // открываем ордер на СЕЛЛ с удвоенным лотом
                  }
                else
                Print("ORDER NE USTANOVLEN!!!");
 
 }
 else // если последний ордер закрылся с положительным результатом (цена больше или равна нулю)то..




                 //ОТКРЫТИЕ ОРДЕРА НА ПОКУПКУ
                 if(OrdersTotal() == 0 && Open[0]<Close[0] && Close[0]==High[0]) // если нет ордеров и восходящая свеча то..
                   {
                   OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Ask-100*Point, Ask+100*Point); // открываем ордер на БАЙ
                   }
                 else
                 Print("BUY - ORDER NE USTANOVLEN!!!");
                                      




                //ОТКРЫТИЕ ОРДЕРА НА ПРОДАЖУ                      
                if(OrdersTotal() == 0 && Open[0]>Close[0] && Close[0]==Low[0]) // если нет ордеров и нисходящая свеча то..
                  {
                  OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, Bid+100*Point, Bid-100*Point); // открываем ордер на СЕЛЛ
                  }
                else
                Print("ORDER NE USTANOVLEN!!!");












  
  
   return(0);
}
 
BEGEMOT33:

попробовал ваш код подставить, но теперь почему-то вообще перестал удваивать лот


Этот код будет определять всегда прибыль и цену открытия ПЕРВОГО (самого старого) ордера в истории, а это, как правило, внесение денег на счёт и профит его тупо не может быть отрицательным. Следовательно, удвоения никогда не будет )))

Из цикла надо организовать выход сразу после  нахождения последнего своего закрытого ордера. А уже потом по усмотрению.

 
не могу понять как это сделать, помогите пожалуйста если у вас есть возможность
 
BEGEMOT33:
не могу понять как это сделать, помогите пожалуйста если у вас есть возможность

Для тестера пойдёт и так:

 for(int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
      {
       if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic && OrderType()<2)
         {
          OrPrice=OrderProfit(); //узнаем профит закрытого ордера
          OrLots=OrderLots();  //узнаем объем(лот)закрытого ордера
          break;
         }
      }
   }
 

теперь даже не компилируется)

ошибка - Magic - undeclared identifier

код подставил так

//+------------------------------------------------------------------+
//|                                                      Begemot.mq4 |
//|                                                        Begemot32 |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Begemot32"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict


extern double Lot; 
double OrPrice;         
double OrLots;         
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
  {



   return(0);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
  {
//---
   
//---
   return(0);
  }
//+------------------------------------------------------------------+
//| Expert start function                                             |
//+------------------------------------------------------------------+
int start()
{
  
  
 for(int i=OrdersHistoryTotal()-1; i>=0; i--)
   {
    if(OrderSelect(i,SELECT_BY_POS,MODE_HISTORY))
      {
       if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
         {
          OrPrice=OrderProfit(); //узнаем профит закрытого ордера
          OrLots=OrderLots();  //узнаем объем(лот)закрытого ордера
          break;
         }
      }
   }


if(OrPrice<0) {           //если профит меньше нуля (отрицательный показатель) то..
 Lot=OrLots*2;       // ...умножаем лот на 2
         
 
 

                 if(OrdersTotal() == 0 && Open[0]<Close[0]) // если нет ордеров и восходящая свеча то..
                   {
                   OrderSend(Symbol(), OP_BUY, Lot, Ask, 3, Ask-40*Point, Ask+40*Point); // открываем ордер на БАЙ с удвоенным лотом
                   }
                 else

                 
                 
                 
                if(OrdersTotal() == 0 && Open[0]>Close[0]) // если нет ордеров и нисходящая свеча то..
                  {
                  OrderSend(Symbol(), OP_SELL, Lot, Bid, 3, Bid+40*Point, Bid-40*Point); // открываем ордер на СЕЛЛ с удвоенным лотом
                  }
                else
                Print("ORDER NE USTANOVLEN!!!");
 
 }
 else // если последний ордер закрылся с положительным результатом (цена больше или равна нулю)то..




                 //ОТКРЫТИЕ ОРДЕРА НА ПОКУПКУ
                 if(OrdersTotal() == 0 && Open[0]<Close[0]) // если нет ордеров и восходящая свеча то..
                   {
                   OrderSend(Symbol(), OP_BUY, 0.1, Ask, 3, Ask-40*Point, Ask+40*Point); // открываем ордер на БАЙ
                   }
                 else
                 Print("BUY - ORDER NE USTANOVLEN!!!");
                                      




                //ОТКРЫТИЕ ОРДЕРА НА ПРОДАЖУ                      
                if(OrdersTotal() == 0 && Open[0]>Close[0]) // если нет ордеров и нисходящая свеча то..
                  {
                  OrderSend(Symbol(), OP_SELL, 0.1, Bid, 3, Bid+40*Point, Bid-40*Point); // открываем ордер на СЕЛЛ
                  }
                else
                Print("ORDER NE USTANOVLEN!!!");












  
  
   return(0);
}
 

тогда может лучше подскажите в чем проблема у этого кода, это такой же советник по принципу действия. Проблема с ним такая - в тестере он почему-то работает без проблем, а вот на реальном графике он не открывает ордера, пробовал и на 4х и на 5и знаке, ставил минимальный лот, увеличивал лося и профит до 300, но ни как не хочет работать

//+------------------------------------------------------------------+
//|                                                      Begemot.mq4 |
//|                                                        Begemot32 |
//|                                              https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Begemot32"
#property link      "https://www.mql5.com"
#property version   "1.00"
#property strict
#define MAGIC  49274975

extern double Lot             = 0.01;   // Лот
extern int    StopLoss        = 10;    // Стоп Лосс
extern int    TakeProfit      = 10;    // Тейк Профит
extern double Multiplier      = 2;     // Множитель лота
extern int    Slippage        = 3;     // Проскальзывание

int ticket; 
double SL, TP;
bool UpBar = false, DownBar = false;
datetime PrevTime;
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int init()
{
   if (Digits == 3 || Digits == 5)
   {
      StopLoss   *= 10;
      TakeProfit *= 10;
      Slippage   *= 10;
   }
   return(0);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
int deinit()
{

   return(0);
}
//+------------------------------------------------------------------+
//| Expert start function                                             |
//+------------------------------------------------------------------+
int start()
{
    if (PrevTime == Time[0]) return(0);
    PrevTime = Time[0];
  
    if (Open[1] < Close[1]) UpBar   = true;
       else UpBar = false;
    if (Open[1] > Close[1])  DownBar = true;
       else DownBar = false;
   
   if (LossOrder(GetLastOrderHist()) < 0)  //если профит меньше нуля (отрицательный показатель) то..
   {
      double maxlot  = MarketInfo(Symbol(), MODE_MAXLOT);  //...расчитываем максимально допустимый лот,
      double lastlot = NormalizeDouble(LotLossOrder(GetLastOrderHist()) * Multiplier, 2);  // нормализируем умноженный лот на множитель
      if (lastlot > maxlot) lastlot = maxlot;  // если лот превышает максимальный то он равняется ему
      if (CountTrades() == 0 && UpBar == true) // если нет ордеров и восходящая свеча то..
      {
         SL = NormalizeDouble(Ask - StopLoss*Point, Digits);   // ...расчитываем стоп лосс
         TP = NormalizeDouble(Ask + TakeProfit*Point, Digits); // ...расчитываем тейк профит
         ticket = OrderSend(Symbol(), OP_BUY, lastlot, Ask, Slippage, SL, TP, "", MAGIC); // открываем ордер на БАЙ с удвоенным лотом
      }
      else if(CountTrades() == 0 && DownBar == true) // если нет ордеров и нисходящая свеча то..
      {
         SL = NormalizeDouble(Bid + StopLoss*Point, Digits);   // ...расчитываем стоп лосс
         TP = NormalizeDouble(Bid - TakeProfit*Point, Digits); // ...расчитываем тейк профит
         ticket = OrderSend(Symbol(), OP_SELL, lastlot, Bid, Slippage, SL, TP, "", MAGIC); // открываем ордер на БАЙ с удвоенным лотом
      }
   }
   else // если последний ордер закрылся с положительным результатом (цена больше или равна нулю)то..
   {
   //ОТКРЫТИЕ ОРДЕРА НА ПОКУПКУ
   if(CountTrades() == 0 && UpBar == true) // если нет ордеров и восходящая свеча то..
   {
      SL = NormalizeDouble(Ask - StopLoss*Point, Digits);   // ...расчитываем стоп лосс
      TP = NormalizeDouble(Ask + TakeProfit*Point, Digits); // ...расчитываем тейк профит
      ticket = OrderSend(Symbol(), OP_BUY, Lot, Ask, Slippage, SL, TP, "", MAGIC); // открываем ордер на БАЙ
   }
                                      
   //ОТКРЫТИЕ ОРДЕРА НА ПРОДАЖУ                      
   if(CountTrades() == 0 && DownBar == true) // если нет ордеров и нисходящая свеча то..
   {
      SL = NormalizeDouble(Bid + StopLoss*Point, Digits);   // ...расчитываем стоп лосс
      TP = NormalizeDouble(Bid - TakeProfit*Point, Digits); // ...расчитываем тейк профит
      ticket = OrderSend(Symbol(), OP_SELL, Lot, Bid, Slippage, SL, TP, "", MAGIC); // открываем ордер на БАЙ с удвоенным лотом
   }
   }


   return(0);
}

//+------------------------------------------------------------------+
//| Количество открытых сделок                                       |
//+------------------------------------------------------------------+
int CountTrades()
{
  int count = 0;
  for (int i = OrdersTotal()-1; i>=0; i--)
  {
    if(OrderSelect(i,SELECT_BY_POS, MODE_TRADES))
    {
      if(OrderSymbol() == Symbol() && OrderMagicNumber() == MAGIC)
        count++;
    }
  }
  return(count);
}

//+------------------------------------------------------------------+
//| Возвращает тикет последнего ордера истории                       |
//+------------------------------------------------------------------+
int GetLastOrderHist(int type = -1) 
{
  int iticket = -1;
  datetime dt = 0;
  int cnt = OrdersHistoryTotal();
    
  for (int i=0; i < cnt; i++) {
    if (!OrderSelect(i, SELECT_BY_POS, MODE_HISTORY)) continue;

    //Опционально
    if (OrderSymbol() != Symbol()) continue;
    if (OrderMagicNumber() != MAGIC) continue;
    
    if (type != -1 && OrderType() != type) continue;
    
    if (OrderCloseTime() > dt) {
      dt = OrderCloseTime();
      iticket = OrderTicket();
    }
  }
  
  return (iticket);
}

//+------------------------------------------------------------------+
//| Возвращает профит ордера истории за тикетом                      |
//+------------------------------------------------------------------+
double LossOrder(int iticket){
//------------вспомогательные переменные-----------
   int cnt, total;
   double profit = 0;
//-------------------------------------------------
   total=OrdersHistoryTotal();//общее количество рыночных и отложенных ордеров истории
   for(cnt=total-1;cnt>=0;cnt--)//цикл по ордерам
   {
      if(!OrderSelect(iticket, SELECT_BY_TICKET, MODE_HISTORY))
      {
         Print("Ошибка выбора ордера ", GetLastError());
         return(-1);
      }
      if(OrderType()==OP_BUY)// нашли  ордер Buy
      {
         //определение убытка в пунктах для длинной позиции
         profit = OrderProfit(); 
      }
      if(OrderType()==OP_SELL)// нашли  ордер Sell
      {
         //определение убытка в пунктах для короткой позиции
         profit = OrderProfit();
      }
   }//конец цикла по ордерам
   return(profit);
}

//+------------------------------------------------------------------+
//| Возвращает лот ордера истории за тикетом                         |
//+------------------------------------------------------------------+
double LotLossOrder(int iticket){
//------------вспомогательные переменные-----------
   int cnt, total;
   double lot = 0;
//-------------------------------------------------
   total=OrdersHistoryTotal();//общее количество рыночных и отложенных ордеров истории
   for(cnt=total-1;cnt>=0;cnt--)//цикл по ордерам
   {
      if(!OrderSelect(iticket, SELECT_BY_TICKET, MODE_HISTORY))
      {
         Print("Ошибка выбора ордера ", GetLastError());
         return(-1);
      }
      if(OrderType()==OP_BUY)// нашли  ордер Buy
      {
         //определение убытка в пунктах для длинной позиции
         lot = OrderLots(); 
      }
      if(OrderType()==OP_SELL)// нашли  ордер Sell
      {
         //определение убытка в пунктах для короткой позиции
         lot = OrderLots();
      }
   }//конец цикла по ордерам
   return(lot);
}
 

Ну так не используете магик - уберите его из кода, вот этот кусок, который я вычеркнул:

if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic && OrderType()<2)
 
большое вам спасибо за помощь!
Причина обращения: