Domande dai principianti MQL5 MT5 MetaTrader 5 - pagina 763

 
Vitaly Muzichenko:

Sembra così nei cicli, e si può fare a meno della funzione

Grazie.

Tuttavia, rimossa la funzione - i freni rimangono.... dannazione.

 
Aleksey Vyazmikin:

Grazie.

Tuttavia, rimossa la funzione - i freni rimangono.... Dannazione.

Una volta ho iniziato a riscrivere il programma da 4=>5, poi in 4, ho sostituito tutti i costrutti come Low[1], Time[0] e altri con quelli moderni, cioèCopyLow,CopyTime, il programma è diventato più veloce anche in 4. Ora non uso più i vecchi costrutti, solo quelli nuovi. Quindi il codice è facilmente portabile alla 5a piattaforma, basta cambiare le funzioni di trading

 
Vitaly Muzichenko:

Una volta che ho iniziato a riscrivere il programma da 4=>5 e poi ho sostituito tutti i costrutti come Low[1], Time[0] e altri con quelli moderni, cioèCopyLow,CopyTime, il programma è diventato più veloce anche in 4. Ora non uso più i vecchi costrutti, solo quelli nuovi. Quindi il codice è facilmente trasferibile alla 5a piattaforma, basta cambiare le funzioni di trading

Riempire l'array ad ogni starnuto non è un consumo di risorse?

Forse ha senso copiare le informazioni nell'array all'apertura della barra, e poi prenderle da lì mentre il codice si sviluppa? Faccio trading sull'apertura delle barre.


 
Aleksey Vyazmikin:

Riempire un array ad ogni starnuto non consuma risorse?

Forse ha senso copiare le informazioni in un array quando si apre una barra e poi prenderle da lì mentre il codice procede? Faccio trading sull'apertura delle barre.

L'array può essere riempito su una nuova barra, consumerà meno risorse. Se lavorate con iLow[1] in diversi posti, dovreste memorizzarlo in una variabile una volta e leggerlo al posto dell'array.

Supponiamo che questo

// Инициализация TIME[0] TIME[1]
  ArraySetAsSeries(TM,true);
  if(CopyTime(dSymbol,Period(),0,2,TM)<0) return;
  TIME_0=TM[0];
  TIME_1=TM[1];
Allora lavoriamo con le variabiliTIME_0 eTIME_1 invece diTM[0] eTM[1].
 
Vitaly Muzichenko:

L'array può essere riempito su una nuova barra, richiederà meno risorse. Se lavorate con iLow[1] in diversi posti, per esempio, è auspicabile scriverlo una volta in una variabile, e leggere la variabile invece dell'array.

Supponiamo così

Ma comunque, MT4 è molto più veloce - sono deluso.

 

Forum sul trading, sistemi di trading automatico e test di strategie di trading

Bug, bug, domande

Aleksey Vyazmikin, 2017.07.21 15:07

Perché stai fantasticando? Ho capito la tua idea e ho confermato che funziona, e avrà un effetto se la richiesta avviene una volta e se si sa quante barre sono necessarie perché l'EA funzioni.

O forse hai suggerito di usare la struttura in un modo diverso? Allora per favore spiega, ma non ti offendere!


Nessuna fantasia. Se avete bisogno di ottenere 2 o più parametri di una candela, allora usando le funzioni dei vostri messaggi/domande dovremo chiamare queste funzioni separatamente per ogni parametro della candela. Cioè 2 o più volte per produrre Copy***(), ma usando CopyRates() avete bisogno di una sola chiamata di Copy.

Per quanto riguarda il numero da copiare, questa è un'altra domanda. Forse dovremmo prima calcolare la barra che contiene il valore dell'indicatore richiesto e poi copiarla. Se ricordo bene, si parlava di una quantità sconosciuta da copiare. Di che tipo di fantasia stiamo parlando?

In casi estremi, possiamo copiare, per esempio, 10 barre e cercare tra di esse. Se non si trova, copiamo altre 10 barre. Copiare è un'operazione che richiede tempo, è più economico copiare un array.

In generale, ci sono molte variazioni. Non puoi scrivere tutto questo nella documentazione e non sarà affatto una documentazione. Lo insegnano alle lezioni di programmazione. Ma, purtroppo, non tutti gli insegnanti sono in grado di farlo e non tutti gli studenti vogliono capirlo a lezione. E l'inizio è alle lezioni di aritmetica nei gradi 2-5, quando l'insegnante richiede una spiegazione dettagliata del problema. Ma qui i problemi sono gli stessi.

 
Alexey Viktorov:

Niente roba di lusso. Se hai bisogno di ottenere 2 o più parametri di una candela, allora usando le funzioni dei tuoi messaggi/domande dovresti chiamare queste funzioni separatamente per ogni parametro della candela. Cioè 2 o più volte per eseguire Copy***(), ma usando CopyRates() avrete bisogno di una sola chiamata di Copy.

Per quanto riguarda il numero da copiare, questa è un'altra domanda. Forse dovremmo prima calcolare su quale barra è disponibile il valore corretto dell'indicatore, e poi copiarlo. Se ricordo bene, si parlava di una quantità sconosciuta da copiare. Di che tipo di fantasia stiamo parlando?

E, come ultima risorsa, possiamo copiare, diciamo, 10 barre e cercarle e, se non lo troviamo, copiamo altre 10 barre. Copiare è un'operazione piuttosto costosa; sarebbe più economico cercare nell'array.

Ci sono molte varianti in questo caso. Tutto questo non può essere scritto nella documentazione; in realtà, non sarà più documentazione. Lo insegnano alle lezioni di programmazione. Ma, purtroppo, non tutti gli insegnanti sanno come farlo e non tutti gli studenti vogliono capirlo durante le lezioni. E l'inizio è alle lezioni di aritmetica nei gradi 2-5, quando l'insegnante richiede una spiegazione dettagliata del problema. Ma qui i problemi sono gli stessi.

Sulla fantasia - era una risposta alla tua affermazione "Invece di cercare di capire quello che è stato detto, di capire cosa si ottiene, fai delle obiezioni incredibili", e non al fatto che la versione che hai offerto è del campo della fantasia.

Capisco perfettamente il tuo concetto, ed era incorporato nella risposta a te.

Tuttavia, non capisco bene come proponi di lavorare con una quantità sconosciuta di dati - puoi darmi un esempio sotto forma di codice?


 

Si prega di aiutare nella verifica e nell'ottimizzazione dell'indicatore utilizzando questo link https://www.mql5.com/ru/code/16805 - il problema è che l'indicatore inizia a rallentare molto quando appare un gran numero di barre - si manifesta durante i test.

Voglio sapere come farlo funzionare in modo che non venga calcolato su ogni tick, ma solo all'apertura della barra? Il metodo dell'Expert Advisor non è adatto - dopo il primo tick tutti i valori scompaiono e appaiono solo sulla barra successiva...

Donchian Channel MTF
Donchian Channel MTF
  • voti: 13
  • 2016.12.13
  • Mladen Rakic
  • www.mql5.com
Мультитаймфреймовая версия канала Дончиана.
 
Aleksey Vyazmikin:

Riguardo alla fantasia - era una risposta alla tua affermazione "Invece di cercare di capire quello che si dice, di capire cosa funzionerà, si tirano fuori delle obiezioni incredibili", e non che l'opzione che hai proposto sia del regno della fantasia.

Capisco perfettamente il tuo concetto, ed era incorporato nella risposta a te.

Tuttavia, non capisco bene come proponi di gestire una quantità sconosciuta di dati - puoi darmi un esempio sotto forma di codice?


La risposta è stata data prima...

Alexey Viktorov:

Come ultima risorsa, potete copiare, diciamo, 10 barre alla volta e cercare tra di esse; se non lo trovate, ne copiate altre 10. La copia è un'operazione costosa, è più economico cercare attraverso l'array.

Ma è meglio non cercare di ottenere il numero massimo di barre dall'array, ma cercare di fare con una copia.

Non ho intenzione di scrivere un esempio di codice. Un normale programmatore ha solo bisogno di un suggerimento. Ecco un algoritmo di esempio:

  1. Determinare il numero approssimativo di barre in cui il canale è attraversato. Che siano 15.
  2. Copia entrambi i buffer dell'indicatore.
  3. Copiare i valori delle barre usando CopyRates()
  4. Nel ciclo, iniziamo a confrontare i valori del limite superiore del canale e delle barre alte simultaneamente al confronto delle barre basse con il limite inferiore del canale. Se uno di questi incroci viene trovato, l'indice della barra viene memorizzato in una variabile, e si continua a cercare il secondo incrocio. Usciamo dal ciclo quando entrambe le variabili delle barre di intersezione hanno dei valori.

Così, è possibile trovare due intersezioni in una copia e un ciclo, se necessario. Non c'è nemmeno bisogno di ArraySetAsSeries() perché quando si trova l'incrocio è possibile e, secondo me, meglio ricordare il tempo della barra, non il suo numero. Anche se, conoscendo l'ora del bar, non c'è difficoltà a determinarne il numero.

Domanda: cosa è più veloce, un ciclo con la copia del buffer dell'indicatore di 1 valore e la copia della barra alta di 1 e il confronto di questi valori o una singola copia di una certa quantità e il confronto dei valori dei due array tra loro?

 

L'ho scritto proprio ieri:

Compito:

su ogni tick ottenere "InpCountCopy" elementi aperti, alti, bassi, chiusi e tempo.

Attuazione:

  1. loop da "0" a "InpCountCopy-1" - il loop prende un open, high, low, close e time alla volta.
  2. In una volta otteniamo elementi "InpCountCopy" nella struttura MqlRates e poi facciamo un ciclo attraverso la struttura.

Caratteristiche:

Potete scegliere come controllare: in OnTick o in OnTimer (1 secondo).

//+------------------------------------------------------------------+
//|                                      Copy OHLC vc Copy Rates.mq5 |
//|                              Copyright © 2017, Vladimir Karputov |
//|                                           http://wmua.ru/slesar/ |
//+------------------------------------------------------------------+
#property copyright "Copyright © 2017, Vladimir Karputov"
#property link      "http://wmua.ru/slesar/"
#property version   "1.001"
//--- input parameter
input int InpCountCopy=1000;
input bool OnTickOnTimer=false; // OnTickOnTimer: false -> OnTick, true -> OnTimer 1 second
//+------------------------------------------------------------------+
//| Expert initialization function                                   |
//+------------------------------------------------------------------+
int OnInit()
  {
//---
   if(OnTickOnTimer)
      EventSetTimer(1);
//---
   return(INIT_SUCCEEDED);
  }
//+------------------------------------------------------------------+
//| Expert deinitialization function                                 |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
  {
//---

  }
//+------------------------------------------------------------------+
//| Expert tick function                                             |
//+------------------------------------------------------------------+
void OnTick()
  {
   if(OnTickOnTimer)
      return;
   Testing();
  }
//+------------------------------------------------------------------+
//| Timer function                                                   |
//+------------------------------------------------------------------+
void OnTimer()
  {
   if(!OnTickOnTimer)
      return;
   Testing();
  }
//+------------------------------------------------------------------+
//| Main function                                                    |
//+------------------------------------------------------------------+
void Testing()
  {
//--- for once one element
   ulong start=GetMicrosecondCount();
   for(int i=0;i<InpCountCopy;i++) // in one operation we get one element.
     {
      double open=iOpen(i);
      double high=iHigh(i);
      double low=iLow(i);
      double close=iClose(i);
      datetime time=iTime(i);
     }
   ulong end=GetMicrosecondCount()-start;
   string text=(OnTickOnTimer)?"OnTimer":"OnTick";
   text=text+"\n"+"OHLC: "+IntegerToString(end);

//--- for one operation we get "InpCountCopy" elements.
   start=GetMicrosecondCount();
   MqlRates Rates[];
   if(!iRates(Rates,0,InpCountCopy))
      return;
   for(int i=0;i<InpCountCopy;i++)
     {
      double open=Rates[i].open;
      double high=Rates[i].high;
      double low=Rates[i].low;
      double close=Rates[i].close;
      datetime time=Rates[i].time;
     }
   end=GetMicrosecondCount()-start;
   text=text+"\n"+"Rates: "+IntegerToString(end);

   Comment(text);
  }
//+------------------------------------------------------------------+ 
//| Get Open for specified bar index                                 | 
//+------------------------------------------------------------------+ 
double iOpen(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Open[1];
   double open=0;
   int copied=CopyOpen(symbol,timeframe,index,1,Open);
   if(copied==1)
      open=Open[0];
   return(open);
  }
//+------------------------------------------------------------------+ 
//| Get the High for specified bar index                             | 
//+------------------------------------------------------------------+ 
double iHigh(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double High[1];
   double high=0;
   int copied=CopyHigh(symbol,timeframe,index,1,High);
   if(copied==1)
      high=High[0];
   return(high);
  }
//+------------------------------------------------------------------+ 
//| Get Low for specified bar index                                  | 
//+------------------------------------------------------------------+ 
double iLow(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   double Low[1];
   double low=0;
   int copied=CopyLow(symbol,timeframe,index,1,Low);
   if(copied==1)
      low=Low[0];
   return(low);
  }
//+------------------------------------------------------------------+ 
//| 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==1)
      close=Close[0];
   return(close);
  }
//+------------------------------------------------------------------+ 
//| Get Time for specified bar index                                 | 
//+------------------------------------------------------------------+ 
datetime iTime(const int index,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   datetime Time[1];
   datetime time=0;
   int copied=CopyTime(symbol,timeframe,index,1,Time);
   if(copied==1)
      time=Time[0];
   return(time);
  }
//+------------------------------------------------------------------+ 
//| Get Rates for specified bar index                                | 
//+------------------------------------------------------------------+ 
bool iRates(MqlRates  &Rates[],const int index,int count,string symbol=NULL,ENUM_TIMEFRAMES timeframe=PERIOD_CURRENT)
  {
   if(symbol==NULL)
      symbol=Symbol();
   if(timeframe==0)
      timeframe=Period();
   int copied=CopyRates(symbol,timeframe,index,count,Rates);
   if(copied!=count)
      return(false);
//---
   return(true);
  }
//+------------------------------------------------------------------+


Motivazione: