Fragen von Anfängern MQL5 MT5 MetaTrader 5 - Seite 575

 

Hier ist meine Variante, das Problem der Wiederholungssuche zu lösen:

//+------------------------------------------------------------------+
//|                                              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>

input int RatesPeriod = 10;                        // Период за который ищутся повторения
input int RoundPoints = 10;                        // Загрубление цены в прайсстепах
class CBar : public CObject
{
private:
   MqlRates m_bar;
public:
            CBar(MqlRates& bar){m_bar = bar;}
   datetime Date(){return m_bar.time;}
   double Open(){return m_bar.open;}
   double High(){return m_bar.high;}
   double Low(){return m_bar.low;}
   double Close(){return m_bar.close;}
};
//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
{
   // Нахождение повторяющихся баров
   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;
}

//+------------------------------------------------------------------+

Damit das Skript funktioniert, muss die Dictionary-Datei in MQL5\Include kopiert werden

Die Suche wird in der gelb markierten for-Schleife in einem Durchgang durchgeführt. Die resultierende Liste enthält keine Wiederholungen (wenn A B wiederholt und B A wiederholt, wird eine Menge {A, B} anstelle von zwei {A, B} und {B, A} ausgegeben). ).

Die Ausgabe dieses Skripts zeigt Folgendes:

2016.05.10 11:09:06.730 FindRetryPrices (Si Splice,M1)  Обнаружено совпадение баров: [2016.05.10 11:02, 67149] [2016.05.10 11:03, 67147] [2016.05.10 11:04, 67144]
2016.05.10 11:09:06.730 FindRetryPrices (Si Splice,M1)  Обнаружено совпадение баров: [2016.05.10 11:01, 67160] [2016.05.10 11:05, 67161]
2016.05.10 11:09:06.730 FindRetryPrices (Si Splice,M1)  Обнаружено совпадение баров: [2016.05.10 11:00, 67132] [2016.05.10 11:06, 67139]
Dateien:
Dictionary.mqh  18 kb
 
Artyom Trishkin:

Aus der Referenz:

Vasiliy Sokolov:

Hier ist meine Version der Lösung für das Problem der Wiederholungssuche:


Ich danke Ihnen allen sehr!!! Ich werde versuchen, das alles heute zu klären. Es ist wichtig, nicht nur ein Stück Code in Expert Advisor zu kopieren, sondern zu verstehen, warum er so geschrieben ist.
 

Bitte helfen Sie mir, eine Funktion zur Berechnung des Standard-RSI zu finden, die Anforderungen sind einfach:

1. Rückgabe des RSI-Wertes für einen bestimmten Balken

2. Berechnen Sie den Index nur für die Balken (falls erforderlich), die angefordert werden (wünschenswert)

3. Mit der angegebenen TF rechnen können

4. Arbeitet auf Kosten von Punkt 2 schneller als der Indikator

Ich möchte die Funktion in den Expert Advisor integrieren, wenn jemand eine fertige Funktion hat, bitte teilen Sie sie mit mir.

Ich frage, weil der Indikator sehr häufig vorkommt und kein Geheimnis ist.

 
-Aleks-:

Bitte helfen Sie mir, eine Funktion zur Berechnung des Standard-RSI zu finden, die Anforderungen sind einfach:

1. Rückgabe des RSI-Wertes für einen bestimmten Balken

2. Berechnen Sie den Index nur für die Balken (falls erforderlich), die angefordert werden (erwünscht)

3. Mit der angegebenen TF rechnen können

4. Arbeitet auf Kosten von Punkt 2 schneller als der Indikator

Ich möchte die Funktion in den Expert Advisor integrieren, wenn jemand eine fertige Funktion hat, bitte teilen Sie sie mit mir.

Ich frage, weil der Indikator sehr häufig vorkommt und kein Geheimnis ist.

Warum gefällt Ihnen der Standard-iRSI nicht? Nicht geheim genug?
 
Vasiliy Sokolov:
Was ist mit dem Standard-iRSI nicht in Ordnung? Nicht geheim genug?
Es gibt einige Änderungen, die ich an der Funktion vornehmen muss...
 
-Aleks-:
Es gibt einige Änderungen, die ich an der Funktion vornehmen muss...

Nehmen Sie dann ein vorgefertigtes Modell und ändern Sie es nach Ihren Wünschen:

//+------------------------------------------------------------------+
//|                                                          RSI.mq5 |
//|                        Copyright 2009, MetaQuotes Software Corp. |
//|                                              http://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright   "2009, MetaQuotes Software Corp."
#property link        "http://www.mql5.com"
#property description "Relative Strength Index"
//--- indicator settings
#property indicator_separate_window
#property indicator_minimum 0
#property indicator_maximum 100
#property  indicator_level1 30
#property  indicator_level2 70
#property indicator_buffers 3
#property indicator_plots   1
#property  indicator_type1   DRAW_LINE
#property  indicator_color1  DodgerBlue
//--- input parameters
input int InpPeriodRSI=14; // Period
//--- indicator buffers
double    ExtRSIBuffer[];
double    ExtPosBuffer[];
double    ExtNegBuffer[];
//--- global variable
int       ExtPeriodRSI;
//+------------------------------------------------------------------+
//| Custom indicator initialization function                         |
//+------------------------------------------------------------------+
void OnInit()
  {
//--- check for input
   if(InpPeriodRSI<1)
     {
      ExtPeriodRSI=12;
      Print("Incorrect value for input variable InpPeriodRSI =",InpPeriodRSI,
            "Indicator will use value =",ExtPeriodRSI,"for calculations.");
     }
   else ExtPeriodRSI=InpPeriodRSI;
//--- indicator buffers mapping
   SetIndexBuffer(0,ExtRSIBuffer,INDICATOR_DATA);
   SetIndexBuffer(1,ExtPosBuffer,INDICATOR_CALCULATIONS);
   SetIndexBuffer(2,ExtNegBuffer,INDICATOR_CALCULATIONS);
//--- set accuracy
   IndicatorSetInteger(INDICATOR_DIGITS,2);
//--- sets first bar from what index will be drawn
   PlotIndexSetInteger(0,PLOT_DRAW_BEGIN,ExtPeriodRSI);
//--- name for DataWindow and indicator subwindow label
   IndicatorSetString(INDICATOR_SHORTNAME,"RSI("+string(ExtPeriodRSI)+")");
//--- initialization done
  }
//+------------------------------------------------------------------+
//| Relative Strength Index                                          |
//+------------------------------------------------------------------+
int OnCalculate(const int rates_total,
                const int prev_calculated,
                const int begin,
                const double &price[])
  {
   int    i;
   double diff;
//--- check for rates count
   if(rates_total<=ExtPeriodRSI)
      return(0);
//--- preliminary calculations
   int pos=prev_calculated-1;
   if(pos<=ExtPeriodRSI)
     {
      //--- first RSIPeriod values of the indicator are not calculated
      ExtRSIBuffer[0]=0.0;
      ExtPosBuffer[0]=0.0;
      ExtNegBuffer[0]=0.0;
      double SumP=0.0;
      double SumN=0.0;
      for(i=1;i<=ExtPeriodRSI;i++)
        {
         ExtRSIBuffer[i]=0.0;
         ExtPosBuffer[i]=0.0;
         ExtNegBuffer[i]=0.0;
         diff=price[i]-price[i-1];
         SumP+=(diff>0?diff:0);
         SumN+=(diff<0?-diff:0);
        }
      //--- calculate first visible value
      ExtPosBuffer[ExtPeriodRSI]=SumP/ExtPeriodRSI;
      ExtNegBuffer[ExtPeriodRSI]=SumN/ExtPeriodRSI;
      if(ExtNegBuffer[ExtPeriodRSI]!=0.0)
         ExtRSIBuffer[ExtPeriodRSI]=100.0-(100.0/(1.0+ExtPosBuffer[ExtPeriodRSI]/ExtNegBuffer[ExtPeriodRSI]));
      else
        {
         if(ExtPosBuffer[ExtPeriodRSI]!=0.0)
            ExtRSIBuffer[ExtPeriodRSI]=100.0;
         else
            ExtRSIBuffer[ExtPeriodRSI]=50.0;
        }
      //--- prepare the position value for main calculation
      pos=ExtPeriodRSI+1;
     }
//--- the main loop of calculations
   for(i=pos;i<rates_total && !IsStopped();i++)
     {
      diff=price[i]-price[i-1];
      ExtPosBuffer[i]=(ExtPosBuffer[i-1]*(ExtPeriodRSI-1)+(diff>0.0?diff:0.0))/ExtPeriodRSI;
      ExtNegBuffer[i]=(ExtNegBuffer[i-1]*(ExtPeriodRSI-1)+(diff<0.0?-diff:0.0))/ExtPeriodRSI;
      if(ExtNegBuffer[i]!=0.0)
         ExtRSIBuffer[i]=100.0-100.0/(1+ExtPosBuffer[i]/ExtNegBuffer[i]);
      else
        {
         if(ExtPosBuffer[i]!=0.0)
            ExtRSIBuffer[i]=100.0;
         else
            ExtRSIBuffer[i]=50.0;
        }
     }
//--- OnCalculate done. Return new prev_calculated.
   return(rates_total);
  }
//+------------------------------------------------------------------+
 
Vasiliy Sokolov:

Nehmen Sie dann ein vorgefertigtes Modell und ändern Sie es nach Ihren Wünschen:

Ich weiß, dass es einen Indikator im Code gibt... Die Frage war, wer sie bereits geändert haben könnte...
 
Vasiliy Sokolov:

Hier ist meine Variante, das Problem der Suche nach Wiederholungen zu lösen:

Vasily, wenn ich#include <Dictionary.mqh> öffne, öffnet es sich genauso wie im EA-Körper. Sollte es so sein, oder sollte da ein anderer Code drin sein?

Denn in dem Code, den ich sehe, ist nicht klar, wie er nach Wiederholungen sucht ((

 
Artyom Trishkin:

// строку int searchPeriod=(Search_Period<1)?1:Search_Period;
// можно расписать так:

input int Search_Period=10; // Количество копируемых свечей ... эту строку вы видите в настройках
int searchPeriod;           // Сюда будем записывать входной параметр
if(Search_Period<1) searchPeriod=1; // Если во входном параметре ввели ноль или меньше нуля, то параметр будет равен нулю
else searchPeriod=Search_Period;    // иначе примем входной параметр

// соответственно и строку int delta=(Delta<0)?0:Delta;
// можно расписать точно так же

Liege ich richtig in der Annahme, dass es sich um einen Tippfehler handelt? Es sollte 0 statt 1 sein.

wie diese:int searchPeriod=(Search_Period<1)?0:Search_Period;

und weiter in dem ausführbaren Skript:

int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // die Anzahl der zu kopierenden Kerzen

In diesem Fall sollten wir wahrscheinlich bereits eine Variable verwenden: searchPeriod. richtig?

------

Eine andere Frage: Was bewirkt diese Linie? Ich habe festgestellt, dass jedes Element der Struktur auf Null zurückgesetzt wird. Und ich verstehe nicht, was wir hier nullen, wenn wir diese Daten scheinbar nur geschrieben haben und sie weiter verwenden sollen.

ZeroMemory(dataCandle); // Nullstellung der Daten in der Struktur

 
Andrey Koldorkin:

Liege ich richtig in der Annahme, dass es sich um einen Tippfehler handelt? Es sollte 0 statt 1 sein.

wie diese:int searchPeriod=(Search_Period<1)?0:Search_Period;

und weiter in dem ausführbaren Skript:

int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // die Anzahl der zu kopierenden Kerzen

In diesem Fall sollten wir wahrscheinlich bereits eine Variable verwenden: searchPeriod. richtig?

------

Eine andere Frage: Was bewirkt diese Linie? Ich habe festgestellt, dass jedes Element der Struktur auf Null zurückgesetzt wird. Und ich verstehe nicht, was wir hier nullen, wenn wir diese Daten scheinbar nur geschrieben haben und sie weiter verwenden sollen.

ZeroMemory(dataCandle); // Löschung der Daten in der Struktur


"so:int searchPeriod=(Search_Period<1)?0:Search_Period;"

Nein, das ist es nicht. So haben Sie es (wörtlich): Wenn der vom Benutzer in den Einstellungen festgelegte Suchzeitraum kleiner als eins ist, ist searchPeriod gleich null; andernfalls ist searchPeriod gleich dem vom Benutzer in den Einstellungen festgelegten Wert von Search_Period. Dies ist nicht korrekt. Wir brauchen keinen Suchbereich, der gleich Null ist. Wenn dieser Bereich also vom Benutzer auf 0 oder weniger als Null (weniger als eins) gesetzt wird, dann setzen wir diesen Bereich gleich dem Minimum - eins.


"int copy_bars=(int)fmin(Search_Period,Bars(Symbol(),Period())); // Anzahl der zu kopierenden Candlesticks
Hier sollten wir bereits die Variable: searchPeriod. verwenden, richtig? "

Ja, das stimmt, es ist ein Tippfehler.


"Noch eine Frage: Wozu dient diese Linie? Wozu ist sie da? Ich habe festgestellt, dass es jedes Element der Struktur auf Null zurücksetzt. Und hier verstehe ich nicht, warum und was wir nullen, wenn wir gerade diese Daten geschrieben haben und sie weiter verwenden sollen. ZeroMemory(dataCandle); // Nullung der Daten in der Struktur".

Dies geschieht, bevor wir die Struktur mit Daten füllen. Zuerst setzen wir ihn auf Null, dann füllen wir ihn. Schauen Sie - wir setzen sie vor der Schleife auf Null. Und dann füllen wir in der Schleife die Struktur mit Daten.

Grund der Beschwerde: