Domande dai principianti MQL5 MT5 MetaTrader 5 - pagina 573

 
Andrey Koldorkin:

Vedrò cosa riesco a capire. Grazie.

Non c'è di che. Salva semplicemente tutti gli alti in un array, e poi stampa tutti i dati salvati nell'array nel log in un ciclo.

Questo script non necessariamente fa esattamente quello di cui avete bisogno. Mostra semplicemente come i dati sono memorizzati nell'array.

 
Artyom Trishkin:

Niente affatto. Semplicemente salva tutti gli alti in un array, e poi stampa tutti i dati salvati nell'array in un ciclo nel registro.

Questo script non fa necessariamente quello di cui avete bisogno. Mostra solo il principio del salvataggio dei dati in un array.

È esattamente quello che stavo cercando. Avevo bisogno che salvasse in qualche modo i dati in un array per il periodo scelto. Questa è la parte che ho capito da te.

Ora la mia domanda è: come posso accedere e confrontare i dati registrati nell'array?

Qui risulta di iterare, scrivere l'array passo dopo passo. Questo è buono. Ma ora dobbiamo confrontare gli elementi tra loro.

È necessario dichiarare un nuovo conteggio delle iterazioni e poi recuperare i dati e confrontarli in qualche modo? Ma questo ancora una volta deve scrivere i risultati da qualche parte e ... Alla fine tutto si ripete.

Approssimativamente, se il periodo di confronto è di 5-7 candele, allora il 1° dovrebbe essere confrontato con altri 6, poi il 2° e così via.... E se due o più di loro hanno un alto uguale, allora in primo luogo, si dovrebbe calcolare questo alto, e in secondo luogo, si dovrebbe trovare la candela con il basso più basso. Cioè la funzione di chiamare le candele concrete alla fine per recuperare tutti i loro parametri.

Ma è possibile farlo?

 
Andrey Koldorkin:

Questo è esattamente quello che stavo cercando. Quello di cui avevo bisogno era salvare in qualche modo i dati in un array per il periodo che stavo selezionando. Ho capito quella parte.

Ora la mia domanda è: come posso accedere e confrontare i dati registrati nell'array?

Qui risulta di iterare, scrivere l'array passo dopo passo. Questo è buono. Ma ora dobbiamo confrontare gli elementi tra loro.

È necessario dichiarare un nuovo conteggio delle iterazioni e poi recuperare i dati e confrontarli in qualche modo? Ma questo ancora una volta deve scrivere i risultati da qualche parte e ... Alla fine tutto si ripete.

Approssimativamente, se il periodo di confronto è di 5-7 candele, allora il 1° dovrebbe essere confrontato con altri 6, poi il 2° e così via.... E se due o più di loro hanno un alto uguale, allora in primo luogo, si dovrebbe calcolare questo alto, e in secondo luogo, si dovrebbe trovare la candela con il basso più basso. Cioè la funzione di chiamare le candele concrete alla fine per recuperare tutti i loro parametri.

Ma è possibile farlo?

Qui stiamo solo interrogando l'array salvato e visualizzando tutti i dati salvati nel log:

for(int i=0; i<ArrayRange(mass_high,0); i++) {
   printf("Время: %s, High: %.5f",TimeToString((int)mass_high[i][1],TIME_DATE|TIME_MINUTES),mass_high[i][0]);
   }

Cerchiamo di essere più specifici sul compito:

Abbiamo bisogno di trovare ... cosa esattamente nell'array salvato?

 
Artyom Trishkin:

Qui è dove viene interrogato l'array salvato e tutti i dati salvati vengono registrati:

Cerchiamo di essere specifici sul compito:

Dobbiamo trovare nell'array salvato ... cosa esattamente?

Ho bisogno di registrare un array di dati per tutte le candele chiuse (cioè quella attuale non viene contata) - High, Low, Open, Close (4 parametri) per il periodo specificato nelle impostazioni. - è.

Poi, ho bisogno di confrontare i parametri. Supponiamo che il periodo di ricerca sia uguale a 10 candele. Qui dobbiamo controllare tutti gli alti per il periodo di 10 candele. Se ci sono due o più partite, dovremmo ritornare:

1. Bandiera - "C'è una corrispondenza".

1. Il valore massimo in cui le candele hanno lo stesso valore.

2. Numeri di queste candele, così possiamo fare riferimento a loro e trovare i parametri Low, Close, Open per loro.

In generale, capisco molto di questo come fare.

Ciò che non è chiaro è come riferirsi a quelle candele che formano il livello. Idealmente, quando si ricalcola, si potrebbe memorizzare il numero di iterazione (i) ma prima c'è un ricalcolo secondo il quale il registro viene scritto e non può essere applicato.

E in quella variante, come il registro di uscita registra - anche qui, non è quello che è richiesto.

Ho capito che devo prima prendere una candela 1 e confrontarla con altre 9, se c'è una corrispondenza, poi estrarre i numeri di queste candele e i loro parametri, attivare la casella di controllo. Poi controlla la candela 2 con le altre e così via fino alla metà del campione, come poi andranno i duplicati dei confronti solo dall'altro lato.

Se il numero di candele fosse stato fisso, l'avrei scritto così: circa 5 cicli di confronto. Ma questa è la domanda - come rendere possibile tale ricalcolo per qualsiasi dimensione del campione.

 
Andrey Koldorkin:

Ho bisogno di scrivere un array di dati per tutte le candele chiuse (cioè quella attuale non viene contata) - candele High, Low, Open, Close (4 parametri) per il periodo specificato nelle impostazioni. - è.

Poi, ho bisogno di confrontare i parametri. Supponiamo che il periodo di ricerca sia uguale a 10 candele. Qui dobbiamo controllare tutti gli alti per il periodo di 10 candele. Se ci sono due o più partite, dovremmo ritornare:

1. Bandiera - "C'è una corrispondenza".

1. Il valore massimo in cui le candele hanno lo stesso valore.

2. Numeri di queste candele, così possiamo fare riferimento a loro e trovare i parametri Low, Close, Open per loro.

In generale, capisco molto di questo come fare.

Ciò che non è chiaro è come riferirsi a quelle candele che formano il livello. Idealmente, quando si ricalcola, si potrebbe memorizzare il numero di iterazione (i) ma prima c'è un ricalcolo secondo il quale il registro viene scritto e non può essere applicato.

E in quella variante, come registra il registro di uscita - anche questo non è ciò che è richiesto.

Ho capito che devo prima prendere una candela 1 e confrontarla con altre 9, se c'è una corrispondenza, poi estrarre i numeri di queste candele e i loro parametri, attivare la casella di controllo. Poi controlla la candela 2 con le altre e così via fino alla metà del campione, come poi andranno i duplicati dei confronti solo dall'altro lato.

Se il numero di candele fosse stato fisso, l'avrei scritto così: circa 5 cicli di confronto. Ma questa è la domanda - come rendere possibile un tale ricalcolo per qualsiasi dimensione del campione.

E a proposito, è improbabile che la coincidenza esatta dei valori dei prezzi sia frequente. Dobbiamo impostare un certo delta, e considerare una coincidenza se i prezzi non differiscono più di questo valore.

Quindi, se abbiamo bisogno di una lista diversa di candele corrispondenti per ogni candela nell'intervallo, proverei a usare un array di strutture. Ci penserò e vi farò sapere.
 
Andrey Koldorkin:

Ho bisogno di scrivere un array di dati per tutte le candele chiuse (cioè quella attuale non viene contata) - candele High, Low, Open, Close (4 parametri) per il periodo specificato nelle impostazioni. - è.

Poi, ho bisogno di confrontare i parametri. Supponiamo che il periodo di ricerca sia uguale a 10 candele. Qui dobbiamo controllare tutti gli alti per il periodo di 10 candele. Se ci sono due o più partite, dovremmo ritornare:

1. Bandiera - "C'è una corrispondenza".

1. Il valore massimo in cui le candele hanno lo stesso valore.

2. Numeri di queste candele, così possiamo fare riferimento a loro e trovare i parametri Low, Close, Open per loro.

In generale, capisco molto di questo come fare.

Ciò che non è chiaro è come riferirsi a quelle candele che formano il livello. Idealmente, quando si ricalcola, si potrebbe memorizzare il numero di iterazione (i) ma prima c'è un ricalcolo secondo il quale il registro viene scritto e non può essere applicato.

E in quella variante, come registra il registro di uscita - anche questo non è ciò che è richiesto.

Ho capito che devo prima prendere una candela 1 e confrontarla con altre 9, se c'è una corrispondenza, poi estrarre i numeri di queste candele e i loro parametri, attivare la casella di controllo. Poi controlla la candela 2 con le altre e così via fino alla metà del campione, come poi andranno i duplicati dei confronti solo dall'altro lato.

Se il numero di candele fosse stato fisso, l'avrei scritto così: circa 5 cicli di confronto. Ma questa è la domanda - come permettere un tale ricalcolo per qualsiasi dimensione del campione.

Invece di flag "coincidenza" impostare il contatore, sul valore alto dove il contatore è più grande, c'è un livello

Il valore alto può essere arrotondato per eccesso, per esempio 1,23456 a 1,2346

e 1,23462 arrotondato a 1,2346

perché è improbabile che su 10 candele, 2 abbiano un massimo di 1,23456

quindi danzare dal livello

e il numero di candele è fisso, si scrive una certa quantità di dati nella struttura

cioè il numero di candele scritte nella struttura è lo stesso numero di iterazioni

 
Andrey Koldorkin:

Ho bisogno di scrivere un array di dati per tutte le candele chiuse (cioè quella attuale non viene contata) - candele High, Low, Open, Close (4 parametri) per il periodo specificato nelle impostazioni. - è.

Poi, ho bisogno di confrontare i parametri. Supponiamo che il periodo di ricerca sia uguale a 10 candele. Qui dobbiamo controllare tutti gli alti per il periodo di 10 candele. Se ci sono due o più partite, dovremmo ritornare:

1. Bandiera - "C'è una corrispondenza".

1. Il valore alto in cui le candele hanno lo stesso valore.

2. Numeri di queste candele, così possiamo fare riferimento a loro e trovare i parametri Low, Close, Open per loro.

In generale, capisco molto di questo come fare.

Ciò che non è chiaro è come riferirsi a quelle candele che formano il livello. Idealmente, quando si ricalcola, si potrebbe memorizzare il numero di iterazione (i) ma prima c'è un ricalcolo secondo il quale il registro viene scritto e non può essere applicato.

E in quella variante, come registra il registro di uscita - anche questo non è ciò che è richiesto.

Ho capito che devo prima prendere una candela 1 e confrontarla con altre 9, se c'è una corrispondenza, poi estrarre i numeri di queste candele e i loro parametri, attivare la casella di controllo. Poi controlla la candela 2 con le altre e così via fino alla metà del campione, come poi andranno i duplicati dei confronti solo dall'altro lato.

Se il numero di candele fosse stato fisso, l'avrei scritto così: circa 5 cicli di confronto. Ma ecco la domanda: come rendere possibile un tale ricalcolo per qualsiasi dimensione del campione.

È un compito interessante, ma la tua comprensione di come risolvere questo problema non è corretta, perché finora non hai molte conoscenze di programmazione.

Guarda: hai una serie di citazioni. Il tuo compito è quello di scegliere da questo insieme solo le barre che soddisfano determinate condizioni. Per esempio, si vuole ottenere un insieme di barre, i cui massimi coincidono tra loro. In effetti, ci possono essere molte condizioni per la selezione, e possono essere aggiunte nel tempo. Una volta che avete una collezione di barre, potete facilmente analizzare qualsiasi altro loro parametro.

Quindi, per il vostro compito, dovete scrivere una funzione che restituisca un array di barre che soddisfano una certa condizione (pseudocodice):

массив_баров = ПолучитьНужныеБары(Символ(), Таймфрейм(), Период(), УсловиеОтбора);
Cioè non c'è davvero nessun problema nel ricordare e iterare alcuni dati e indici. Non avete bisogno degli indici delle barre stesse, ma di una collezione specifica che soddisfi una data condizione. Una volta che ce l'hai, risolvi un sacco di problemi in un colpo solo.
 
Artyom Trishkin:
Quindi, se abbiamo bisogno di una lista diversa di candele corrispondenti per ogni candela nell'intervallo, proverei a usare un array di strutture. Ci penserò e vi farò sapere.

Pensiero. Sto scrivendo uno script di test:

//+------------------------------------------------------------------+
//|                                                     TestCopy.mq4 |
//|              Copyright 2016, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Artem A. Trishkin, Skype artmedia70"
#property link      "https://login.mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property strict
#property script_show_inputs
//--- input parameters
input int Search_Period=10;   // Количество копируемых свечей
int searchPeriod=(Search_Period<1)?1:Search_Period;
input int Delta=2;            // Количество пунктов допуска
int delta=(Delta<0)?0:Delta;
MqlRates array[];             // Массив структур для копирования Open, High, Low, Close, Time
  
struct DataCandle             // Структура для хранения всех совпадений
  {
   int number_matched;           // Количество совпадений
   MqlRates reference_candle;    // Данные эталонной свечи
   MqlRates matched_candles[];   // Массив свечей, совпадающих с эталонной по нужному критерию 
  };
  DataCandle dataCandle[];    // Массив структур данных свечей и их совпадений
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period()));   // количество копируемых свечей
   int copied=CopyRates(Symbol(),PERIOD_CURRENT,1,copy_bars,array);  // копируем данные
   if(copied>0) {                                                    // если скопировали
      ArrayResize(dataCandle,copied);                                // задаём размер структуры равным числу скопированных данных
      ZeroMemory(dataCandle);                                        // Обнуляем данные в структуре
      //--- основной цикл по "эталонным" свечам в массиве array. Их параметры будем искать в доп. цикле
      for(int i=0; i<copy_bars-1; i++) {                             // цикл по скопированным данным от начала до "на один меньше размера массива"
         dataCandle[i].reference_candle.high=array[i].high;          // ищем этот high
         dataCandle[i].reference_candle.low=array[i].low;            // запомнили low для сравнения
         dataCandle[i].reference_candle.time=array[i].time;          // запомнили time для вывода в журнал
         //--- поиск совпадений с эталонной свечой, индексируемой индексом основного цикла i
         int size=0;                                                 // размер массива совпадающих свечей
         ArrayResize(dataCandle[i].matched_candles,size);            // Размер массива совпадений в ноль
         dataCandle[i].number_matched=size;                          // Инициализируем количество совпадений нулём
         //--- теперь ищем совпадения по high свечей в цикле j с high эталонной свечи с индексом i
         for(int j=i+1; j<copy_bars; j++) {                          // в цикле от i+1 до copy_bars
            //--- если совпадают high эталонной свечи (i) и свечи с индексом j (с допуском на величину delta*Point)
            if(NormalizeDouble(delta*Point()-fabs(array[i].high-array[j].high),Digits())>=0) {
               size++;                                               
               ArrayResize(dataCandle[i].matched_candles,size);            // увеличим размер массива совпадающих свечей
               dataCandle[i].number_matched=size;                          // запишем количество совпадений
               dataCandle[i].matched_candles[size-1].high=array[j].high;   // запишем в массив high совпадающей свечи
               dataCandle[i].matched_candles[size-1].low=array[j].low;     // запишем в массив low совпадающей свечи
               dataCandle[i].matched_candles[size-1].time=array[j].time;   // запишем в массив время совпадающей свечи
               //Print("Время свечи ",i," :",TimeToString(dataCandle[i].reference_candle.time=array[i].time),", high=",DoubleToString(dataCandle[i].reference_candle.high=array[i].high,Digits()),". Совпадение со свечой ",TimeToString(dataCandle[i].matched_candles[size-1].time=array[j].time),", её high ",DoubleToString(dataCandle[i].matched_candles[size-1].high=array[j].high,Digits()),". Совпадений: ",(string)dataCandle[i].number_matched);
               }
            }
         }
      }

   //--- Посмотрим чего понаписали в массивы
   for(int i=0; i<ArraySize(dataCandle)-1; i++) {
      string refs_txt="";
      string matched_txt="";
      refs_txt="Свеча "+IntegerToString(i,2,'0')+": время "+TimeToString(dataCandle[i].reference_candle.time)+", high: "+DoubleToString(dataCandle[i].reference_candle.high,Digits())+" имеет совпадений: "+(string)dataCandle[i].number_matched+" шт. ";
      if(dataCandle[i].number_matched>0) {
         for(int j=0; j<ArraySize(dataCandle[i].matched_candles); j++) {
            matched_txt="Совпадение "+IntegerToString(j+1)+": "+TimeToString(dataCandle[i].matched_candles[j].time)+", high: "+DoubleToString(dataCandle[i].matched_candles[j].high,Digits());
            }
         }
      Print(refs_txt,matched_txt);
      }
  }
//+------------------------------------------------------------------+

Ho cercato di descrivere tutti i passi.

Dopo aver riempito tutte le partite nel ciclo, abbiamo un array che contiene tutti i candelieri e i loro candelieri corrispondenti. Dopo di che si può cercare in basso. E puoi organizzarlo direttamente nel ciclo. È più conveniente per voi.

 

Bene, ecco un altro modo per farlo: le partite sono scritte per ogni candela nel range. Nella versione precedente, le corrispondenze venivano scritte solo per una candela - cioè non veniva scritta nessuna corrispondenza per quella che corrispondeva a questa.

//+------------------------------------------------------------------+
//|                                                     TestCopy.mq4 |
//|              Copyright 2016, Artem A. Trishkin, Skype artmedia70 |
//|                       https://login.mql5.com/ru/users/artmedia70 |
//+------------------------------------------------------------------+
#property copyright "Copyright 2016, Artem A. Trishkin, Skype artmedia70"
#property link      "https://login.mql5.com/ru/users/artmedia70"
#property version   "1.00"
#property strict
#property script_show_inputs
//--- input parameters
input int Search_Period=10;   // Количество копируемых свечей
int searchPeriod=(Search_Period<1)?1:Search_Period;
input int Delta=2;            // Количество пунктов допуска
int delta=(Delta<0)?0:Delta;
MqlRates array[];             // Массив структур для копирования Open, High, Low, Close, Time
  
