Domande dai principianti MQL5 MT5 MetaTrader 5 - pagina 1164

 
Roman:

È necessario pensare in anticipo a come il codice viene eseguito a livello di memoria, inizializzazione e restituzione del valore.

Non c'è bisogno di pensarci su, ci sono manuali per queste cose, e non c'è mai stato un manuale per l'allocazione della memoria in MQL, solo messaggi dagli sviluppatori, e spesso con una precisazione che l'implementazione può cambiare

Ok, la discussione si riduce a chi legge quale libro di programmazione, io lo leggo dal liceo e lo leggo ancora da 30 anni.

 
Igor Makanu:

Non c'è bisogno di pensarci su, ci sono manuali per queste cose, e non c'è mai stato un manuale per l'allocazione della memoria in MQL, solo messaggi dagli sviluppatori, e spesso con una precisazione che l'implementazione può cambiare

Ok, la discussione si riduce a chi legge quale libro di programmazione, io lo leggo dal liceo e lo leggo ancora da 30 anni

Naturalmente non devi pensarci su, perché dovresti... Il compilatore farà tutto da solo. ))
C# non è C

E guarda il video su __inline.
Lì si spiega come funzionano le funzioni nella memoria per coloro che non fanno alcuna differenza.

 
Vladimir Karputov:

Disegna prima un'immagine e specifica qual è per te la 'barra zero' di un indicatore con il parametro shift.

Disegnato. La barra dello zero è evidenziata da una linea verticale.


 
RickD:

Disegnato. La barra dello zero è evidenziata da una linea verticale.


Codice di esempio:

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

Risultato:


Come potete vedere, è copiabile senza alcun ritocco.

 
Vladimir Karputov:

Codice di esempio:

Risultato:


Come potete vedere è copiato facilmente, senza alcun tamburello.

Codice di esempio. Sulla base di un indicatore. L'indicatore è occupato ad allocare la memoria del buffer.

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

Quando start_pos = 0, il valore corrispondente alla 0a barra del grafico è sulla posizione 5. 1.017041 È sulla posizione 0 nel tuo EA. Ok.


Ma ho bisogno di ottenere questo valore in posizione zero.

Ho impostato start_pos = 5. Non ottengo il risultato di cui ho bisogno. Il valore che sto cercando è di nuovo alla posizione 5.


Ho impostato start_pos = -5. Non ottengo il risultato desiderato. Ancora una volta il valore che sto cercando è alla posizione 5.


Ho impostato start_pos = -10. E solo ora ottengo il risultato desiderato.


 
RickD:

Codice di esempio. In base all'indicatore. L'indicatore è occupato ad allocare la memoria del buffer.

Quando start_pos = 0, il valore corrispondente alla 0a barra del grafico lo vediamo sulla posizione 5. 1.017041 Nel tuo EA è sulla posizione 0. Ok.


Ma ho bisogno di ottenere questo valore in posizione zero.

Ho impostato start_pos = 5. Non ottengo il risultato desiderato. Il valore che sto cercando è di nuovo alla posizione 5.


Ho impostato start_pos = -5. Non ottengo il risultato desiderato. Ancora una volta il valore che sto cercando è alla posizione 5.


Ho impostato start_pos = -10. E solo ora ottengo il risultato desiderato.


Dobbiamo capire la differenza tra il lavoro dell'Expert Advisor e quello dell'indicatore. Per il lavoro da indicatore usate l'esempio dell'aiuto(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:

Devi capire la differenza tra operare da un EA e da un indicatore. Per lavorare da un indicatore, usate l'esempio della guida(iMA).

Quindi prendete un esempio dalla guida iMA, aggiungete

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

   Comment(comm);   

e verifica che il valore sia diverso dal valore di uscita del tuo EA esattamente di ma_shift di barre.

Io, invece, ho bisogno di ottenere nell'indicatore in iMABuffer[0] il valore che avete nel vostro Expert Advisor in array_ma[0].

Almeno al momento possiamo vedere che il comportamento di CopyBuffer per Expert Advisors e indicatori è diverso. Se capisci la differenza di CopyBuffer quando lavori con un EA e un indicatore, specifica la sezione appropriata della documentazione da studiare.

 

Cercherò di semplificare la domanda. Come faccio a portare questi valori MA (a partire dalla linea verticale rossa e verso sinistra) nel buffer dell'indicatore? Puoi scrivere un esempio?


 
RickD:

Cercherò di semplificare la domanda. Come faccio a portare questi valori MA (a partire dalla linea verticale rossa e verso sinistra) nel buffer dell'indicatore? Puoi scrivere un esempio?


Nella schermata, il display del buffer è spostato di cinque barre a destra. Quindi - per ottenere la quinta barra del buffer dell'indicatore (indice 4), e più a sinistra nella lista, da dove dovremmo prenderli? Da Buffer[4] e più a sinistra.

In teoria. In pratica - non ho aperto il codice dell'indicatore né ci ho lavorato per molto tempo - quasi un anno... Fate una prova.

 
Artyom Trishkin:


In teoria. In pratica - non ho aperto il codice dell'indicatore né ci ho lavorato per molto tempo - quasi un anno... Fate una prova.

Non si può perdere un'abilità.