市場シミュレーション(第12回):ソケット(VI)
はじめに
前回の「市場シミュレーション(第11回):ソケット(V)」では、Excelで使用するPythonアプリケーションの作成方法について説明しました。このアプリケーションの目的は、Pythonでエコーサーバーを構築する方法を示すことでした。その特徴は、接続および切断イベントに関するデータがExcel上に直接表示される点にあります。
実のところ、このサーバーはあまり実用的とは言えません。主な理由は、単一の接続しか扱えないためです。1つの接続しか処理できないサーバーは、実用面での価値が限定的です。ただし、この点にあまりこだわる必要はありません。本来の目的は、Pythonで書かれたスクリプトがExcel内で透過的に動作する様子を示すことにありました。しかし、実際の用途を考えると、サーバーにはもう少し高度な機能が求められます。そのためには、いくつかの追加機能を実装する必要があります。
ここでの目的は、実運用可能なアプリケーションを作成することではありません。前述の通り、ソケットは非常に複雑な分野であり、十分に理解するには多くの時間が必要です。たった一日で堅牢かつ完成度の高いものを開発できると考えるべきではありません。ソケットを扱う際には、さまざまな詳細に踏み込む必要があります。それらの中には比較的単純なものもありますが、非常に複雑なものも存在します。
しかしながら、本アプリケーションではExcelとMetaTrader 5間の通信を実現するために、より高度な仕組みが必要となります。そのため、学習のハードルをやや下げる方針を採用しました。これは、ソケットを学び始めたばかりの方々に、実際にどのように動作するのかを理解してもらうことを目的としているためです。
すでに経験のある方にとっては、本記事の内容が既知のものの繰り返しであったり、新たな知見が少ないと感じられるかもしれません。その点についてはお詫びします。しかし、本内容は初心者にとって非常に有用なものとなるはずです。特に、すべてを純粋なPythonで実装していく点は重要です。
本記事では、ExcelやMQL5を直接扱うことはありません。しかし、MQL5の場合は使用できます。より正確には、本連載のこれまでの記事で開発してきた内容を活用します。本内容を完全に理解するためには、MQL5側で既に実装されている内容を振り返ることも有益です。
興味のある方は、以下の記事も参照してください。
これら2つの記事では、本記事の基盤となる内容を構築しました。当時は、MetaTrader 5のユーザー同士がテキストメッセージで情報をやり取りできるミニチャットを作成しました。ただし、その際のサーバーコードはC++で実装されていました。今回は、同様のサーバーをPythonで開発していきます。
初めに整理しておきたいこと
エコーサーバーをミニサーバーへと拡張すること自体は、最初はそれほど難しい作業には見えません。同様に、ExcelとMetaTrader 5間の通信に適した形へエコーサーバーを改良することも、十分な経験と知識を持つ人にとっては特に難しいものではありません。しかし、ソケットを扱う場合、特に複数のクライアントが同時に同一サーバーを利用する必要がある場合には、状況はやや複雑になります。これは、多くの人、特に初心者が「実際に何をおこなう必要があるのか」を十分に理解していないためです。
前回の記事で扱ったPythonコードを振り返ってみましょう。以下の通りです。
01. import socket 02. import xlwings as xw 03. 04. def Echo(): 05. wb = xw.Book.caller() 06. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 07. server.bind(("127.0.0.1", 27015)) 08. wb.sheets[0]['A1'].value = "Waiting connection..." 09. server.listen(1) 10. client, addr = server.accept() 11. client.send("Welcome to Server in Python\n\r".encode()) 12. wb.sheets[0]['A2'].value = str(f"Client connected by {addr}") 13. while True: 14. info = client.recv(512) 15. if not info: 16. break 17. client.send(b"Echo Server:" + info) 18. wb.sheets[0]['A3'].value = "Client disconnected" 19. client.close()
Pythonサーバー
このコードは、前回の記事の内容がなければそのままでは動作しませんが、調整することで機能させ、モジュールとして利用することが可能です。今回はExcelとPythonを直接連携させないため、一部のコードを削除すると、次のようになります。
01. import socket 02. 03. def Echo(): 04. server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 05. server.bind(("127.0.0.1", 27015)) 06. server.listen() 07. client, addr = server.accept() 08. client.send("Welcome to Server in Python\n\r".encode()) 09. while True: 10. info = client.recv(512) 11. if not info: 12. break 13. client.send(b"Echo Server:" + info) 14. client.close() 15. 16. if __name__ == "__main__": 17. Echo()
Pythonサーバー
さて、Pythonにある程度慣れている方であれば、このコードの動作はすぐに理解できるでしょう。一方で、Pythonに不慣れな方は、これは一体何だろうかと考えているかもしれません。しかし、特別なことをしているわけではありません。もともとのコードはPythonインタープリタから直接実行できませんでしたが、16行目と17行目を追加したことで、単体実行が可能になりました。同時に、これらの行があることで、モジュールとしても引き続き利用できます。
ただし、ここでの本題はそこではありません。問題は、このコードをどのようにして複数のクライアントを受け入れられるようにするかという点です。
さて、前回までの内容を理解していれば、このコードの問題点にも気づいているはずです。このサーバーは、実質的に1つの接続しか処理できない構造になっています。しかし、どうしてそんなことが可能なのでしょうか。その理由は、7行目のaccept関数にあります。この関数は一度実行されると再び呼び出されることがありません。そのため、新しいクライアントは接続できません。たとえ同じクライアントが切断したとしても、再接続はできません。
原因は同じで、acceptが再度実行されないためです。では、「7行目から14行目までをループで囲めば再接続できるのではないか?」と考えるかもしれません。確かに、単純なケースではそのような実装も可能です。しかし、それでも同時に接続できるクライアントは1つだけです。今回のミニチャットの目的には不十分です。
さらに、別の問題も存在します。前回の記事を実際に試した方は、サーバー実行中にExcelの動作が非常に重くなることに気づいたかもしれません。該当記事の中には、以下のものが含まれます。
これらは、まだ前回の記事を読んでいない方のための説明です。ここで疑問が生じます。なぜエコーサーバーが動作している間、Excelの操作が困難になるのでしょうか。この問いに答えるためには、サーバー内部で何が起きているのかを理解する必要があります。まず重要なのは、ExcelがVBAを通じて、実行すべきPythonコードを呼び出しているという点です。そしてPythonコードが実行されると、ExcelとCPU使用を巡って競合します。
OSの視点から見ると、Pythonコードは独立したプロセスではありません。実際にはExcelの一部、あるいはExcelに属するスレッドのようなものとして扱われます。ここで「スレッド」という言葉は厳密には完全に適切ではありません。なぜなら、通常スレッドはメインプログラムとCPU時間を競合するものではないからです。しかし、Excelを終了するとPythonコードも終了するという挙動を考慮すると、ここでは慎重に「スレッド」という表現を使うことができます。ただし、この用語の扱いには注意が必要であり、その理由については後ほど説明します。
とはいえ、ここで依然として残る疑問があります。Excelには独自の処理時間が割り当てられているにもかかわらず、なぜPythonコードがCPU使用を巡って競合するのでしょうか。その原因はコード内の2つの特定の箇所にあります。元のエコーサーバーのコードに戻ってみましょう。10行目にaccept関数の呼び出しがあります。この関数はブロッキングされます。つまり、実行されるとその地点で処理が停止し、接続が確立されるまで先に進みません。この関数は最初のボトルネックであり、PythonスクリプトがExcelとCPU使用を巡った最初の競合点となります。
つまり、コードが実行されると、この時点で停止し、接続が確立されるまで先に進みません。接続が確立されると、次の問題が発生します。これは14行目で起こります。この箇所でもPythonスクリプトは再び再びCPU資源を巡って競合します。そしてこの競合は、14行目に関連する処理が実行されるたびに繰り返されます。その結果、Pythonスクリプトが優先され、Excelに割り当てられる処理時間が減少し、サーバー稼働中はExcelの操作が困難になります。
では、この問題を解決する方法はあるのでしょうか。答えは「はい」であり、いくつかの選択肢があります。最初の方法は、PythonスクリプトをExcelの「真のスレッド」として扱うようにすることです。そうすることで、Excelが自身の実行時間に入った際に、ExcelとPythonスクリプトがCPU使用を巡って競合することはなくなります。これは、OSが各タスクに対して処理時間を分配するようスケジューリングをおこなうためです。マルチコアプロセッサの場合、OSはExcelに1つのコアを割り当て、Pythonスクリプトに別のコアを割り当てることも可能です。ただし、そのためにはExcelがOSに対して、Pythonスクリプトをスレッドとして扱うよう通知する必要があります。
しかし、ここで言う「スレッド」とは具体的にどのようなものなのでしょうか。この点を理解するために、次のトピックへ進みましょう。
スレッドとは何か
大まかに言えば、スレッドとはメインプログラムの中に存在するもう一つのプログラムのようなものです。実際、それはスレッドを説明する最も単純な方法でもあります。スレッドはメインプログラムが実行されている間だけ存在します。今回の例でいえばExcelですが、そのメインプログラムが終了すれば、それに関連するすべてのものも同時に終了します。
スレッドという概念は並列処理とともに登場しました。実際、それこそがスレッドの目的です。スレッドは、メインプログラム内で直接実装するのが困難な処理を実行するために存在します。そのため、コードの一部をメイン処理と並行して実行される領域へ切り出します。
スレッドが処理を終えると、メインプログラムはその結果として計算されたデータ、あるいは受け取ったデータを利用できます。このデータはあらかじめ確保しておいた領域に格納されます。この仕組みは非常に興味深いものです。なぜならスレッドを使用することで、数分かかるような処理であっても、その間メインプログラムを動かし続けることができるからです。
この機能はPythonに限らず多くの言語で非常に魅力的です。しかし、スレッドの利点や内部で何が起きているのかを本当に理解するためには、実際の動作を見る必要があります。ここで単に説明だけで終わらせないために、Pythonにおけるスレッドの使用例を見てみましょう。
01. import socket as sock 02. import threading as thread 03. 04. def NewClientHandler(conn, addr): 05. print(f"Client [%s:%s] is online..." % addr) 06. while True: 07. msg = conn.recv(512).decode().rstrip(None) 08. if msg: 09. print(f"Message from [%s:%s]: {msg}" % addr) 10. if msg.lower() == "/see you later": 11. break 12. print(f"Client [%s:%s] is disconnected..." % addr) 13. conn.close() 14. 15. server = sock.socket(sock.AF_INET, sock.SOCK_STREAM) 16. server.bind(('localhost', 27015)) 17. server.listen() 18. print("Waiting connections...") 19. while True: 20. conn, addr = server.accept() 21. conn.send("Welcome to Server.\n\r".encode()) 22. thread.Thread(target=NewClientHandler, args=(conn, addr)).start()
Pythonサーバー
このサーバーは、上記のコードの通り、スレッドを使用して複数のクライアントを同時に処理しています。いくつか重要な点に注意してください。まず、このサーバーはあるクライアントの情報を他のクライアントへ転送することはありません。次に、これは教育目的、すなわちスレッドの使用方法を示すためのものです。しかし、ここで起きていることを理解できれば、このコードを少し変更するだけでさまざまな面白いものを作ることができます。
では、まずこのコードの中で何が起きているのかを理解しましょう。すでにPythonに慣れている方は、初心者の方に少し付き合っていただく必要があるかもしれません。かつて誰かがあなたに教えたか、あるいはドキュメントから学んだことを思い出してください。どうか少しだけ辛抱してください。
1行目ではsocketパッケージをインポートしています。ここでは少し書き方を変えていることに注意してください。2行目ではスレッドを扱うためのパッケージをインポートしています。1行目と同様に少し見慣れない書き方かもしれませんが、心配する必要はありません。Pythonをより分かりやすく扱うためにエイリアス(別名)を設定しているだけです。
4行目から13行目までは手続き(関数)です。ここはいったん置いておき、15行目に進みましょう。15行目から18行目までは、これまでの記事とほぼ同じコードであることが分かります。この部分はサーバーソケットを作成するための処理なので、同じ内容になっています。重要な点として、ここではTCPプロトコルを使用しています。ただし、ネットワークには他にもプロトコルが存在するため、サーバーによってコードが多少異なることがあります。この点については後ほど説明します。
いずれにせよ18行目では、サーバーが接続受付の準備ができたことを示しています。ここで以前説明した「acceptの前にループを置く必要がある」という点を思い出してください。まさにここでそれを実現しています。そのため、クライアントが切断しても、ループによって再び接続することが可能になります。さらに重要な点として、accept関数はブロッキング処理であり、接続があるまでコードの実行を停止します。接続が確立されると21行目へ進み、新しいクライアントに対してウェルカムメッセージを送信します。これにより接続が確立されたことが通知されます。そして22行目でPythonのスレッドが生成されます。
ここからが非常に重要なポイントであり、本質的な仕組みが現れます。もし4行目から13行目のコードを22行目の代わりに直接実行した場合、サーバーの動作は完全に異なるものになります。その場合、接続は1つしか受け付けられなくなります。
「どういうことだ?」と思うかもしれません。しかし重要なのは、22行目は特別な魔法のような行ではないということです。この行は単に4行目の関数を呼び出しているだけです。ただし、通常の呼び出しとスレッド化された呼び出しには大きな違いがあります。スレッドとして実行される場合、OSはそのコードをメモリに配置し、実行時間(CPU時間)をメインコードとスレッドに分割します。
最初は少し分かりにくいかもしれませんが、こう考えてください。OSがプログラムに割り当てる実行時間はチョコレートバーのようなものです。スレッドがない場合、プログラムはそのバーをすべて独占できます。しかしスレッドがある場合、そのバーは小さな断片に分割されます。そしてメインプログラムはその一部しか利用できず、残りはスレッドに割り当てられます。これはCPUが単一コアの場合の単純な説明です。
コードに戻ると、22行目の実行後、プログラムは2つの部分に「分裂」します。一方は19行目に戻り、再び20行目で接続待ち状態になります。ここでもacceptはブロッキングするため、処理は停止します。もう一方は4行目へと進みます。
さて、「でも、20行目で止まっているのに、どうして4行目のコードが動くのか?」と混乱するかもしれません。これは非常に紛らわしいです。しかし心配はいりません。チョコレートバーの例を思い出してください。メインのコードは20行目で新しい接続を待ちながらブロックされています。しかし4〜13行目のコードは、その新しい接続とは独立して実行されます。重要なのは、このサーバーが接続済みクライアントからの情報受信を開始するという点です。そのため、6行目には新しいループが存在します。この点は非常に重要なので注意してください。ここを理解できないとスレッドの仕組みが分からなくなります。
この6行目から11行目までのループはスレッド内にのみ存在します。そして各クライアントはそれぞれ独自のループを持ちます。つまり、2つ以上のクライアントが接続していても、それぞれが互いに干渉することはありません。まるで各クライアントに専用のサーバーが存在しているかのようです。言い換えれば、接続されている、あるいは今後接続される各クライアントは、それぞれ専用のサーバーを持つことになります。そしてそのサーバーは、そのクライアントにのみ応答します。
これがスレッドの「魔法」です。しかし、この仕組みは完璧ではありません。スレッドの使用には問題もあります。特に、プログラマがスレッドを無分別に使用し始めたときに多くの問題が発生します。スレッドは並列に見えても、実際にはメインプログラムの処理時間を消費していることを常に忘れてはいけません。CPUコア数には限りがあるため、スレッドを過剰に使用すると全コアを消費してしまい、結果として処理時間が増加し、逆に性能が低下することもあります。
さらに別の疑問も浮かぶかもしれません。このコードは複数のクライアントを処理できますが、クライアント同士で通信することはできません。スレッドを使えばクライアント間で情報をやり取りできるのではないか、と考えるかもしれません。もしそう考えたのであれば、それはまだスレッドの仕組みを完全には理解していないということです。しかし心配する必要はありません。むしろ、その疑問を持ったこと自体が重要です。コードを見てその疑問に至ったのであれば、このサーバーの仕組みを正しく理解している証拠でもあります。ただし同時に、まだスレッドの概念を完全には習得していない段階でもあります。それでは、この疑問を解消していきましょう。話を整理するために、次のセクションで詳しく見ていきます。
クライアント間の通信のスレッドによる管理
この仕組みを理解するためには、これまでに説明した内容をしっかり把握している必要があります。もし前の内容を完全に理解していない場合は、もう一度読み返してください。理解しておくことが重要です。そうでなければ、このセクションではさらに混乱し、比較的短い内容であるにもかかわらず、何が起きているのか分からなくなる可能性があります。
コードを見てみましょう。
01. import socket as sock 02. import threading as thread 03. 04. CONN_LIST = [] 05. 06. def NewClientHandler(conn, addr): 07. global CONN_LIST 08. CONN_LIST.append(conn) 09. print(f"Client [%s:%s] is online..." % addr) 10. while True: 11. msg = conn.recv(512).decode().rstrip(None) 12. if msg: 13. print(f"Message from [%s:%s]: {msg}" % addr) 14. for slave in CONN_LIST: 15. if slave != conn: 16. slave.send(f"[{addr[0]}]: {msg}\n\r".encode()) 17. if msg.lower() == "/see you later": 18. break 19. print(f"Client [%s:%s] is disconnecting..." % addr) 20. conn.close() 21. CONN_LIST.remove(conn) 22. 23. server = sock.socket(sock.AF_INET, sock.SOCK_STREAM) 24. server.bind(('0.0.0.0', 27015)) 25. server.listen() 26. print("Waiting connections...") 27. while True: 28. conn, addr = server.accept() 29. conn.send("Welcome to Server.\n\r".encode()) 30. thread.Thread(target=NewClientHandler, args=(conn, addr)).start()
Pythonサーバー
「これは何だ。コードを少し追加しただけに見えるが、本当にこれでクライアント同士がメッセージを送れるのか。」はい、その通りです。このコードはクライアント間で情報を転送できるだけでなく、そのメッセージをサーバー側のコマンドプロンプトにも表示します。これはサーバーが実行されているコマンドプロンプト画面で確認できます。
ただし、このコードには重要な点があります。それは、過去のメッセージにはアクセスできないということです。つまり、サーバーに現在接続しているクライアントのみがメッセージを受信します。「しかし、これはどのように動作しているのだろう。コードを見てもよく分からない。」
サーバーが他のクライアントへメッセージを転送できる仕組みを理解するためには、スレッドの動作を理解する必要があります。これは前のセクションで説明しました。スレッドの仕組みを理解していれば、次はスレッド同士がどのように通信するのかを理解する段階です。その通りです。スレッドが他のクライアントへメッセージを送るためには、情報を共有する必要があります。では、それはどのように行われるのでしょうか。最も単純なケースでは、これは共有メモリ領域を通じて行われます。この共有領域は明示的に4行目で定義されています。つまり、4行目で宣言されたリストはすべてのスレッドから参照可能です。
すべてが正しく動作するようにするために、7行目ではこのリストをグローバルとして宣言しています。これにより、Pythonがローカル変数として新しく作成することを防ぎます。ローカルとして作成されてしまうと、スレッド間でメモリが共有されなくなってしまいますが、それはまさに避けたい動作です。8行目では、このスレッドを生成した接続をリストに追加しています。このステップは非常に重要です。なぜなら、新しい接続ごとに新しいスレッドが生成され、そのたびにリストへ追加されるからです。
11行目が実行されると、接続からのデータ受信を待つためにブロックされます。そしてこれは各スレッド内で独立して発生します。クライアントがサーバーに何かを送信すると、14行目のループに入ります。ここが「魔法」が起きる部分です。ここでは、各スレッドによって作成された接続のリストを走査しています。ただし、このループはスレッドの存在を意識しているわけではありません。メモリがスレッド間で共有されているため、すべての接続が順番に処理されます。
15行目の条件が偽の場合、つまり現在のスレッドが管理している接続と一致する場合は何もおこないません。しかし条件が真の場合、16行目が実行されます。この行では、現在のスレッドが受信したデータを、別のスレッドが管理している接続へ送信します。ここは理解してほしい重要なポイントです。各スレッドは1つの接続に対応しています。ある接続でデータが受信されると、そのスレッド内でループが動き、他の接続へそのデータが転送されます。しかし、それによって他のスレッドが「起動する」わけではありません。
「待ってくれ。それはどういうことだ。あるスレッドが他の接続にデータを送るなら、他のスレッドも動き出すはずではないか。」いいえ、その考えは正しくありません。完全に間違っているわけではありませんが、重要な点を見落としています。サーバーはスレッド内部の動作を監視しているのではなく、クライアント側の通信を監視しています。それぞれのクライアントから見ると、サーバーは専用のサーバーとして接続されているように見えます。そしてクライアント自身は、自分がスレッド内にいることを知りません。
最後に、クライアントが切断した場合、その接続は21行目でリストから削除されます。その結果、他のすべてのスレッドはその接続を参照しなくなります。
まとめ
一見するとやや複雑に思えるかもしれませんが、スレッドというテーマはソケットと同じくらい重要です。ただし、このスレッドを使った解決方法は、あくまで数あるアプローチの一つにすぎません。次の記事では、この問題を解決する別の方法について説明します。というのも、このスレッドベースの方法ではExcelの問題を解決できないからです。その理由は、accept関数が依然としてサーバーをブロッキングしてしまい、特にソケットを必要とするユーザーにとって、Excel上でPythonを使う体験をあまり快適なものにしていないためです。
| ファイル | 説明 |
|---|---|
| Experts\Expert Advisor.mq5 | Chart TradeとEA間の相互作用をデモンストレーションする(相互作用にはMouse Studyが必要) |
| Indicators\Chart Trade.mq5 | 送信する注文を設定するウィンドウを作成する(Mouse Studyが必要) |
| Indicators\Market Replay.mq5 | リプレイ/シミュレーションサービスと対話するためのコントロールを作成する(Mouse Studyが必要) |
| Indicators\Mouse Study.mq5 | グラフィカルコントロールとユーザー間のインタラクションを提供する(リプレイシステムと実際の市場運営の両方に必要) |
| Services/Market Replay.mq5 | 市場リプレイ/シミュレーションサービス(システム全体のメインファイル)を作成および維持する |
| Code VS C++ Server.cpp | C++で作成されたソケットサーバーを作成および維持する(ミニチャット版) |
| Python\Server.pyのコード | MetaTrader 5とExcel間の通信用のPythonソケットを作成および維持する |
| ScriptsCheckSocket.mq5 | 外部ソケットとの接続テストを可能にする |
| Indicators\Mini Chat.mq5 | インジケーターを介してミニチャットを実装する(サーバーが動作している必要がある) |
| Experts\Mini Chat.mq5 | EAにミニチャット機能を実装する(サーバーが正常に動作している必要がある) |
MetaQuotes Ltdによりポルトガル語から翻訳されました。
元の記事: https://www.mql5.com/pt/articles/12745
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。
取引におけるニューラルネットワーク:カオス理論を時系列予測に統合する(最終回)
取引におけるニューラルネットワーク:カオス理論を時系列予測に統合する(Attraos)
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
Market Memory Zonesインジケーターの開発:価格が戻りやすい領域
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索
情報ありがとうございます...異なるブローカーの2つのMT5ターミナルを接続するために、ソケットはどのように役立つのでしょうか?一方のFXと他方のmoex - 2つのターミナルからのペア取引は、ソケットを介して実現することができますか?
私はこのトピックを自分で調べています...私の質問が少しトピックから外れていたら、あらかじめ謝っておきます...。私はまだ記事を読んでいて、2つのMT5が連動して取引し、本質的に異なる取引所からシンボルの相場を取得し、2-3-4-5シンボルの相場のデータを分析した後に連動して取引するためのソリューションを探しています。
ソケッティングします:
端末間交換:MT5 AとMT5 Bの間で直接データをやり取りする。
イベント: OnSocketEvent()は、データが受信されると即座に トリガーさ れます。
データの柔軟性:JSON、バイナリ構造体、配列の転送が可能。
スピード:レイテンシは、可変ポーリングよりも桁違いに低い。
信頼性:再送と確認のメカニズムがある。
このような観点から、私はスプレッド計算、ACK/NACK、ポジション状態の保存、モニタリング用のウェブインターフェースを備えた高度なPythonサーバーを 作ろうと考えている;
私はこのトピックを自分で調べています...私の質問が少しトピックから外れていたら、あらかじめ謝っておきます...。私はまだ記事を読んでいて、2つのMT5をソケットで取引し、本質的に異なる取引所からシンボルの引用符を取得し、2-3-4-5シンボルの引用符のデータを分析した後にソケットで取引するための解決策を探しています......。
私はソケット取引をするつもりです:
端末間交換 :MT5 AとMT5 Bの間で直接データをやり取りする。
イベント : OnSocketEvent()は データが受信されると即座に トリガーされる 。
データの柔軟性 :JSON、バイナリ構造体、配列の伝送が可能。
スピード :可変ポーリングに比べ、レイテンシが桁違いに低い。
信頼性 :再送と確認応答のメカニズムがある。
このような観点から、私は、スプレッド計算、ACK/NACK、ポジション状態の保存、モニタリング用のウェブ・インターフェースを備えた高度なPythonサーバーを 作ることを計画している;
あなたの質問は適切で興味深い。しかし、あなたは性急な結論を下していると思います。MQL5はソケットを実装していますが、私の記事で説明しているように、サーバーを作ることはできません。クライアントだけだ。したがって、あなたがやろうとしていることの多くは不可能だ。 不可能です MQL5で実装することは不可能です。外部コードが必要になる。あなたの場合、Pythonの使用について言及していますが、それ自体がすでに解決策です。
実際、必要なことの多くはPythonで実装できる。しかし、あなたがやろうとしていること、つまりブローカーと直接やりとりすることには少し問題があります。なぜこんなことを言うのか?セキュリティ上の理由から、ブローカーは一般的にソケット経由でのアクセスを受け付けません。このようなやり取りには特別なプロトコルがあり、ブローカーの内部メカニズムが中断されるのを防ぐために特別に設計されています。しかし、試すことは不可能ではない。通信プロトコルを教えてくれるので、都合のいいときにアクセスすればいい。しかし、あなたが必要な情報を提供することができる証券会社に非常に親しい友人がいない限り、これは簡単だと思わないでください。
私が注目したもう一つの点は、MetaTrader 5の2つの異なるインスタンス間の相互作用と情報交換です。私の率直な意見では、あなたがやろうとしていることは良い考えではありません。あなたは並列プログラミングの概念と関連する問題を理解していません。もし差し支えなければ、「producer-consumer」タスクを勉強してみてください。取引目的で異なるMetaTrader 5インスタンス間で情報を転送する際に遭遇する可能性のある複雑さと落とし穴のレベルを理解するのに役立つでしょう。
とにかく、プロジェクト頑張ってくださいᙂ👍。
あなたの質問は適切で興味深い。しかし、あなたは性急な結論を下していると思います。MQL5はソケットを実装しているが、私の記事で説明しているように、サーバーを作ることはできない。クライアントだけだ。したがって、あなたがやろうとしていることの多くは不可能だ。 不可能です MQL5で実装することは不可能です。外部コードが必要になる。あなたの場合、Pythonの使用について言及していますが、それ自体がすでに解決策です。
実際、必要なことの多くはPythonで実装できる。しかし、あなたがやろうとしていること、つまりブローカーと直接やりとりすることには少し問題があります。なぜこんなことを言うのか?セキュリティ上の理由から、ブローカーは一般的にソケット経由でのアクセスを受け付けません。このようなやり取りには特別なプロトコルがあり、ブローカーの内部メカニズムが中断されるのを防ぐために特別に設計されています。しかし、試すことは不可能ではない。通信プロトコルを教えてくれるので、都合のいいときにアクセスすればいい。しかし、あなたが必要な情報を提供することができ、証券会社に非常に親しい友人を持っていない限り、これは簡単だと思わないでください。
私が注目したもう一つの点は、MetaTrader 5の2つの異なるインスタンス間の相互作用と情報交換です。私の率直な意見では、あなたがやろうとしていることは良い考えではありません。あなたは並列プログラミングの概念と関連する問題を理解していません。もし差し支えなければ、「producer-consumer」タスクを勉強してみてください。これは、取引目的で異なるMetaTrader 5インスタンス間で情報を転送するときに遭遇する可能性のある複雑さと落とし穴のレベルを理解するのに役立ちます。
とにかく、プロジェクト頑張ってくださいᙂ👍。
フィードバックありがとうございました。証券会社に友達がいない!!!)2つの異なる証券会社にMT5端末がある!!!友達にする必要がある....これは来年のプロジェクトです!
ここで - 試している...記事を読んで、内容を勉強しています!スピードが許せば、ファイルを通して直接やるかもしれません。アクセス - 以前のハードディスクがバイオで2つ接続されていたように:マスター1つ、スレーブ1つ...)
それで...強力なコンピュータ上の2つのMT5端末 1マスター(メイン) - 他のスレーブ(2番目)、一方の証券取引所 - もう一方のMT5外国為替!多分ファイルを通じて実現)読み取り - 書き込みが行われます...しかし、私は、読み取りの面でより速く簡単に実装したいと思います - データのバリアントを受信....クライアント端末のグローバル変数の種類によって(私はファイルを使用していない - 長い時間)、しかし、クライアント端末のグローバル変数は、この端末でのみ表示されます....外部プロセスに接続する必要があるメモリ上にテーブルを作る接続のDLLライブラリのように、私は実現する!
良い一日を!