Projekt des Beraters - Seite 7

 
George Merts:

Was meinen Sie mit "ATR gilt nicht als Indikator"?

Und wieso ist es "nicht als Einstiegssignal geeignet"? Ich bin ein Narr, der "Volatilitätsdurchbruch" nur mit diesem Indikator verwendet...?

Ich denke, Sie haben Ihr eigenes Verständnis von Indikatoren. Für mich ist ein Indikator ein Objekt, das einen variablen Wert in Abhängigkeit von der Zeit erzeugen kann. Auch ein gewöhnliches Kerzendiagramm des Preises ist ein Indikator. Aber für Sie ist es etwas anderes... Folglich ist unser Verständnis ein anderes.

Im Wesentlichen
Indikator = ein Hilfsmittel (Werkzeug), das Veränderungen in einer Sache anzeigt.
In diesem Sinne ist ATP ein Indikator.
Wenn Sie sich das Diagramm ansehen, werden Sie feststellen, dass der Indikator am genauesten ist (d.h. der Indikator ist kein eigenständiger Indikator - er ist ein Positionsindikator) und Sie müssen ihn im Markt halten.

meinen Respekt.

 

Я не вижу особой разницы - как я понимаю, WS (WareStore, вероятно ?) - это все тот же мой дата-провайдер.

Dies ist eine Abkürzung für WorkSymbol. Die Abkürzung ist absichtlich gewählt, da dieses Objekt häufig erwähnt wird.

Ich vermute, dass es bei der Initialisierung des WS-Objekts einige vorbereitende Schritte geben muss.

WS ist eine Instanz des CSymbol-Objekts, dessen Konstruktor standardmäßig das aktuelle Symbol()-Symbol verwendet. Daher muss WS nicht von außen initialisiert werden. Sie wird einfach zusammen mit der Strategieklasse erstellt.

In einem EA können viele verschiedene Container mit unterschiedlichen Symbolen und unterschiedlichen Zeitrahmen vorhanden sein. Die Ideologie des Datenanbieters erlaubt es, sie nicht zu duplizieren. Denn in Wirklichkeit sind alle Zeitreihen darin gespeichert, und die Container verweisen einfach auf die benötigten Zeitreihen.

Das Ergebnis ist ein Mega-Kernel, auf den die Expertenklassen zugreifen. Wie unterscheidet es sich von der grundlegenden MQL, wenn es den MetaTrader-Kernel und Hunderte seiner Funktionen gibt, die auf ihn zugreifen?

Wenn wir MT4-5 selbst als Datenlieferant betrachten und unsere Klasse nur für die Bereitstellung des Zugriffs verwendet wird - dann stellt sich heraus, dass wir gemäß Ihrem Verweis auf den Eröffnungskurs die Funktion CopyOpen() für einen Wert aufrufen müssen - das erscheint mir unvernünftig.

Ganz genau. Nur ein solcher Aufruf garantiert die Einheitlichkeit der Datendarstellung und die vollständige Synchronisierung der Zustände. Es müssen keine Aktualisierungen von Kursen vorgenommen werden (die man vergessen kann), es müssen keine zusätzlichen Kippschalter verwendet werden, die bei der Erstellung eines Datenspeichers zwangsläufig auftreten. Es ist nicht notwendig, die Datenbank nach Daten zu durchsuchen, die mit den angeforderten Daten übereinstimmen. Wenn mein EA das tut:

Trade.SellLimit(WS.High[1]);

Dann ist garantiert, dass WS.High[1] seinen vorherigen Extremwert zurückgibt, unabhängig davon, wie das Handelsumfeld aktualisiert wird. Ja, es ist zu teuer, CopyHigh bei jedem Aufruf aufzurufen und einen einzelnen Double-Wert zu kopieren, aber es ist 100% zuverlässig. Da Deckungsklassen keine Daten speichern, sondern nur den Aufruf von Systemfunktionen weitergeben, kann es nicht vorkommen, dass die gespeicherten Daten nicht der aktuellen Umgebung entsprechen.

Ich halte es auch für sehr unvernünftig, an jeder Stelle des Programms vollen globalen Zugriff auf alle Variablen zu gewähren; im Gegenteil, ich versuche, an jeder Stelle des Programms nur auf die Strukturen und Daten zuzugreifen, die für eine bestimmte Aktion benötigt werden. Alles andere muss unzugänglich sein. Die Ideologie des Datenanbieters erlaubt es lediglich, diesen Zugang zu kontrollieren.

Georg, Sie haben diesen globalen Zugang ja bereits geschaffen. Sie haben einen großen Oberklassenanbieter, auf den alle zugreifen. Dabei handelt es sich um einen großen globalen Pool von Objekten (Indikatoren, Zeitreihen usw.), die unter dem Deckmantel der OOP gesammelt werden. Mit anderen Worten: In dem Beispiel mit dem Datenanbieter ist OOP zu einer Fiktion geworden. Sie existiert zwar formal, aber nicht in der Realität.

 
Vasiliy Sokolov:

Georg, Sie haben diesen globalen Zugang ja bereits eingerichtet. Sie haben einen großen Anbieter der Superklasse, auf den jeder Zugriff hat. Dabei handelt es sich um einen großen globalen Pool von Objekten (Indikatoren, Zeitreihen usw.), die unter dem Deckmantel der OOP zusammengefasst sind. Mit anderen Worten: In dem Beispiel mit dem Datenanbieter ist OOP zu einer Fiktion geworden. Formal ist sie da, aber in der Realität nicht.

Nein, ich habe die Laufgeschwindigkeiten verglichen, wenn ich einen Puffer im Datenprovider platziere oder die Daten jedes Mal über CopyXXX abrufe - ich habe mal schnelleren Zugriff auf meinen Puffer. Deshalb habe ich mich für meine Puffer entschieden, und der Datenanbieter ist nur ein zentraler Speicher für diese Puffer.

In der Tat birgt das Vorhandensein eines "Layers" - eben dieses Datenanbieters - das Risiko einer Datenunsynchronisation. Aber bisher bin ich noch nie auf ein solches Problem gestoßen, sondern der Datenanbieter spart ganz klar Geschwindigkeit. Ich glaube, dieser Test wurde bereits von vielen Leuten durchgeführt - es stellte sich heraus, dass es bei der Verarbeitung eines Ticks profitabler ist, die Daten einmal zu kopieren und zu verwenden, als jedes Mal zum Terminal zu gehen, um Daten zu holen.

Jetzt ist es anders? Und die Geschwindigkeit einer Reihe von Aufrufen über CopyXXX für jede doppelte Wert ist die gleiche wie die Geschwindigkeit von einem Aufruf auf einmal für den gesamten Bereich, und dann - Aufruf an den Puffer für Werte?

 
George Merts:

Nein, ich habe die Geschwindigkeiten verglichen, wenn ich den Puffer in den Datenprovider lege oder die Daten jedes Mal mit CopyXXX abrufe - ich habe einen viel schnelleren Zugriff auf meinen Puffer. Deshalb habe ich mich für meine Puffer entschieden, und der Datenanbieter ist nur ein zentraler Speicher für diese Puffer.

In der Tat birgt das Vorhandensein eines "Layers" - eben dieses Datenanbieters - das Risiko einer Datenunsynchronisation. Aber bisher bin ich noch nie auf ein solches Problem gestoßen, sondern der Datenanbieter spart ganz klar Geschwindigkeit. Ich denke, dass viele diesen Test bereits durchgeführt haben - jeder hat erfahren, dass es bei der Verarbeitung von Häkchen profitabler ist, die Daten einmal zu kopieren und zu verwenden, anstatt jedes Mal zum Terminal zu gehen, um Daten zu holen.

Jetzt ist es anders? Und die Geschwindigkeit der Anzahl von Aufrufen über CopyXXX für jeden doppelten Wert ist die gleiche wie die Geschwindigkeit von einem Aufruf auf einmal für den gesamten Bereich, und dann - Aufruf an den Puffer für Werte?

Zweifellos ist es viel schneller, alle Zitate auf einmal in den internen Speicher des EA zu kopieren (Date Provider) und dann die Werte daraus abzurufen, als ständig den CopyBuffer aufzurufen. Aber das ist der Preis für ein staatliches System. Im Grunde genommen ist unsere gesamte Domäne - das Schreiben von EAs, Skripten usw. - die Programmierung von Systemen, die auf Zuständen basieren: Wir haben einen Auftrag - verarbeiten die Regeln für seine Handhabung. Wenn keine Bestellung vorliegt, prüfen wir die Bedingungen für die Öffnung der Bestellung.

Was CopyBuffer betrifft, so ist das Kopieren großer Teile von Anführungszeichen und die Messung des Leistungsgewinns nur in synthetischen Tests möglich. In der Praxis arbeitet der Expert Advisor in 90 % der Fälle mit dem letzten Balken auf jedem Tick oder im Moment der Eröffnung eines neuen Balkens. Daher werden immer die Daten des letzten Balkens angefordert, und es erfolgt ein ständiger Aufruf der CopyBuffer-Funktion, die den letzten Balken in den Cache kopiert.

Die einzige wirkliche Produktivitätssteigerung tritt ein, wenn der Expert Advisor die letzten N Balken benötigt, wobei die Zahl N viel größer als 1 ist. Aber was wird von den letzten N Takten verlangt? Es handelt sich um die Arbeit im Schiebefenster (99% der gesamten Arbeit des Expert Advisors). Und ein Schiebefenster ist im Grunde genommen ein Ringspeicher. Wenn Sie also die letzten N Balken abfragen, müssen Sie in Wirklichkeit nur einen letzten Balken aktualisieren oder hinzufügen. D.h. all dieses Zeug mit dem Kopieren von Datenblöcken ist eine sehr schöne Geschichte, aber es funktioniert nicht in dem Bereich, für den es geschaffen wurde, während Ringpuffer recht erfolgreich arbeiten.

Jetzt funktioniert mein CSymbol einfach durch Übergabe des richtigen Index. Aber ich kann es so aufrüsten, dass es N letzte Balken zwischenspeichert und N wird von CSymbol selbst gewählt, abhängig von maximal angeforderten Index. Und dann wird CSymbol bei einigen Aufgaben ohne externe Änderungen um ein Vielfaches schneller arbeiten als der permanente Aufruf von CopyBuffer. Das ist die Stärke von OOP. Nach einem gewissen Overhead, der mit der Verwendung zusätzlicher Wrapper verbunden ist, kommt es zu einem qualitativen Sprung, bei dem die Verwendung von Speicher oder CPU-Zeit durch die adaptiven Algorithmen drastisch reduziert werden kann.

 
Gregory Kovalenko:
Hallo.
Wenn die Menge des Codes wächst, wird es manchmal schwierig und verwirrend.
Ich habe EA-Code mit einer riesigen Anzahl von Codezeilen gesehen. Ich frage mich, wie komplexe EAs entworfen werden, gibt es irgendwelche Tools oder Techniken für die Arbeit mit solch komplexen Algorithmen?

Ich schreibe riesige Codeblöcke, die Hunderte von Zeilen umfassen. Fast keine Kommentare. Ohne OOP. Der Code ist auf Russisch. Alles funktioniert sehr effizient. Ich habe keine Probleme mit der Orientierung im Programm, obwohl etwa 100 Dateien mit ihm verbunden sind. Wahrscheinlich, weil ich mich daran gewöhnt habe und mich an alles vor langer Zeit erinnert habe. Das Wichtigste ist, dass Sie Ihr Programm kennen und verstehen, alles andere ist zweitrangig. Imho.

 
Реter Konow:

Das Schreiben großer Codeblöcke, die Hunderte von Zeilen umfassen. Fast keine Kommentare. Kein OOP. Code auf Russisch. Alles funktioniert sehr effizient. Ich habe keine Probleme mit der Orientierung im Programm, obwohl etwa 100 Dateien mit ihm verbunden sind. Wahrscheinlich, weil ich mich daran gewöhnt habe und mich an alles vor langer Zeit erinnert habe. Das Wichtigste ist, dass Sie Ihr Programm kennen und verstehen, alles andere ist zweitrangig. Meiner Meinung nach ist es das Wichtigste, sein eigenes Programm zu kennen, und der Rest ist zweitrangig.

Sind Sie von 1C auf MMS umgestiegen?
 
Vasiliy Sokolov:
Sind Sie von 1C auf MMS umgestiegen?

Ich bin Autodidakt. Die erste Programmiersprache, die ich gelernt habe, war MQL4. Danach habe ich ein wenig in C# und C++ geübt.


Ich habe noch nie von 1C gehört. Was ist das?

 
Vasiliy Sokolov:

Wie bei CopyBuffer ist das Kopieren großer Teile von Anführungszeichen und die Messung des Leistungsgewinns nur in synthetischen Tests möglich. In der Praxis arbeitet der Expert Advisor in 90 % der Fälle mit dem letzten Balken eines jeden Ticks oder mit dem Zeitpunkt der Eröffnung eines neuen Balkens. Daher werden immer die Daten des letzten Taktes angefordert und es erfolgt ein ständiger Aufruf des CopyBuffer, der den letzten Takt in den Cache kopiert.

Wir brauchen also die Geschwindigkeit im "synthetischen Test" - die Geschwindigkeit wird kritisch bei der Suche nach Varianten im Strategietester. Es ist der Strategietester für mich ein "Flaschenhals", wo wir Geschwindigkeit brauchen.

Gerade in der realen Arbeit reicht die Geschwindigkeit des direkten Zugriffs auf die Daten über CopyXXX jedes Mal aus. Aber für den Prog im Tester ist der Geschwindigkeitsunterschied sehr wichtig.

 
Kommentare, die für dieses Thema nicht relevant sind, wurden nach"OOP vs. prozedurale Programmierung" verschoben.
 
George Merts:

Aber gerade beim "synthetischen Test" ist Schnelligkeit gefragt - die Geschwindigkeit wird entscheidend, wenn man Optionen im Strategietester ausprobiert. Der Strategietester ist für mich ein "Flaschenhals", wenn Geschwindigkeit gefragt ist.

Gerade in der realen Arbeit reicht die Geschwindigkeit des direkten Zugriffs auf die Daten über CopyXXX jedes Mal aus. Aber für Prog. in Tester - Unterschied in der Geschwindigkeit ist sehr wichtig.

Einfacher ausgedrückt: An der Basis Ihres Datenanbieters gibt es die Funktion CopyXXX, die das letzte Zeichen kopiert. An der Basis meines CSymbols befindet sich auch CopyXXX, das das gleiche letzte Zeichen kopiert. Beide Funktionen sind langsam. Daher sind sowohl Ihr Code als auch mein Code langsam, da der CopyXXX-Aufruf nicht umgangen werden kann. Aber mein Code ist einfacher und kleiner. Wozu also dieses mehrstöckige Gebäude über CopyXXXXX, wenn es das Problem von CopyXXX selbst nicht löst?