struct DataCandle             // Структура для хранения всех совпадений
  {
   int number_matched;           // Количество совпадений
   MqlRates reference_candle;    // Данные эталонной свечи
   MqlRates matched_candles[];   // Массив свечей, совпадающих с эталонной по нужному критерию 
  };
  DataCandle dataCandle[];    // Массив структур данных свечей и их совпадений
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
   int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period()));   // количество копируемых свечей
   int copied=CopyRates(Symbol(),PERIOD_CURRENT,1,copy_bars,array);  // копируем данные
   if(copied>0) {                                                    // если скопировали
      ArrayResize(dataCandle,copied);                                // задаём размер структуры равным числу скопированных данных
      ZeroMemory(dataCandle);                                        // Обнуляем данные в структуре
      //--- основной цикл по "эталонным" свечам в массиве array. Их параметры будем искать в доп. цикле
      for(int i=0; i<copy_bars; i++) {                               // цикл по скопированным данным от начала до конца
         dataCandle[i].reference_candle.high=array[i].high;          // ищем этот high
         dataCandle[i].reference_candle.low=array[i].low;            // запомнили low для сравнения
         dataCandle[i].reference_candle.time=array[i].time;          // запомнили time для вывода в журнал
         //--- поиск совпадений с эталонной свечой, индексируемой индексом основного цикла i
         int size=0;                                                 // размер массива совпадающих свечей
         ArrayResize(dataCandle[i].matched_candles,size);            // Размер массива совпадений в ноль
         dataCandle[i].number_matched=size;                          // Инициализируем количество совпадений нулём
         //--- теперь ищем совпадения по high свечей в цикле j с high эталонной свечи с индексом i
         for(int j=0; j<copy_bars; j++) {                            // в цикле от 0 до copy_bars
            if(j==i) continue;                                       // пропустим свечу "саму себя"
            //--- если совпадают high эталонной свечи (i) и свечи с индексом j (с допуском на величину Point)
            if(NormalizeDouble(delta*Point()-fabs(array[i].high-array[j].high),Digits())>=0) {
               size++;                                               
               ArrayResize(dataCandle[i].matched_candles,size);            // увеличим размер массива совпадающих свечей
               dataCandle[i].number_matched=size;                          // запишем количество совпадений
               dataCandle[i].matched_candles[size-1].high=array[j].high;   // запишем в массив high совпадающей свечи
               dataCandle[i].matched_candles[size-1].low=array[j].low;     // запишем в массив low совпадающей свечи
               dataCandle[i].matched_candles[size-1].time=array[j].time;   // запишем в массив время совпадающей свечи
               //Print("Время свечи ",i," :",TimeToString(dataCandle[i].reference_candle.time=array[i].time),", high=",DoubleToString(dataCandle[i].reference_candle.high=array[i].high,Digits()),". Совпадение со свечой ",TimeToString(dataCandle[i].matched_candles[size-1].time=array[j].time),", её high ",DoubleToString(dataCandle[i].matched_candles[size-1].high=array[j].high,Digits()),". Совпадений: ",(string)dataCandle[i].number_matched);
               }
            }
         }
      }

   //--- Посмотрим чего понаписали в массивы
   for(int i=0; i<ArraySize(dataCandle)-1; i++) {
      string refs_txt="";
      string matched_txt="";
      refs_txt="Свеча "+IntegerToString(i,2,'0')+": время "+TimeToString(dataCandle[i].reference_candle.time)+", high: "+DoubleToString(dataCandle[i].reference_candle.high,Digits())+" имеет совпадений: "+(string)dataCandle[i].number_matched+" шт. ";
      if(dataCandle[i].number_matched>0) {
         for(int j=0; j<ArraySize(dataCandle[i].matched_candles); j++) {
            matched_txt+=" Совпадение "+IntegerToString(j+1)+": "+TimeToString(dataCandle[i].matched_candles[j].time)+", high: "+DoubleToString(dataCandle[i].matched_candles[j].high,Digits());
            }
         }
      Print(refs_txt,matched_txt);
      }
  }
//+------------------------------------------------------------------+
 
L'idea di aprire ordini su un segnale di acquisto o di presa dell'orso, come fare in modo che ci sia solo un trade di acquisto/vendita e un trade di ordine pendente, ne ho uno aperto su ogni tick del trade. Aiuta a risolvere il problema.
File:
ritfv.png  46 kb
ohs.txt  5 kb