Paketbasierter Ansatz mit KnitPkg für die MQL5-Entwicklung
Einführung
Ein Trader-Entwickler muss häufig mehrere MQL5-Projekte (EAs, Indikatoren, Tools) pflegen, die denselben mathematischen und Hilfscode verwenden. Heutzutage erfolgt diese Wiederverwendung meist noch auf die altbewährte Art: durch das Kopieren von Ordnern zwischen Projekten und das manuelle Bearbeiten von #include-Anweisungen. Mit jedem Update kommt es zu Versionsabweichungen – hier gibt es einen neuen Fix, dort eine alte Datei –, und ein Build in einer „reinen“ MetaTrader-Umgebung hängt davon ab, was in diesem Terminal bereits manuell gepatcht wurde. Was wirklich benötigt wird, ist eine Möglichkeit, eine Komponente einmalig in Git zu implementieren, sie gemäß SemVer zu versionieren und in verschiedene Projekte einzubinden, sodass Installation und Builds auf jedem Rechner reproduzierbar sind: Die Abhängigkeiten sind fest vorgegeben, Artefakte werden automatisch generiert (als Include-Baum oder als flacher, generierter Header), und das Verschieben von Code zwischen Projekten erfordert keine Bearbeitung von Pfaden oder das Kopieren und Einfügen von Dateien mehr.
Dieser Artikel stellt einen solchen Workflow für MQL4/MQL5 vor, der auf KnitPkg-Paketen basiert: Jede Funktion wird als wiederverwendbare, versionierte Komponente definiert und anschließend projektübergreifend über ein Manifest statt per Copy-Paste genutzt. Im Laufe dieses Artikels werden wir sehen, wie dieser Ansatz die Zusammenstellung, die Wiederverwendung zwischen EAs und Indikatoren sowie die Veröffentlichung robuster macht, indem verstreute Code-Schnipsel in strukturierte, abhängigkeitsverwaltete Bausteine umgewandelt werden.
Was ist KnitPkg?
KnitPkg ist ein Git-first-Paket- und Projektmanager für MQL4/MQL5. Es löst das chronische Problem aus Copy-Paste, manuellen #include-Anpassungen und Versionsdrift, das die MetaTrader-Entwicklung belastet, indem es:
- Nur Metadaten werden in einer zentralen Registry gespeichert, während der Quellcode in gewöhnlichen Git-Repositories liegt.
- Abhängigkeiten mit semantischer Versionierung (^, ~, * usw.) bereitstellt, damit Sie genau angeben können, welche Paketversion Sie benötigen.
- Eine Sperrdatei für reproduzierbare Builds erstellt.
- Zwei Installationsmodi zur Verfügung stellt – der Include-Modus (ein klassischer Include-Baum) und der Flat-Modus (ein einziger generierter Header, nützlich für die Verbreitung von Code im MQL5-Markt).
Kurz gesagt: Mit KnitPkg können Sie sich ganz auf das Schreiben von übersichtlichem, testbarem und über Git verwaltetem MQL-Code konzentrieren, während das Tool die Auflösung von Abhängigkeiten, die Installation und die Kompilierung übernimmt.
In diesem Abschnitt geben wir einen kurzen Überblick über die wichtigsten Kernideen hinter KnitPkg. Eine ausführlichere Erläuterung finden Sie in KnitPkg Documentation und auf KnitPkg Home Page.
1. Manifest. Das Manifest ist das Gehirn eines KnitPkg-Projekt-Repositorys: Es teilt KnitPkg mit, um was für ein Repository es sich handelt, wie es erstellt werden soll und welche Abhängigkeiten es benötigt. Das Manifest wird im YAML-Format in einer Datei namens knitpkg.yaml oder knitpkg.yml gespeichert. Das JSON-Format wird ebenfalls unterstützt; in diesem Fall lautet der Dateiname knitpkg.json.
2. Projekte und Pakete. Ein Projekt ist der Standard-Container: Es kann sich dabei um einen Indikator, einen Experten, ein Skript, eine Bibliothek, einen Dienst oder sogar ein Test-Repository handeln. In KnitPkg-Projekten befindet sich Ihr Quellcode in der Regel im Verzeichnis src/, und KnitPkg generiert automatisch Abhängigkeitsartefakte (Include-Baum oder Flat-Dateien) im Verzeichnis knitpkg/.
Ein Paket ist ein Projekt, dessen Hauptzweck darin besteht, von anderen Projekten über Abhängigkeiten importiert zu werden. Das bedeutet, dass der Code auf vorhersehbare Weise strukturiert sein muss, damit andere Personen (oder Ihre anderen Projekte) die Header-Dateien mit #include einbinden können. Nicht jedes Projekt ist ein Paket, aber jedes Paket ist ein Projekt.
Einzelne und zusammengesetzte Pakete. In KnitPkg gibt es zwei Arten von Paketen:
- Einfaches Paket: eigenständig, ohne angegebene Abhängigkeiten.
- Zusammengesetztes Paket: Ein Paket, das (direkt oder indirekt) von einem oder mehreren anderen Paketen abhängt.
Zusammengesetzte Pakete müssen ein bestimmtes Problem lösen. Während der Entwicklung möchte der Autor, dass IntelliSense und Unit-Tests reibungslos kompiliert werden, doch das Paket hängt von Code ab, der sich außerhalb des Repositorys befindet. Wenn das Paket zudem von anderen als Abhängigkeit installiert wird, muss das nutzende Projekt die tatsächlichen #include-Anweisungen erhalten, die auf die installierten Header-Dateien der Abhängigkeit verweisen. KnitPkg löst dieses Problem durch die Kombination folgender Elemente:
- eine Entwicklungshilfsdatei (autocomplete.mqh) sowie
- Anweisungen @knitpkg:include, die KnitPkg während der Ausführung des Befehls kp install in echte #include-Zeilen umwandelt.
KnitPkg stellt spezielle Befehle bereit, um die Include-Datei autocomplete.mqh zu generieren und die Richtigkeit der Anweisungen zu überprüfen, damit der Installationsprozess reibungslos funktioniert, wenn das Paket von anderen Projekten genutzt wird.
Verwendung von Paketen. Die Implementierung eines Pakets kann strukturiert oder objektorientiert sein, wie es von MQL4 und MQL5 unterstützt wird. In diesem Artikel wird nicht auf den Implementierungsstil eingegangen, da dieser von der Aufgabe der Komponente, den Leistungsanforderungen, den Präferenzen der Entwickler usw. abhängt.
Unabhängig von der Art der Implementierung lässt sich ein gut konzipiertes Paket dank KnitPkg auf verschiedene Weise nutzen:
- Direkte Nutzung des Codes über im Manifest deklarierte KnitPkg-Abhängigkeiten.
- Über eine MQL-Bibliothek: Eine Bibliothek kapselt und stellt die Funktionalität eines Pakets bereit. Die Bibliothek wird ebenfalls als KnitPkg-Projekt erstellt.
- Über einen MQL-Indikator: Ein Indikator kann ein Paket für Berechnungen nutzen und die Ergebnisse anschließend über seine Puffer bereitstellen. Der Indikator visualisiert die Daten im Chart und stellt zugleich Berechnungsergebnisse bereit, die andere EAs nutzen können. Auf diese Weise kann jede EA die von der Komponente durchgeführte Berechnung über den Indikator abrufen, genau wie bei einer nativen Funktion.
Zusammenfassend lassen sich folgende Vorteile der Implementierung von Paketen mit KnitPkg nennen:
- Jede Funktion wird einmal in einem Git-Repository implementiert, wobei die SemVer-Versionierung angewendet wird.
- Das Paket kann in jedem Projekt beliebig oft wiederverwendet werden, ohne dass Code doppelt geschrieben werden muss.
- Das Paket kann in der für den Anwendungsfall am besten geeigneten Form wiederverwendet werden (direkter Codeaufruf, Indikator oder Bibliothek).
3. Unit-Tests. KnitPkg empfiehlt die Verwendung von Unit-Tests zur Validierung von Paketen. Unit-Tests sind kleine, wiederholbare Prüfungen, mit denen bestimmte Verhaltensweisen des Codes Ihres Pakets überprüft werden. Sie helfen Ihnen dabei, Regressionen frühzeitig zu erkennen, und dienen – sofern sie aussagekräftig benannt sind – als ausführbare Dokumentation dafür, wie sich Ihre öffentliche API verhalten soll.
Dies ist besonders für Pakete von Bedeutung, da diese dazu gedacht sind, als Abhängigkeiten wiederverwendet zu werden: Wenn Sie eine neue Paketversion veröffentlichen, möchten Sie sicher sein, dass die Kernfunktionen weiterhin wie erwartet funktionieren.
Unit-Tests werden im Manifest unter dem Eintrag compile deklariert, sodass sie automatisch kompiliert und direkt ausgeführt werden können.
4. Registry. KnitPkg ist in zwei Teile gegliedert:- Die CLI: Das Tool, das Sie lokal ausführen und mit dem Sie direkt interagieren (Beispiel: kp install).
- Die Registry: Ein Webdienst, der aus Projektmanifesten extrahierte Metadaten speichert und diese Metadaten an die CLI bereitstellt.
Die Registry dient dazu, dass die CLI-Projekte zuverlässig erkennen und Abhängigkeiten auflösen können, während der Quellcode weiterhin in Git-Repositorys gespeichert bleibt. Es speichert Manifest-Metadaten für von KnitPkg verwaltete Projekte und wird von der CLI verwendet, um öffentliche Projekte zu durchsuchen und abzufragen, Versionsbereiche von Abhängigkeiten in eine konkrete Version aufzulösen und die genaue Quellcode-Revision (Commit) zu ermitteln, die dieser aufgelösten Version entspricht. Diese Git-Repositorys können auf MQL5Forge, GitHub, GitLab oder Bitbucket gehostet werden.
Alle registrierten Projekte können auch über die Weboberfläche der Registry durchsucht werden, die Entwicklern und Tradern das Auffinden der benötigten Pakete, EAs und Indikatoren erleichtern soll.
Fallstudie – Aufbau wiederverwendbarer Pakete mit KnitPkg
In dieser Fallstudie besteht das Hauptziel darin, eine einzelne Berechnung (eine SMA) zusammenzustellen und in drei verschiedenen Artefakten wiederzuverwenden: einem Paket, einem Indikator und einem EA. Die Handelsregeln sind bewusst einfach gehalten; im Mittelpunkt steht, wie dieselbe Komponente deklariert, versioniert, installiert und ohne Kopieren-Einfügen wiederverwendet wird.- Das endgültige ausführbare Artefakt ist ein EA, der auf der Grundlage von zwei gleitenden Durchschnitten eine Long-Position eröffnet, wenn der kurzfristige SMA (sma1) den langfristigen SMA (sma2) von unten nach oben kreuzt. Als Filter muss ein dritter SMA (sma3) die Bedingung Close > sma1 > sma2 > sma3 erfüllen, bevor ein Einstieg zulässig ist. Die Position sollte geschlossen werden, wenn der SMA1 den SMA2 nach unten kreuzt. Der EA sollte so wenig CPU-Leistung wie möglich beanspruchen.
- Zur Unterstützung des EA werden wir einen Indikator namens KnitPkgSMA erstellen, der den einfachen gleitenden Durchschnitt für das aktuelle Chart berechnet. Der SMA sollte nur bei einer neuen Bar (neu) berechnet werden, nicht bei jedem Tick.
- Der SMA-Berechnungscode sollte in einem Paket untergebracht werden, damit er wiederverwendet werden kann.
- Das SMA-Paket muss eine generische Schnittstelle akzeptieren, die eine Zeitreihe (TimeSeries) darstellt, wobei der Index 0 stets den aktuellsten Kurs repräsentiert (der Index funktioniert wie shift).
- Das Paket, das die SMA-Implementierung (und zukünftige Indikatoren) enthält, sollte sowohl vom Indikator KnitPkgSMA als auch von jedem anderen Paket oder Projekt wiederverwendbar sein.
- Um eine effiziente Wiederverwendung des SMA in einem EA zu ermöglichen, muss eine standardisierte Methode bereitgestellt werden, mit der bei jedem Tick überprüft werden kann, ob sich eine neue Bar gebildet hat.
- Wenn ein EA auf OHLCV-Daten zugreifen muss, sollte er dies ebenfalls über eine Standard-Zeitreihen-Schnittstelle tun (Index 0 für die aktuellsten Werte).
Zielpaket-Artefakte. Um die Anforderungen zu erfüllen, wurden die folgenden Pakete erstellt:
- @douglasrechia/bar – enthält die Schnittstellen für Zeitreihen und OHLCV-Bar sowie Funktionen zur Erkennung der Erstellung einer neuen Bar bei jedem Tick. Siehe das Git-Repository zum Paket bar
- @douglasrechia/calc – calc basiert auf dem Paket bar und enthält die SMA-Implementierung sowie weitere zukünftige Indikatoren. Informationen zum Paket calc finden Sie im Git repository .
Anmerkung 1: In KnitPkg wird ein Projekt als @<Organisation>/<Repository-Name> bezeichnet, wobei Organisation und Repository-Name aus den letzten beiden Elementen der Git-URL extrahiert und beide in Kleinbuchstaben geschrieben werden.
Anmerkung 2: Um die Konsistenz dieses Artikels auch dann zu gewährleisten, wenn sich die Repositorys im Laufe der Zeit weiterentwickeln (neue Commits), verweisen die Links auf den Commit, der zum Zeitpunkt der Erstellung des Artikels die aktuellste Version der Pakete darstellt.
1. Das Bar-Paket erkunden. Gemäß der KnitPkg-Konvention befinden sich die Header-Dateien des bar-Pakets im Verzeichnis knitpkg/include/<Organisation>/<Projektname>, in diesem Fall also: knitpkg/include/douglasrechia/bar/Nur Projekte vom Typ Paket dürfen Code unter knitpkg/include/ hinzufügen; bei allen anderen Projekttypen darf das Verzeichnis knitpkg/ nicht manuell bearbeitet werden.
Die Header-Dateien im Verzeichnis knitpkg/include/douglasrechia/bar/ enthalten die Klassen und Schnittstellen für TimeSeries, Bar (ein Accessor im Zeitreihenstil für OHLCV-Daten) und BarWatcher (zur Erkennung einer neuen Bar bei jedem Tick). Die Leser sind herzlich eingeladen, das Repository durchzublättern und den Code zu studieren.
Im Bar-Repository ist knitpkg.yaml wie folgt:
target: mql5 type: package organization: douglasrechia name: bar version: 1.1.0 version_description: New constructor for TimeSeriesArray # Search fields description: Simple, fast and reliable bar access with time series and new bar detection. keywords: [ "bar", "array", "timeseries", "demo", "showcase" ] author: Douglas Rechia license: MIT compile: - tests/UnitTestsBarArray.mq5 - tests/UnitTestsBarMqlRates.mq5 - tests/UnitTestsTimeSeries.mq5
Technisch gesehen wird ein Paket in MetaTrader als Skript-Projekt angelegt. Die Unit-Test-Skripte zeigen nach der Kompilierung an, ob die Ausgabe den Erwartungen entspricht. Laden wir dieses Paket nun herunter und führen die Unit-Tests aus.
2. Herunterladen und Ausführen der Unit-Tests des bar-Pakets. Wir gehen davon aus, dass Sie die KnitPkg-Installationsanleitung bereits befolgt haben und über eine Neuinstallation von MetaTrader unter C:\Program Files\MetaTrader 5 verfügen.
Öffnen Sie MetaTrader und wählen Sie Datei > Datenordner öffnen. Klicken Sie dann mit der rechten Maustaste in den Ordner und wählen Sie Open in Terminal:

Sie sollten nun sehen, dass das Terminal im Datenordner von MetaTrader geöffnet wurde:

Um den Quellcode des Pakets bar herunterzuladen und direkt in Ihrer MetaTrader-Umgebung zu kompilieren, führen Sie folgenden Befehl aus:
kp get mql5 @douglasrechia/bar -v 1.1.0
Hinweis: Die Option -v ist bei kp get optional; hier wird die Version 1.1.0 vorgegeben, um die Übereinstimmung dieses Artikels mit der Versionsnummer des Pakets zu gewährleisten. Wird der Parameter -v nicht verwendet, wird für kp get die aktuellste stabile Version ermittelt.
Sehen Sie unten, wie das Terminal nach kp get aussieht:

Auf diese Weise erhalten Sie nicht nur eine lokale Kopie des Quellcodes von bar, Version 1.1.0, sondern auch die aus dem Quellcode kompilierten Binärdateien der Unit-Tests. Kehren Sie zu MetaTrader zurück und aktualisieren Sie den Bereich Skripte im Navigator. Die Testskripte finden Sie unter Scripts/bar/bin/. Führen Sie die Skripte UnitTestsBarArray, UnitTestsBarMqlRates und UnitTestsTimeSeries aus (machen Sie einfach einen Doppelklick darauf). Die Testergebnisse finden Sie in der Toolbox auf der Registerkarte Experten:

Sie können das heruntergeladene Projekt bar unter Scripts/bar öffnen und erkunden. Beachten Sie, dass es sich hierbei um ein Git-versioniertes Repository handelt.

Beachten Sie außerdem, dass die Manifestdatei knitpkg.yaml vorhanden ist, ebenso wie die Header-Dateien im Verzeichnis knitpkg/include/douglasrechia/bar/, die in alle Projekte exportiert werden, die dieses Paket nutzen.
Hinweis: Verwenden Sie den Windows Explorer und Ihren bevorzugten Editor, um YAML-Dateien und andere Nicht-MQL-Quelldateien anzuzeigen; VS Code wird empfohlen. Zur Bearbeitung von MQL-Code wird der MetaEditor empfohlen.
Befehl get: Was im Hintergrund passiert. Wenn Sie kp get ausführen (und einige andere Befehle, die Ähnliches bewirken), wendet sich die KnitPkg-Befehlszeilenschnittstelle an die Registry, um die neueste stabile Version des angeforderten Pakets abzurufen. Die Registry gibt die URL des Git-Repositorys und den Commit-Hash für diese Version zurück. Dann klont der Befehl kp get dieses Repository anhand des angegebenen Hash-Werts. Das erklärt, warum der obige git status-Befehl anzeigt, dass sich das Repository im Status HEAD detached befindet. Weitere Informationen finden Sie in der Referenz von kp get.
Das Paket bar ist ein einfaches Paket ohne Abhängigkeiten. Kommen wir nun zum Paket calc, wo es erst richtig interessant wird.
Meilenstein 1 – Paket ohne Copy-Paste installiert. Zu diesem Zeitpunkt ist die Version 1.1.0 des Pakets @douglasrechia/bar in Ihrer MetaTrader 5-Umgebung verfügbar, und die Unit-Tests bestätigen, dass es wie erwartet funktioniert. Dies ist auch die Umgebung, in der das Paket aktiv weiterentwickelt wird: Entwicklungszweige werden angelegt, Fehler behoben, neue Funktionen implementiert, Änderungen festgeschrieben und schließlich eine neue Paketversion erstellt – und das alles, ohne Projekte zu berühren, die von bar abhängen.
3. Paket calc: Beispiel für ein Composite-Paket. Wie wir bereits wissen, ist das Paket calc für die Umsetzung der SMA-Berechnung zuständig. Allerdings wird calc @douglasrechia/bar als Abhängigkeit verwenden: Die Schnittstelle TimeSeries wird als Argument für die Funktion zur Berechnung des gleitenden Durchschnitts verwendet. Der Vorteil besteht darin, dass die SMA-Funktion die Implementierung von TimeSeries abstrahiert. Es spielt keine Rolle, ob TimeSeries mit einem einfachen Array oder einer anderen Datenstruktur implementiert ist. SMA muss die Berechnung lediglich unter der Annahme durchführen, dass das aktuellste Element an Position 0 der Zeitreihe steht, das vorherige an Position 1 und so weiter.
Wiederholen wir nun den Vorgang. Wir führen den folgenden Befehl aus, um calc zu erhalten: Version 1.0.1:
kp get mql5 @douglasrechia/calc -v 1.0.1
Als Übung gehen Sie zurück zu MetaTrader und aktualisieren Sie den Bereich Skripte im Navigator. Die Testskripte finden Sie unter Scripts/calc/bin/. Führen wir die Tests durch und sehen wir uns die Registerkarte Experten in der Toolbox an.
Schauen wir uns nun das calc-Projekt und einige bestimmte Aspekte seines Codes genauer an. Zunächst sehen wir uns das Calc-Manifest an: knitpkg.yaml. Hier gibt es etwas Neues: Der Eintrag dependencies gibt an, dass calc von @douglasrechia/bar abhängt:
target: mql5 type: package organization: douglasrechia name: calc version: 1.0.1 version_description: 'ATR fix' description: Common indicators built on @douglasrechia/bar (SMA, ATR, etc) keywords: [ "indicator", "sma", "atr", "showcase" ] author: Douglas Rechia license: MIT dependencies: '@douglasrechia/bar': ^1.0.0 compile: - tests/UnitTestSMA.mq5 - tests/UnitTestATR.mq5
Schauen wir uns den Quellcode der SMA-Funktion an: knitpkg/include/douglasrechia/calc/Calc.mqh. Im Folgenden gehen wir auf einige wichtige Punkte zu diesem Header sowie auf die spezifischen Aspekte ein, die für Composite-Pakete charakteristisch sind.
Der #include-Befehl für autocomplete.mqh. In der Datei Calc.mqh ermöglicht der #include-Befehl für autocomplete.mqh das Erstellen eines Composite-Pakets ohne unnötigen Aufwand.
//............... //------------------------------------------------------------------ // Development autocomplete — resolves dependencies and enables // MetaEditor IntelliSense; automatically neutralized by KnitPkg // installer. // Run `kp autocomplete` to regenerate. //------------------------------------------------------------------ #include "../../../autocomplete/autocomplete.mqh" //------------------------------------------------------------------ // KnitPkg include directives — used by KnitPkg installer at the time // this package is installed as a dependency into another KnitPkg // project. //------------------------------------------------------------------ /* @knitpkg:include "douglasrechia/bar/TimeSeries.mqh" */ /* @knitpkg:include "douglasrechia/bar/Bar.mqh" */ namespace douglasrechia { //...............
Interessanterweise ist autocomplete.mqh nicht im Git-Repository enthalten. Der Befehl kp autocomplete generiert diesen Header in der Datei knitpkg/autocomplete/autocomplete.mqh. Der Befehl kp get (den wir oben verwendet haben) ruft im Rahmen seines Ausführungszyklus automatisch kp autocomplete auf, weshalb get das Paket und seine Unit-Tests automatisch kompilieren konnte.
So funktioniert die Autovervollständigung. Überprüfen Sie in Ihrer lokalen Calc-Installation den Inhalt der Datei autocomplete.mqh (diesen Header werden Sie im Repository nicht finden; dort existiert er nicht):
//+------------------------------------------------------------------+ //| autocomplete.mqh | //| Generated by `kp autocomplete` — DO NOT EDIT | //+------------------------------------------------------------------+ #include "knitpkg/include/douglasrechia/bar/Bar.mqh" #include "knitpkg/include/douglasrechia/bar/BarArray.mqh" #include "knitpkg/include/douglasrechia/bar/BarMqlRates.mqh" #include "knitpkg/include/douglasrechia/bar/BarTimeSeries.mqh" #include "knitpkg/include/douglasrechia/bar/BarWatcher.mqh" #include "knitpkg/include/douglasrechia/bar/TimeSeries.mqh" #include "knitpkg/include/douglasrechia/bar/TimeSeriesArray.mqh"
Beachten Sie, dass sich die Header von bar nun unter knitpkg/autocomplete/knitpkg/include/douglasrechia/bar befinden (nur lokal), und genau deshalb ermöglicht autocomplete.mqh, dass IntelliSense in MetaEditor für Calc.mqh funktioniert und die Unit-Tests kompiliert werden können. Diese Header werden beim Ausführen von kp autocomplete erstellt bzw. aufgelöst. Dabei wird in .knitpkg/cache/ ein Git-Clone (oder Fetch) für die in der Datei manifest deklarierten Abhängigkeiten durchgeführt. Auf diese Weise können Sie problemlos Pakete entwickeln, die von anderen Paketen abhängen.
In einem Composite-Paket ist diese automatisch generierte Datei autocomplete.mqh nicht nur eine Komfortfunktion, sondern die Standardmethode, um die Kompilierung im MetaEditor und IntelliSense zu ermöglichen, während die eigentlichen Abhängigkeiten weiterhin von KnitPkg aufgelöst und installiert werden. Ohne diesen Schritt würden Paketautoren unweigerlich wieder auf die manuelle Verwaltung von #include-Anweisungen zurückgreifen, wodurch genau jene Abweichungen und Probleme beim Kopieren und Einfügen wieder entstehen würden, die KnitPkg eigentlich beseitigen soll.
Hinweis: Der Inhalt des Verzeichnisses knitpkg/autocomplete/ wird automatisch generiert und darf nicht bearbeitet werden.
Namespace (nur MQL5). Für MQL5 wird empfohlen, den Code eines Pakets in einem Namespace unterzubringen, dessen Name mit dem Namen der Organisation übereinstimmt (in MQL4 sind Namespaces nicht verfügbar). Dadurch werden Symbolkonflikte bei der Verwendung von Paketen verschiedener Organisationen vermieden. Die Verwendung von Namespaces in Verbindung mit der Konvention für den Speicherort von Header-Dateien knitpkg/include/<Organisation>/<Projektname> gewährleistet, dass keine Konflikte auftreten und beim Erstellen des Include-Baums keine Header-Datei überschrieben wird.
Die SMA-Funktion. SMA ist eine Funktion, die eine Zeitreihe (die Schnittstelle ITimeSeries) als Argument entgegennimmt und den Mittelwert zurückgibt, wobei die Periode (Anzahl der Elemente im Mittelwert) und die Verschiebung (die Position, an der der Mittelwert relativ zur Zeitreihe berechnet wird, wobei 0 für den aktuellsten Wert, 1 für den vorherigen Wert usw. steht) vorgegeben werden.
double SMA(douglasrechia::ITimeSeries<double> &series, int period, int shift = 0) { if(series.Size() < (period + shift)) return 0.0; double sum = 0.0; for(int i = shift; i < shift + period; i++) sum += series.ValueAtShift(i); return sum / period; }
Wie bereits erwähnt, besteht der Vorteil der Implementierung von SMA hier im Paket und nicht im Indikatorcode darin, dass dieser Code in jedem anderen Projekt verwendet werden kann.
Vorbereitung eines Composite-Pakets zur Installation: @knitpkg:include. Beachten Sie die folgenden Anweisungen in der Datei Calc.mqh:
/* @knitpkg:include "douglasrechia/bar/TimeSeries.mqh" */ /* @knitpkg:include "douglasrechia/bar/Bar.mqh" */
Auf den ersten Blick sieht das wie auskommentierter Code aus, den der Compiler ignorieren wird. Für KnitPkg haben diese Anweisungen, die durch die Kommentarzeichen /* und */ begrenzt sind, jedoch eine besondere Bedeutung: Sie beziehen sich auf die Header, die außerhalb von Calc liegen und von denen Calc.mqh abhängt. Tatsächlich sind beide Header in autocomplete.mqh enthalten, und deshalb kann MetaEditor Calc.mqh während der Entwicklung sowie die Skripte für die Unit-Tests problemlos kompilieren.
Wenn calc in anderen Projekten als Abhängigkeit verwendet wird, wird Calc.mqh so umgewandelt, dass der #include-Befehl für autocomplete.mqh deaktiviert wird und die @knitpkg:include-Anweisungen in die tatsächlichen externen Header aufgelöst werden. Es liegt in der Verantwortung des Paketautors, die @knitpkg:include-Anweisungen auf dem neuesten Stand zu halten, damit sie ausschließlich auf die Header verweisen, die die von diesem Header benötigten Symbole definieren.
Um Entwicklern dabei zu helfen, diese Direktiven korrekt zu halten, bietet KnitPkg den Befehl kp checkinstall. Dieser Befehl löst das aktuell unter knitpkg/autocomplete/include/ entwickelte Paket auf, in diesem Fall knitpkg/autocomplete/knitpkg/include/douglasrechia/calc (ja, der Pfad ist etwas lang), und lokal können Sie sehen, wie Calc.mqh aussehen wird, wenn es als Abhängigkeit installiert ist (Sie werden dies nicht im Repository finden; es ist dort nicht vorhanden):
//------------------------------------------------------------------ // Development autocomplete — resolves dependencies and enables // MetaEditor IntelliSense; automatically neutralized by KnitPkg // installer. // Run `kp autocomplete` to regenerate. //------------------------------------------------------------------ // #include "../../../autocomplete/autocomplete.mqh" /*** ← disabled by KnitPkg install (dev helper) ***/ //------------------------------------------------------------------ // KnitPkg include directives — used by KnitPkg installer at the time // this package is installed as a dependency into another KnitPkg // project. //------------------------------------------------------------------ #include "../bar/TimeSeries.mqh" /*** ← dependency added by KnitPkg ***/ #include "../bar/Bar.mqh" /*** ← dependency added by KnitPkg ***/
Der Befehl kp checkinstall ist Teil des Zyklus kp get, daher ist diese Datei bereits vorhanden, wenn Sie das Projekt mit kp get heruntergeladen haben. In der Praxis kann der Paketautor den Befehl kp checkinstall ausführen, sobald die @knitpkg:include-Anweisungen geändert werden, oder wenn er sicherstellen möchte, dass das Paket von anderen Projekten korrekt installiert wird.
Zusammen bilden die Anweisungen @knitpkg:include und der Befehl kp checkinstall die Überprüfungsphase des Workflows. Während der Entwicklung ermöglichen sie Ihnen eine komfortable Arbeit mit autocomplete.mqh und dem IntelliSense des MetaEditors; bei der Installation schreibt KnitPkg diese Anweisungen in echte #include-Anweisungen um, die auf die richtigen Abhängigkeits-Header verweisen. Damit wird der Kreis zwischen der lokalen Entwicklung und der zuverlässigen Einbindung in andere Projekte geschlossen, sodass keine manuellen Änderungen an den #include-Pfaden erforderlich sind und keine Header-Dateien unbemerkt übersehen werden.
Meilenstein 2 – Gemeinsames Verhalten validiert und zusammengesetztes Paket zur Wiederverwendung bereit. Nachdem das calc-Paket installiert und dessen Unit-Tests kompiliert und erfolgreich bestanden wurden, ist die SMA-Logik nun einmalig in einer getesteten Komponente auf Basis von @douglasrechia/bar implementiert. Als Composite-Paket wurden bei calc auch die @knitpkg:include-Anweisungen mittels kp checkinstall überprüft, wodurch bestätigt wird, dass seine Header korrekt umgeschrieben und mit den installierten Bar-Headern verknüpft werden, wenn das Paket als Abhängigkeit verwendet wird. Dadurch steht @douglasrechia/calc nun anderen Projekten (Indikatoren, EAs, Bibliotheken) zur Verfügung, indem diese es einfach in ihren knitpkg.yaml-Manifesten deklarieren – ganz ohne manuelle Anpassungen der #include-Pfade oder Code-Duplikate.
4. Der SMA-Indikator. Da wir nun alle Teile beisammen haben, setzen wir sie zusammen, um zu sehen, wie der Indikator aufgebaut ist. Zunächst laden wir @douglasrechia/sma Version 1.0.1 herunter:
kp get mql5 @douglasrechia/sma -v 1.0.1
Hinweis: In den vorangegangenen Abschnitten haben wir den Befehl kp get für die Projekte barundcalc jeweils separat ausgeführt, damit Sie diese isoliert betrachten konnten. Dies ist für die Verwendung des SMA-Indikators nicht erforderlich. Es reicht aus, den Befehl kp get mql5 @douglasrechia/sma auszuführen: KnitPkg ermittelt und lädt automatisch alle erforderlichen Abhängigkeiten (einschließlich bar und calc) herunter, ohne dass vorherige Schritte erforderlich sind.
Im Folgenden sehen wir, wie das Terminal nach dem Befehl kp get aussieht:

Auf dem obigen Bild ist zu sehen, dass sowohl bar als auch calc im Abhängigkeitsbaum korrekt aufgelöst und – wo nötig – heruntergeladen werden. Werfen wir nun einen Blick auf das manifest von sma:
target: mql5 type: indicator organization: douglasrechia name: sma version: 1.0.1 version_description: Dependencies updated # Registry search fields description: KnitPkg for Metatrader - SMA Indicator Demo keywords: [ "indicator", "sma", "showcase" ] author: Douglas Rechia license: MIT # Include mode resolution include_mode: flat # File to be flattened with all the dependencies for this project entrypoints: - src/KnitPkgSMA.mqh compile: - src/KnitPkgSMA.mq5 # Dependencies of the project dependencies: '@douglasrechia/calc': ^1.0.0
Beachten Sie die oben hervorgehobenen wichtigsten Teile des Manifests; wir werden darauf näher eingehen.
- Abhängigkeiten – sma hängt von @douglasrechia/calc ab. Auch wenn nur calc als direkte Abhängigkeit deklariert ist, wird bar ebenfalls als indirekte Abhängigkeit von sma aufgelöst und heruntergeladen, da calc von bar abhängt.
- include_mode: flat – sma verwendet den Flat-Modus, wobei src/KnitPkgSMA.mqh als Einstiegspunkt deklariert ist. Das bedeutet, dass alle vom SMA-Indikator benötigten Abhängigkeiten in einer einzigen flach generierten Datei zusammengefasst werden: knitpkg/flat/KnitPkgSMA_flat.mqh. Nachfolgend ein Ausschnitt aus src/KnitPkgSMA.mqh:
/* @knitpkg:include "douglasrechia/calc/Calc.mqh" */ /* @knitpkg:include "douglasrechia/bar/TimeSeriesArray.mqh" */
Ein als Einstiegspunkt deklarierter Header (in diesem Fall src/KnitPkgSMA.mqh) wird nur im Flat-Modus verwendet und muss stets @knitpkg:include-Anweisungen enthalten, die auf die vom Projekt benötigten externen Header verweisen.
Wir können uns nun die Hauptquelldatei des Indikators ansehen: src/KnitPkgSMA.mq5. Nachfolgend finden Sie einen Auszug aus dieser Datei:
// ..................... #include "../knitpkg/flat/KnitPkgSMA_flat.mqh" // ..................... //+------------------------------------------------------------------+ //| Custom indicator iteration function | //+------------------------------------------------------------------+ int OnCalculate(const int32_t rates_total, const int32_t prev_calculated, const int32_t begin, const double &price[]) { //--- if (rates_total < InpSMAPeriod) return(0); if (prev_calculated >= rates_total) return rates_total; douglasrechia::TimeSeriesArray<double> priceArray(price, prev_calculated - InpSMAPeriod - 1, rates_total-1, false); // The following loop recalculates the SMA for the most recent bars. // This is necessary because the current bar's data can change with each tick // until its formation is complete. The `shiftStart` variable determines // the initial index for recalculation, ensuring that the SMA is accurately // updated for the latest bar and any preceding bars affected by recent data changes. int shiftStart = rates_total-prev_calculated; if (shiftStart >= rates_total) shiftStart--; for (int shift=shiftStart; shift >= 0 && !IsStopped(); shift--) { SMABuffer[shift] = douglasrechia::SMA(priceArray, InpSMAPeriod, shift); } return(rates_total); }
Beachten Sie, dass wir ein Standard-MQL-#include verwenden, das auf die abgeflachte Datei ../knitpkg/flat/KnitPkgSMA_flat.mqh verweist. Die flach generierte Datei wird von KnitPkg automatisch auf der Grundlage des Einstiegspunkts und der während des kp install-Schritts aufgelösten Abhängigkeiten generiert, sodass diese Datei nicht im Repository vorhanden ist (der Befehl kp install ist ebenfalls Teil des kp get-Workflows).
An dieser Stelle dürfte dem Leser klar sein, worin der Vorteil der Verwendung von Paketen besteht: Die konkrete Umsetzung der SMA-Berechnung ist nicht in den Indikator eingebettet. Dadurch wird der Indikatorcode wesentlich einfacher, da er lediglich die in calc implementierte Funktion aufruft und dabei eine TimeSeries übergibt, die aus dem an OnCalculate() übergebenen Kurs-Array erstellt wurde.
Wenn Sie den obigen Befehl kp get ausgeführt haben, um SMA herunterzuladen, kehren Sie zu MetaTrader zurück, aktualisieren Sie die Indikatorenliste im Navigator-Fenster und fügen Sie dem aktuellen Chart den Indikator hinzu, der unter Indikatoren/sma/bin/KnitPkgSMA angezeigt wird:

Meilenstein 3 – Wiederverwendbares flaches Artefakt erstellt und kompilierter Indikator. Nach dem Ausführen von kp get generiert KnitPkg aus dem Einstiegspunkt und den aufgelösten Abhängigkeiten den abgeflachten Header knitpkg/flat/KnitPkgSMA_flat.mqh und kompiliert den Indikator anschließend erfolgreich. Dies bestätigt, dass das Paket @douglasrechia/calc korrekt verwendet wurde, um die SMA-Berechnung durchzuführen. Genau wie es hier vom Indikator verwendet wurde, steht dasselbe Calc-Paket zur Wiederverwendung in jedem anderen Projekt – EAs, anderen Indikatoren oder Bibliotheken – zur Verfügung, ohne dass auch nur eine einzige Quelldatei kopiert werden muss.
5. Der Expert Advisor expertdemo. Nun kommen wir zum letzten Teil des Puzzles: dem Demo-Expert-Advisor, der ein System auf Basis des Crossovers von gleitenden Durchschnitten umsetzt. Laden Sie die EA-Version 2.0.1 von expertdemo:
kp get mql5 @douglasrechia/expertdemo -v 2.0.1
Beginnen wir damit, die wichtigsten Teile des manifest zu erläutern. expertdemo hängt von @douglasrechia/bar (das Sie bereits kennen) und @douglasrechia/barhelper ab. Um diesen Artikel kurz zu halten, werden wir nicht näher auf die Einzelheiten von barhelper eingehen. Dem Leser genügt es zu wissen, dass barhelper eine Funktion namens NewTimeSeriesFromIndicator bereitstellt. Diese Funktion gibt eine konkrete Implementierung von ITimeSeries zurück, die die von einem beliebigen Indikator berechneten Werte in ihrem Ausgabepuffer enthält (je nach Bedarf kann es sich dabei um den gesamten Puffer oder nur um eine Teilmenge handeln).
Dies ist notwendig, da expertdemo den Indikator KnitPkgSMA verwendet und nicht die SMA-Funktion aus dem calc-Paket. Ein aufmerksamer Leser wird feststellen, dass das expertdemo-Manifest das calc-Paket nicht auflistet. Dies veranschaulicht die verschiedenen Möglichkeiten, wie die Funktionalität eines Pakets genutzt werden kann: Da KnitPkgSMA auf calc aufbaut, hängt expertdemo nicht direkt von calc ab, sondern von einem Indikator, der damit erstellt wurde. Interessant, nicht wahr?
Der expertdemo-EA verwendet ebenfalls den Flat-Modus, daher müssen die für das Projekt erforderlichen externen Header im Einstiegspunkt src/KnitPkgExpertDemo.mqh deklariert werden.
Schließlich gelangen wir zur Hauptquelldatei src/KnitPkgExpertDemo.mq5. Nachfolgend ein Auszug daraus:
//................................ //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { //--- barWatcher = new douglasrechia::BarWatcher(); myBar = new douglasrechia::BarMqlRates(); //--- Validate that sma1.period < sma2.period < sma3.period if(!(sma1period < sma2period && sma2period < sma3period)) { Print("Invalid moving average periods"); return(INIT_FAILED); } //--- Handlers for SMA indicators calculated at three different periods sma1handle = iCustom(_Symbol, _Period, "sma/bin/KnitPkgSMA", sma1period); sma2handle = iCustom(_Symbol, _Period, "sma/bin/KnitPkgSMA", sma2period); sma3handle = iCustom(_Symbol, _Period, "sma/bin/KnitPkgSMA", sma3period); if(sma1handle == INVALID_HANDLE || sma2handle == INVALID_HANDLE || sma3handle == INVALID_HANDLE) { Print("Could not initialize KnitPkgSMA indicator"); return(INIT_FAILED); } //--- return(INIT_SUCCEEDED); } //............................... //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- barWatcher.Update(); if(barWatcher.IsFirstTick()) { Print("Hello world! This is KnitPkg's debut EA. I'm mostly here for show, but hey, looking good is half the battle! ;-)"); } else if(barWatcher.IsNewBar()) { OnNewBar(); } } //+------------------------------------------------------------------+ //| OnNewBar — called when a new bar is formed | //+------------------------------------------------------------------+ void OnNewBar() { //--- Get latest 5 bars data myBar.Refresh(5); //--- Get the 5 most recent values of SMA into the TimeSeries. //--- Do it for the three SMAs. douglasrechia::TimeSeriesArray<double>* sma1 = douglasrechia::NewTimeSeriesFromIndicator(sma1handle, 0, 0, 5); douglasrechia::TimeSeriesArray<double>* sma2 = douglasrechia::NewTimeSeriesFromIndicator(sma2handle, 0, 0, 5); douglasrechia::TimeSeriesArray<double>* sma3 = douglasrechia::NewTimeSeriesFromIndicator(sma3handle, 0, 0, 5); if(sma1 != NULL && sma2 != NULL && sma3 != NULL) { if(!positionInfo.Select(_Symbol)) { //--- No position. Check filter conditions. if(!filterEnabled || (myBar.Close(1) > sma1.ValueAtShift(1) && sma1.ValueAtShift(1) > sma2.ValueAtShift(1) && sma2.ValueAtShift(1) > sma3.ValueAtShift(1))) { //--- Open position if Short term sma1 crosses up Mid term sma2 if(douglasrechia::CrossUp(sma1, sma2, 1)) { Print(StringFormat("[%s] Let's do it", TimeToString(myBar.Time(0)))); trade.Buy(1); } } } else { //--- Position is found. Close it if Short term sma1 crosses down Mid term sma2. if(douglasrechia::CrossUp(sma2, sma1, 1)) { Print(StringFormat("[%s] Time to go", TimeToString(myBar.Time(0)))); trade.PositionClose(_Symbol); } } } else { Print("ERROR: could not get TimeSeries from indicators buffers."); } if(sma1 != NULL) delete sma1; if(sma2 != NULL) delete sma2; if(sma3 != NULL) delete sma3; }
Der EA verfügt über sauberen, leicht verständlichen Code, der mit Funktionen auf hoher Abstraktionsebene erstellt wurde. In OnInit() werden die globalen Objekte barWatcher und myBar instanziiert. Die Handles für die drei SMAs werden anhand der genauen Pfade initialisiert, die der Befehl kp get für den Indikator KnitPkgSMA bereitgestellt hat.
Hinweis: Da expertdemo davon abhängt, dass sich die Binärdatei KnitPkgSMA.ex5 an dem Ort befindet, auf den die Funktion iCustom verweist, wie in OnInit() deklariert, muss der Benutzer von expertdemo vor dem Ausführen von expertdemo einmalig den Befehl kp get mql5 @douglasrechia/sma ausführen.
In OnTick() wird das BarWatcher-Objekt aus @douglasrechia/bar verwendet, um eine neue Bar zu erkennen; sobald eine neue Bar erscheint, wird OnNewBar() aufgerufen.
Der Kern des Expert Advisors liegt in der Funktion OnNewBar(). Mithilfe der Funktion NewTimeSeriesFromIndicator aus @douglasrechia/barhelper lassen sich ganz einfach die letzten fünf Elemente jedes SMA-Indikators abrufen (in der Praxis würden drei ausreichen). Anschließend eröffnet oder schließt der EA mithilfe der CrossUp-Funktion (die ebenfalls in barhelper implementiert ist) eine Position, je nachdem, ob der kurzfristige SMA den mittelfristigen SMA kreuzt.
Für die Positionsprüfung und die Handelsausführung werden die Klassen CTrade und CPositionInfo aus der MQL-Standardbibliothek verwendet. Es ist wichtig zu beachten, dass KnitPkg vollständig mit der MQL-Standardbibliothek kompatibel ist und keine Einschränkungen hinsichtlich deren Nutzung mit sich bringt (im Gegenteil: Die Standardbibliothek ist eine ausgereifte, hochwertige Bibliothek, deren Nutzung wir Ihnen empfehlen).
Meilenstein 4 – Der Stack Paket → Indikator → EA läuft ohne Copy-Paste. Der expertdemo-EA nutzt nun die SMA-Logik über den Indikator KnitPkgSMA, der wiederum auf den Paketen bar und calc aufbaut. Es wurden keine Quelldateien zwischen Projekten kopiert und keine #include-Pfademanuell bearbeitet: Die gesamte Verknüpfung wird in den knitpkg.yaml-Manifesten festgelegt und von KnitPkg zu einer reproduzierbaren Installation aufgelöst.
Schlussfolgerung
KnitPkg verändert die Art und Weise, wie MQL4/MQL5-Code wiederverwendet wird: Anstatt Ordner zwischen Terminals zu kopieren, Pfade umzubenennen und #include-Anweisungen manuell anzupassen, wird jeder Logikteil einmalig als versioniertes Paket implementiert und anschließend deklarativ über ein Manifest genutzt. In der Praxis verwandelt dies einen anfälligen, manuellen Arbeitsablauf in eine wiederholbare Build-Pipeline, in der Abhängigkeiten klar definiert sind, Versionen kontrolliert werden und Aktualisierungen nicht länger zu „chirurgischen“ Eingriffen in mehreren Projekten gleichzeitig führen
Nach der Lektüre dieses Artikels wissen Sie nun, wie Sie die MQL-Entwicklung als eine Reihe wiederverwendbarer Komponenten – Pakete, Indikatoren, Bibliotheken und EAs – strukturieren können, die auf vorhersehbare Weise zusammengesetzt werden. Genauer gesagt profitieren Sie von folgenden Vorteilen:
- Ein klares mentales Modell von KnitPkg: Die Registry speichert Metadaten, die Git-Repositorys bleiben die verbindliche Quelle, und die semantische Versionierung (^, ~, *) ermöglicht kontrollierte Upgrades.
- Die Rolle der Manifestdatei (knitpkg.yaml): Ein zentraler Ort, an dem die Projektidentität, die Build-Ziele und die Abhängigkeiten deklariert werden, wodurch die Builds reproduzierbar werden.
- Ein praktischer Installationsablauf: Den Unterschied zwischen dem Include-Modus (klassischer Include-Baum) und dem Flat-Modus (ein einziger generierter Header, nützlich für den Vertrieb im MQL5-Market) verstehen.
- So funktionieren Composite-Pakete: Verwendung von autocomplete.mqh für die Entwicklung und von @knitpkg:include-Anweisungen, die KnitPkg bei der Installation in echte Einbindungen umwandelt.
- Warum Unit-Tests in MQL wichtig sind: Die Tests werden zusammen mit dem Projekt kompiliert und tragen dazu bei, sicherzustellen, dass neue Paketversionen keine abhängigen EAs oder Indikatoren beeinträchtigen.
Die Fallstudie verknüpft diese Ideen: Eine SMA-Implementierung wird gebündelt, von einem Indikator wiederverwendet und anschließend von einem EA genutzt, wobei zur Effizienzsteigerung die Erkennung neuer Bars zum Einsatz kommt. Dies bietet einen praktischen Leitfaden für den Aufbau wiederverwendbarer Paket → Indikator/Bibliothek → EA-Stacks und zur Reduzierung von Kopier- und Einfügevorgängen bei der MQL-Entwicklung.
Anhänge
Der Quellcode für alle in diesem Artikel vorgestellten Projekte ist in den Git-Repositorys verfügbar, auf die im Text verwiesen wird. Die unten aufgeführten Anhänge entsprechen Dateien, die von KnitPkg automatisch generiert wurden, nachdem der Befehl kp get ausgeführt wurde, wodurch implizit die Prozesse hinter kp autocomplete, kp checkinstall und kp install aufgerufen wurden. Diese Dateien werden nicht in Git gespeichert, aber die Leser können sie lokal nachbilden, indem sie dieselben Befehle kp get ausführen, die im Artikel beschrieben sind.
| Dateiname | Beschreibung |
|---|---|
| autocomplete.mqh | Autocomplete-Helper, der im Rahmen von kp get (knitpkg/autocomplete/autocomplete.mqh) für das Paket calc generiert wurde. |
| Calc.mqh | Der aufgelöste Include-Header für das Paket calc, der während kp get / kp checkinstall generiert und verifiziert wurde (knitpkg/autocomplete/knitpkg/include/douglasrechia/calc/Calc.mqh). |
| KnitPkgSMA_flat.mqh | Im Projekt SMA bei Ausführung von kp get bzw. kp install generierte, vereinfachte SMA-Indikator-Header (knitpkg/flat/KnitPkgSMA_flat.mqh). |
Übersetzt aus dem Englischen von MetaQuotes Ltd.
Originalartikel: https://www.mql5.com/en/articles/21429
Warnung: Alle Rechte sind von MetaQuotes Ltd. vorbehalten. Kopieren oder Vervielfältigen untersagt.
Dieser Artikel wurde von einem Nutzer der Website verfasst und gibt dessen persönliche Meinung wieder. MetaQuotes Ltd übernimmt keine Verantwortung für die Richtigkeit der dargestellten Informationen oder für Folgen, die sich aus der Anwendung der beschriebenen Lösungen, Strategien oder Empfehlungen ergeben.
Graphentheorie: Tiefensuche (DFS) zur Traversierung von Marktstrukturen im Handel
Entwicklung eines dynamischen Multi-Pair-EA (Teil 7): Paarübergreifende Korrelationsabbildung für die Handelsfilterung in Echtzeit
MetaTrader 5 – Leitfaden für maschinelles Lernen (Teil 8): Bayes’sche Hyperparameter-Optimierung mit Purged Cross-Validation und Trial Pruning
Larry Williams’ Marktgeheimnisse (Teil 15): Handel mit Hidden-Smash Day-Umkehrungen unter Berücksichtigung des Marktkontexts
- Freie Handelsapplikationen
- Über 8.000 Signale zum Kopieren
- Wirtschaftsnachrichten für die Lage an den Finanzmärkte
Sie stimmen der Website-Richtlinie und den Nutzungsbedingungen zu.
Klingt interessant, aber ich habe da einige Bedenken.
Wenn jemand ein Git-Repository mit einem MQL5-Projekt, -Programm oder -Paket klont, das eigentlich von KnitPkg verwaltet werden soll, erhält er höchstwahrscheinlich nicht kompilierbare Quelldateien, da automatisch generierte Dateien (wie z. B. _flat) im Repository fehlen. Wäre es nicht möglich, alle erforderlichen automatisch generierten Quelldateien in Git zu committen, damit die Version unabhängig davon, wie sie bezogen wird, kompilierbar ist?
Ich bin mir nicht sicher, wie praktisch es wäre, Änderungen an den Abhängigkeiten vorzunehmen, da wir den automatisch generierten Code tatsächlich kompilieren und debuggen und nicht einfach zum entsprechenden Ursprung „springen“ können – habe ich da etwas übersehen? Beispielsweise muss man das „bar“-Paket ändern, während man am Indikator (oder am Expert Advisor) arbeitet. Wie würdet ihr das machen?
Schließlich habe ich Bedenken hinsichtlich einiger Aspekte bei der Umsetzung der Beispiele (wahrscheinlich, weil es sich nur um Beispiele handelt), wie zum Beispiel „new/delete“ bei jedem Tick/Bar. Außerdem machst du zum Beispiel Folgendes:
Was ist der Zweck, das Preis-Array an den Konstruktor von `priceArray` zu übergeben (wo eine Kopie eines Teils des Arrays erstellt wird) und dann `priceArray` an SMA zu übergeben – warum übergibt man nicht das ursprüngliche Preis-Array per Referenz an SMA, ohne es zu kopieren?
Ich bin mir nicht sicher, wie praktisch es wäre, Änderungen an den Abhängigkeiten vorzunehmen, da wir den automatisch generierten Code tatsächlich kompilieren und debuggen und nicht einfach zum entsprechenden Ursprung „springen“ können – habe ich da etwas übersehen? Beispielsweise muss man das „bar“-Paket ändern, während man am Indikator (oder am Expert Advisor) arbeitet. Wie würdet ihr das machen?
Schließlich habe ich Bedenken hinsichtlich einiger Aspekte bei der Umsetzung der Beispiele (wahrscheinlich, weil es sich nur um Beispiele handelt), wie zum Beispiel „new/delete“ bei jedem Tick/Bar. Außerdem macht man zum Beispiel Folgendes:
Was ist der Zweck, das Preis-Array an den Konstruktor von `priceArray` zu übergeben (wo eine Kopie eines Teils des Arrays erstellt wird) und dann `priceArray` an SMA zu übergeben – warum übergibt man nicht das ursprüngliche Preis-Array per Referenz an SMA, ohne es zu kopieren?
Hallo Stanislav,
vielen Dank, dass du dir die Zeit genommen hast, den Artikel zu lesen und diese Punkte anzusprechen.
Zum Committen von generiertem Code: Die Idee hinter KnitPkg ist, dass automatisch generierte Artefakte (Flat-Header, aufgelöste Includes usw.) nicht im Git-Repository liegen sollten, da man sonst effektiv Code über Repos hinweg dupliziert und riskiert, dass dieser nicht mehr synchron ist. Wenn eine Funktionalität in einem Paket/Repository implementiert ist, ist dies die einzige verlässliche Quelle; Nutzer deklarieren eine Abhängigkeit (unter Verwendung von SemVer-Bereichen) und lassen kp install bzw. kp autocomplete die abgeleiteten Dateien lokal neu generieren. Auf diese Weise kann Ihr Projekt, wenn eine Abhängigkeit innerhalb des zulässigen SemVer-Bereichs aktualisiert wird, die neue Version nahtlos übernehmen, anstatt mit veraltetem, generiertem Code „festzustecken“, der in das eigene Repo committet wurde. Ein konkretes Beispiel für die Aktualisierung von Abhängigkeitsversionen finden Sie hier in der Dokumentation.
Zu Ihrer Sorge, „wie bequem es sein wird, Änderungen an Abhängigkeiten vorzunehmen“: Das war ein Aspekt, über den ich bei der Entwicklung des Tools nachgedacht habe. KnitPkg unterstützt die Verwendung lokaler Abhängigkeiten, sodass Sie ein Projekt direkt auf ein Paket in einem lokalen Verzeichnis verweisen, dieses Paket ändern und die Änderungen während der Entwicklung in einem echten Verbraucherprojekt testen können. Der Arbeitsablauf wird im Abschnitt „Lokale Abhängigkeiten“ der KnitPkg-Dokumentation ausführlicher beschrieben: https://docs.knitpkg.dev/user-guide/local-dependencies/
Was „price“ → „TimeSeriesArray“ → „SMA“ betrifft: Dabei geht es nicht darum, die effizienteste Mikrooptimierung zu zeigen, sondern eine standardisierte Schnittstelle zu veranschaulichen. SMA erhält ein `ITimeSeries` (nicht direkt ein `TimeSeriesArray`) und achtet lediglich darauf, dass „der aktuellste Wert am Index 0 steht, der nächste am Index 1 usw.“. TimeSeriesArray ist lediglich eine im Beispiel verwendete Implementierung, die zufällig einen Ausschnitt von „price“ kopiert. Andere könnten eine andere ITimeSeries-Implementierung entwickeln, die eine cachefreundlichere Struktur nutzt. Der springende Punkt ist, die Berechnung vom konkreten Speicherlayout zu entkoppeln; wie intelligent oder effizient die ITimeSeries-Implementierung ist, wird zu einer Frage des Designs und der Kreativität.
Ich freue mich immer über Diskussionen zu diesen Designentscheidungen, und Feedback zu KnitPkg – sei es zum Workflow oder zum Beispielcode – ist sehr willkommen. Zögern Sie also nicht, diese Ideen zu hinterfragen oder zu erweitern.