Preguntas de los principiantes MQL5 MT5 MetaTrader 5 - página 649

 
Artyom Trishkin:

He visto un trozo de su código para encontrar vértices en zigzag - creo que es de Igor Kim. Aquí, en el código de búsqueda de extremos se inserta adicionalmente el ahorro del tiempo de extremo encontrado. Lo estás buscando en el bucle... A la hora de identificarlo, recuerde el momento al que apunta el índice del bucle cuando el extremo ya está identificado: antes de la devolución del valor de su precio. Es decir, pasar adicionalmente la variable datetime por referencia a la función en la que se debe escribir el tiempo en el que se encuentra el extremo del zigzag. Cuando la función devuelva el valor del precio, escribirá adicionalmente en esta variable el valor de la hora de apertura de la barra donde se encuentra el extremo requerido del zigzag.

Lo siento, pero estoy lejos del ordenador del trabajo y no puedo darte un ejemplo de código.

Todo salió bien, ¡gracias!
 
Hola! Yo escribo algo en MQL4, pero no soy muy bueno en MQL5. Necesito un pequeño ayudante para calcular la diferencia entre la máxima y la mínima del día. La 4ª versión tiene buenas funciones para este propósito iHigh e iLow, pero están ausentes aquí. He intentado usar copyHigh y copyLow, pero sigue dando muchos errores después de restar el valor mínimo del máximo. ¿Podría decirme cómo resolver este problema, preferiblemente con un fragmento de código? Gracias de antemano.
 
Александр Богданов:
Hola! Yo escribo un poco en MQL4, pero no soy muy bueno en MQL5. Necesito un pequeño ayudante para calcular la diferencia entre la máxima y la mínima del día. La 4ª versión tiene buenas funciones para este propósito iHigh y iLow, pero están ausentes aquí. He intentado usar copyHigh y copyLow, pero sigue dando muchos errores después de restar el valor mínimo del máximo. ¿Podría decirme cómo resolver este problema, preferiblemente con un fragmento de código? Gracias de antemano.
Será mejor que me muestres tu fragmento de código con muchos errores y que te den un montón de comentarios sobre lo que está mal.
 
Александр Богданов:
Hola! Escribo un poco en MQL4, sin embargo soy un completo cero en MQL5. Necesitaba escribir un pequeño ayudante para calcular la diferencia entre la máxima y la mínima del día. La 4ª versión tiene buenas funciones para este propósito iHigh e iLow, pero están ausentes aquí. He intentado usar copyHigh y copyLow, pero sigue dando muchos errores después de restar el valor mínimo del máximo. ¿Podría decirme cómo resolver este problema, preferiblemente con un fragmento de código? Gracias de antemano.
Insértelo al principio del código

Foro sobre comercio, sistemas de comercio automatizados y prueba de estrategias de comercio

Probando 'CopyTicks'

fxsaber, 2016.10.19 07:59

// Позволяет, как в MT4, работать с таймсериями: Open[Pos], High[Pos], Low[Pos], Close[Pos], Time[Pos], Volume[Pos].
// А так же задает привычные MT4-функции: iOpen, iHigh, iLow, iClose, iTime, iVolume.
#define DEFINE_TIMESERIE(NAME,FUNC,T)                                                                         \
  class CLASS##NAME                                                                                           \
  {                                                                                                           \
  public:                                                                                                     \
    static T Get( const string Symb, const int TimeFrame, const int iShift )                                  \
    {                                                                                                         \
      T tValue[];                                                                                             \
                                                                                                              \
      return((Copy##FUNC((Symb == NULL) ? _Symbol : Symb, _Period, iShift, 1, tValue) > 0) ? tValue[0] : -1); \
    }                                                                                                         \
                                                                                                              \
    T operator []( const int iPos ) const                                                                     \
    {                                                                                                         \
      return(CLASS##NAME::Get(_Symbol, _Period, iPos));                                                       \
    }                                                                                                         \
  };                                                                                                          \
                                                                                                              \
  CLASS##NAME NAME;                                                                                           \
                                                                                                              \
  T i##NAME( const string Symb, const int TimeFrame, const int iShift )                                       \
  {                                                                                                           \
    return(CLASS##NAME::Get(Symb, TimeFrame, iShift));                                                        \
  }

DEFINE_TIMESERIE(Volume, TickVolume, long)
DEFINE_TIMESERIE(Time, Time, datetime)
DEFINE_TIMESERIE(Open, Open, double)
DEFINE_TIMESERIE(High, High, double)
DEFINE_TIMESERIE(Low, Low, double)
DEFINE_TIMESERIE(Close, Close, double)
Esto le permite utilizar iHigh e iLow como está acostumbrado en MT5.
 
fxsaber:
fxsaber:
Inserte esto al principio del código
Esto le permitirá utilizar los conocidos iHigh e iLow en MT5.
¡Muchas gracias! Esto hará que sea muy fácil
 
Александр Богданов:
Hola! Yo escribo un poco en MQL4, pero no estoy familiarizado con MQL5. Necesito un pequeño ayudante para calcular la diferencia entre la máxima y la mínima del día. La 4ª versión tiene buenas funciones para este propósito iHigh e iLow, pero están ausentes aquí. He intentado usar copyHigh y copyLow, pero sigue dando muchos errores después de restar el valor mínimo del máximo. ¿Podría decirme cómo resolver este problema, preferiblemente con un fragmento de código? Gracias de antemano.

Si la tarea es sólo para mostrar en la pantalla, entonces la mejor solución es un indicador. El indicador, en OnCalculate() tiene todas las series de tiempo necesarias:

//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {

Por defecto, en el indicador MQL5, la barra más a la derecha tiene el índice rates_total-1. Y su tarea se reduce a una resta elemental:

   double difference=high[rates_total-1]-low[rates_total-1];


Aunque, este simple enfoque sólo se mostrará correctamente si el indicador se ejecuta en el marco de tiempo D1. Si se ejecuta en otros plazos, entonces se debe utilizar CopyHigh y CopyLow - básicamente, nada complicado.

Ahora escribiré un ejemplo....

//+------------------------------------------------------------------+
//|                                               High minus Low.mq5 |
//|                              Copyright © 2016, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2016, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
#property indicator_chart_window
#property indicator_plots 0
//--- input parameter
input ENUM_TIMEFRAMES period=PERIOD_D1;   // для какого периода считать High-Low
//---
double multiplier=0.0;
double High[],Low[];
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- indicator buffers mapping
   multiplier=MathPow(10,Digits());
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Custom indicator iteration function                              |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const datetime &time[],
                const double &open[],
                const double &high[],
                const double &low[],
                const double &close[],
                const long &tick_volume[],
                const long &volume[],
                const int &spread[])
  {
//--- разницу цен переводим в пункты
   double difference=(iHigh(Symbol(),period,0)-iLow(Symbol(),period,0))*multiplier;
//--- вывод результата на экран
   Comment("High-Low=",DoubleToString(difference,0));
//--- return value of prev_calculated for next call
   return(rates_total);
  }
//+------------------------------------------------------------------+
//| Получим Low для заданного номера бара                            |
//+------------------------------------------------------------------+
double iLow(string symbol,ENUM_TIMEFRAMES timeframe,int index)
  {
   double low=0;
   ArraySetAsSeries(Low,true);
   int copied=CopyLow(symbol,timeframe,0,Bars(symbol,timeframe),Low);
   if(copied>0 && index<copied) low=Low[index];
   return(low);
  }
//+------------------------------------------------------------------+
//| Получим High для заданного номера бара                           |
//+------------------------------------------------------------------+
double iHigh(string symbol,ENUM_TIMEFRAMES timeframe,int index)
  {
   double high=0;
   ArraySetAsSeries(High,true);
   int copied=CopyHigh(symbol,timeframe,0,Bars(symbol,timeframe),High);
   if(copied>0 && index<copied) high=High[index];
   return(high);
  }
//+------------------------------------------------------------------+


Ahora puede ejecutar el indicador en cualquier marco de tiempo del símbolo actual y seleccionar para qué marco de tiempo calcular la diferencia entre el Alto y el Bajo.
Archivos adjuntos:
 
Александр Богданов:
Hola! Yo escribo un poco en MQL4, pero no soy muy bueno en MQL5. Necesito un pequeño ayudante para calcular la diferencia entre la máxima y la mínima del día. La 4ª versión tiene buenas funciones para este propósito iHigh e iLow, pero están ausentes aquí. He intentado usar copyHigh y copyLow, pero sigue dando muchos errores después de restar el valor mínimo del máximo. ¿Podría decirme cómo resolver este problema, preferiblemente con un fragmento de código? Gracias de antemano.
Si desea obtener los máximos y mínimos diarios (máximos y mínimos del día actual), puede utilizar SymbolInfoDouble() con los identificadores SYMBOL_BIDHIGH y SYMBOL_BIDLOW (o cualquier otro, como prefiera).
 
Hola 2016.10.21_19:58 MSC. Comprobando el EA en el probador de estrategias. El EA funciona, abre y cierra una operación. Pero el probador de la estrategia da un error: posición de inicio incorrecta 0 para la función ArrayMinimum; -1; array fuera de rango en 'CLose.mqh' (86,59); el pase de prueba se detuvo debido a un error crítico en el EA. Hay una captura de pantalla del Asesor Experto y el código del archivo CLose.mqh para ser activado. No veo ningún error fuera del array en este código. Por eso no entiendo cuál es el error. Por favor, aconséjeme si puede. Eso es todo por ahora. 20:08 MSC. Error crítico
//+------------------------------------------------------------------+
//|                                                        CLose.mqh |
//|                                              Nickityuk N., 2016. |
//|                             https://www.mql5.com/users/nicityuk/ |
//+------------------------------------------------------------------+
#property copyright "Nickityuk N., 2016."
#property link      "https://www.mql5.com/users/nicityuk/"
#property strict
#include <Expert\OPen.mqh>
//#include <ARrayMinimum.mqh>
double AOmax,AOmax2,AOmin,AOmin2,AOm0,AOn0,z5max0,z5min0,clm,cln,AO[];
int aom,aom2,aon,aon2;
datetime ttm,ttn,hm,hn;
//+------------------------------------------------------------------+
//| Calculate for close order                                        |
//+------------------------------------------------------------------+
void CLose()
  {if(buy==0 && sell==0) {return;}
   else if(OrderType()==OP_BUY) {CloseBuy();}
        else                     CloseSell();}
//+------------------------------------------------------------------+
void St()
  {St0=iStochastic(NULL,0,24,5,3,MODE_SMA,0,MODE_MAIN,0);
   Si0=iStochastic(NULL,0,24,5,3,MODE_SMA,0,MODE_SIGNAL,0);
   St1=iStochastic(NULL,0,24,5,3,MODE_SMA,0,MODE_MAIN,1);
   Si1=iStochastic(NULL,0,24,5,3,MODE_SMA,0,MODE_SIGNAL,1);}
void CloseBuy()
  {St(); if(St0-20>0 && Si0-20>0)
           {if(St1-Si1>0 && St0-Si0<0) {AOm0=iAO(NULL,0,0);
               if(AOm0-AOm1>=0) {AOm1=iAO(NULL,0,0); return;}
               else if(St0-80>0 && St0-100<=0 && Si0-80>0)
                      {if(Si0-100<=0 && St1-Si1>0 && St0-Si0<0)
                         {TwoExtremeAO_Buy(); OneExtremeBuy(); ExpirationBuy();}
                       else return;}            
                    else return;}
            else return;}        
         else return;}
void CloseSell()
  {St(); if(St0-80<0 && Si0-80<0)
           {if(St1-Si1<0 && St0-Si0>0) {AOn0=iAO(NULL,0,0);
               if(AOn0-AOn1<=0) {AOn1=iAO(NULL,0,0); return;}
               else if(St0-20<0 && St0>=0 && Si0-20<0)
                      {if(Si0>=0 && St1-Si1<0 && St0-Si0>0)
                         {TwoExtremeAO_Sell(); OneExtremeSell(); ExpirationSell();}
                       else return;}  
                    else return;}
            else return;}        
         else return;}
//+------------------------------------------------------------------+                      
void CalculateClose()
  {v0=iVolume(NULL,PERIOD_M1,0); //--- go trading only for first tiks of new bar
   v1=iVolume(NULL,PERIOD_M1,1);
   v2=iVolume(NULL,PERIOD_M1,2);
   v3=iVolume(NULL,PERIOD_M1,3);
   v4=iVolume(NULL,PERIOD_M1,4);
   if(v0+v1+v2+v3+v4-10/12>0) return;  
   for(index=0;index<24;index++)
     {AO[index]=iAO(NULL,PERIOD_M5,index);}
   ArrayResize(AO,24,4);
   ArraySetAsSeries(AO,true);}
   //index=0; AO[index]=iAO(NULL,PERIOD_M5,index);}
//+------------------------------------------------------------------+      
void TwoExtremeAO_Buy()
  {CalculateClose();
   if(ArrayMaximum(AO,23,0)==0) return;
   else aom=ArrayMaximum(AO,23,0); AOmax=AO[aom];
   if(ArrayMinimum(AO,aom,0)>0) {aon=ArrayMinimum(AO,aom,0);}
   else return;
   if(ArrayMaximum(AO,aon,0)==0) return;
   else aom2=ArrayMaximum(AO,aon,0); AOmax2=AO[aom2];
     if(AOmax2-AOmax>0) {return;}
     else if(AOmax2-AOmax<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                {Print("OrderClose error.",GetLastError());}
                              else //index=2;
                                   //while(iFractals(NULL,0,MODE_UPPER,index)==0) {index++;}
                                   //Sleep(3000); luf=iFractals(NULL,0,MODE_UPPER,index);
                                   //SL=NormalizeDouble(luf+(Ask-Bid)+(1*_Point),_Digits);
                                   TP=NormalizeDouble(Ask-tp*_Point,_Digits);
                                   tic=OrderSend(Symbol(),OP_SELL,LotsCalculated(),Bid,50,0,TP,"",MAGIC,0,Red);
                                   AOn1=iAO(NULL,0,index); return;}
          else return;}
//+------------------------------------------------------------------+          
void TwoExtremeAO_Sell()
  {CalculateClose();
   if(ArrayMinimum(AO,23,0)==0) return;
   else aon=ArrayMinimum(AO,23,0); Print(aon,""); AOmin=AO[aon];
   if(ArrayMaximum(AO,aon,0)>0) {aom=ArrayMaximum(AO,aon,0);}
   else return;
   if(ArrayMinimum(AO,aom,0)==0) return;
   else aon2=ArrayMinimum(AO,aom,0); AOmin2=AO[aon2]; //Print(aon2,"");
     if(AOmin2-AOmin>0) {return;}
     else if(AOmin2-AOmin<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                {Print("OrderClose error.",GetLastError());}
                              else //index=2;
                                   //while(iFractals(NULL,0,MODE_LOWER,index)==0) {index++;}
                                   //Sleep(3000); ldf=iFractals(NULL,0,MODE_LOWER,index);
                                   //SL=NormalizeDouble(ldf-(1*_Point),_Digits);
                                   TP=NormalizeDouble(Bid+tp*_Point,_Digits);
                                   tic=OrderSend(Symbol(),OP_BUY,LotsCalculated(),Ask,50,0,TP,"",MAGIC,0,Blue);
                                   AOm1=iAO(NULL,0,0); return;}
          else return;}
//+------------------------------------------------------------------+                      
void OneExtremeBuy()
  {index=0;
   while(iCustom(NULL,PERIOD_M5,"ZigZag",12,5,3,1,index)==0) {index++;}
   z5max0=iCustom(NULL,PERIOD_M5,"ZigZag",12,5,3,1,index); ttm=iTime(NULL,0,index); clm=iClose(NULL,PERIOD_M5,0); //Sleep(3000);
   if((clm-(z5max0-300*Point))<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                       {Print("OrderClose error.",GetLastError());}
                                   else return;}
   else return;}
void OneExtremeSell()
  {index=0;
   while(iCustom(NULL,PERIOD_M5,"ZigZag",12,5,3,2,index)==0) {index++;}
   z5min0=iCustom(NULL,PERIOD_M5,"ZigZag",12,5,3,2,index); ttn=iTime(NULL,0,index); cln=iClose(NULL,PERIOD_M5,0); //Sleep(3000);
   if((cln-(z5min0+300*Point))>0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                       {Print("OrderClose error.",GetLastError());}
                                   else return;}
   else return;}
//+------------------------------------------------------------------+                                                                      
void ExpirationBuy()
  {hm=TimeHour(ttm); if((hm+3)-TimeCurrent()<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                                   {Print("OrderClose error.",GetLastError());}
                                                 else return;}
                     else return;}
void ExpirationSell()
  {hn=TimeHour(ttn); if((hn+3)-TimeCurrent()<0) {if(OrderClose(OrderTicket(),OrderLots(),Bid,300,White)==false)
                                                   {Print("OrderClose error.",GetLastError());}
                                                 else return;}
                     else return;}
//+------------------------------------------------------------------+          
 
Николай Никитюк:
Hola 2016.10.21_19:58 MSC. Comprobación del asesor en el probador de estrategias. El asesor trabaja, abre y cierra una operación. Pero el probador de la estrategia da un error: posición de inicio incorrecta 0 para la función ArrayMinimum; -1; array fuera de rango en 'CLose.mqh' (86,59); el pase de prueba se detuvo debido a un error crítico en el EA. Hay una captura de pantalla del Asesor Experto y el código del archivo CLose.mqh para ser activado. No veo ningún error fuera del array en este código. Por eso no entiendo cuál es el error. Por favor, aconséjeme si puede. Eso es todo por ahora. 20:08 MSC.

¿Se puede convertir a int (con aon=NormalizeDouble(aon,0)), porque parece doble y no está muy claro cuál es el resultado?

:

if(ArrayMinimum(AO,aom,0)>0) {aon=ArrayMinimum(AO,aom,0);}
 
Karputov Vladimir:

Simplemente introduzca un parámetro de entrada en su EA y, dependiendo del valor que se le asigne al iniciar, sólo comprará o sólo venderá:

input bool Long=true;            // allow only "Long"
//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
...
void OnTick()
  {
   if(!Long)
      trade.Sell(0.01);
   if(Long)
      trade.Buy(0.01);
  }
Y para el comercio manual, ¿qué sugieres?