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

 
Artyom Trishkin:
De alguna manera (solución de @fxsaber):

//+------------------------------------------------------------------+
//| Возвращает смещение бара по времени                              |
//+------------------------------------------------------------------+
int GetBarShift(const string symbol_name, const ENUM_TIMEFRAMES timeframe, const datetime time) {
   int res=-1;
   datetime last_bar;
   if(SeriesInfoInteger(symbol_name,timeframe,SERIES_LASTBAR_DATE,last_bar)) {
      if(time>last_bar) res=0;
      else {
         const int shift=Bars(symbol_name,timeframe,time,last_bar);
         if(shift>0) res=shift-1;
         }
      }
   return(res);
}
//+------------------------------------------------------------------+
Alguien escribió en algún lugar que en la línea seleccionada debe hacer esto: if (time>=last_bar) res=0;

No lo he comprobado, para ser sincero, no lo consigo siempre. Compruébalo y escribe el resultado, por favor.
Yo lo escribí. Y es lógico, porque si la hora coincide con la de apertura de la barra actual, su índice también será 0. Sí, la solución fxsaber pura funcionará con errores.
 
Alexey Kozitsyn:
No sé si mi solución es "más fácil", pero pruebe ésta: https://www.mql5.com/ru/forum/160945#comment_4053382

¿No hay una función estándar en el lenguaje y cada uno tiene que construir su propia bicicleta y luego medir su rendimiento?

Parece que he encontrado todos menos este, pero después de mirar diferentes soluciones, es obvio que son "quién puede hacer qué".

 
Vitaly Muzichenko:

¿No hay una función estándar en el lenguaje y cada uno tiene que construir su propia bicicleta y luego medir su rendimiento?

Parece que he encontrado todas menos ésta, pero después de mirar las diferentes soluciones, es obvio que son "quién puede hacer qué".

No hay uno estándar. Ha proporcionado una variante del artículo https://www.mql5.com/ru/articles/81. Allí también se describe la "muleta".
Переход с MQL4 на MQL5
Переход с MQL4 на MQL5
  • 2010.05.11
  • Sergey Pavlov
  • www.mql5.com
Данная статья, построенная в форме справочника по функциям MQL4, призвана помочь переходу с MQL4 на MQL5. Для каждой функции языка MQL4 приведено описание и представлен способ ее реализации на MQL5, что позволит вам значительно ускорить перевод своих программ с MQL4 на MQL5. Для удобства функции разбиты на группы, как в документации по MQL4.
 

Una última pregunta. Hoy en la base de código he visto un código de un "maestro", por lo que utiliza esto:

   double open_1=iOpen(1);
   double open_2=iOpen(2);
   double high_0=iHigh(0);
   double high_1=iHigh(1);
   double high_2=iHigh(2);
   double high_3=iHigh(3);
   double low_0=iLow(0);
   double low_1=iLow(1);
   double low_2=iLow(2);
   double low_3=iLow(3);
   double close_1=iClose(1);
   double close_2=iClose(2);


Justo ayer escribí uno similar, pero lo escribí de esta manera:

ArraySetAsSeries(Tick,true);
if(CopyRates(dSymbol,0,1,3,Tick)<0) return;
  open1 = Tick[0].open;  open2 = Tick[1].open;  open3 = Tick[2].open;
  high1 = Tick[0].high;  high2 = Tick[1].high;  high3 = Tick[2].high;
  low1  = Tick[0].low;   low2  = Tick[1].low;   low3  = Tick[2].low;
  close1= Tick[0].close; close2= Tick[1].close; close3= Tick[2].close;


Después de lo que he visto hoy, he empezado a dudar de lo correcto de mi decisión.

Pregunta: ¿Qué opción es mejor, porque estoy aprendiendo?

 
Vitaly Muzichenko:

Una última pregunta. Hoy en el codebase he visto un código de un "maestro", por lo que utiliza esto:

   double open_1=iOpen(1);
   double open_2=iOpen(2);
   double high_0=iHigh(0);
   double high_1=iHigh(1);
   double high_2=iHigh(2);
   double high_3=iHigh(3);
   double low_0=iLow(0);
   double low_1=iLow(1);
   double low_2=iLow(2);
   double low_3=iLow(3);
   double close_1=iClose(1);
   double close_2=iClose(2);


