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

 
Roman:

Es necesario pensar de antemano cómo se ejecuta el código a nivel de memoria, inicialización y devolución de valores.

No hay que pensarlo, hay manuales para estas cosas, y nunca ha habido un manual para la asignación de memoria en MQL, sólo mensajes de los desarrolladores, y a menudo con una aclaración de que la implementación puede cambiar

Vale, la discusión se reduce a quién lee qué libro de programación, yo lo leo desde el instituto y lo sigo leyendo desde hace 30 años.

 
Igor Makanu:

No hay que pensarlo, hay manuales para estas cosas, y nunca ha habido un manual para la asignación de memoria en MQL, sólo mensajes de los desarrolladores, y a menudo con una aclaración de que la implementación puede cambiar

Vale, la discusión se reduce a quién lee qué libro de programación, yo lo leo desde el instituto y lo sigo leyendo desde hace 30 años

Por supuesto que no tienes que pensarlo bien, por qué deberías... El compilador lo hará todo por sí mismo. ))
C# no es C

Y mira el vídeo en __inline.
Allí se explica cómo funcionan las funciones en la memoria para los que no hacen ninguna diferencia.

 
Vladimir Karputov:

Haz un dibujo primero y especifica lo que es para ti la "barra cero" de un indicador con el parámetro de desplazamiento.

Dibujado. La barra de cero se resalta con una línea vertical.


 
RickD:

Dibujado. La barra de cero se resalta con una línea vertical.


Ejemplo de código:

//+------------------------------------------------------------------+
//|                                        iMA Values on a Chart.mq5 |
//|                              Copyright © 2019, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2019, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.00"
//--- input parameters
input int                  Inp_MA_ma_period     = 12;          // MA: averaging period
input int                  Inp_MA_ma_shift      = 5;           // MA: horizontal shift
input ENUM_MA_METHOD       Inp_MA_ma_method     = MODE_SMA;    // MA: smoothing type
input ENUM_APPLIED_PRICE   Inp_MA_applied_price = PRICE_CLOSE; // MA: type of price
//---
int    handle_iMA;                           // variable for storing the handle of the iMA indicator
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//--- create handle of the indicator iMA
   handle_iMA=iMA(Symbol(),Period(),Inp_MA_ma_period,Inp_MA_ma_shift,
                  Inp_MA_ma_method,Inp_MA_applied_price);
//--- if the handle is not created
   if(handle_iMA==INVALID_HANDLE)
     {
      //--- tell about the failure and output the error code
      PrintFormat("Failed to create handle of the iMA indicator for the symbol %s/%s, error code %d",
                  Symbol(),
                  EnumToString(Period()),
                  GetLastError());
      //--- the indicator is stopped early
      return(INIT_FAILED);
     }
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
//---
   double array_ma[];
   ArraySetAsSeries(array_ma,true);
   int start_pos=0,count=3;
   if(!iGetArray(handle_iMA,0,start_pos,count,array_ma))
      return;

   string text="";
   for(int i=0; i<count; i++)
      text=text+IntegerToString(i)+": "+DoubleToString(array_ma[i],Digits()+1)+"\n";

   Comment(text);
  }
//+------------------------------------------------------------------+
//| Get value of buffers                                             |
//+------------------------------------------------------------------+
bool iGetArray(const int handle,const int buffer,const int start_pos,
               const int count,double &arr_buffer[])
  {
   bool result=true;
   if(!ArrayIsDynamic(arr_buffer))
     {
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, this a no dynamic array!",__FILE__,__FUNCTION__);
      return(false);
     }
   ArrayFree(arr_buffer);
//--- reset error code
   ResetLastError();
//--- fill a part of the iBands array with values from the indicator buffer
   int copied=CopyBuffer(handle,buffer,start_pos,count,arr_buffer);
   if(copied!=count)
     {
      //--- if the copying fails, tell the error code
      PrintFormat("ERROR! EA: %s, FUNCTION: %s, amount to copy: %d, copied: %d, error code %d",
                  __FILE__,__FUNCTION__,count,copied,GetLastError());
      //--- quit with zero result - it means that the indicator is considered as not calculated
      return(false);
     }
   return(result);
  }
//+------------------------------------------------------------------+

Resultado:


Como puedes ver, es copiable sin necesidad de retoques.

Archivos adjuntos:
 
Vladimir Karputov:

Ejemplo de código:

Resultado:


Como se puede ver se copia fácilmente, sin ninguna pandereta.

Ejemplo de código. Basado en un indicador. El indicador está ocupado asignando memoria intermedia.

#property copyright "Copyright 2019"
#property link      ""
#property version   "1.00"

#property indicator_chart_window
#property indicator_buffers 1
#property indicator_plots   0

//---

input int                  MA_period = 12;
input int                  MA_shift = 5;
input ENUM_MA_METHOD       MA_method = MODE_SMA;
input ENUM_APPLIED_PRICE   MA_applied_price = PRICE_CLOSE;

int start_pos = 0;

//---

double MA_Calc_Buf[];

int hMA = INVALID_HANDLE;


int OnInit()
{
  SetIndexBuffer(0, MA_Calc_Buf, INDICATOR_CALCULATIONS); 
  ArraySetAsSeries(MA_Calc_Buf, true);
 
  hMA = iMA(NULL, 0, MA_period, MA_shift, MA_method, MA_applied_price);   
  if (hMA == INVALID_HANDLE)
  {
    int LErr = GetLastError();
    PrintFormat("iMA create failed (%d)", LErr);
    return (INIT_FAILED);
  }
 
  return (INIT_SUCCEEDED);
}

void OnDeinit(const int reason)
{
  if (hMA != INVALID_HANDLE)
  {
    IndicatorRelease(hMA);
    hMA = INVALID_HANDLE;
  }
}

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[])
{ 
  int copied;
  copied = CopyBuffer(hMA, 0, start_pos, rates_total, MA_Calc_Buf);
  if (copied == -1)
  {
    int LErr = GetLastError();
    PrintFormat("CopyBuffer(hMA) failed (%d)", LErr);
    return (prev_calculated);
  }
 
  if (copied == 0)
  {
    PrintFormat("CopyBuffer(hMA) copied 0 bars");
    return (prev_calculated);
  } 
 
  string text = "";
  for (int i=0; i<15; i++)
    text = text + IntegerToString(i) + ": " + DoubleToString(MA_Calc_Buf[i], Digits()+1) + "\n";
 
  Comment(text);

  return (rates_total);
}

Cuando start_pos = 0, el valor correspondiente a la barra 0 del gráfico está en la posición 5. 1.017041 Está en la posición 0 en su EA. Bien.


Pero necesito obtener este valor en la posición cero.

He puesto start_pos = 5. No obtengo el resultado deseado. El valor que busco está de nuevo en la posición 5.


He puesto start_pos = -5. No obtengo el resultado deseado. De nuevo, el valor que busco está en la posición 5.


He puesto start_pos = -10. Y sólo ahora obtengo el resultado deseado.


 
RickD:

Ejemplo de código. Basado en el indicador. El indicador está ocupado asignando memoria intermedia.

Cuando start_pos = 0, el valor correspondiente a la barra 0 del gráfico lo vemos en la posición 5. 1.017041 En su EA está en la posición 0. Bien.


Pero necesito obtener este valor en la posición cero.

He puesto start_pos = 5. No obtengo el resultado deseado. El valor que busco está de nuevo en la posición 5.


He puesto start_pos = -5. No obtengo el resultado deseado. De nuevo, el valor que busco está en la posición 5.


He puesto start_pos = -10. Y sólo ahora obtengo el resultado deseado.


Tenemos que entender la diferencia entre el trabajo del Asesor Experto y del indicador. Para trabajar a partir del indicador utilice el ejemplo de la ayuda(iMA).

Документация по MQL5: Технические индикаторы / iMA
Документация по MQL5: Технические индикаторы / iMA
  • www.mql5.com
//|                                                     Demo_iMA.mq5 | //|                        Copyright 2011, MetaQuotes Software Corp. | //|                                             https://www.mql5.com | //| Перечисление способов создания хэндла                            |  Creation             type=Call_iMA;                ...
 
Vladimir Karputov:

Hay que entender la diferencia entre operar desde un EA y desde un indicador. Para trabajar a partir de un indicador, utilice el ejemplo de la ayuda(iMA).

Así que toma un ejemplo de la ayuda de iMA, añade

   ArraySetAsSeries(iMABuffer, true);
   comm = (string)DoubleToString(iMABuffer[0], Digits());
   ArraySetAsSeries(iMABuffer, false);

   Comment(comm);   

y verifique que el valor es diferente del valor de salida de su EA por exactamente ma_shift de barras.

Por otro lado, necesito obtener en el indicador en iMABuffer[0] el valor que tienes en tu Expert Advisor en array_ma[0].

Al menos por el momento podemos ver que el comportamiento del CopyBuffer para los Asesores Expertos y los indicadores es diferente. Si entiende la diferencia de CopyBuffer cuando se trabaja con un EA y un indicador, por favor especifique la sección apropiada de la documentación para estudiar.

 

Intentaré simplificar la pregunta. ¿Cómo puedo llevar estos valores de MA (a partir de la línea vertical roja y hacia la izquierda) al buffer del indicador? ¿Puede escribir un ejemplo?


 
RickD:

Intentaré simplificar la pregunta. ¿Cómo puedo llevar estos valores de MA (a partir de la línea vertical roja y hacia la izquierda) al buffer del indicador? ¿Puede escribir un ejemplo?


En la captura de pantalla, la visualización de la memoria intermedia se desplaza cinco barras hacia la derecha. Entonces - para obtener la quinta barra del buffer de indicadores (índice 4), y más a la izquierda en la lista, ¿de dónde debemos obtenerlas? De Buffer[4] y más a la izquierda.

En teoría. En la práctica, no he abierto el código del indicador ni he trabajado con él durante mucho tiempo, casi un año... Pruébalo.

 
Artyom Trishkin:


En teoría. En la práctica, no he abierto el código del indicador ni he trabajado con él durante mucho tiempo, casi un año... Pruébalo.

No puedes perder una habilidad.

Razón de la queja: