iBarShift와 유사함 - 페이지 16

 

일반적으로 나는 대각선으로 읽고 첫 페이지 만 (가운데 누군가의 밝은 머리가 있었습니까? :)), 모든 사람이 기록에 액세스하기 위해 매우 불편한 터미널 인터페이스에 목발을 부착하려고 시도하는 것, 개스킷을 작성하는 것이 더 쉽습니다. 터미널과 공예품 사이(일반적으로 std 라이브러리에 있어야 함). 또한 이로 인해 4/5에 대해 서로 다른 스크립트를 작성할 필요가 없습니다. 난 이걸했다:

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

다음은 간단한 사용 예입니다.

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

4/5에 대한 자체 정의를 통해 refresh(). 차트에는 기간이 하나만 있습니다(M1 또는 정의를 통해 지정된 다른 기간, 왜 이 치질이 풍부합니까?).

나는 또한 몇 가지 편리한 것들을 망쳤습니다. reverse_mode() 모든 면에서 인덱싱합니다(왼쪽에서 오른쪽으로 인덱싱하면 차트가 업데이트될 때 인덱스가 유효한 상태로 유지됩니다). 테스터와 유사한 set_curtainpos() 차트의 가장자리를 설정하고 이동하는 기능 - 테스트하고, 테두리를 이동하고, 테스트하고, 이동했습니다. My_point 구조에는 비교 연산자가 오버로드되었습니다(다음과 같은 상황에서 유효한 동작: 0.0000000009 == 1.0000000000).

누군가가 고통을 겪고 있다면 비슷한 접근 방식을 권장합니다. 개인적으로 후회하지 않았습니다.

추신: 그리고 시가/종가/고가/저가가 있는 고전적인 양초를 버리고 기본에 포인트 를 두었습니다. 하나의 양초는 두 개의 포인트를 제공합니다. 정말 매우 편리합니다.

 
Aleksey Vyazmikin :

최종 양식으로 수정될 때까지 기다리겠습니다. 답변 감사합니다.

시험 잘 치세요!

그것은 많은 뉘앙스로 밝혀졌습니다.

그것이 얼마나 혼란스러운지 알았다면 나는 관여하지 않았을 것입니다)))

이 옵션은 올바르게 작동해야 합니다.
누군가 잘못된 작업을 발견하면 문제를보고하면 감사하겠습니다.


 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() 는 표준 Bars()와 성능이 어떻게 다릅니까?
 
Artyom Trishkin :
iBars()는 표준 Bars()와 성능이 어떻게 다릅니까?

사용 방법을 참조하십시오.
iBar에 대한 각 호출이 TF 또는 기호를 변경하면 내 iBar는 어딘가에서 두 배 느리게 작동합니다.

그러나 이것은 실제적인 관점에서 볼 때 절대 실제 상황이 아닙니다.

예를 들어 다음과 같이 사용하는 경우:

그러면 일반 막대에 비해 iBar 의 이득은 10배 또는 그 이상이 될 것입니다.

그러나 가장 중요한 것은 매달리는 버그가 없다는 것입니다.

   Print ( "1" );
   Print ( Bars ( _Symbol , PERIOD_D1 , D'2018.05.02 01:58:03' , D'2018.05.02 12:56:11' )); // вычисляется более 10 секунд !!!!
   Print ( "2" );
파일:
 
0 = PERIOD_CURRENT 가 TF로 전송된 경우 오류가 발생했습니다.
위의 코드에서 수정되었습니다. 라인 추가:
 if (timeframe== 0 ) timeframe= _Period ;
 
Nikolai Semko :

사용 방법을 참조하십시오.
iBar에 대한 각 호출이 TF 또는 기호를 변경하면 내 iBar는 어딘가에서 두 배 느리게 작동합니다.

그러나 이것은 실제적인 관점에서 볼 때 절대 실제 상황이 아닙니다.

예를 들어 다음과 같이 사용하는 경우:

그러면 일반 막대에 비해 iBar의 이득은 10배 또는 그 이상이 될 것입니다.

그러나 가장 중요한 것은 매달리는 버그가 없다는 것입니다.

존경합니다!

 
Nikolai Semko :

사용 방법을 참조하십시오.
iBar에 대한 각 호출이 TF 또는 기호를 변경하면 내 iBar는 어딘가에서 두 배 느리게 작동합니다.

그러나 이것은 실제적인 관점에서 볼 때 절대 실제 상황이 아닙니다.

예를 들어 다음과 같이 사용하는 경우:

그러면 일반 막대에 비해 iBar의 이득은 10배 또는 그 이상이 될 것입니다.

그러나 가장 중요한 것은 매달리는 버그가 없다는 것입니다.

어서 해봐요 !

당신의 10초는 어디에 있습니까?

2018.05.05 17:45:36.860 유로 USD,M5: 2
2018.05.05 17:45:36.860 유로 USD,M5: 0
2018.05.05 17:45:36.860 유로 USD,M5: 1

 
Renat Akhtyamov :

어서 해봐요 !

당신의 10초는 어디에 있습니까?

2018.05.05 17:45:36.860 유로 USD,M5: 2
2018.05.05 17:45:36.860 유로 USD,M5: 0
2018.05.05 17:45:36.860 유로 USD,M5: 1

MT5였나?
MT4에는 그런 버그가 없습니다.
 
Nikolai Semko :
MT5였나?
MT4에는 그런 버그가 없습니다.
MT4
 
Renat Akhtyamov :
MT4

MT5에서 시도하고 놀라십시오.

이 버그는 @Aleksey Vyazmikin 의 게시물 덕분에 아주 우연히 발견되었습니다. 그에게 많은 감사를 드립니다.

나는 전에 이러한 동결을 관찰했지만, 그 기원의 본질을 어떤 식으로든 설명할 수 없었습니다. 누가 이런일이 일어날 거라고 생각 했 겠어...

사유: