Einen neuen Balken anzeigen

 

Ich frage mich, wie man anzeigen kann, wann ein neuer Balken das Licht der Welt erblickt.
In erster Linie mache ich mir Sorgen um die Leistung. Bei einigen Symbolen habe ich alle 20 ms Ticks gesehen. Nicht so viel Zeit zum Reagieren.

Eine Idee ist rates.tick_volume

Mqlrates rates[1];

OnInit()
    {
    if(CopyRates(_Symbol,_Period,0,1,rates) < 1)
       if(rates[0].tick_volume == 1)
          {
          ... deal with new bar ...
          }

Eine weitere Idee könnte die Überprüfung sein, ob die Anzahl der Balken erhöht wurde

OnInit()
  {
  if(BarsOld < Bars(_Symbol,_Period))
     {
     BarsOld = Bars(_Symbol,_Period);
     ... deal with new bar ...
     }

Ich habe auch OnChartEvent überprüft, aber ich habe keine Möglichkeit gefunden, neue Balken von anderen Dingen zu unterscheiden.

Vielen Dank für Ihre Bewertung

WIllbur

 

Balken und Volumen sind unzuverlässig, um einen neuen Balken zu erkennen.

Ein Computer arbeitet in Nanosekunden, so dass eine gut codierte EA kann eine Menge in 20 ms tun.

The "New Bar" Event Handler
The "New Bar" Event Handler
  • 2010.10.11
  • Konstantin Gruzdev
  • www.mql5.com
MQL5 programming language is capable of solving problems on a brand new level. Even those tasks, that already have such solutions, thanks to object oriented programming can rise to a higher level. In this article we take a specially simple example of checking new bar on a chart, that was transformed into rather powerful and versatile tool. What tool? Find out in this article.
 
Siehe dieses Thema :
Improve your time execution by removing Bars function calls
Improve your time execution by removing Bars function calls
  • www.mql5.com
After a basic profiling I get the following results :. - - Category: trading systems
 

Danke, Alain,

sehr interessant ... genau das, was ich vermute ... 10 mal schneller ... hmmm.

Bedeutet: TimeCurrent() ist schnell und syncron zu den Balkengrenzen ?

Warum .... hmmm ...

Ich brauche eine Weile, um darüber nachzudenken.

Willbur

 

Ok - für Leute, die so etwas mögen: Meine Studie über dieses Problem.

Ich habe in jedem "OnTick" Event einen Satz in eine Datei geschrieben.

TimeLocal (PC CLock), TimeCurrent(), mit SymbolInfoTick() einige Informationen über den letzten Tick, der hereinkam und - mit CopyRates() - einige Informationen über den aktuellen Bar.


Ein Beispiel aus "USD/JPY" - Periode ist "M1":

Es ist 19:43:01 auf der PC-Uhr, als der erste Tick der 43. Minute eintrifft, gleichzeitig ist ein neuer Bar entstanden.
Abgesehen von der Tatsache, dass das Tick-Volumen nicht 1 ist, ist dies der normale Lauf der Dinge.



Manchmal ist es nicht so einfach - wie in diesem Fall:

Der PC zeigt bereits 19:42:00 an, als drei weitere Ticks des 41min-Balkens eintrafen. Sie haben immer noch einen Zeitstempel von 19:41:59.

Jetzt holt die Welt tief Luft - 8.150 msec völlige Stille.

Dann - der PC zeigt bereits 19:42:09 - kommt der erste Tick des neuen Balkens - des 42-Minuten-Balkens - herein.
Der Tick ist mit 19:42:07 markiert und - da es sich um den 19:42 Balken handelt - ist der Zeitstempel des Balkens 19:42:00


Jetzt .... hmmm ....

1. Ist TimeCurrent() immer gleich dem Zeitstempel des Ticks?

Ich habe 40.000 Datensätze überprüft und nur fünf Fälle gefunden, in denen TimeCurrent bereits umgeschaltet ist, der Zeitstempel des letzten Ticks aber nicht.

2. Ist last_tick immer vor der Eröffnung des neuen Balkens?

(Fortsetzung folgt)

 

TimeCurrent() ist die Zeit des letzten Ticks vom Server, es hängt von Ihrem Code ab, ob es von Ihrem Chart-Symbol ist oder nicht.

Ich verstehe Ihr Problem mit dem "letzten Tick" nicht, Sie sollten den Code zeigen, der diese Ausgabe erzeugt.

 

Hallo Alain

ich überprüfe die TimeCurrent() in OnTick(), die sicherstellen sollte, dass sie zu dem Symbol gehört, mit dem ich arbeite.

Nun, das sollte mein "New Bar Identifier" sein - klein und schnell - was denkst du?

//---  New Bar           
bool   NewBar = false;
long   currPeriodSeconds;
double currPeriodProgress = 0;

int OnInit(void)  //-----------------------------------------------
{
      currPeriodSeconds = PeriodSeconds();
      return(INIT_SUCCEEDED);
}

void OnTick()  //--------------------------------------------------
{
      if(MathMod(TimeCurrent(),currPeriodSeconds) < currPeriodProgress)
           NewBar = true;
      else NewBar = false;
     

      currPeriodProgress = MathMod(TimeCurrent(),currPeriodSeconds);

Ich werde es mit dieser Sequenz überprüfen:

//---  Just for testing
int    ExtHdlFile1=0;
       MqlRates rates[1];
        
//---  New Bar           
bool   NewBar = false;
long   currPeriodSeconds;
double currPeriodProgress = 0;

int OnInit(void) // -------------------------------------------------------
{
      currPeriodSeconds = PeriodSeconds();

      ExtHdlFile1=FileOpen("NewBarTest.csv",FILE_READ|FILE_WRITE|FILE_CSV);
      FileSeek (ExtHdlFile1,0,SEEK_END); 
      FileWrite(ExtHdlFile1,  "TimeLocal",
                              "TimeCurrent",
                              "rates[0].time",
                              "rates[0].tick");
      return(INIT_SUCCEEDED);
}

void OnTick() // -----------------------------------------------------------
{
      if(MathMod(TimeCurrent(),currPeriodSeconds) < currPeriodProgress)
           NewBar = true;
      else NewBar = false;
     
      currPeriodProgress = MathMod(TimeCurrent(),currPeriodSeconds);

//--- lets check this

      if(NewBar)
         {
         // last Time Stamp of old Bar
         FileWrite(ExtHdlFile1, " ",
                                " ",
                                TimeToString(rates[0].time, TIME_MINUTES|TIME_SECONDS),
                                IntegerToString(rates[0].tick_volume));
         // get the new bar                     
         if(CopyRates(Symbol(),Period(),0,1,rates)!= 1) return;
         // first Time Stamp of new Bar       
         FileWrite(ExtHdlFile1,TimeToString(TimeLocal(),TIME_MINUTES|TIME_SECONDS),
                               TimeToString(TimeCurrent(), TIME_MINUTES|TIME_SECONDS),
                               TimeToString(rates[0].time, TIME_MINUTES|TIME_SECONDS),
                               IntegerToString(rates[0].tick_volume));
         }

      if(CopyRates(Symbol(),Period(),0,1,rates)!= 1) return; // != clean code - just a test
}

void OnDeinit(const int reason)
{
      FileClose(ExtHdlFile1);
      return;
}

 
Willbur:

Hallo Alain

ich überprüfe die TimeCurrent() in OnTick(), die sicherstellen sollte, dass sie zu dem Symbol gehört, mit dem ich arbeite.

Nun, das sollte mein "New Bar Identifier" sein - klein und schnell - was denkst du?

Interessant, aber ich glaube nicht, dass es universell ist (funktioniert in allen Fällen)... Ich werde es überprüfen, habe aber im Moment keine Zeit.
 
 

Hier ist meine endgültige Version.

Ich bin sogar ein bisschen besorgt, weil es so einfach ist.

Alain: Es wäre schön, wenn Sie den Segen erteilen würden.

// -----------------------------------------------------------------------
bool NewBar(void)
{
bool iNewBar = false;
static double currPeriodProgress = 0;

   if(MathMod(TimeCurrent(),PeriodSeconds()) < currPeriodProgress) iNewBar = true;

   currPeriodProgress = MathMod(TimeCurrent(),PeriodSeconds());

   return(iNewBar);
}
// ------------------------------------------------------------------------
void OnTick()
{
    if(NewBar())     PlaySound("tick.wav");


Grüße aus Köln
Willbur

 

Der einfachste Weg:

static datetime tlastbar=0;

datetime tnewbar=iTime(NULL,PERIOD_CURRENT,0);

bool isnewbar=tnewbar!=tlastbar;

tlastbar=tnewbar;