C'est intéressant.
Comme toujours, je me régale de l'idée de R. Il me semble que vous êtes la bonne personne avec qui discuter au moins de cette idée.
L'idée est la suivante.
Aujourd'hui, il est possible de faire glisser un fichier exesh, qui a été généré par le compilateur mcl4/5, vers le graphique du terminal.
Est-il possible de faire un développement pour pouvoir enchaîner un script R sur le graphique ?
C'est intéressant.
Comme toujours, je me régale à l'idée de R. Il me semble que vous êtes la bonne personne avec qui discuter au moins de cette idée.
L'idée est la suivante.
Aujourd'hui, il est possible de faire glisser un fichier exesh, qui a été généré par le compilateur mcl4/5, vers le graphique du terminal.
Et est-il possible de faire un développement pour pouvoir enchaîner un script R sur le graphique ?
Au fait, à propos de R :-) Avez-vous porté votre attention sur le kit de distribution R ?
Eh bien, il y a un répertoire library/tcltk, qui contient le R tcl intégré. Lorsqu'un langage/une plateforme manque de facilités, on lui ajoute le tcl, alias "Tool Common Language". R n'a pas d'interface graphique et met tcl/tk dedans (tout comme en Python et Ruby).
Il me manquait de nombreuses fonctionnalités dans MQL, à l'exception des graphiques, alors je me suis procuré ATcl.
ATcl peut aussi faire des statistiques :-) Un autre petit cas de test - le calcul des valeurs statistiques de base pour un ensemble de données. Le script prend Close, dont le nombre sera donné dans le paramètre d'entrée.
#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(); }

Vous trouverez ci-joint le script. Il n'y a qu'une seule ligne de calcul :-)
Et un autre exemple :-)
Prenons un zip et calculons les sommes de contrôle des fichiers qu'il contient. Nous calculons MD5 et 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(); }
En guise d'avant-goût, bien sûr, une capture d'écran :-) Il s'agit d'un serveur tcp EA en 60 lignes de mql + 60 lignes de tcl.
Et MQ4 du conseiller expert lui-même :
#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(); }Jusqu'à présent, tout (bibliothèque et interpréteur) fonctionne dans les EA ou les scripts. Pour les indicateurs, ce n'est pas encore prêt :-( Il y a une sorte de bizarrerie avec les séquences OnInit/OnDeinit, le chargement des DLL et les timers.
Tout devient de plus en plus stable, EventLoop fonctionne en toute confiance dans les EA et les scripts (mais pas encore dans les indicateurs).
Nouvelle démo utile - Client HTTP asynchrone et analyseur syntaxique. Le code source (mq4 et tcl) est d'environ 60 lignes.
La requête est exécutée parallèlement à l'Expert Advisor et l'analyse html est effectuée correctement, via l'analyseur DOM.
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(); }Je suis presque satisfait. Il ne faudra pas longtemps avant que je puisse retirer de mes faux MQL tout ce qui n'est pas directement lié au trading et ajouter les communications normales avec le monde extérieur (bases de données, emails, rapports et même GUI).
Si ce n'est pour le problème actuel des indicateurs et des minuteurs :-(.
Vous ne pouvez pas joindre plus d'un fichier zip ici ?
ou y a-t-il un problème avec les fichiers de même nom...
La version actuelle d'atcl n'est toujours pas jointe :-) Le site est en panne ou quelque chose d'autre... pour l'instant, vous pouvez l'obtenir à partir de la page du projet.
Lorsque les problèmes seront résolus, je l'attacherai ici.
Dans un peu plus de temps, vous pourriez retirer de vos créations MQL tout ce qui n'est pas directement lié au trading et ajouter des communications normales avec le monde extérieur (bases de données, e-mails, rapports et même une interface graphique).
Et qu'est-ce qui vous empêche d'aller vers le monde extérieur par la tuyauterie ?
Le résultat est le même : vous pouvez pratiquement oublier mql - écrire un serveur une fois et c'est tout.
Qu'est-ce qui vous empêche d'aller vers le monde extérieur via les pipelines ?
le résultat est le même : vous pouvez pratiquement oublier le µl - écrire un serveur une fois et c'est tout.
et il y a un niveau d'intégration complètement différent - les données peuvent facilement être transférées entre tcl et mql - elles se trouvent dans une seule mémoire, dans un seul processus. En théorie (je n'ai pas vérifié le travail, mais cela devrait fonctionner) et avec une certaine précision, vous pouvez relier des variables.
Il s'avère que toutes les fonctionnalités et les bibliothèques qui sont dans tcl mais qui manquent dans mql sont facilement disponibles.
Les INDICATEURS sont vaincus (presque) :-) En d'autres termes, ATcl fonctionne maintenant dans les indicateurs, y compris l'infortuné EventLoop.
Sur la capture d'écran - le même programme que la dernière fois (client http asynchrone), mais maintenant en indicateur :
Bien sûr, l'algorithme d'initialisation de la DLL n'est pas le même :-)
Nous pouvons dire que la révision de l'API est presque terminée, il ne reste plus qu'à nettoyer le code source et la documentation, et nous pourrons alors annoncer la version bêta.
Attachez la dinde et la bibliothèque. Et je vais fêter ça avec de la bière :-)

- Applications de trading gratuites
- Plus de 8 000 signaux à copier
- Actualités économiques pour explorer les marchés financiers
Vous acceptez la politique du site Web et les conditions d'utilisation
Les vacances ont été fructueuses, et j'ai le plaisir de vous présenter ATcl - l'interprète Tcl intégré pour MT4.
L'idée du projet était (et est toujours) de créer l'interface la plus pratique pour l'interpréteur sans un portage direct des fonctions de l'Api C de Tcl.
Voici ce que j'ai obtenu (exemple de travail - un script qui enregistre une citation dans une base de données SQLite) :
À ce stade, il s'agit d'une alpha ou "API Preview" - évaluation de la convivialité de l'API. Mais comme vous pouvez le constater, les interfaces avec le SGBD fonctionnent, avec une certaine précision, même EventLoop fonctionne, c'est-à-dire que vous pouvez utiliser des commandes asynchrones, des E/S et des temporisateurs.
J'ai joint l'archive avec la version actuelle, vous pouvez l'essayer...
La documentation, que je mets à jour autant que je peux, et les dernières versions peuvent être trouvées sur la page du projet http://luxtrade.tk/atcl.
Dans ce fil de discussion, je suis prêt à répondre aux questions concernant Tcl/Tk lui-même et la bibliothèque ATcl mentionnée. Les idées, commentaires, suggestions et critiques seront appréciés.
UPDATE : joint le code source du script dans ce sujet
UPDATE : mise à jour de atcl.zip