Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам - страница 1781

 
MakarFX #:

Еще раз делаю акцент в чем разница

1 вариант

2 вариант

да. спасибо. я понял.

 
Mihail Matkovskij #:

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

OrderSelect

пробую.спасибо.

 
//+-----------------------------------------------------------------------------------------------+
//|                                                                     Simple Moving Average.mq4 |
//|                                                                                               |
//+-----------------------------------------------------------------------------------------------+
#property copyright "Copyright 2021"
#property link      "https://www.mql5.com/ru/users/"
#property version   "1.00"
#property strict

// Параметры советника
input string  sParametersEA = "";     // Параметры советника
input double  Lot           = 0.01;   // Количество лотов
input double  LotControl    = 0.01;   // Контрольная лотность
input int     StopLoss      = 30;     // Уровень убытка
input int     TakeProfit    = 30;     // Уровень прибыли
input int     Deviation     = 20;     // Отступ цены входа
input int     Slippage      = 3;      // Проскальзование (в пунктах)
input int     Magic         = 1;      // Индентификатор советника
input double  K_Martin1     = 2.0;    // Множитель мартин 1
input double  K_Martin2     = 2.0;    // Множитель мартин 2
input double  K_Martin3     = 2.0;    // Множитель мартин 3
input int     OrdersClose   = 5;      // Ограничение лотности мартин1
input int     OrdersClose2  = 5;      // Ограничение лотности мартин2
input int     DigitsLot     = 2;      // Точность лотности
// Параметры индикатора
input string  ParametersMA  = "";     // Параметры индикатора
input int     PeriodMA      = 14;     // Период мувинга
input int     MovingShift   = 1;      // Сдвиг мувинга
// Глобальные переменные
string AC;
datetime Start;
double dMA;
double MaxMartinLot;
double MaxMartinLot2;
double openPrice;   // цена открытия позиции
//+-----------------------------------------------------------------------------------------------+
int OnInit()
  {
Start          = TimeCurrent();
MaxMartinLot   = Lot*MathPow(1.4,OrdersClose);
MaxMartinLot2  = Lot*MathPow(K_Martin2,OrdersClose2);
AC             = StringConcatenate(" ", AccountCurrency());
return(INIT_SUCCEEDED);
  }
//+-----------------------------------------------------------------------------------------------+
void OnDeinit(const int reason)
  {

  }
//+-----------------------------------------------------------------------------------------------+
void OnTick()
{
// Получим значение индикатора
   dMA = iMA(Symbol(), 0,PeriodMA, MovingShift, MODE_SMA, PRICE_CLOSE, 0); // MODE_SMA - простое усреднение , значение 0. PRICE_CLOSE- цена закрытия, значение 0.
   
   if(GetLotSize()<LotControl)  openPrice = dMA;
   
    else 
    openPrice = dMA + Deviation * _Point;
// Если нет открытых ордеров, то входим в условие
   if(CountOrders()==0)
   {

// Если появился сигнал на покупку, то откроем ордер на покупку
      if(bSignalBuy() == true)
         vOrderOpenBuy();

// Если появился сигнал на продажу, то откроем ордер на продажу
      if(bSignalSell() == true)
         vOrderOpenSell();
   }
}
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция проверки открытых оредров |
//+-----------------------------------------------------------------------------------------------+
int CountOrders() 
  {
   int cnt=0;
   int i=OrdersTotal()-1;
   for(int pos=i;pos>=0;pos--)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol()==_Symbol)
           {
            if(OrderMagicNumber()==Magic) cnt++;
           }
        }
     }
   return(cnt);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
bool bSignalBuy()
  {
   if (openPrice > Open[1] && openPrice < Close[1]) //Open[1] и Close[1]- цены открытия и закрытия каждого бара текущего графика.
   
  return(true);
   
  return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на продажу |
//+-----------------------------------------------------------------------------------------------+
bool bSignalSell()
   
  {
   if(openPrice< Open[1] && openPrice > Close[1])

   return(true);

   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на покупку |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenBuy()
  {
// Тикет ордера
   int iOTi = 0;   

   iOTi = OrderSend(Symbol(), OP_BUY, LOT(), Ask, Slippage, 0, 0, "", Magic, 0, clrNONE);
   
// Проверим открылся ли ордер
   if(iOTi > 0)
// Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
// Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                            Функция открытия ордера на продажу |
//+-----------------------------------------------------------------------------------------------+
void vOrderOpenSell()
  {
// Тикет ордера  
   int iOTi = 0;   
//Print(bCheckOrders());
   iOTi = OrderSend(Symbol(), OP_SELL, LOT(), Bid, Slippage, 0, 0, "", Magic, 0, clrNONE);

// Проверим открылся ли ордер
   if(iOTi > 0)
// Есди да, то выставим уровни убытка и прибыли
      vOrderModify(iOTi);
   else
// Если нет, то получим ошибку
      vError(GetLastError());
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                    Функция модификации ордера |
//+-----------------------------------------------------------------------------------------------+
void vOrderModify(int iOTi)
  {
   int    iOTy = -1;    // Тип ордера
   double dOOP = 0;     // Цена открытия ордера
   double dOSL = 0;     // Стоп Лосс
   int    iMag = 0;     // Идентификатор советника
   double dSL  = 0;     // Уровень убытка
   double dTP  = 0;     // Уровень прибыли

// Выберем по тикету открытый ордер, получим некоторые значения
   if(OrderSelect(iOTi, SELECT_BY_TICKET, MODE_TRADES))
     {
      iOTy = OrderType();
      dOOP = OrderOpenPrice();
      dOSL = OrderStopLoss();
      iMag = OrderMagicNumber();
     }

// Если ордер открыл данный советник, то входим в условие
   if(OrderSymbol() == Symbol() && OrderMagicNumber() == iMag)
     {
// Если Стоп Лосс текущего ордера равен нулю, то модифицируем ордер
      if(dOSL == 0)
        {
         if(iOTy == OP_BUY)
           {
            dSL = NormalizeDouble(dOOP - StopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP + TakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }             
         if(iOTy == OP_SELL)
           {
            dSL = NormalizeDouble(dOOP + StopLoss * Point, Digits);
            dTP = NormalizeDouble(dOOP - TakeProfit * Point, Digits);

            bool bOM = OrderModify(iOTi, dOOP, dSL, dTP, 0, clrNONE);
           }
        }
     }
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                                      Функция обработки ошибок |
//+-----------------------------------------------------------------------------------------------+
void vError(int iErr)
  {
   switch(iErr)
     {
      case 129:   // Неправильная цена
      case 135:   // Цена изменилась
      case 136:   // Нет цен
      case 138:   // Новые цены
         Sleep(1000);
         RefreshRates();
         break;

      case 137:   // Брокер занят
      case 146:   // Подсистема торговли занята
         Sleep(3000);
         RefreshRates();
         break;
     }
  }
//+-----------------------------------------------------------------------------------------------+
double LOT()
{
   int n=0;
   int m=0;
   int v=0;
   double OL=Lot;
   for (int j = OrdersHistoryTotal()-1; j >= 0; j--)
   {
      if (OrderSelect(j, SELECT_BY_POS,MODE_HISTORY))
      {
         if (OrderSymbol() == Symbol() && OrderMagicNumber() == Magic)
         {
            if (OrderProfit()>0) 
            {

               if (n==0) OL=NormalizeDouble(OrderLots()+K_Martin1,DigitsLot);
               n++;
               
               if ((OL>=MaxMartinLot)&& (m==0)) OL=NormalizeDouble(OrderLots()*K_Martin2,DigitsLot);
               m++;
               
               if ((OL>=MaxMartinLot2) && (v==0)) OL=NormalizeDouble(OrderLots()*K_Martin3,DigitsLot);
               v++;
            }
            else
            {
               if (n==0) {return(Lot);}
               else {return(OL);}
            }
         }
      }
   }  
   return(OL);
}
//+------------------------------------------------------------------+
//|  Функция считает по символу и магику                             |
//|  размер лота с начала цикла                                      |
//+------------------------------------------------------------------+
double GetLotSize()
  {
   double Ls=0;
   datetime t=0;
   int i=OrdersHistoryTotal();
   for(int pos=0; pos<i; pos++)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime()) {t=OrderCloseTime(); Ls=OrderLots();}
              }
           }
        }
     }
   return Ls;
  }

переделал часть void OnTick()

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

в итоге работает с проблемами:

во первых тестирование на истории стало почти останавливаться после 500 сделок (1-2 сделки в мин). 

(начинается с нормальной скоростью, и далее идёт все медленнее и медленнее)

во вторых   Deviation подключается не после  (LotControl) а через один два шага после указанной лотности.

 
законопослушный гражданин #:

переделал часть void OnTick()

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

в итоге работает с проблемами:

во первых тестирование на истории стало почти останавливаться после 500 сделок (1-2 сделки в мин). 

(начинается с нормальной скоростью, и далее идёт все медленнее и медленнее)

во вторых   Deviation подключается не после  (LotControl) а через один два шага после указанной лотности.

Попробуй так:

убери из void OnTick()

// Получим значение индикатора
   dMA = iMA(Symbol(), 0,PeriodMA, MovingShift, MODE_SMA, PRICE_CLOSE, 0); // MODE_SMA - простое усреднение , значение 0. PRICE_CLOSE- цена закрытия, значение 0.
   
   if(GetLotSize()<LotControl)  openPrice = dMA;
   
    else 
    openPrice = dMA + Deviation * _Point;

и поставь здесь

//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
bool bSignalBuy()
  {
   dMA = iMA(Symbol(), 0,PeriodMA, MovingShift, MODE_SMA, PRICE_CLOSE, 0);
   openPrice = dMA + Deviation * _Point;
   if(GetLotSize()<LotControl) openPrice = dMA;
   if(openPrice > Open[1] && openPrice < Close[1]) //Open[1] и Close[1]- цены открытия и закрытия каждого бара текущего графика.
   
   return(true);
   
   return(false);
  }
//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на продажу |
//+-----------------------------------------------------------------------------------------------+
bool bSignalSell()
  {
   dMA = iMA(Symbol(), 0,PeriodMA, MovingShift, MODE_SMA, PRICE_CLOSE, 0);
   openPrice = dMA + Deviation * _Point;
   if(GetLotSize()<LotControl) openPrice = dMA;
   if(openPrice< Open[1] && openPrice > Close[1])

   return(true);

   return(false);
  }
 
MakarFX #:

Попробуй так:

убери из void OnTick()

и поставь здесь

аналогичный результат.

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

 
MakarFX #:

Попробуй так:

убери из void OnTick()

и поставь здесь

 сначала грешил на эту штуку:

double GetLotSize()
  {
   double Ls=0;
   datetime t=0;
   int i=OrdersHistoryTotal();
   for(int pos=0; pos<i; pos++)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_HISTORY))
        {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(t<OrderCloseTime()) {t=OrderCloseTime(); Ls=OrderLots();}
              }
           }
        }
     }
   return Ls;
  }

но два других сова с ней нормально работают на тестере

 
законопослушный гражданин #:

 сначала грешил на эту штуку:

С этой штукой все в порядке.

Я позже посмотрю твой код, напиши какой таймфрейм используешь в тестере и какую пару. Проверю будут ли тормоза у меня.

 
MakarFX #:

С этой штукой все в порядке.

Я позже посмотрю твой код, напиши какой таймфрейм используешь в тестере и какую пару. Проверю будут ли тормоза у меня.

да любую пару. 

я AUD/USD использую М15.

у меня такие же проблемы с вашим индикатором были (приложил)

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

double GetProfitFromStart()
  {
   double lp=0,cp=0;
   for(int i=0; i<OrdersHistoryTotal(); i++)
     {
      if(OrderSelect(i, SELECT_BY_POS, MODE_HISTORY))
        {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL)
              {
               if(Start<OrderCloseTime()) {lp+=OrderProfit()+OrderCommission()+OrderSwap();}
              }
           }
        }
     }
   for(int pos=OrdersTotal()-1;pos>=0;pos--)
     {
      if(OrderSelect(pos, SELECT_BY_POS, MODE_TRADES))
        {
         if(OrderSymbol()==_Symbol && OrderMagicNumber()==Magic)
           {
            if(OrderType()==OP_BUY || OrderType()==OP_SELL) {cp=OrderProfit()+OrderCommission()+OrderSwap();}
           }
        }
     }
   return(lp+cp);
  }
Файлы:
 
законопослушный гражданин #:

да любую пару. 

я AUD/USD использую М15.

у меня такие же проблемы с вашим индикатором были (приложил)

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

поменяй перебор ордеров

for (int i= OrdersHistoryTotal()-1; i>= 0; i--)
 
MakarFX #:

поменяй перебор ордеров

Ребят, как ни крути, но если не запоминаете значение индекса цикла на прошлой проверке, то у вас цикл бежит по всей имеющейся истории. И чем её больше, тем дольше цикл.

Причина обращения: