Cualquier pregunta de los recién llegados sobre MQL4 y MQL5, ayuda y discusión sobre algoritmos y códigos - página 1781

 
MakarFX #:

Una vez más, subrayo la diferencia

1 variante

2 variantes.

Sí. Gracias. Lo tengo.

 
Mihail Matkovskij #:

Intenta entender lo que estás codificando en lugar de copiar ciegamenteOrdersTotal,OrdersHistoryTotal,

OrderSelect

Lo intentaré.

 
//+-----------------------------------------------------------------------------------------------+
//|                                                                     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;
  }

rehacer la parte void OnTick()

para que cuando se alcance un determinado lote (LotControl), se añada un número determinado de puntos a la señal (el parámetro Deviation)

Como resultado, funciona con problemas:

en primer lugar las pruebas en la historia comenzó a casi detener después de 500 oficios (1-2 oficios por min).

(comienza con una velocidad normal, y luego va cada vez más lento)

En segundo lugar, la desviación no se conecta después de (LotControl) sino en uno o dos pasos después del lote especificado.

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

rehacer la parte void OnTick()

para que cuando se alcance un determinado lote (LotControl), se añada un número determinado de puntos a la señal (el parámetro Deviation)

Como resultado, funciona con problemas:

en primer lugar las pruebas en la historia comenzó a casi detener después de 500 oficios (1-2 oficios por min).

(comienza con una velocidad normal, y luego va cada vez más lento)

En segundo lugar, la desviación no se conecta después de (LotControl), sino uno o dos pasos después del lote especificado.

Inténtalo de esta manera:

eliminar del 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;

y poner aquí

//+-----------------------------------------------------------------------------------------------+
//|                                                             Функция поиска сигнала на покупку |
//+-----------------------------------------------------------------------------------------------+
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 #:

Inténtalo de esta manera:

eliminar del void OnTick()

y poner aquí

el resultado será el mismo.

No se trata de la señal. Tengo otros dos EAs similares a este, y no hay frenos

 
MakarFX #:

Inténtalo de esta manera:

eliminar del void OnTick()

y ponerlo aquí

Al principio me preocupaba esta cosa:

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;
  }

pero los otros dos búhos funcionan bien con él en el probador

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

al principio pensé que era esta cosa:

No hay nada malo en esta cosa.

Miraré tu código más tarde, escribe qué marco temporal estás usando en el probador y qué par. Comprobaré si se me ralentiza.

 
MakarFX #:

No hay nada malo en esta cosa.

Miraré tu código más tarde, postea qué marco temporal estás usando en el probador y qué par. Comprobaré si voy más despacio.

Sí, cualquier par.

Utilizo M15 para el AUD/USD.

Tuve el mismo problema con su indicador (adjunto)

Descubrí por el método de eliminación que es esto lo que me frena:

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);
  }
Archivos adjuntos:
 
законопослушный гражданин #:

Sí, cualquier par.

Utilizo M15 para el AUD/USD.

Tuve el mismo problema con su indicador (adjunto)

Descubrí por eliminación que es esto lo que ralentiza el proceso:

Cambiar el orden de anulación

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

Modificar el rebasamiento de las órdenes

Chicos, tanto como podáis, si no recordáis el valor del índice del bucle en la última comprobación, entonces tenéis un bucle recorriendo todo el historial disponible. Y cuanto más sea, más largo será el bucle.

Razón de la queja: