Interessantes Zeug.
Ich nasche wie immer an der Idee von R. Ich denke, dass Sie die richtige Person sind, um diese Idee zumindest zu diskutieren.
Die Idee ist die folgende.
Heute ist es möglich, eine exesh-Datei, die vom mcl4/5-Compiler erzeugt wurde, in die Terminalkarte zu ziehen.
Ist es möglich, eine Entwicklung zu machen, um ein R-Skript mit dem Diagramm zu verbinden?
Interessantes Zeug.
Ich nasche wie immer an der Idee von R. Ich denke, dass Sie die richtige Person sind, um die Idee zumindest zu diskutieren.
Die Idee ist die folgende.
Heute ist es möglich, eine exesh-Datei, die vom mcl4/5-Compiler erzeugt wurde, in die Terminalkarte zu ziehen.
Und ist es möglich, eine Entwicklung zu machen, um ein R-Skript mit dem Diagramm zu verbinden?
Übrigens, über R :-) Haben Sie dem R-Verteiler-Bausatz Ihre Aufmerksamkeit geschenkt?
Nun, es gibt ein Verzeichnis library/tcltk, das eingebautes R tcl enthält. Wenn es einer Sprache/Plattform an Möglichkeiten mangelt, fügen sie ihr tcl, auch bekannt als "Tool Common Language", hinzu. R fehlte eine GUI und tcl/tk wurde in sie integriert (genau wie in Python und Ruby).
In MQL fehlten mir viele Funktionen, außer den Graphen, also habe ich ATcl gekauft.
ATcl kann auch Statistiken erstellen :-) Ein weiterer kleiner Testfall - die Berechnung grundlegender statistischer Werte für einen Datensatz. Das Skript nimmt Close, wie viele wird im Eingabeparameter angegeben
#property copyright "Maxim A.Kuznetsov" #property link "luxtrade.tk" #property version "1.00" #property strict #property script_show_inputs //--- input parameters input int DEPTH=200; #include "ATcl.mqh" const string NAMES[]={ "mean", "minimum", "maximum", "number of data", "sample standard deviation", "sample variance", "population standard deviation","population variance" }; void OnStart() { ATcl_OnInit(); ATcl *tcl=new ATcl; if (tcl==NULL || !tcl.Ready()) { ATcl_OnDeinit(); Alert("Ошибка при создании интерпретатора"); } bool ok=false; do { if (tcl.Eval("package require math::statistics")!=TCL_OK) break; tcl.Set("data",tcl.Obj(Close,0,DEPTH)); if (tcl.Eval("math::statistics::basic-stats $data")!=TCL_OK) break; Tcl_Obj stats=tcl.Result(); tcl.Ref(stats); int total=tcl.Count(stats); for(int i=0;i<total;i++) { PrintFormat("stats %d \"%s\" = %s",i,(i<ArraySize(NAMES)?NAMES[i]:"??"),tcl.String(stats,i)); } tcl.Unref(stats); ok=true; } while(false); if (!ok) { PrintFormat("Что-то пошло не так : %s",tcl.StringResult()); } delete tcl; ATcl_OnDeinit(); }

Im Anhang finden Sie das Skript. Es gibt nur eine Rechenzeile :-)
Und noch ein Beispiel :-)
Nehmen wir ein Zip-Archiv und berechnen wir die Prüfsummen der darin gespeicherten Dateien. Wir berechnen MD5 und SHA256
#property copyright "Maxim A.Kuznetsov" #property link "luxtrade.tk" #property version "1.00" #property strict #property script_show_inputs //--- input parameters input string ZIP="MQL4\\Scripts\\atcl.zip"; #include "ATcl.mqh" void OnStart() { ATcl_OnInit(); ATcl *tcl=new ATcl; if (tcl==NULL || !tcl.Ready()) { ATcl_OnDeinit(); Alert("Ошибка при создании интерпретатора"); } bool ok=false; do { if (tcl.Eval("package require vfs::zip")!=TCL_OK) break; if (tcl.Eval("package require md5")!=TCL_OK) break; if (tcl.Eval("package require sha256")!=TCL_OK) break; tcl.Set("archive",tcl.Obj(ZIP)); if (tcl.Eval("set z [ vfs::zip::Mount $archive $archive ]")!=TCL_OK) break; if (tcl.Eval("set list [ glob -directory $archive -nocomplain *.* ]")!=TCL_OK) break; Tcl_Obj list=tcl.Result(); tcl.Ref(list); int total=tcl.Count(list); // создадим новую процедуру if (tcl.Eval("proc content { name } { set f [ open $name rb ] ; set ret [ read $f ] ; close $f ; set ret }")!=TCL_OK) break; for(int i=0;i<total;i++) { string fileName=tcl.String(list,i); tcl.Set("fileName",tcl.Obj(fileName)); PrintFormat("%s",fileName); if (tcl.Eval("set content [ content $fileName ]")!=TCL_OK) { PrintFormat("Не удалось прочесть файл %s:%s",fileName,tcl.StringResult()); continue; } string sha256=tcl.StringEval("sha2::sha256 -hex -- $content"); PrintFormat(" sha256: %s",sha256); string md5=tcl.StringEval("md5::md5 -hex -- $content"); PrintFormat(" md5: %s",md5); } tcl.Unref(list); tcl.Eval("vfs::zip::Unmount $z $archive"); ok=true; } while(false); if (!ok) { PrintFormat("Что-то пошло не так : %s",tcl.StringResult()); } delete tcl; ATcl_OnDeinit(); }
Für den Anfang natürlich ein Bildschirmfoto :-) Dies ist ein EA tcp-server in 60 Zeilen mql + 60 Zeilen tcl
Und MQ4 des Expert Advisors selbst:
#property copyright "Maxim A.Kuznetsov" #property link "luxtrade.tk" #property version "1.00" #property strict //--- input parameters input ushort PORT=8000; #include "ATcl.mqh" ATcl *tcl=NULL; // интерпретатор Tcl_Obj StartServer=0,StopServer=0,SendMsg=0,SymName=0,PortNum=0; // объекты Tcl - имена команд и имя символа int OnInit() { ATcl_OnInit(); // включить ATcl tcl=new ATcl; // создать интерпретатор if (tcl==NULL || !tcl.Ready()) { return INIT_FAILED; } // прочтём исходник c командами if (tcl.Eval("source ./MQL4/Experts/atcl_tcpserv.tcl")!=TCL_OK) { PrintFormat("Error in Source:%s",tcl.StringResult()); return INIT_FAILED; } StartServer=tcl.Ref(tcl.Obj("StartServer")); // команда запуска сервера StopServer=tcl.Ref(tcl.Obj("StopServer")); // остановка сервера SendMsg=tcl.Ref(tcl.Obj("SendMsg")); // рассылка сообщения всем клиентам SymName=tcl.Ref(tcl.Obj(Symbol())); // запомним имя текущего символа PortNum=tcl.Ref(tcl.Obj((long)PORT)); // и номер порта /// запускаем сервер if (tcl.Call(StartServer,PortNum)!=TCL_OK) { PrintFormat("Error on StartServer:%s",tcl.StringResult()); return INIT_FAILED; } EventSetTimer(2); Print("Server started"); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { if (tcl!=NULL) { if (tcl.Ready()) { // остановить сервер tcl.Call(StopServer); } // освободить все объекты tcl.Unref(StartServer); tcl.Unref(StopServer); tcl.Unref(SendMsg); tcl.Unref(SymName); tcl.Unref(PortNum); // удалить интерпретатор delete tcl; } ATcl_OnDeinit(reason); } void OnTick() { MqlTick tick; tcl.Update(); if (SymbolInfoTick(Symbol(),tick)!=0) { Tcl_Obj message=tcl.Obj(); tcl.Ref(message); tcl.Append(message,SymName); tcl.Append(message,tcl.Obj((long)tick.time)); tcl.Append(message,tcl.Obj((long)tick.time_msc)); tcl.Append(message,tcl.Obj((double)tick.bid)); tcl.Append(message,tcl.Obj((double)tick.ask)); tcl.Append(message,tcl.Obj((long)tick.volume)); if (tcl.Call(SendMsg,message)!=TCL_OK) { PrintFormat("Error in SendMsg:%s",tcl.StringResult()); } tcl.Unref(message); } } void OnTimer() { tcl.Update(); } void OnChartEvent(const int id, // идентификатор события const long& lparam, // параметр события типа long const double& dparam, // параметр события типа double const string& sparam // параметр события типа string ) { tcl.Update(); }Bislang funktioniert alles (Bibliothek und Interpreter) in EAs oder Skripten. Für Indikatoren ist es noch nicht fertig :-( Es gibt noch einige Ungereimtheiten mit OnInit/OnDeinit Sequenzen, DLL Laden und Timern.
Alles wird immer stabiler, EventLoop funktioniert zuverlässig in EAs und Skripten (und noch nicht in Indikatoren)
Neue, nützliche Demo - Asynchroner HTTP-Client und Parser. Der Quellcode (mq4 und tcl) umfasst etwa 60 Zeilen.
Die Abfrage wird parallel zum Expert Advisor ausgeführt, und das HTML-Parsing wird über den DOM-Parser korrekt durchgeführt.
input int EVERY_MINUTS=15; #include "ATcl.mqh" ATcl *tcl=NULL; Tcl_Obj StartClient=0,StopClient=0,report=0,minutes=0; int OnInit() { ATcl_OnInit(); // включить ATcl tcl=new ATcl; // создать интерпретатор if (tcl==NULL || !tcl.Ready()) { return INIT_FAILED; } // прочтём исходник c командами if (tcl.Eval("source ./MQL4/Experts/atcl_httpclient.tcl")!=TCL_OK) { PrintFormat("Error in Source:%s",tcl.StringResult()); return INIT_FAILED; } StartClient=tcl.Ref(tcl.Obj("StartClient")); StopClient=tcl.Ref(tcl.Obj("StopClient")); report=tcl.Ref(tcl.Obj("report")); minutes=tcl.Ref(tcl.Obj((long)EVERY_MINUTS)); if (tcl.Call(StartClient,minutes)!=TCL_OK) { Print("call failed"); return INIT_FAILED; } EventSetTimer(1); return(INIT_SUCCEEDED); } void OnDeinit(const int reason) { if (tcl!=NULL) { if (tcl.Ready()) { tcl.Call(StopClient); } tcl.Unref(StartClient); tcl.Unref(StopClient); tcl.Unref(report); tcl.Unref(minutes); delete tcl; } ATcl_OnDeinit(reason); } void OnTimer() { tcl.Update(); if (tcl.IsSet(report)) { string comment=tcl.String(tcl.Get(report)); tcl.Unset(report); Comment(comment); } } void OnTick() { tcl.Update(); }Ich bin fast zufrieden. Es wird nicht lange dauern, bis ich in der Lage sein werde, aus meinen MQL-Fälschungen alles zu entfernen, was nicht direkt mit dem Handel zusammenhängt, und die normale Kommunikation mit der Außenwelt hinzuzufügen (Datenbanken, E-Mails, Berichte und sogar GUI).
Wenn da nur nicht das aktuelle Problem mit den Indikatoren und Timern wäre :-(.
Sie können hier nicht mehr als eine Zip-Datei anhängen?
oder gibt es ein Problem mit den gleichnamigen Dateien...
Die aktuelle atcl-Version ist immer noch NICHT angeschlossen :-) Die Website ist fehlerhaft oder etwas anderes... für jetzt können Sie es von der Projektseite bekommen.
Wenn die Probleme vorbei sind, werde ich es hier anhängen
In kurzer Zeit könnten Sie alles aus Ihren MQL-Kreationen entfernen, was nicht direkt mit dem Handel zu tun hat, und die normale Kommunikation mit der Außenwelt (Datenbanken, E-Mails, Berichte und sogar eine grafische Benutzeroberfläche) hinzufügen.
Und was hindert Sie daran, über Rohrleitungen in die Außenwelt zu gehen?
Das Ergebnis ist das gleiche: Sie können mql praktisch vergessen - schreiben Sie einmal einen Server und das war's.
Was hindert Sie daran, über Pipelines in die Außenwelt zu gehen?
das Ergebnis ist dasselbe: Sie können µl praktisch vergessen - schreiben Sie einmal einen Server und das war's.
und es gibt eine ganz andere Ebene der Integration - Daten können leicht zwischen tcl und mql übertragen werden - sie sitzen direkt in einem Speicher, in einem einzigen Prozess. Theoretisch (ich habe die Arbeit nicht überprüft, aber es sollte funktionieren) und mit einiger Genauigkeit können Sie Variablen verknüpfen.
Es stellt sich heraus, dass alle Funktionen und Bibliotheken, die in tcl vorhanden sind, aber in mql fehlen, leicht verfügbar sind.
INDICATORS sind (fast) besiegt :-) Das heißt, ATcl funktioniert jetzt in Indikatoren, einschließlich des unseligen EventLoop.
Auf dem Screenshot - das gleiche Programm wie beim letzten Mal (asynchroner http-Client), aber jetzt als Indikator:
Natürlich ist der Algorithmus zur Initialisierung der DLL nicht derselbe :-)
Wir können sagen, dass die API-Vorschau fast fertig ist, wir müssen nur noch den Quellcode und die Dokumentation aufräumen, und dann können wir die Beta-Version ankündigen
Truthahn und Bibliothek anhängen. Und das werde ich mit Bier feiern :-)

- 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.
Die Ferien waren fruchtbar, und ich freue mich, ATcl - einen eingebauten Tcl-Interpreter für MT4 - vorstellen zu können.
Die Idee des Projekts war (und ist immer noch), die bequemste Schnittstelle zum Interpreter zu schaffen, ohne eine direkte Portierung von Tcl C Api Funktionen.
So sieht es aus (Arbeitsbeispiel - ein Skript, das ein Zitat in einer SQLite-Datenbank speichert):
In diesem Stadium handelt es sich um eine ruhende Alpha- oder API-Vorschau - Bewertung der Benutzerfreundlichkeit der API. Aber wie Sie sehen können, funktionieren die Schnittstellen zum DBMS, mit einiger Genauigkeit auch EventLoop, d.h. Sie können asynchrone Befehle, I/O und Timer verwenden.
Ich habe das Archiv mit der aktuellen Version angehängt, Sie können es ausprobieren...
Die Dokumentation, die ich so oft wie möglich aktualisiere, und die neuesten Versionen sind auf der Projektseite http://luxtrade.tk/atcl zu finden .
Dieser Thread ist dazu da, Fragen zu Tcl/Tk selbst und der erwähnten ATcl-Bibliothek zu beantworten. Ideen, Kommentare, Vorschläge und Kritik sind erwünscht.
UPDATE: Quellcode des Skripts in diesem Thema angehängt
UPDATE: atcl.zip aktualisiert