Yeni başlayanlardan sorular MQL5 MT5 MetaTrader 5 - sayfa 575

 

İşte tekrar bulma sorununa benim çözümüm:

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

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

Komut dosyasının çalışması için Sözlük dosyasını MQL5\Include dizinine kopyalayın

Gerçek arama, sarı renkle vurgulanan döngü için tek geçişte yapılır. Sonuç listesi tekrar içermez (A, B'yi tekrar ederse ve B, A'yı tekrar ederse, iki {A, B} ve {B, A} yerine bir {A, B} kümesi görüntülenecektir).

Bu betiğin çıktısı aşağıdakileri gösterdi:

 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 ]
Dosyalar:
Dictionary.mqh  18 kb
 
Artyom Trishkin :

Yardımdan:

Vasili Sokolov :

İşte tekrar bulma sorununa benim çözümüm:


Hepinize çok teşekkürler!! Bugün her şeyi anlamaya çalışacağım. Sadece bir kod parçasını bir Expert Advisor'a kopyalamak değil, kodun neden bu şekilde yazıldığını anlamak benim için önemli, bu yüzden muhtemelen daha fazla soru soracağım.
 

Standart RSI'yi hesaplamak için bir fonksiyon bulma konusunda yardım istiyorum, bunun gereksinimleri basit:

1. Belirli bir çubuktaki RSI değerini döndürün

2. Göstergeyi yalnızca istenen (arzu edilir) çubuklar (gerekirse) için hesaplayın

3. Belirli bir TF'ye güvenebilme

4. 2. nokta daha hızlı göstergesi sayesinde çalışır

Danışmana bir fonksiyon entegre etmek istiyorum, hazır olan varsa paylaşmanızı rica ediyorum.

Soruyorum çünkü gösterge çok yaygın ve bir sır değil.

 
-Aleks- :

Standart RSI'yi hesaplamak için bir fonksiyon bulma konusunda yardım istiyorum, bunun gereksinimleri basit:

1. Belirli bir çubuktaki RSI değerini döndürün

2. Göstergeyi yalnızca istenen (arzu edilir) çubuklar (gerekirse) için hesaplayın

3. Belirli bir TF'ye güvenebilme

4. 2. nokta daha hızlı göstergesi sayesinde çalışır

Danışmana bir fonksiyon entegre etmek istiyorum, hazır olan varsa paylaşmanızı rica ediyorum.

Soruyorum çünkü gösterge çok yaygın ve bir sır değil.

Neden standart iRSI'yi sevmiyorsunuz? Yeterince gizli değil mi?
 
Vasiliy Sokolov :
Neden standart iRSI'yi sevmiyorsunuz? Yeterince gizli değil mi?
İşlevde yapmam gereken değişiklikler var ...
 
-Aleks- :
İşlevde yapmam gereken değişiklikler var ...

Ardından bitmiş olanı alın ve gereksinimlerinize göre değiştirin:

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

Ardından bitmiş olanı alın ve gereksinimlerinize göre değiştirin:

Bu yüzden kodda bir gösterge olduğunu biliyorum ... soru zaten kimin değiştirebileceğiydi ...
 
Vasiliy Sokolov :

İşte tekrar bulma sorununa benim çözümüm:

Vasily, #include <Dictionary.mqh> dosyasını açtığımda EA gövdesindekiyle aynı şey açılıyor. Böyle mi olmalı? Yoksa içinde başka bir kod mu var?

Çünkü gördüğüm kodda tekrarları nasıl aradığı net değil ((

 
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;
// можно расписать точно так же

Bunun bir yazım hatası olduğunu düşünmekte haklı mıyım? 1 yerine 0 olmalıdır.

bunun gibi: int searchPeriod=(Search_Period<1)?0:Search_Period;

ve yürütülebilir komut dosyasında daha da ileri:

int copy_bars=(int)fmin( Search_Period ,Bars(Symbol(),Period())); // kopyalanan mum sayısı

tam orada, teorik olarak, şu değişkeni zaten kullanmalıyız: searchPeriod . Böyle?

------

Başka bir soru, bu hat ne işe yarıyor? ne için gerekli? Yapının her bir elemanının sıfırlandığı bulundu. Ve burada, teorik olarak, bu verileri yeni yazdıysak ve kullanmaya devam etmemiz gerekiyorsa, neden ve neyi sıfırladığımızı anlayamıyorum.

ZeroMemory (dataCandle); // Yapıdaki verileri sıfırla

 
Andrey Koldorkin :

Bunun bir yazım hatası olduğunu düşünmekte haklı mıyım? 1 yerine 0 olmalıdır.

bunun gibi: int searchPeriod=(Search_Period<1)?0:Search_Period;

ve yürütülebilir komut dosyasında daha da ileri:

int copy_bars=(int)fmin( Search_Period ,Bars(Symbol(),Period())); // kopyalanan mum sayısı

tam orada, teorik olarak, şu değişkeni zaten kullanmalıyız: searchPeriod . Böyle?

------

Başka bir soru, bu hat ne işe yarıyor? ne için gerekli? Yapının her bir elemanının sıfırlandığı bulundu. Ve burada, teorik olarak, bu verileri yeni yazdıysak ve kullanmaya devam etmemiz gerekiyorsa, neden ve neyi sıfırladığımızı anlayamıyorum.

ZeroMemory(dataCandle); // Yapıdaki verileri sıfırla


"böyle: int searchPeriod=(Search_Period<1)?0:Search_Period; "

Hayır böyle değil. Yani (tam anlamıyla): Kullanıcı tarafından ayarlarda Search_Period ayarlanırsa birden küçükse, searchPeriod sıfıra eşit olacaktır, aksi takdirde searchPeriod , kullanıcı tarafından ayarlarda ayarlanan Search_Period değerine eşit olacaktır . Bu doğru değil. Sıfıra eşit bir arama aralığına ihtiyacımız yok. Bu nedenle, bu aralık kullanıcı tarafından 0 veya sıfırdan küçük (birden küçük) olarak ayarlanırsa, bu aralığı minimuma - bire eşitleriz.


"int copy_bars=(int)fmin( Search_Period ,Bars(Symbol(),Period())); // kopyalanan mum sayısı
tam orada, teorik olarak, şu değişkeni zaten kullanmalıyız: searchPeriod . Böyle? "

Evet, evet, bir yazım hatası oldu.


"Başka bir soru, bu satır ne işe yarıyor? Ne için? Yapının her bir öğesinin sıfırlandığını buldum. Ve sonra neden ve neyi sıfırladığımızı anlayamıyorum, eğer teorik olarak, az önce yazmışsak. bu veri ve onu kullanmaya devam etmelidir. ZeroMemory ( dataCandle); // Yapıdaki verileri sıfırlayın"

Bunu yapıyı verilerle doldurmadan önce yaparız. Önce sıfırlıyoruz, sonra dolduruyoruz. Bakın - döngüden önce sıfırlıyoruz. Ve sonra döngüde yapıyı verilerle doldururuz.