ATcl - MT4的Tcl解释器 - 页 2

 
Maxim Kuznetsov:
谁来控制点数、执行协议和分析结果呢? 这很漫长,很慢,而且只能通过投票。

能否给我几个关于这个atcl的阅读链接,这样你就不必把所有的东西都看一遍,而是可以更专注于这个话题。

 
Alexey Oreshkin:

可以用几个链接来阅读这个atcl不挖空心思,更有目的性地熟悉这个话题。

MT4的库-集成器(我正在努力工作的那个)的主要链接是这里的当前主题,加上主题中提到的http://luxtrade.tk/atcl:start(历史上我的网站,一直处于混乱状态 :-) )

Tcl(根站点)本身 :http://www.tcl.tk

wiki:http://wiki.tcl.tk

"标准库" :https://core.tcl.tk/tcllib/doc/tcllib-1-18/embedded/www/toc.html(链接到文档,它们可能是主要的兴趣所在)

目前ActiveState的主要经销商:https://www.activestate.com/activetcl 。

它们 "紧随 "MagicSplat http://www.magicsplat.com/ 和 IronTclhttps://irontcl.com/

作为一种语言和脚本平台,Tcl至少是经过时间考验的--1990年首次发布,现在它已经事实上存在于Linux/UNIX中,现在也在Android下。98%的人在你的机器上都有它的一些简化形式--python、ruby、R、maxima、octave和其他使用它的GUI(tkinter等等)。

PS.希望他们不会把我的帖子和我以及大量的链接一起杀掉?这都是免费的。

PPS。对于本地外包商来说--也有一个 "美味 "的赏金https://github.com/flightaware/Tcl-bounties。 但只有2500美元的困难任务,而且有严格的纪律。

ATcl
  • luxtrade.tk
До любого обращения к ATcl должна быть вызвана функций ATcl_OnInit() и в завершении скрипта/индикатора/советника ATcl_OnDeinit(const int reason). Между вызовами этих двух функций возможны обращения ко всем прочим функциям библиотеки. При разработке советников и индикторов также рекомендуется вызывать функции ATcl_OnEvent(..) ATcl_OnTimer...
 

带着对未来的思考。

在一些补丁和这样一个母亲的帮助下,这就是我们得到的东西。


虽然这是一个实验,甚至在目前的版本中,我还不会包括运行Tk的补丁(首先,这太早了,其他的故障已经满了,其次,它是为啤酒做的,我以后再来回顾)。

但你可以看到,在最后你想得到的,而且有信心在技术上是可能的。是的,是的,一个完全可编写脚本的GUI也是可能的。

顺便说一下,对本地GUI建设者来说,窗口(有阿尔法通道的那个)被过分地描述成这样(这是tcl)。

set symbol "symbol"
set bid "bid"
set ask "ask"
set lots 0.1
set minLot 0.01
set maxLot 1
set lotStep 0.01
proc TradeFrame { w } {
        # всё в отдельном фрейме
        frame $w
        # виджеты
        label $w.symbol -textvariable symbol
        label $w.bid -textvariable bid
        label $w.ask -textvariable ask
        button $w.buy -text "BUY" -command {Trade buy}
        button $w.sell -text "SELL" -command {Trade sell}
        global minLot
        global maxLot
        global lotStep
        ttk::spinbox $w.lots -font "Courier 12" -from $minLot -to $maxLot -increment $lotStep -textvariable lots
        # размещение в таблице
        grid $w.symbol -row 0 -column 0 -columnspan 2 -sticky "ew"
        grid $w.bid    -row 1 -column 0 -sticky "e"
        grid $w.ask    -row 1 -column 1 -sticky "w"
        grid $w.buy    -row 2 -column 0 -sticky "nsew"
        grid $w.sell    -row 2 -column 1 -sticky "nsew"
        grid $w.lots   -row 3 -column 0 -columnspan 2 -sticky "ew"
        # настройка таблицы
        grid rowconfigure $w 2 -weight 1
        grid columnconfigure $w 0 -uniform same -weight 1
        grid columnconfigure $w 1 -uniform same -weight 1
        # привязки и прочие настройки
#       $w.lots set $minLot
        return $w
}
proc TradeWindow { w } {
        toplevel $w 
        wm title $w "TradePanel"
        wm attributes $w -alpha 0.75
        TradeFrame $w.panel 
        pack $w.panel -fill both -expand yes
        raise $w
}
proc Trade { op } {
        global symbol
        global lots
        tk_messageBox -message "Your request $op $lots $symbol lots"
}
 

我把文件按顺序放好--现在在ZIP中,它们被放在指标、脚本、专家、库、包括等文件夹中,在安装库的想法中,只需要
解压到data目录中,一切都应该归位,可以开始工作了(除了Tcl本身需要被放进去 :-) )。

该API是这样的。

class ATcl {
protected:
   Tcl_Interp interp;
public:
   ATcl(bool safe=false);  // создание нового инерпретатора
   ATcl(Tcl_Interp);       // создание объекта из готового интерпретатора

   Tcl_Interp CreateSlave(string name,bool safe=false); // создать дочерный интерпретатор
   Tcl_Interp CreateSlave(Tcl_Obj name,bool safe=false);

   Tcl_Interp Interp(); // получить интерпретатор (например для вызова Tcl C API)
   
   ~ATcl();
   
   bool Ready();  // =true если можно исполнять команды
   int Update(); // запустить проход EventLoop
   
   // MQL specific handlers
   int OnInit();
   void OnDeinit(const int reason);
   void OnTimer();
   void OnChartEvent();
   void OnChartEvent(const int id,const long lparam,const double dparam,const string sparam);

   // Objects
   Tcl_Obj Obj();             // создать пустой временный объект
   Tcl_Obj Ref(Tcl_Obj obj);  // увеличить счётчик ссылок
   Tcl_Obj Unref(Tcl_Obj obj);// уменьшить счётчик ссылок, удалить объект при обнулении
   int Shared(Tcl_Obj obj);   // =true если объект зашарен и не может быть изменнён
   Tcl_Obj Clone(Tcl_Obj obj);// дублировать объект
   
   ///////////////////////////////  
   // Исполнение команд и скриптов
   ///////////////////////////////
   // методы возвращают код реультата: (стандартные коды: TCL_OK - успех, TCL_ERROR, TCL_BREAK,TCL_CONTINUE)
   // и сохраняют объект-"результат", который можно потом получить методоми Result(),StringResult(),...
   // Флаги: TCL_EVAL_GLOBAL - исполнять на глобальном уровне, TCL_EVAL_DIRECT - исполнять сразу, без компиляции
   int Eval(string script,int flags=0);
   int Eval(Tcl_Obj script,int flags=0);
   Tcl_Obj ObjEval(string script,int flags=0);  // simplified - Eval and return Result as Tcl_Obj
   Tcl_Obj ObjEval(Tcl_Obj script,int flags=0);
   
   int Call(Tcl_Obj &objv[],int flags=0);
   int Call(Tcl_Obj obj1,Tcl_Obj obj2=0,Tcl_Obj obj3=0,Tcl_Obj obj4=0,Tcl_Obj obj5=0,Tcl_Obj obj6=0,Tcl_Obj obj7=0,Tcl_Obj obj8=0,Tcl_Obj obj9=0,Tcl_Obj obj10=0,Tcl_Obj obj11=0);
   
   Tcl_Obj ObjCall(Tcl_Obj &objv[],int flags=0);// simplified - Call and return Result as Tcl_Obj
   Tcl_Obj ObjCall(Tcl_Obj obj1,Tcl_Obj obj2=0,Tcl_Obj obj3=0,Tcl_Obj obj4=0,Tcl_Obj obj5=0,Tcl_Obj obj6=0,Tcl_Obj obj7=0,Tcl_Obj obj8=0,Tcl_Obj obj9=0,Tcl_Obj obj10=0,Tcl_Obj obj11=0);
   
   Tcl_Obj Result(int ignoreThis=0);  // получить объект-результат
   int   ResetResult();             // сбросить(обнулить) результат

   ////////////////////////////////////////
   // Source - чтение и исполнение скриптов
   //////////////////////////////////////// 
   // use : Eval("source filename.tcl") оr Call("source","filename.tcl");
   // int Source(const string fileName,const string encoding="");
   // int Source(Tcl_Obj fileName,Tcl_Obj encoding=0);

   /////////////////
   // List - Списки
   /////////////////
   Tcl_Obj ListIndex(Tcl_Obj obj,int index=0);
   
   int ListLength(Tcl_Obj obj);  // =кол-во элементов списка
   int Count(Tcl_Obj obj);       // синоним
   
   int ListAppend(Tcl_Obj list,Tcl_Obj element);   // добавить эл-т к списку. список должен быть !Shared()
   int Append(Tcl_Obj list,Tcl_Obj element); // синоним
   
   /////////////////////////////////////////
   // Set: задать объект-значение переменной
   /////////////////////////////////////////
   // аналог в tcl: set var $value ; set hash($key) $value 
   Tcl_Obj Set(Tcl_Obj var,Tcl_Obj value);
   Tcl_Obj Set(Tcl_Obj hash,Tcl_Obj key,Tcl_Obj value);
   Tcl_Obj Set(string var,Tcl_Obj value);
   Tcl_Obj Set(string hash,string key,Tcl_Obj value);
   
   ///////////////////////////////////////////
   // Get: получить значение переменной в виде объекта
   //////////////////////////////////////////
   // аналог в tcl: set var ; set hash($key)
   Tcl_Obj Get(Tcl_Obj var);
   Tcl_Obj Get(Tcl_Obj hash,Tcl_Obj key);
   Tcl_Obj Get(string var);
   Tcl_Obj Get(string hash,string key);
   
   // IsSet: проверить существование переменной
   int IsSet(Tcl_Obj var);
   int IsSet(Tcl_Obj hash,Tcl_Obj key);
   int IsSet(string var);
   int IsSet(string hash,string key);
   
   // IsArray - проверить что hash это действительно хеш :-)
   int IsArray(Tcl_Obj hash);
   int IsArray(string hash);
   
   // Unset: удалить переменную или элемент хеша
   int Unset(Tcl_Obj var);
   int Unset(Tcl_Obj hash,Tcl_Obj key);
   int Unset(string var);
   int Unset(string hash,string key);
   
   // Link: связать скалярную переменную с элементом массива
   int Link(double &arr[],int pos,Tcl_Obj hash,Tcl_Obj key=0);
   int Link(double &arr[],int pos,string hash,string key="");
   // Unlink: разорвать свзяь
   int Unlink(Tcl_Obj hash,Tcl_Obj key=0);
   int Unlink(string hash,string key="");

   //////////////////////////
   // Double
   Tcl_Obj Obj(double);                // создать объект из double
   Tcl_Obj Obj(const double &arr[],int pos=0,int count=WHOLE_ARRAY); // создать объект из массива double
   double Double(Tcl_Obj);             // конвертировать объект в double
   double Double(Tcl_Obj,int index);   // получить эл-т списка как double   
   double DoubleResult(int ignoreThis=0);  // получить последний результат как double
   // упрощенный доступ к Call,Eval   
   // исполнить скрипт и срузу получить результат как double (0 при ошибке)
   double DoubleEval(string script,int flags=0); 
   double DoubleEval(Tcl_Obj script,int flags=0);
   // вызвать команду и сразу получить результат как double
   double DoubleCall(Tcl_Obj command,Tcl_Obj arg1=0,Tcl_Obj arg2=0,Tcl_Obj arg3=0,Tcl_Obj arg4=0,Tcl_Obj arg5=0,Tcl_Obj arg6=0,Tcl_Obj arg7=0,Tcl_Obj arg8=0,Tcl_Obj arg9=0,Tcl_Obj arg10=0);
   double DoubleCall(Tcl_Obj &objv[],int objc=WHOLE_ARRAY);
   
   ///////////////////////////
   // String
   Tcl_Obj Obj(string);
   Tcl_Obj Obj(const string &arr[],int pos=0,int count=WHOLE_ARRAY);
   string String(Tcl_Obj);
   string String(Tcl_Obj,int index);
   string StringResult(int ignoreThis=0);
   
   string StringEval(string script,int flags=0); 
   string StringEval(Tcl_Obj script,int flags=0);
   string StringCall(Tcl_Obj command,Tcl_Obj arg1=0,Tcl_Obj arg2=0,Tcl_Obj arg3=0,Tcl_Obj arg4=0,Tcl_Obj arg5=0,Tcl_Obj arg6=0,Tcl_Obj arg7=0,Tcl_Obj arg8=0,Tcl_Obj arg9=0,Tcl_Obj arg10=0);
   string StringCall(Tcl_Obj &objv[],int objc=WHOLE_ARRAY);
   
   ///////////////////////////
   // Long
   Tcl_Obj Obj(long);
   Tcl_Obj Obj(const long &arr[],int pos=0,int count=WHOLE_ARRAY);
   long Long(Tcl_Obj);
   long Long(Tcl_Obj,int index);
   long LongResult(int ignoreThis=0);
   
   long LongEval(string script,int flags=0); 
   long LongEval(Tcl_Obj script,int flags=0);
   long LongCall(Tcl_Obj command,Tcl_Obj arg1=0,Tcl_Obj arg2=0,Tcl_Obj arg3=0,Tcl_Obj arg4=0,Tcl_Obj arg5=0,Tcl_Obj arg6=0,Tcl_Obj arg7=0,Tcl_Obj arg8=0,Tcl_Obj arg9=0,Tcl_Obj arg10=0);
   long LongCall(Tcl_Obj &objv[],int objc=WHOLE_ARRAY);
   
   ///////////////////////////
   // Datetime
   Tcl_Obj Obj(datetime);
   Tcl_Obj Obj(const datetime &arr[],int pos=0,int count=WHOLE_ARRAY);
   datetime Datetime(Tcl_Obj);
   datetime Datetime(Tcl_Obj,int index);
   datetime DatetimeResult(int ignoreThis=0);
   
   datetime DatetimeEval(string script,int flags=0); 
   datetime DatetimeEval(Tcl_Obj script,int flags=0);
   datetime DatetimeCall(Tcl_Obj command,Tcl_Obj arg1=0,Tcl_Obj arg2=0,Tcl_Obj arg3=0,Tcl_Obj arg4=0,Tcl_Obj arg5=0,Tcl_Obj arg6=0,Tcl_Obj arg7=0,Tcl_Obj arg8=0,Tcl_Obj arg9=0,Tcl_Obj arg10=0);
   datetime DatetimeCall(Tcl_Obj &objv[],int objc=WHOLE_ARRAY);
   
};

似乎相当紧凑,可以使用。

上面的zip-archive是附件,如果有人需要它,并且在安装时有任何问题,请在这里或当面发表。

附加的文件:
atcl.zip  135 kb
 

屋顶上的例子

"即时编译,并在MQL脚本内使用ATcl的C/C++"

#property copyright "Maxim A.Kuznetsov"
#property link      "luxtrade.tk"
#property version   "1.00"
#property strict
#property description "ATcl demo"
#property description "------------"
#property description "This script demonstrate how to compile and use C/C++ on-the-fly"


#include <ATcl\\ATcl.mqh>

const string c=
"static double sum(double x, double y) {"
"    return x+y;"
"}";

ATcl *tcl;
void OnStart()
{
   ATcl_OnInit();
   tcl=new ATcl;
   if (tcl!=NULL && tcl.Ready()) {
      tcl.Eval("package require critcl");             // use critcl package (compiler environment)
      tcl.Call(tcl.Obj("critcl::ccode"),tcl.Obj(c));  // pass some c/c++ to compiler
      tcl.Eval("critcl::cproc mysum { double x double y } double { return sum(x,y);}");      // make callable proc
      double ret=tcl.DoubleCall(tcl.Obj("mysum"),tcl.Obj((double)5.0),tcl.Obj((double)7.1)); // call :-)
      PrintFormat("ret=%f",ret);
   }
   delete tcl;
   ATcl_OnDeinit();
}
附加的文件:
atcl.zip  149 kb
 

好吧,祝贺你的测试结果 !:-)

简而言之,通过ATcl的功能,现在可以很容易地从MT4获得。

Tcl功能

  • 简单--简单的脚本语言
  • 便携式- 运行脚本和算法,你可以在任何系统中使用(Windows、Linux、Android和其他)。
  • 事件驱动--内部事件模型
  • 面向对象--所有现代的OOP特性。
  • 线程- 你可以使用多线程编程的所有功能 - 系统线程、互斥、条件变量、有可能永久存储的共享变量。
  • 虚拟文件系统--作为一个文件系统透明地访问zip、tar、ftp、webdav
  • 数据库- 统一的接口 tdbc 和 sqlite 包含在 tcl 核心中。它积极支持PostresSQL、MySQL、MonetDB、Oracle和任何ODBC数据库。
  • 网络- 客户/服务器:TCP,http,mail,websocket,zmq。几乎所有你可能需要的协议和服务。
  • 密码学--校验和、电子签名、加密散列。对称和非对称加密。公钥基础设施支持,TLS,SASL。
  • 窗口- 窗口环境工具 - 注册表、DDE、COM客户/服务器、ldap客户机
  • tcllib- Tcl的标准库提供了额外的功能(编程工具、文本处理、数学和统计等)。
  • c/c++- TinyC编译器包含在库中,Critcl包允许使用系统C/C++编译器(vc,gcc,clang)。模块和函数可以被编译并在运行中使用。
  • 许多库和系统都提供了Tcl API,你可以在你的程序中轻松使用它们
更多信息请见博客网站:https://www.mql5.com/ru/blogs/post/715411(没有人看:-))
并在项目页面:http://luxtrade.tk/atcl:start


乐于回答任何有关该主题的问题,并听取意见和评论。


ATcl - безграничные возможности для ваших програм
ATcl - безграничные возможности для ваших програм
  • 2018.01.26
  • Maxim Kuznetsov
  • www.mql5.com
Рад представить вам библиотеку ATcl v1 beta - интерпретатор Tcl для MT4. Безграничные возможности расширения и интеграции программ MT4 Расширяйте возможности ваших программ MQL, используйте СУБД, дополняйте сетевыми средствами, интегрируйте их с любыми программами используя Tcl. threading - вы можете использовать все возможности...
 

祝贺你!

做一些实际的例子会很有用,类似于kodobase和文章中的内容。
例如,连接到MySQL、Telegram或只是通过TCP连接两个终端。

 
Andrey Khatimlianskii:

祝贺你!

做一些实际的例子会很有用,类似于kodobase和文章中的内容。
例如,与MySQL、Telegram的通信,或简单地通过TCP连接两个终端。

在民主党(在档案)。

- 脚本将报价存入SQLite数据库。对于MySQL也是如此,但不是每个人都有:-)

- tcp服务器作为指标和顾问(两种变体)--启动后,它接受8000端口的连接(可在启动时的设置中设置),并在那里翻译传入的ticks。你可以telnet并看到

- http客户端指标,它定期去网站,获取工作页面,解析它并在图表中显示信息摘要,如Comment

演示肯定会继续增长,你可以提出想法。

随着我们的进展,我可能会做一些演示来说明

- "网络服务器",以显示你可以使用浏览器,以及它是如何做到的。

- 使用TSV(线程共享变量),这是GlobalVariable的扩展类似物 - 在应用程序中使用共享数据。

我必须想出更多的脚本:-),使其清晰、简明,至少有一点用处。

 

有一段相当精彩的Skype对话,其中一些内容我想我需要说出来,因为我觉得它很有用 :-)

1.为什么是一些Tcl而不是更流行的Python、Ruby?

当然,这不会是第一个,因为我很了解它,而且我不仅在使用它进行交易。技术方面也非常重要--Python和Ruby与metatrader线程模型不兼容。理论上它们是可以运行的,但我必须要么挖出很低的API,要么破坏语言。 R和许多其他语言也是如此。
要使它们发挥作用,必须满足"在一个进程和一个线程中可以独立创建几个孤立的实例"的条件。
Lua是我所知道的唯一能做到这一点的其他脚本语言,但它是 "一种没有标准的语言"。
顺便说一下, 所有的DLL开发者 在他们的产品中都应该 遵守 这个粗体字

2.如何正确和快速地分析数据

正确和快速 - 是 在metatrader中进行计算。这就是metatrader的设计目的--接收数据,进行计算并发出订单。在你的DLL中重复它的功能是很愚蠢的。毕竟,MQL本身与C++相当相似,程序员只需要一两天就可以开始用它来编写。而在DLL中,我们要做的是平台没有覆盖和物理上不能覆盖的事情--与数据库、服务、集成等的通信。并加上可以和应该在MetaTrader之外使用的东西。

3.第5版在哪里和什么时候推出?

尽快 :-)从技术上讲,把DLL从4号拖到5号是很容易的,脚本并不关心。Tcl有32位和64位两种。但在4上开发要方便得多,它没有被碰过:-)它很稳定,预计不会有什么惊喜。但是,我们将看到的5,平台开发人员承诺 "服务任务"(以及指标、脚本和专家顾问),肯定有一些与DLL和线程有关的东西将连续改变几个版本。在这个问题得到解决之前,不会有5的版本。

 

在运行过程中,根据用户反馈,发现了一些与msvcrt DLL依赖性有关的问题。
和一个小小的错误(我的)在寻找同一个DLL。ATcl.mqh处理程序中的相对路径是规定的:-)

都修好了,你可以得到更正的版本(附件),安装说明在传统的地方http://luxtrade.tk/atcl:install


对于DLL开发人员来说,这是一个有用的信息。

- DLL编译时定义了-D_CRTIMP_ALTERNATIVE,这迫使编译器内联了CRT的几乎所有内容 :-)

- 现在,DLL是用/MT开关构建的,它迫使链接器使用静态链接,不造成不必要的依赖。Redistributable(VC支持包)就像不必到处拖动一样

DLL的体积增大了,但依赖性减少了,拖着库走应该更容易。

PS/小更新--改变了所附的档案。该库是以完全的多线程支持而构建的
Install
  • luxtrade.tk
ATcl является библиотекой-интегратором и поэтому в первую очередь нужен сам по себе Tcl. Tcl свободно доступен и не имеет лицензионных отягощений (лицензии как правило BSD-like). Для работы с MT4 вам потребуется 32-х битная (это важно! MT4 32-х битный...
附加的文件:
atcl.zip  243 kb