Mt4 Ende der Unterstützung. - Seite 27

 
Реter Konow:
Linear, nicht-linear... Reden Sie wieder von der Oper in der Programmierung?

auf keinen Fall.

 
Реter Konow:

GUT. Ihre Lösung funktioniert nur bei Zecken. Meiner ist mit einer Zeitschaltuhr ausgestattet. Glauben Sie, dass meine Methode der Zeitmessung mit Balkenauftritten einen Nachteil hat? Ja. So soll es sein. Ich werde eine Prüfung auf das Eintreffen eines Angebots hinzufügen, bevor ich eine neue Balkenmarkierung setze. Ich werde der Funktion einen weiteren Parameter hinzufügen - ein Symbol. Der Benutzer wählt das Symbol, mit dem er das neue Taktereignis empfangen möchte, und sendet es an die Funktion. Die Funktion prüft den Zeitpunkt des letzten Zitats dieses Symbols. Dann vergleichen wir den Zeitpunkt des formellen Auftretens des Balkens mit dem Zeitpunkt des Angebots und setzen das Ereignisflag.

Ich habe gerade erst angefangen, dieses Thema zu studieren, aber ich sehe keine Schwierigkeiten.

Forum zum Thema Handel, automatisierte Handelssysteme und Strategietests

Mt4 Ende der Unterstützung.

Artyom Trishkin, 2017.09.10 22:27

Ich weiß, wie man Kostenvoranschläge einholt :)

In einem Programm mit mehreren Währungen - in einem Timer in einer Schleife auf den rechten Symbolen. Und die Eröffnung eines neuen Balkens (physisch, nicht virtuell - fehlerhaft - wie bei Ihnen) wird durch die Zeit der letzten Notierung und den Vergleich dieser Zeit mit der Zeit des Null-Bar-Symbols gesteuert.

Sie hingegen entscheiden nach dem Zufallsprinzip - eine virtuelle Bar, die es vielleicht gar nicht gibt. Man hat sie am Wochenende nicht, aber man soll sie haben - das ist das einfachste Beispiel.

Und du bist der Einzige, der es nicht so machen würde. Der Rest von uns macht es auf die richtige und zuverlässige Weise. Aber das ist natürlich nur Ihre eigene Angelegenheit.

Ich wollte Ihnen sagen, wie man es richtig macht, und den großen Unterschied zwischen der Einfachheit des Schreibens in OOP und den komplizierten Wendungen im prozeduralen Stil bei der Lösung der gleichen Aufgabe aufzeigen.

Aber Sie wissen wahrscheinlich mehr und brauchen es nicht. Ich wage es nicht, so zu tun, als wüsste ich mehr. Entschuldigung.


 
Galina Bobro:

Kein Problem. Hedge, um den Vergleich von String-Operationen zu speichern, gut, wenn der Kunde ist ein Verrückter und wird auf alle Zeichen gleichzeitig zu handeln.

Aber es scheint, dass es nirgendwo anders möglich ist, Operationen und Speicher zu speichern - alles ist minimal

void OnTimer(){

   Alert(Fn_new_bar("EURUSD", PERIOD_D1)); }

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

uint Sp_Adler32(string line){

   ulong s1 = 1;

   ulong s2 = 0;

   uint buflength=StringLen(line);

   uchar char_array[];

   ArrayResize(char_array, buflength,0);

   StringToCharArray(line, char_array, 0, -1, CP_ACP);

   for (uint n=0; n<buflength; n++){

      s1 = (s1 + char_array[n]) % 65521;

      s2 = (s2 + s1)     % 65521;}

   return ((s2 << 16) + s1);}

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

bool Fn_new_bar(string symb, ENUM_TIMEFRAMES tf){

   static datetime st_time[]; 

   static uint     st_id[];

   

   //---- set

   datetime new_time = iTime(symb, tf, 0);     if(new_time==0) return(false); 

   uint     new_id   = Sp_Adler32(StringConcatenate(symb,EnumToString(tf))); 

   datetime old_time = 0; 

   uint     old_id   = 0;

   

   //---- find

   int size = ArraySize(st_time); 

   for(int i=0; i<size; i++){

      if(st_id[i]!=new_id) continue; 

      old_id   = st_id  [i]; 

      old_time = st_time[i];

      break;}

   

   //----add new element

   if(old_time==0){

      ArrayResize(st_time, size+1); st_time[size]=new_time;

      ArrayResize(st_id,   size+1); st_id  [size]=new_id; }

   

   //----

   return(old_time>0 && old_time<new_time);}


Es scheint der strukturell sinnvollste Code bisher zu sein. Er hat eine Prüfung auf ein neues Symbol und ein tf, prüft nicht alles, sondern nur das, was man braucht, keine unnötigen Operationen, was bedeutet, dass er ziemlich schnell laufen sollte.

Mit freundlichen Grüßen.

P.S. Die einzige Kleinigkeit, die hier hinzugefügt werden könnte, ist die Kombination der Arrays st_time und st_id in einer Struktur, da sie miteinander in Beziehung stehen, was die Anzahl der Array-Inkrement-Operationen im Code reduzieren würde.

 
Artyom Trishkin:

Mein Ziel war es, dass sein prozeduraler Code am Ende in einer Schleife wie dieser funktioniert:

 ENUM_TIMEFRAMES array_timeframes[]=
      {
      PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
      };
   int total=SymbolsTotal(true), total_tf=ArraySize(array_timeframes);
   for(int i=0; i<total; i++){
      string symbol_name=SymbolName(i,true);
      for(int j=0; j<total_tf; j++){
         if(IsNewBar(symbol_name,array_timeframes[j])){
            Print("Новый бар на ",symbol_name," ",EnumToString(array_timeframes[j]));
            }
         }
      }


etwa so (Code für MQL5):

int OnInit()
  {
   IsNewBar();  // сбор информации - можно включить здесь, но не обязательно
   EventSetMillisecondTimer(100);
   return(INIT_SUCCEEDED);
  }

void OnDeinit(const int reason)
  {
   EventKillTimer();
  }

void OnTimer()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }

void OnTick()
  {
   IsNewBar();   // сбор информации - можно включить здесь, но не обязательно
                 // различные варианты проверки новых баров
   if(IsNewBar(true)) Print("Пришел новый бар текущего ТФ текущего инструмента");   // режим вывода информации
   if(IsNewBar(true,PERIOD_H4)) Print("Пришел новый бар H4 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_D1)) Print("Пришел новый бар D1 текущего инструмента");  // режим вывода информации
   if(IsNewBar(true,PERIOD_M1,"GBPUSD.m")) Print("Пришел новый бар M1 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M3,"GBPUSD.m")) Print("Пришел новый бар M3 GBPUSD");     // режим вывода информации
   if(IsNewBar(true,PERIOD_M2,"USDCHF.m")) Print("Пришел новый бар M2 USDCHF");     // режим вывода информации
  }
//+---------------------------------------------------------------------------------------------------+
//|   Функция определения нового бара по всем ТФ всех инструментов в окне "Обзор рынка"               |
//|   два режима работы:                                                                              |
//|   - режим сбора информации, out=false (значение по умолчанию). Достаточно запустить IsNewBar();   |
//|   - режим вывода информации, out=true                                                             |
//|   tf - период таймфрейма, по умолчанию текущий ТФ (необходим только при выводе информации)        |
//|   Sym - символ инструмента, по умолчанию текущий символ (необходим только при выводе информации)  |
//+---------------------------------------------------------------------------------------------------+
bool IsNewBar(bool out=false, ENUM_TIMEFRAMES tf=PERIOD_CURRENT, string Sym="") 
  {
   static const ENUM_TIMEFRAMES TF[22]=
     {
      PERIOD_CURRENT,PERIOD_M1,PERIOD_M2,PERIOD_M3,PERIOD_M4,PERIOD_M5,PERIOD_M6,PERIOD_M10,PERIOD_M12,PERIOD_M15,PERIOD_M20,PERIOD_M30,
      PERIOD_H1,PERIOD_H2,PERIOD_H3,PERIOD_H4,PERIOD_H6,PERIOD_H8,PERIOD_H12,PERIOD_D1,PERIOD_W1,PERIOD_MN1
     };
   static bool newbar[];
   static long acb[]; // array of current bars
   static int N_Sym=0;
   if(Sym=="") Sym=Symbol();
   int total=SymbolsTotal(true);
   int n_cur=-1;
   for(int i=0; i<total; i++) if(Sym==SymbolName(i,true)){ n_cur=i; break;}
   if(n_cur<0) { Print("данного символа нет в списке MarketWatch(окошко слева - Обзор рынка)"); return(false);}
   if(out && N_Sym>0) // если режим вывода информации 
     {
      int curtf=0;
      while(TF[curtf]!=tf) curtf++;
      return (newbar[n_cur*22+curtf]);
     }
// режим сбора информации
   if (total!=N_Sym) {ArrayResize(acb,22*total);ArrayInitialize(acb,0); ArrayResize(newbar,22*total); ArrayInitialize(newbar,false); N_Sym=total;}
   for(int j=0,j1=0; j<total; j++,j1+=22)
      for(int i=0;i<22;i++)
        {
         long CurBars=SeriesInfoInteger(SymbolName(j,true),TF[i],SERIES_LASTBAR_DATE);
         if(acb[j1+i]<CurBars) // пришел новый бар
           {
            //if (acb[j1+i]>0) Print ("Новый бар: "+SymbolName(j,true)+"   "+EnumToString(TF[i]));
            acb[j1+i]=CurBars;
            newbar[j1+i]=true;
           }
         else
           {
            newbar[j1+i]=false;
            if(i==1) for(;i<22;i++) newbar[j1+i]=false;   // если минутный бар тот же, то нет смысла продолжать проверять старшие ТФ
           }
        }
   return(false);
  }

Aber ich sage es noch einmal - ich bin ein Befürworter von OOP.
Nur ein wirklich unglückliches Beispiel, um zu zeigen, was in der prozeduralen Programmierung nicht möglich ist.

 
Andrey Kisselyov:
Es geht nicht um den Aufruf einer Funktion in einem EA, sondern um das Schreiben universeller Schnittstellen (Handler).

Sie haben 1000 Aufgaben, um Roboter zu schreiben; in der Tat besteht jede von ihnen aus
1 Funktion, ein Signal zum Öffnen zu erhalten
2. Funktion der Auftragseröffnung
3 Funktion der Auftragsverfolgung
4) Die Funktion, ein Signal zum Schließen eines Auftrags zu erhalten.
und so weiter.
Diese Funktionen sind für jeden Roboter unterschiedlich, aber sie wiederholen sich innerhalb von 1000 Projekten, so dass man die Funktionen zu universellen Modulen zusammenfassen und je nach Aufgabe die richtige aufrufen kann.

Nun, wenn Sie diese Funktionen haben, brauchen Sie nichts weiter zu tun. Der Eingabeparameter der Funktion ist die Schnittstelle. Jede zusätzliche Komplikation erhöht die Anzahl der möglichen Fehler und verlängert die Arbeitszeit des Programmierers.

 
Nikolai Semko:

oder so ähnlich (Code für MQL5):

Aber ich wiederhole - ich bin ein Befürworter von OOP.
Es ist wirklich nur ein unglückliches Beispiel, um zu zeigen, was in der prozeduralen Programmierung nicht möglich ist.

Gibt es prinzipiell ein solches Beispiel? Auch wenn es nicht Ihre sind? Ich habe große Zweifel. In den frühen 2000er Jahren hörte ich auf, die Anzahl der von mir geschriebenen fehlerbereinigten und funktionierenden Codezeilen zu zählen, weil sie eine Million überstieg - es wurde uninteressant. Und ich war nie gezwungen, meine eigene Klasse zu gründen, obwohl die Vielfalt und der Umfang meiner Aufgaben sehr unterschiedlich waren. Ich musste Variablen vom Typ Prozedur verwenden, wenn es notwendig war, die Arbeit für mehrere Personen zu parallelisieren, aber nicht mehr. Warum ist das so?

Übrigens, warum sprechen Sie von prozeduraler Programmierung als Alternative zu OOP? Es gibt Sprachen ohne OOP, die im Prinzip nicht prozedural sind (SQL), es gibt sogar eine Richtung der Sprachentwicklung - die funktionale Programmierung https://ru.wikipedia.org/wiki/%D0%A4%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D0%B5:"Einige Konzepte und Paradigmen sind spezifisch für die funktionale Programmierung und sind der imperativen Programmierung (einschließlich der objektorientierten Programmierung) meist fremd", "Ein weiterer Vorteil funktionaler Programme ist, dass sie umfangreiche Möglichkeiten für automatische Es stellt sich heraus, dass OOP die automatische Parallelisierung von Berechnungen verhindert. Dies sollte nun als ein sehr schwerwiegender Nachteil angesehen werden, die Perspektive ist nicht für OOP.

 
Vladimir:

Gibt es im Prinzip ein Beispiel dafür? Auch wenn es nicht Ihre sind? Ich habe große Zweifel.


Ich halte es für durchaus möglich, dass ein solches Beispiel nicht zu finden ist. Ich persönlich glaube, dass die Hauptvorteile von OOP in der bequemeren Programmierung großer Projekte und in einem bequemen Mechanismus für die künftige Nutzung Ihrer Entwicklungen liegen. Das ist hier schon oft zu Recht gesagt worden.

 
Andrei:

Es wurde bereits erörtert, dass eine einzige Schnittstelle für die Programmierung von Berechnungsaufgaben überhaupt nicht geeignet ist... Schöne Dinge in Form von Schnittstellen zu gestalten, ist ein rein kosmetisches Verfahren, das nur auf bereits fertigen Code anwendbar ist und das auch die weitere Unterstützung und Verfeinerung des Codes verhindert...

Nein. Es heißt nicht "überhaupt nicht anwendbar", sondern "es hat keinen Sinn, sie zu verwenden".

Schnittstellen sind kein "rein kosmetisches Verfahren, das auf vorgefertigten Code anwendbar ist".

Ganz im Gegenteil: Schnittstellen sind das Herzstück der Systemarchitektur. Hier beginnt das Design. Schnittstellen stehen der Unterstützung und Nacharbeit keineswegs im Wege", sondern helfen ihnen vielmehr, indem sie die Grenzen des Zulässigen klar abstecken. Wenn es keine Schnittstellen gibt, ist es leicht, diese Grenzen zu überschreiten und Änderungen dort vorzunehmen, wo sie nicht beabsichtigt waren, was zu schwer zu berechnenden Fehlern führt.

Jedes komplexe System (nicht nur in der Programmierung) beginnt mit der Entwicklung der grundlegenden Prinzipien der Interaktion zwischen seinen Teilen. Aber beim Programmieren gehen sie in die entgegengesetzte Richtung, weil die ursprüngliche Aufgabe meist sehr klein ist. Zuerst werden die Teile geschrieben, und dann werden sie zu einem Ganzen zusammengefügt, wobei man oft auf die Tatsache stößt, dass die Teile nicht miteinander kompatibel sind - dies erklärt übrigens den Wunsch, "Zugang zu allen verfügbaren Variablen zu haben".

 

Das ist in Ordnung, bis auf die Tatsache, dass die Funktion isNewBar() überhaupt nicht existieren sollte. Es ist schon komisch, dass so viel um eine so triviale Sache herumgetanzt wird.

Es ist nur eine Variable, die einfach mit der Zeit des Taktes verglichen wird; wenn alle Fälle erfolgreich sind, wird der Variablen die Zeit des neuen Taktes am Ende zugewiesen. Andernfalls wird für alle Fälle nur ein Versuch angesetzt.

 
Dmitry Fedoseev:

Das ist in Ordnung, bis auf die Tatsache, dass die Funktion isNewBar() überhaupt nicht existieren sollte. Es ist schon komisch, dass so viel um eine so triviale Sache herumgetanzt wird.

Es ist nur eine Variable, die einfach mit der Zeit des Taktes verglichen wird; wenn alle Fälle erfolgreich sind, wird der Variablen die Zeit des neuen Taktes am Ende zugewiesen. Andernfalls wird für alle Fälle nur ein Versuch angesetzt.


+1