iBarShift'e benzer - sayfa 16

 

Genelde çapraz okuyorum ve sadece ilk sayfaları (belki de ortada birinin parlak kafası vardı? :) ), herkesin tarihe erişmek için son derece elverişsiz terminal arayüzüne koltuk değneği takmaya çalıştığı bir şey, conta yazmak daha kolay terminal ve zanaatlarınız arasında (genel olarak std kitaplığında olmalıdır). Ayrıca bunun sonucunda 4/5 için farklı scriptler yazmaya gerek kalmaz. Bunu ben yaptım:

 // comp.comp() returns true if the first argument is less than the second.
// If failure, returns UINT_MAX.
template < typename A, typename T, typename Comp>
uint alg_lower_bound( const A &ar[], uint minindex, uint maxindex,
                     const T &value, Comp &comp, bool rev= false )
{
   uint count = maxindex - minindex + 1 ;
   uint first = minindex;
   if (rev)
      first = maxindex;
      
   while (count != 0 )
   {
       uint it = first;
       uint step = count / 2 ;
       if (rev)
         it -= step;
       else
         it += step;
       if (comp.comp(ar[it], value))
      {
         if (rev)
            first = --it;
         else
            first = ++it;
         count -= step + 1 ;
      }
       else
         count = step;
   }
   
   if (first < minindex  ||  first > maxindex)
      first = UINT_MAX ;
   return first;
}

class Chart
{
   struct Bar_trend
   {
       double p1;
       double p2;
       datetime time;
   };
   Bar_trend bar_trend[];
   upindex_t sz;
   upindex_t curtain;
   bool reverse_f;
   void refresh_base( datetime min = 0 , datetime max = 0 );
public :
   // Empty chart will be created.
   Chart(): sz( 0 ), curtain(UPINDEXT_MAX), reverse_f( false ) {}
   // Chart with points whose time is in interval min:max will be created.
   Chart( datetime min, datetime max): sz( 0 ), curtain(UPINDEXT_MAX), reverse_f( false ) { refresh_base(min, max); }
   // Reverse flag is not changed. For whole chart min and max are 0.
   void init( datetime min, datetime max);
   My_point operator [](upindex_t i) const ;
   // If exact is true then time of point with returned index is equal to time.
   // If point is not found then function returns UPINDEXT_MAX.
   upindex_t bar_shift( datetime time, bool exact= true ) const ;
   upindex_t size() const   { return this .curtain == UPINDEXT_MAX  ?   this .sz * 2   :   this .curtain;}
   // pos can not be greater than the size(). UPINDEXT_MAX for deletion of curtain.
   // It will be reset when refresh(). Returns true in case of success.
   bool set_curtainpos(upindex_t pos);
   upindex_t get_curtainpos() const   { return this .curtain;}
   bool reverse_mode() const   { return this .reverse_f;}
   // Returns true in case of success.
   bool reverse_mode( bool mode);
   // if chart size == 0 then lowest = highest == UPINDEXT_MAX.
   void extremums(upindex_t &lowest, upindex_t &highest) const ;
   // if chart is reverse then indexes will be invalidated.
   void refresh()  { refresh_base(); }
};

upindex_t Chart::bar_shift( datetime time, bool exact) const
{
   class Comp
   {
   public :
       bool comp( const Bar_trend &bt, datetime time)  { return bt.time > time;}
   }comp;
   
   uint res = alg_lower_bound( this .bar_trend, 0 , this .sz- 1 , time, comp, true );
   if (res != UINT_MAX )
   {
       uchar shift = this .bar_trend[res].time!=time ? 1 : 0 ;

       if (exact  &&   this .bar_trend[res].time+shift != time)
         res = UINT_MAX ;
       else
         res = this .reverse_f ? 
               (( this .sz - 1 - res) * 2 + !shift) :  
               (res * 2 + shift);
   }
   return res == UINT_MAX ? UPINDEXT_MAX : res;
}

Ve işte basit bir kullanım örneği:

Chart chart();
chart.refresh();
for ( int i = 0 ;  i < chart.size();  ++i)
   Print (chart[i].price, chart[i].time);

yenileme () aracılığıyla 4/5 için kendi tanımını yapar. Grafiğin yalnızca bir periyodu vardır (M1 veya başka bir tanımla belirtilir, neden bollukları olan bu hemoroid?).

Ayrıca birkaç uygun şeyi de vidaladım - herhangi bir taraftan ters_mode() indeksleme (soldan sağa ise, grafik güncellendiğinde indeksler geçerli kalır). Test cihazının bir analogu olan set_curtainpos () grafiğinin kenarını ayarlama ve hareket ettirme yeteneği - test ettik, sınırı hareket ettirdik, test ettik, hareket ettik. My_point yapısı aşırı yüklenmiş karşılaştırma operatörlerine sahiptir (bu gibi durumlarda geçerli davranış için: 0.0000000009 == 1.0000000000).

Birisi acı çekiyorsa, benzer bir yaklaşım öneririm, şahsen pişman olmadım.

Not: ve açık/kapalı/yüksek/düşük ile klasik mumları terk edin ve Point'i temellere koyun - bir mum iki Puan verir, düşüş yüksek-> düşük, yükseliş düşük-yüksek. Gerçekten çok uygun.

 
Aleksey Vyazmikin :

Son haliyle düzeltmeleri bekleyeceğim, cevapladığınız için teşekkürler.

Sınavlarında iyi şanslar dilerim!

Birçok nüans olduğu ortaya çıktı.

Ne kadar kafa karıştırıcı olacağını bilseydim, karışmazdım)))

Bu seçenek doğru şekilde çalışmalıdır.
Birisi yanlış bir iş bulursa, sorunu bildirirse minnettar olacağım.


 int iBarShift ( const string Symb, const ENUM_TIMEFRAMES TimeFrame, datetime time, bool exact= false )
  {
   int Res= iBars (Symb,TimeFrame,time+ 1 , UINT_MAX );
   if (exact) if ((TimeFrame!= PERIOD_MN1 || time> TimeCurrent ()) && Res== iBars (Symb,TimeFrame,time- PeriodSeconds (TimeFrame)+ 1 , UINT_MAX )) return (- 1 );
   return (Res);
  }
 int iBars ( string symbol_name, ENUM_TIMEFRAMES   timeframe, datetime start_time, datetime stop_time) // stop_time > start_time
  {
   static string LastSymb= NULL ;
   static ENUM_TIMEFRAMES LastTimeFrame= 0 ;
   static datetime LastTime= 0 ;
   static datetime LastTime0= 0 ;
   static int PerSec= 0 ;
   static int PreBars= 0 ,PreBarsS= 0 ,PreBarsF= 0 ;
   static datetime LastBAR= 0 ;
   static datetime LastTimeCur= 0 ;
   static bool flag= true ;
   static int max_bars= TerminalInfoInteger ( TERMINAL_MAXBARS );
   datetime TimeCur;
   if (timeframe== 0 ) timeframe= _Period ;
   const bool changeTF=LastTimeFrame!=timeframe;
   const bool changeSymb=LastSymb!=symbol_name;
   const bool change=changeTF || changeSymb || flag;

   LastTimeFrame=timeframe; LastSymb=symbol_name;
   if (changeTF) PerSec=:: PeriodSeconds (timeframe); if (PerSec== 0 ) { flag= true ; return ( 0 );}

   if (stop_time<start_time)
     {
      TimeCur=stop_time;
      stop_time=start_time;
      start_time=TimeCur;
     }
   if (changeSymb)
     {
       if (! SymbolInfoInteger (symbol_name, SYMBOL_SELECT ))
        {
         SymbolSelect (symbol_name, true );
         ChartRedraw ();
        }
     }
   TimeCur= TimeCurrent ();
   if (timeframe== PERIOD_W1 ) TimeCur-=(TimeCur+ 345600 )%PerSec; // 01.01.1970 - Thursday. Minus 4 days.
   if (timeframe< PERIOD_W1 ) TimeCur-=TimeCur%PerSec;
   if (start_time>TimeCur) { flag= true ; return ( 0 );}
   if (timeframe== PERIOD_MN1 )
     {
       MqlDateTime dt;
       TimeToStruct (TimeCur,dt);
      TimeCur=dt.year* 12 +dt.mon;
     }

   if (changeTF || changeSymb || TimeCur!=LastTimeCur)
      LastBAR=( datetime ) SeriesInfoInteger (symbol_name,timeframe, SERIES_LASTBAR_DATE );

   LastTimeCur=TimeCur;
   if (start_time>LastBAR) { flag= true ; return ( 0 );}

   datetime tS,tF= 0 ;
   if (timeframe== PERIOD_W1 ) tS=start_time-(start_time+ 345599 )%PerSec- 1 ;
   else if (timeframe< PERIOD_MN1 ) tS=start_time-(start_time- 1 )%PerSec- 1 ;
   else    //  PERIOD_MN1
     {
       MqlDateTime dt;
       TimeToStruct (start_time- 1 ,dt);
      tS=dt.year* 12 +dt.mon;
     }
   if (change || tS!=LastTime) { PreBarsS= Bars (symbol_name,timeframe,start_time, UINT_MAX ); LastTime=tS;}
   if (stop_time<=LastBAR)
     {
       if (PreBarsS>=max_bars) PreBars= Bars (symbol_name,timeframe,start_time,stop_time);
       else
        {
         if (timeframe< PERIOD_W1 ) tF=stop_time-(stop_time)%PerSec;
         else if (timeframe== PERIOD_W1 ) tF=stop_time-(stop_time+ 345600 )%PerSec;
         else //  PERIOD_MN1
           {
             MqlDateTime dt0;
             TimeToStruct (stop_time- 1 ,dt0);
            tF=dt0.year* 12 +dt0.mon;
           }
         if (change || tF!=LastTime0)
           { PreBarsF= Bars (symbol_name,timeframe,stop_time+ 1 , UINT_MAX ); LastTime0=tF; }
         PreBars=PreBarsS-PreBarsF;
        }
     }
   else PreBars=PreBarsS;
   flag= false ;
   return (PreBars);
  }
//+------------------------------------------------------------------+
int iBars ( string symbol_name, ENUM_TIMEFRAMES   timeframe) { return ( Bars (symbol_name,timeframe));}
//+------------------------------------------------------------------+
 
iBars() performansınız standart Bars() 'dan ne kadar farklı?
 
Artyom Trishkin :
iBars()'ınızın performansı standart Bars()'dan nasıl farklıdır?

Nasıl kullanılacağını görün.
iBar'a yapılan her çağrı TF'yi veya sembolü değiştirecekse, iBar'ım bir yerde iki kat daha yavaş çalışacaktır.

Ancak bu, pratik açıdan kesinlikle gerçek bir durum değildir.

Örneğin, şöyle kullanırsanız:

o zaman iBar'larımın normal Barlara göre kazancı 10 kat veya daha fazla olacak.

Ama en önemlisi, asılı bir hata yok:

   Print ( "1" );
   Print ( Bars ( _Symbol , PERIOD_D1 , D'2018.05.02 01:58:03' , D'2018.05.02 12:56:11' )); // вычисляется более 10 секунд !!!!
   Print ( "2" );
Dosyalar:
 
0 = PERIOD_CURRENT TF olarak iletilirse oluşan bir hata oluştu
Yukarıdaki kodda düzeltildi. Bir satır eklendi:
 if (timeframe== 0 ) timeframe= _Period ;
 
Nikolai Semko :

Nasıl kullanılacağını görün.
iBar'a yapılan her çağrı TF'yi veya sembolü değiştirecekse, iBar'ım bir yerde iki kat daha yavaş çalışacaktır.

Ancak bu, pratik açıdan kesinlikle gerçek bir durum değildir.

Örneğin, şöyle kullanırsanız:

o zaman iBar'larımın normal Barlara göre kazancı 10 kat veya daha fazla olacak.

Ama en önemlisi, asılı bir hata yok:

RRRR SAYGI!

 
Nikolai Semko :

Nasıl kullanılacağını görün.
iBar'a yapılan her çağrı TF'yi veya sembolü değiştirecekse, iBar'ım bir yerde iki kat daha yavaş çalışacaktır.

Ancak bu, pratik açıdan kesinlikle gerçek bir durum değildir.

Örneğin, şöyle kullanırsanız:

o zaman iBar'larımın normal Barlara göre kazancı 10 kat veya daha fazla olacak.

Ama en önemlisi, asılı bir hata yok:

Haydi !

10 saniyen nerede?

2018.05.05 17:45:36.860 ve EURUSD,M5:2
2018.05.05 17:45:36.860 ve EURUSD,M5: 0
2018.05.05 17:45:36.860 ve EURUSD,M5: 1

 
Renat Akhtyamov :

Haydi !

10 saniyen nerede?

2018.05.05 17:45:36.860 ve EURUSD,M5:2
2018.05.05 17:45:36.860 ve EURUSD,M5: 0
2018.05.05 17:45:36.860 ve EURUSD,M5: 1

MT5 miydi?
MT4'te böyle bir hata yok.
 
Nikolai Semko :
MT5 miydi?
MT4'te böyle bir hata yok.
MT4
 
Renat Akhtyamov :
MT4

MT5'te deneyin ve şaşırın.

Bu hata, @Aleksey Vyazmikin'in bir gönderisi sayesinde tesadüfen keşfedildi. Bunun için ona çok teşekkürler.

Bu donmaları daha önce de gözlemledim ama kökenlerini hiçbir şekilde açıklayamadım. Kim düşünebilirdi ki...