ATcl - MT4用Tclインタプリタ - ページ 2

 
Maxim Kuznetsov:
誰がpipsをコントロールし、プロトコルを実行し、結果を分析するのか。それは長く、遅く、ポーリングによってのみ行われます。

この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でも使用されています。

PS.彼らが私の投稿と多くのリンクと一緒に私を殺さないことを望みます?すべて無料です。

PPSです。地元のアウトソーサーにとって - 「おいしい」報奨金もあるhttps://github.com/flightaware/Tcl-bounties. しかし、2500USDからは難しい課題ばかりで、厳しい規律がある。

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の中のIndicators、Scripts、Experts、Libraries、Includeというフォルダにファイルが格納されており、ライブラリをインストールするためのアイデアは以下の通りです。
でアーカイブを解凍し、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の特徴

  • simple- シンプルなスクリプト言語
  • ポータブル- あらゆるシステム(Windows、Linux、Androidなど)で使用できるスクリプトとアルゴリズムを実行します。
  • イベントドリブン- 内部イベントモデル
  • オブジェクト指向- 現代的なOOPの機能をすべて備えています。
  • スレッド- システムスレッド、ミューテックス、条件変数、永久保存が可能な共有変数など、マルチスレッドプログラミングのすべての機能を使用できます。
  • 仮想ファイルシステム- zip, tar, ftp, webdav をファイルシステムとして透過的に利用可能
  • データベース- 統一インターフェース tdbc と sqlite が tcl コアに含まれています。PostresSQL、MySQL、MonetDB、OracleとあらゆるODBCデータベースを積極的にサポートします。
  • ネットワーク- クライアント/サーバー:TCP、http、メール、websocket、zmq。必要なプロトコルとサービスはほぼすべて揃っています。
  • 暗号技術- チェックサム、電子署名、暗号ハッシュ。対称型暗号と非対称型暗号。公開鍵基盤対応、TLS、SASL。
  • Windows- Windows環境ツール - レジストリ、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への接続、あるいは2つの端末をTCPで接続することなどです。

 
Andrey Khatimlianskii:

おめでとうございます。

kodobaseやアーティクルにあるような、実用的な例をやると便利だと思います。
例えば、MySQLやTelegramとの通信、あるいは単純に2つの端末をTCPで接続することなどです。

in dems (in archive):

- 引用符をSQLite データベースに保存するスクリプトです。MySQLの場合も同じですが、誰もが持っているわけではありません:-)

- インジケーターとアドバイザーとしてのtcpサーバー(2つのバリエーション) - スタート後、ポート8000(スタート時の設定で設定可能)での接続を受け付け、そこに入ってくるティックを変換します。telnetで、見ることができます。

- httpクライアントインジケータは、定期的にサイトにアクセスし、求人ページを取得、解析し、チャートにCommentとして情報の要約を表示します。

デモはこれからも確実に増えていくので、アイデアを提案することができます。

今後、このようなデモを制作していく予定です。

- "ウェブサーバー "を使って、ブラウザを使うことができることを示し、その方法を説明します。

- GlobalVariableの拡張アナログであるTSV(スレッド共有変数)の使用 - アプリケーションでの共有データの使用

もっとスクリプトを考えないと :-) 明確で簡潔で、少なくとも少しは役に立つものにしないと。

 

かなり魅力的なSkypeでの会話があり、そのうちのいくつかは、私が役に立つと思うので、声に出す必要があると思います:-)

1.なぜ、もっと人気のあるPythonやRubyではなく、Tclなのでしょうか?

もちろん、トレードだけでなく、よく知っているし、使っているので、最初の1台にはならないでしょう。PythonとRubyはメタトレーダーのスレッドモデルと互換性がありません。理論的には実行できるのですが、非常に低いAPIを掘り出すか、言語を壊すかのどちらかをしなければなりません。 Rやその他多くのものにも同じことが当てはまります。
これらを動作させるためには、1つのプロセス、1つのスレッド内で複数の孤立したインスタンスを独立して作成できる」という条件を満たす必要がある。
私が知っている他のスクリプト言語では、Luaが唯一それが可能ですが、「標準のない言語」です。
ちなみに、この太字は、 すべてのDLL開発者の 製品で遵守されるべきものです

2.適切かつ迅速なデータ解析の方法

正しく、速く、 メタトレーダーで計算を実行 することです。メタトレーダーは、データを受け取り、計算を行い、注文を出す、このために設計されています。その機能をあなたのDLLに複製するのは愚かなことです。結局のところ、MQL自体はむしろC++に似ていて、プログラマーが1日か2日あれば書き始めることができるのです。そしてDLLでは、データベースとの通信、サービス、インテグレーションなど、プラットフォームがカバーしないこと、物理的にカバーできないことをやらなければなりません。そしてプラス、MetaTrader以外で使えるもの、使うべきもの。

3.バージョン5はどこで、いつ発売されるのですか?

できるだけ早く :-)技術的には4から5へDLLをドラッグ&ドロップするのは難しくありません、スクリプトは気にしないでください。Tclは32ビットと64ビットの両方に対応しています。でも、4で開発する方がずっと便利だし、触れないし :-) 安定しているし、サプライズも期待できないし。しかし、我々が見る5で、プラットフォームの開発者は、(指標、スクリプト、Expert Advisorsと一緒に) "サービスタスク "を約束し、確かにDLLとスレッドの関係で何かが連続し、いくつかのビルドを変更することになります。これが決着するまでは、5用のバージョンはありません。

 

実行中およびユーザーからのフィードバックにより、msvcrt DLLの依存性に関連するいくつかの問題が発見されました。
と同じDLLを見つけるという小さなバグ(私の)があります。ATcl.mqhハンドラ内の相対パスが規定されていた :-)

は、修正されたバージョン(添付)を取得することができます、インストール手順は、伝統的な場所にあるhttp://luxtrade.tk/atcl:install


DLL開発者にとって、これは有益な情報です。

- D_CRTIMP_ALTERNATIVE を定義してコンパイルした DLL は、コンパイラに CRT のほぼすべてをインライン化させる :-)。

- DLLは、/MTスイッチでビルドされるようになり、リンカーにスタティックリンクを使用させ、不要な依存関係を発生させないようにしました。再頒布可能ファイル(VCサポートパッケージ)は、あちこちに持ち歩かなくていい感じです

DLLはサイズが大きくなったが、依存関係が少なくなり、ライブラリを持ち歩くのが楽になったはずだ

PS/小さな更新 - 添付のアーカイブを変更しました。ライブラリは完全なマルチスレッドサポートで構築されている
Install
  • luxtrade.tk
ATcl является библиотекой-интегратором и поэтому в первую очередь нужен сам по себе Tcl. Tcl свободно доступен и не имеет лицензионных отягощений (лицензии как правило BSD-like). Для работы с MT4 вам потребуется 32-х битная (это важно! MT4 32-х битный...
ファイル:
atcl.zip  243 kb