Ecco la mia variante per risolvere il problema della ricerca a ripetizione:
//+------------------------------------------------------------------+//| FindRetryPrices.mq5 |//| Copyright 2016, Vasiliy Sokolov. |//| http://www.mql5.com |//+------------------------------------------------------------------+#property copyright"Copyright 2016, Vasiliy Sokolov."#property link"http://www.mql5.com"#property version"1.00"#include <Dictionary.mqh>
inputint RatesPeriod = 10; // Период за который ищутся повторенияinputint RoundPoints = 10; // Загрубление цены в прайсстепахclass CBar : public CObject
{
private:
MqlRates m_bar;
public:
CBar(MqlRates& bar){m_bar = bar;}
datetime Date(){return m_bar.time;}
doubleOpen(){return m_bar.open;}
doubleHigh(){return m_bar.high;}
doubleLow(){return m_bar.low;}
doubleClose(){return m_bar.close;}
};
//+------------------------------------------------------------------+//| Script program start function |//+------------------------------------------------------------------+voidOnStart()
{
// Нахождение повторяющихся баровMqlRates rates[];
int total = CopyRates(Symbol(), Period(), 0, RoundPoints, rates);
CDictionary* BarsCollections = new CDictionary(total);
for(int i = 0; i < total; i++)
{
double price = PriceToLevel(rates[i].high);
CBar* bar = new CBar(rates[i]);
if(!BarsCollections.ContainsKey(price))
BarsCollections.AddObject(price, new CList());
CList* equal_bars = BarsCollections.GetObjectByKey(price);
equal_bars.Add(bar);
}// Вывод повторов
FOREACH_DICT(BarsCollections)
{
CList* list = node;
if(list.Total() < 2)continue;
string retry_bars = "";
for(CBar* bar = list.GetFirstNode(); bar != NULL; bar = list.GetNextNode())
retry_bars += " [" + TimeToString(bar.Date()) + ", " + DoubleToString(bar.High(), Digits()) + "]";
printf("Обнаружено совпадение баров:" + retry_bars);
}
delete BarsCollections;
}
//+------------------------------------------------------------------+//| Округляет цену в соответствии с параметром RoundPoints |//+------------------------------------------------------------------+double PriceToLevel(double price)
{
double price_step = RoundPoints*Point();
double mn = MathFloor(price/price_step);
return mn * price_step;
}
//+------------------------------------------------------------------+
Perché lo script funzioni, il file Dictionary deve essere copiato in MQL5\Include
La ricerca viene eseguita nel ciclo for one-pass evidenziato in giallo. La lista risultante non contiene ripetizioni (se A ripete B e B ripete A, verrà emesso un insieme {A, B} invece di due {A, B} e {B, A}). ).
L'output di questo script ha mostrato quanto segue:
Ecco la mia versione della soluzione al problema della ricerca delle ripetizioni:
Grazie a tutti voi!!! Cercherò di capire tutto oggi. È importante non solo copiare un pezzo di codice in Expert Advisor, ma capire perché è scritto in questo modo, quindi forse farò altre domande.
Ecco la mia variante per risolvere il problema della ricerca delle ripetizioni:
Vasily, quando apro#include <Dictionary.mqh>, si apre come nel corpo dell'EA. Dovrebbe essere così, o dovrebbe esserci qualche altro codice all'interno?
Perché nel codice, che vedo, non è chiaro come cerca le ripetizioni ((
// строку int searchPeriod=(Search_Period<1)?1:Search_Period;// можно расписать так:inputint Search_Period=10; // Количество копируемых свечей ... эту строку вы видите в настройкахint searchPeriod; // Сюда будем записывать входной параметрif(Search_Period<1) searchPeriod=1; // Если во входном параметре ввели ноль или меньше нуля, то параметр будет равен нулюelse searchPeriod=Search_Period; // иначе примем входной параметр// соответственно и строку int delta=(Delta<0)?0:Delta;// можно расписать точно так же
È corretto supporre che questo sia un errore di battitura? Dovrebbe essere 0 invece di 1.
come questo:int searchPeriod=(Search_Period<1)?0:Search_Period;
e poi nello script eseguibile:
int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // il numero di candele da copiare
In questo caso, probabilmente dovremmo già usare una variabile: searchPeriod. giusto?
------
Un'altra domanda: cosa fa questa linea? Ho scoperto che ogni elemento della struttura si azzera. E non capisco cosa stiamo azzerando qui se sembra che abbiamo appena scritto questi dati e dovremmo usarli ulteriormente.
ZeroMemory(dataCandle); // Azzeramento dei dati nella struttura
È corretto supporre che questo sia un errore di battitura? Dovrebbe essere 0 invece di 1.
come questo:int searchPeriod=(Search_Period<1)?0:Search_Period;
e poi nello script eseguibile:
int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // il numero di candele da copiare
In questo caso, probabilmente dovremmo già usare una variabile: searchPeriod. giusto?
------
Un'altra domanda: cosa fa questa linea? Ho scoperto che ogni elemento della struttura si azzera. E non capisco cosa stiamo azzerando qui se sembra che abbiamo appena scritto questi dati e dovremmo usarli ulteriormente.
ZeroMemory(dataCandle); // cancellare i dati nella struttura
No, non lo è. Ecco come si ha (letteralmente): se Search_Period impostato dall'utente nelle impostazioni è inferiore a uno, allora searchPeriod sarà uguale a zero; altrimenti, searchPeriod sarà uguale al valore di Search_Period impostato dall'utente nelle impostazioni. Questo non è corretto. Non abbiamo bisogno di un intervallo di ricerca che sia uguale a zero. Quindi, se questo intervallo è impostato dall'utente a 0 o meno di zero (meno di uno), allora imposteremo questo intervallo uguale al minimo - uno.
"int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // numero di candele da copiare qui, in teoria, dovremmo già usare la variabile: searchPeriod. giusto? "
Sì, è vero, è un refuso.
"Un'altra domanda: cosa fa questa linea, a cosa serve? Ho scoperto che azzera ogni elemento della struttura. E qui non riesco a capire perché e cosa stiamo azzerando se abbiamo appena scritto questi dati e dovremmo usarli ulteriormente. ZeroMemory(dataCandle); // Azzeramento dei dati nella struttura".
Lo facciamo prima di riempire la struttura con i dati. Prima lo azzeriamo e poi lo riempiamo. Guarda - lo azzeriamo prima del ciclo. E poi nel ciclo riempiamo la struttura con i dati.
Ecco la mia variante per risolvere il problema della ricerca a ripetizione:
Perché lo script funzioni, il file Dictionary deve essere copiato in MQL5\Include
La ricerca viene eseguita nel ciclo for one-pass evidenziato in giallo. La lista risultante non contiene ripetizioni (se A ripete B e B ripete A, verrà emesso un insieme {A, B} invece di due {A, B} e {B, A}). ).
L'output di questo script ha mostrato quanto segue:
Dal riferimento:
Ecco la mia versione della soluzione al problema della ricerca delle ripetizioni:
Per favore aiutatemi a trovare una funzione per calcolare l'RSI standard, i requisiti sono semplici:
1. Restituisce il valore RSI a una data barra
2. Calcolare l'indice solo per quelle barre (se necessario), che sono richieste (desiderabile)
3. Essere in grado di calcolare sul TF specificato
4. Lavora a spese del punto 2 più velocemente dell'indicatore
Voglio integrare la funzione nell'Expert Advisor, se qualcuno ne ha una pronta, la prego di condividerla con me.
Lo chiedo perché l'indicatore è molto comune e non è un mistero.
Per favore aiutatemi a trovare una funzione per calcolare l'RSI standard, i requisiti sono semplici:
1. Restituisce il valore RSI a una data barra
2. Calcolare l'indice solo per quelle barre (se necessario), che sono richieste (desiderabile)
3. Essere in grado di calcolare sul TF specificato
4. Lavora a spese del punto 2 più velocemente dell'indicatore
Voglio integrare la funzione nell'EA, se qualcuno ne ha una pronta, la prego di condividerla con me.
Lo chiedo perché l'indicatore è molto comune e non è un mistero.
Cosa c'è di sbagliato nell'iRSI standard? Non abbastanza segreto?
Ci sono le mie modifiche che dovrò fare alla funzione...
Prendetene uno già pronto e modificatelo secondo le vostre esigenze:
Prendetene uno già pronto e modificatelo secondo le vostre esigenze:
Ecco la mia variante per risolvere il problema della ricerca delle ripetizioni:
Vasily, quando apro#include <Dictionary.mqh>, si apre come nel corpo dell'EA. Dovrebbe essere così, o dovrebbe esserci qualche altro codice all'interno?
Perché nel codice, che vedo, non è chiaro come cerca le ripetizioni ((
È corretto supporre che questo sia un errore di battitura? Dovrebbe essere 0 invece di 1.
come questo:int searchPeriod=(Search_Period<1)?0:Search_Period;
e poi nello script eseguibile:
int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // il numero di candele da copiare
In questo caso, probabilmente dovremmo già usare una variabile: searchPeriod. giusto?
------
Un'altra domanda: cosa fa questa linea? Ho scoperto che ogni elemento della struttura si azzera. E non capisco cosa stiamo azzerando qui se sembra che abbiamo appena scritto questi dati e dovremmo usarli ulteriormente.
ZeroMemory(dataCandle); // Azzeramento dei dati nella struttura
È corretto supporre che questo sia un errore di battitura? Dovrebbe essere 0 invece di 1.
come questo:int searchPeriod=(Search_Period<1)?0:Search_Period;
e poi nello script eseguibile:
int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // il numero di candele da copiare
In questo caso, probabilmente dovremmo già usare una variabile: searchPeriod. giusto?
------
Un'altra domanda: cosa fa questa linea? Ho scoperto che ogni elemento della struttura si azzera. E non capisco cosa stiamo azzerando qui se sembra che abbiamo appena scritto questi dati e dovremmo usarli ulteriormente.
ZeroMemory(dataCandle); // cancellare i dati nella struttura
"come questo:int searchPeriod=(Search_Period<1)?0:Search_Period;"
No, non lo è. Ecco come si ha (letteralmente): se Search_Period impostato dall'utente nelle impostazioni è inferiore a uno, allora searchPeriod sarà uguale a zero; altrimenti, searchPeriod sarà uguale al valore di Search_Period impostato dall'utente nelle impostazioni. Questo non è corretto. Non abbiamo bisogno di un intervallo di ricerca che sia uguale a zero. Quindi, se questo intervallo è impostato dall'utente a 0 o meno di zero (meno di uno), allora imposteremo questo intervallo uguale al minimo - uno.
"int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // numero di candele da copiare
qui, in teoria, dovremmo già usare la variabile: searchPeriod. giusto? "
Sì, è vero, è un refuso.
"Un'altra domanda: cosa fa questa linea, a cosa serve? Ho scoperto che azzera ogni elemento della struttura. E qui non riesco a capire perché e cosa stiamo azzerando se abbiamo appena scritto questi dati e dovremmo usarli ulteriormente. ZeroMemory(dataCandle); // Azzeramento dei dati nella struttura".
Lo facciamo prima di riempire la struttura con i dati. Prima lo azzeriamo e poi lo riempiamo. Guarda - lo azzeriamo prima del ciclo. E poi nel ciclo riempiamo la struttura con i dati.