Justo ayer escribí algo parecido, pero lo escribí de esta manera:

ArraySetAsSeries(Tick,true);
if(CopyRates(dSymbol,0,1,3,Tick)<0) return;
  open1 = Tick[0].open;  open2 = Tick[1].open;  open3 = Tick[2].open;
  high1 = Tick[0].high;  high2 = Tick[1].high;  high3 = Tick[2].high;
  low1  = Tick[0].low;   low2  = Tick[1].low;   low3  = Tick[2].low;
  close1= Tick[0].close; close2= Tick[1].close; close3= Tick[2].close;


Después de lo que he visto hoy, he empezado a dudar de lo correcto de mi decisión.

Pregunta: ¿Qué variante es mejor, porque estoy aprendiendo?

En este caso su implementación debería funcionar más rápido - ya que hay menos llamadas a copiar - se copian tres valores a la vez en lugar de uno.

Aunque nadie te impide convertir el código para obtener un valor a la vez:

//+------------------------------------------------------------------+
//| Get Close for specified bar index                                |
//+------------------------------------------------------------------+
double iClose(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Close[1];
   double close=0;
   int copied=CopyClose(symbol,timeframe,index,1,Close);
   if(copied>0) close=Close[0];
   return(close);
  }

en el código para obtener varios valores a la vez. Es que me da pereza :)

 
Vladimir Karputov:

En este caso su implementación debería funcionar más rápido - ya que hay menos llamadas de copia - se copian tres valores a la vez en lugar de uno a la vez.

Aunque nadie te impide convertir el código para obtener un valor a la vez:

//+------------------------------------------------------------------+
//| Get Close for specified bar index                                |
//+------------------------------------------------------------------+
double iClose(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  }

en el código para obtener varios valores a la vez. Es que me da pereza :)

Gracias por la respuesta.

Entonces, ¿es mejor aplicar la solución, que he publicado? Es suficiente una comprobación, no habrá errores?

 
Vitaly Muzichenko:

Gracias por la respuesta.

Entonces, ¿es mejor aplicar la solución que he publicado? ¿Con una comprobación es suficiente, no habrá errores?

CopyRates necesita al menos dos comprobaciones:

  1. comprobación de errores (si ... <0)
  2. comprobar si la función ha devuelto la cantidad correcta (¿qué pasa si se piden tres y sólo se devuelven dos?)
También es muy deseable: comprobar los precios de la basura (es posible que devuelva "0" en lugar del precio)

 
Vitaly Muzichenko:

Gracias por la respuesta.

Entonces, ¿es mejor aplicar la solución que he publicado? ¿Con una comprobación es suficiente, no habrá errores?

Tu solución tampoco es óptima, porque inicializas un montón de variables con valores del array que ya tienes. La pregunta es: ¿por qué? ¿Cuándo se puede utilizar sólo una matriz? Nómbralo Bars y serás feliz:

ArraySetAsSeries(Bars, true);
if(CopyRates(Symbol(), 0, 1, 3, Bars)<0) return;
double value = Bars[0].open;
...
 
Vasiliy Sokolov:

Tu solución tampoco es óptima, porque inicializas un montón de variables con valores de un array ya derivado. La pregunta es: ¿por qué? ¿Cuándo se puede utilizar sólo una matriz? Llámalo Bares y serás feliz:

ArraySetAsSeries(Bars, true);
if(CopyRates(Symbol(), 0, 1, 3, Bars)<0) return;
double value = Bars[0].open;
...

Lo llamasBars y el compilador te da un tirón de orejas. ¿Has comprobado esta construcción o simplemente has asumido que debería funcionar, o estoy haciendo algo mal?

 
Vitaly Muzichenko:

Lo llamóBars, el compilador está regañado como el infierno. ¿Has probado este diseño, o simplemente has asumido que debería funcionar?

barras[]