English Русский 中文 Español Deutsch Português
preview
市場シミュレーション(第15回):ソケット(IX)

市場シミュレーション(第15回):ソケット(IX)

MetaTrader 5テスター |
23 0
Daniel Jose
Daniel Jose

はじめに

前回の「市場シミュレーション(第14回):ソケット(VIII)」では、Pythonにおいてサードパーティ製パッケージや外部ツールに依存せずに、さまざまな処理を実現する方法について取り上げました。もちろん、Pythonで作業を効率化するパッケージの利用を否定するつもりはありません。しかし、本連載の目的は、使用しているプログラミング言語そのものが提供する仕組みに、より深い関心を持っていただくことにあります。外部ライブラリや既成ソリューションに頼る前に、まず基礎となる技術を理解することは非常に重要です。

前回の記事では、そのような考え方に対する興味を少しでも喚起できたのではないかと思っています。実際、多くの方は一般的な教材や講座で学んでいても、内部でどのように動作しているかを詳しく知る機会はあまりありません。その代表例のひとつが、前回軽く触れたCOM技術です。こうした技術や手法を理解しておくことで、プログラミングのさまざまな場面で応用できるようになります。

本記事では、これまで実演してきた内容、すなわち「ExcelユーザーがMetaTrader 5上で操作を実行できるようにする方法」の一例について解説します。ここでの目的は、注文送信やポジションの新規建てや決済を直接おこなうことではありません。ユーザーはExcelを用いて特定銘柄のファンダメンタル分析をおこない、その結果をもとに、Excelだけを使ってMetaTrader 5上で稼働しているエキスパートアドバイザー(EA)に対し、特定ポジションの新規建てまたは決済を指示できるようにします。

これまでに紹介してきた内容は、基本的にデータ通信に焦点を当てたものであり、いわばチャットのような仕組みとして実装していました。しかし、ソケット通信にまだ慣れていない方にとっては、このような方法のほうが基本概念を理解しやすかったのではないかと思います。ただし、これまで扱ってきた内容は、「ソケット通信」という巨大な氷山のごく一部にすぎません。ぜひ、この技術についてさらに学習を進めてみてください。仕組みを理解できるようになると、その柔軟性や応用範囲の広さに驚かされるはずです。

それでは本題に進みましょう。今回実装する内容には、比較的複雑な部分もあれば、非常にシンプルな部分もあります。そのため、できるだけ丁寧に段階を追って説明していきます。すべてを詳細に実装するわけではありませんが、仕組みさえ理解できれば、ここで紹介する内容を応用して、さらに優れた独自ソリューションを構築できるようになるでしょう。本連載の主な目的は教育的な理解にあります。それでは始めましょう。


Pythonでサーバーを作成する

前回までの記事でも説明したように、Excel内部で直接サーバーを作成して実行することはできません。もちろん不可能ではありませんが、その場合はサーバーがExcelの通常操作へ干渉しないように、さまざまな工夫が必要です。そのひとつとして、スレッド内でサーバーを動作させる方法があります。しかし、Excel上でスレッドを生成し、その中でサーバーを実行するのはやや複雑です。決して実現不可能なほど難しいわけではありませんが、今回紹介する方法と比べると、はるかに複雑になることは間違いありません。

そこで最初におこなうべきなのは、Pythonで独立したサーバーを作成することです。このサーバーが実際にExcelのスプレッドシートへアクセスする役割を担います。ただし、ここでもいくつか考慮すべき点があります。繰り返しになりますが、ここで紹介する内容はあくまで教育目的です。今回提示する構成は、さらに大きく改善し、最適化することが可能です。以下に示すのは、Pythonサーバーの基本コードです。私はこれを「メインコード」と呼んでいます。なぜなら、このコードは用途に応じて柔軟に拡張でき、必要な部分だけを調整すればさまざまな用途へ適応できるからです。ただし、その前にまずは動作の仕組みを理解しましょう。内部構造を理解することで、変更点と改善点も見えてきます。

001. import socket as sock
002. import select
003. import sys
004. from win32com import client as win32
005. 
006. class LinkMT5Excel:
007.     def __init__(self, host, port, sheet, cell) -> None:
008.         try:
009.             self.__CMD = ''
010.             self.__MT5 = None
011.             self.__server = sock.socket(sock.AF_INET, sock.SOCK_STREAM)
012.             self.__server.setblocking(False)
013.             self.__server.bind((host, int(port)))
014.             self.__server.listen()
015.             self.__CONN_LIST = [self.__server]
016.             EXCEL = win32.GetActiveObject('Excel.Application')
017.             self.__SHEET = EXCEL.Worksheets(sheet)
018.             self.__COLUNN, L = cell.split('$')
019.             self.__LINE = int(L)
020.         except:
021.             self.__CONN_LIST.clear()
022. 
023.     def __WriteInExcel(self, index, msg) -> None:
024.         try:
025.             if self.__SHEET:
026.                 self.__SHEET.Range(self.__COLUNN + str(self.__LINE + index)).Value = msg
027.         except:
028.             self.__SHEET = None
029.             self.__ShutdownServer()
030. 
031.     def __ReadInExcel(self, index) -> str:
032.         try:
033.             if self.__SHEET:
034.                 return self.__SHEET.Range(self.__COLUNN + str(self.__LINE + index)).Value
035.         except:
036.             self.__SHEET = None
037.             self.__ShutdownServer()    
038.         return ''
039. 
040.     def __MT5_Disconnect(self, conn) -> None:
041.         if conn == self.__MT5:
042.             self.__WriteInExcel(2, 'MetaTrader 5 is offline.')
043.             self.__MT5 = None
044.         if conn:
045.             conn.close()
046.             if self.__CONN_LIST:
047.                 self.__CONN_LIST.remove(conn)
048. 
049.     def __ShutdownServer(self) -> None:
050.         for conn in self.__CONN_LIST:
051.             conn.close()
052.         self.__CONN_LIST.clear()
053. 
054.     def __Command(self, cmd, conn) -> bool:
055.         if cmd.lower() == '/force server shutdown':
056.             self.__ShutdownServer()
057.             return True
058.         elif cmd.lower() == '/shutdown':
059.             self.__MT5_Disconnect(conn)
060.             return True
061.         self.__CMD = '' if cmd.lower() == 'n/d' else cmd
062.         return False
063.     
064.     def __Refused(self, conn) -> bool:
065.         conn.send('Connection Refused...\n\r'.encode())
066.         conn.close()
067.         return False
068. 
069.     def __Checking(self, conn) -> bool:
070.         try:
071.             info, cmd = conn.recv(512).decode().rstrip(None).split(':')
072.             if info.lower() != '<mt5 with excel>':
073.                 return self.__Refused(conn)
074.             if self.__Command(cmd, conn):
075.                 return True
076.             if (self.__MT5) or (cmd.lower() != 'mt5'):
077.                 return self.__Refused(conn)
078.             self.__MT5 = conn
079.             self.__WriteInExcel(2, 'MetaTrader 5 is online.')
080.         except:
081.             return self.__Refused(conn)
082.         return True
083.     
084.     def __SwapMsg(self, rec, conn) -> None:
085.         try:
086.             if rec:
087.                 data = conn.recv(1024).decode().rstrip(None)
088.                 if data:
089.                     if '/' in data:
090.                         if self.__Command(data, conn):
091.                             return
092.                     else:
093.                         self.__WriteInExcel(4, data)
094.                 else:
095.                     self.__MT5_Disconnect(conn)
096.                     return
097.             conn.send((self.__ReadInExcel(3) + f'[{self.__CMD}]').encode())
098.         except:
099.             self.__MT5_Disconnect(conn)
100. 
101.     def Run(self) -> None:
102.         self.__WriteInExcel(0, 'Server online.')
103.         self.__MT5_Disconnect(None)
104.         while self.__CONN_LIST:
105.             read, write, err = select.select(self.__CONN_LIST, [], [], 0.5)
106.             for slave in read:
107.                 if slave is self.__server:
108.                     conn, addr = slave.accept()
109.                     conn.setblocking(False)
110.                     if not self.__Checking(conn):
111.                         continue
112.                     self.__CONN_LIST.append(conn)
113.                     self.__SwapMsg(False, conn)
114.                 else:
115.                     self.__SwapMsg(True, slave)
116. 
117.     def __del__(self) -> None:
118.         for n in range(3):
119.             self.__WriteInExcel(n, '')
120.         self.__WriteInExcel(0, 'Server offline...')
121. 
122. if __name__ == '__main__':
123.     if len(sys.argv) == 5:
124.         Mt5_Excel = LinkMT5Excel(sys.argv[1], sys.argv[2], sys.argv[3], sys.argv[4])
125.         Mt5_Excel.Run()
126.         del Mt5_Excel
127.     else:
128.         print(f'Usage: {sys.argv[0]} <HOST> <PORT> <SHEET> <CELL>')

Pythonコード

このリプレイ/シミュレーションサービスの段階、特にソケット通信の説明部分をここまで追ってきた方であれば、このコードに特別奇妙な点は感じないでしょう。また、Pythonを長く学習している方にとっては、さらに理解しやすいはずです。とはいえ、まだ慣れていない方も心配する必要はありません。ここから、実際に何がおこなわれているのかを順番に見ていきます。これまで順を追って読み進めてきた方には少し辛抱していただくことになりますが、特に経験の浅い方にとっては、このコードの中でしっかり理解しておくべき重要なポイントがいくつもあります。

まず、01行目から04行目では、必要なパッケージをインポートしています。ここで注目してほしいのは、標準のPython環境以外のパッケージを使用していない点です。また、この段階では特別複雑な処理もしていません。もちろん、pandas、xlwings、openpyxlなどを利用して、本記事で紹介する処理を実装することも可能です。しかし、特定パッケージを推奨しているような印象を避けるため、ここではPython標準環境のみを使用します。そのほうが、後から自分に合ったパッケージを自由に選択しやすくなります。私たちの目的は、特定の方向へ偏ることなく、可能な限りシンプルな構成を実現することです。

インポートが完了した後、06行目でクラスの作成を開始します。クラスを使わずに実装することもできますが、クラス化することでさまざまな利点を得られます。そして07行目では、クラスの初期化処理を定義しています。ここでは、サーバーが正常に動作するために必要な重要情報を引数として受け取ります。これらのパラメータがどこで使用されているかを確認すれば、このコードが何を想定しているのか、またどのように改善できるのかが見えてくるでしょう。 

09行目と10行目では、後ほど重要になる2つの変数を宣言して初期化しています。続いて13行目では、渡された引数を実際に使用し始めます。ここでは、サーバーへ接続を許可するホストを指定しています。つまり、どこからの接続を受け付けるかを定義しているわけです。ホスト値が0.0.0.0であれば、すべてのクライアントアドレスからの接続を受け入れます。一方、特定アドレスだけを許可することも可能です。この点は利用者の判断に委ねられます。ここで重要なのは、サーバーがExcel側から初期化されるため、渡される引数が文字列であるという点です。そのため、使用するポート番号は文字列から整数へ変換する必要があります。これによってPythonは正しく値を解釈できるようになります。その後の11行目から14行目では、ソケットを初期化し、サーバーがポート監視および接続を待機できるようにしています。この部分について疑問がある場合は、前回までの記事を参照してください。

ここで08行目に戻りましょう。先ほどまでの処理は通常であれば問題なく動作しますが、08行目では例外処理の準備をしています。これは、実行時に発生する可能性のあるエラーへ対応するためです。スクリプト実行中にユーザーへ不可解なメッセージを表示させないようにするため、すべての例外をコード側で処理するようにしています。

16行目では、現在アクティブなExcelセッションを取得しようとしています。サーバー自身が初期化をおこなうため、この処理は通常成功します。しかし17行目では、失敗が発生する可能性があります。ここではExcelワークシートへアクセスしようとしていますが、対象シートがブック内に存在しない場合があります。当然、このシートは存在している必要があります。アクセスに成功すると、18行目でサーバーが利用する特定セルを取得します。この処理を2段階に分けている点にも注目してください。18行目では列と数値を取得し、19行目ではその数値を整数へ変換しています。これは後ほどサーバー内部で簡単な計算をおこなうためです。ただし、この意味は後で自然に理解できるようになります。

ここで理解しておくべき重要な点は、初期化中にエラーが発生した場合、21行目ではサーバーを停止し、以後Excelへデータを送信しようとする試みを防ぎます。これは非常に重要です。必要なリソースへアクセスできなかったり、設定が正しくおこなわれていなかった場合、ユーザーへ理解不能なメッセージを表示させたくないからです。

ここから、実際にシステムを動作させるための重要な処理へ入ります。23行目では、Excelへ値を書き込むための手続きを定義しています。ただし、どこへでも自由に書き込むわけではありません。制限された形で書き込みます。そのため、初期化時に指定された列と行を基準に移動するためのインデックスが必要になります。ただし、今回は教育目的であるため、列方向は使用せず、行方向のみを利用します。つまり、最初の行番号を基準にして、初期化時に指定したシートへデータを書き込む構成になっています。ただし、この処理も失敗する可能性があるため、24行目で例外発生を前提とした処理をおこなっています。

25行目では、対象変数が有効かどうかを確認しています。これは非常に重要です。たとえば終了処理中にシートが存在しなくなった場合、サーバーが無限ループのように「例外発生→終了処理→例外発生」と終了処理を繰り返す状態に陥る可能性があります。それを防ぐために25行目でチェックをおこなっています。そして26行目では、実際にExcelシートへデータを書き込みます。しかしここでも、ユーザーが誤って必要なシートを削除してしまう可能性があります。その場合は27行目以降の処理が実行され、サーバーは停止します。

続いて31行目です。ここでは、スプレッドシート内の特定セルの内容を取得しています。このセルは、初期化時に指定したセルを基準としています。このように、一つひとつの処理を丁寧に理解していくことが非常に重要です。セルへの書き込み時と同様に、読み込み時にもエラーが発生する可能性があります。しかし正常に読み込みが成功すれば、34行目でセル値がサーバーへ返されます。

ここで、「31行目の関数でExcelを読み取れるなら、初期化時にシートやセルを指定しておけば、残りの情報も直接Excelから取得できるのではないか?」と考えた方もいるかもしれません。もしそう考えたのであれば、本当に素晴らしいことです。すでに、このPythonスクリプトへ加えられる改善点に気づいているということだからです。しかし、まだ見るべきものが残っているので、先に進みましょう。

40行目には、MetaTrader 5が何らかの理由で利用不能になったことをExcelユーザーへ通知する手続きがあります。これは、デバイスの接続切断時に実行されます。非常にシンプルな処理なので、特別な説明は不要でしょう。49行目には、サーバーを停止するための別の手続きがあります。停止理由の多くはサーバースクリプト実行中のエラーですが、それ以外の理由も後ほど登場します。現時点では気にしなくて構いません。そして54行目には、非常に興味深い関数があります。ここから、内容が本格的に面白くなっていきます。しかしその前に、54行目の関数で何がおこなわれているのかを確認しておきましょう。

この関数は単純で、ソケットへ送信されたコマンドを解析するためのものです。サーバーは、このコマンドを実行する必要があります。現時点では、実装されているコマンドは2種類だけです。1つ目は55行目にあり、サーバーを強制終了するためのものです。非常に単純な処理です。2つ目は58行目にあり、クライアントを強制切断するためのコマンドです。この場合のクライアントとは、MetaTrader 5を指しています。サーバーがコマンド実行要求を受信していなかった場合、62行目でfalseが返されます。つまり、受信した内容はコマンドではなかった、という意味になります。

では、なぜfalseを返しているのでしょうか。その理由は、69行目の関数にあります。この関数の主な役割は、サーバーへ接続を試みているクライアントを受け入れるべきかどうかを判定することです。ここから、処理内容がより興味深いものになります。理論上は、誰でもサーバーへ接続することが可能です。しかし、この関数はそれを防ぐために設計されています。どのように防いでいるのでしょうか。方法は非常に単純です。サーバーが接続確認の直後に、クライアントがソケットへ送信してくる内容を検査するのです。72行目では、初期接続ヘッダーを確認しています。このヘッダーは接続時にのみ必要であり、それ以外のタイミングでは必要ありません。後ほど、これらが実際にどのように機能しているのかを詳しく説明します。

ここで理解しておくべき重要な点は、71行目でヘッダーと送信コマンドを分離していることです。その理由は非常に単純で、次回の記事でExcel VBA側のコードを確認すると理解できるようになります。クライアントが送信したヘッダーがサーバー側の期待値と一致しない場合、64行目の関数が実行されます。この関数は、接続してきたクライアントを認識できなかったため、サーバー側から切断することを通知します。

一方、ヘッダーが期待どおりだった場合、74行目でクライアントから送信されたコマンドの実行を試みます。コマンドではなかった場合、76行目では、すでにMetaTrader 5との接続が存在しているかどうかを確認します。既にMetaTrader 5との接続が存在する場合、またはコマンドが期待値(mt5)と異なる場合には接続は拒否されます。これらの条件に該当しない場合に限り、78行目と79行目でMetaTrader 5がオンラインであることを通知します。なお、途中で例外が発生した場合には、80行目の実行によって接続は拒否されます。

続いて、84行目にある非常に重要な手続きへ進みます。この手続きは、MetaTrader 5とExcel間のメッセージ交換を管理する役割を持っています。ここは特に注意深く理解してください。この手続き自体は比較的単純ですが、ここを理解しないままでは、自分の目的に合わせてコードを変更することは難しいでしょう。もちろん、今後の記事を読み進めることで、すべての処理がより明確につながっていきます。しかし現時点では、Pythonスクリプト内部で何が起きているのかを理解することが重要です。

エラーが発生する可能性があるため、85行目では、例外が発生することを前提としてコードを実行しています。呼び出し元が、この手続きに対してソケットの読み込みを要求している場合、86行目が成功し、87行目でソケットからデータの一部を読み取ります。

ここから先の説明は、後ほど非常に重要になりますので、注意深く読んでください。88行目では、ソケットから何らかのデータを受信したかどうかを確認しています。もし何も受信していなければ、MetaTrader 5を切断します。一方、ソケット上にデータが存在する場合には、89行目で、受信したメッセージ内に特定文字が含まれているかどうかを確認します。その文字が存在していれば、それはMetaTrader 5から送信されたコマンドであることを意味し、90行目が実行されます。ただし、この実行が失敗した場合には、それ以上の情報は公開されません。コマンド処理部分のコードを見ることで、MetaTrader 5からどのようなデータが送信される想定なのか理解できるでしょう。MQL5側のコードを扱う段階になった際に、この点について再度詳しく説明します。現時点では、「MetaTrader 5はサーバーへコマンドを送信できる」ということだけ理解しておけば十分です。

では、もし受信内容がコマンドではなかった場合はどうなるのでしょうか。これは89行目の判定が失敗したケースです。その場合、93行目が実行されます。ここでは、Excelからの要求に対してMetaTrader 5が返してきた情報を、特定セルへ書き込みます。では、その「要求」とは何なのでしょうか。ここで、97行目が登場します。この行では、サーバーを利用してMetaTrader 5へ要求を送信しています。この要求には、2つの形式があります。

  • 1つ目は、Excel内の特定セル、あるいはセル範囲から読み取った内容です。ただし、今回は簡略化のため、セル範囲ではなく単一セルのみを使用しています。
  • 2つ目は、Excelからの指示に従って、MetaTrader 5へ実行させるコマンドです。

後ほど、Excel内で作成されたこれらのコマンドや要求が、MetaTrader 5側でどのように実行されるのかを説明します。現時点では、非常にシンプルな通信プロトコルを使用していることに注目してください。つまり、セルに記載された内容、あるいはExcelから送信されたコマンドが、そのままMetaTrader 5へ渡される構成になっています。この段階では、サーバー自身はメッセージ交換へ積極的に介入しません。サーバーは、この手続き内で指定されたポイントにおいてログを記録するだけであり、実際の処理はExcel VBAとMQL5が担当します。

もちろん、ExcelとMetaTrader 5間で交換する情報量や品質を向上させたい場合には、Pythonを利用して、Excel VBA (Visual Basic for Applications)やMQL5側の作業を簡略化することも可能です。しかし今回は、できる限り教育的で分かりやすい構成にするため、Excel内の1セルのみを利用した非常に単純なメッセージプロトコルを採用しています。この仕組みを理解できれば、自分の用途に合わせて自由に拡張できるようになるでしょう。

なお、ここで使用されるすべてのセル位置は、サーバー初期化時に指定された最初のセルを基準としています。この点は非常に重要です。なぜなら、残りの処理はすべてExcel VBA側で直接実装されるからです。そして、その部分は非常に簡単に作成し、実行できます。

さて、ここで一通りの説明が終わり、101行目へ進みます。この手続きについては、ソケット通信に関する以前の記事でほとんど説明済みですが、いくつか注目すべき点があります。たとえば113行目には、一見すると奇妙に見える処理があります。しかし、ここまでの流れを理解していれば、不自然な処理ではありません。110行目の判定が成功した場合、新しく接続してきたクライアントへメッセージが送信されます。通常、この種のメッセージは挨拶として使用されます。

しかし今回は、まったく異なる使い方をしています。Excelは長時間オンライン状態を維持しないため、送信される情報はMetaTrader 5向けであると理解しています。そのため、先ほど説明した84行目の手続きが非常に重要になります。最初の呼び出しでは、ソケットの読み込みをおこなわず、書き込みだけを実行します。その後、MetaTrader 5から応答が返されると、115行目が実行されます。そして今度は、ソケットの読み込みと書き込みの両方をおこないます。このようにして、MetaTrader 5から継続的に情報を受信し、その情報をExcelに渡し続けるループになります。

最後に、多くの方が少し奇妙に感じるかもしれない手続きがあります。それがクラスデストラクタです。__init__というコンストラクタが存在するように、Pythonには__del__というデストラクタも存在します。通常、Pythonスクリプトでは、このデストラクタを明示的に記述することはほとんどありません。Pythonにはガベージコレクタが存在し、スクリプト終了時にオブジェクトを削除し、使用していたメモリを自動的に解放するからです。しかし、このデストラクタには、もう少し重要な役割があります。それは、サーバーがオフライン状態になったことをExcelへ通知することです。通常、サーバーがオンラインであることを表示している場所へ、「サーバーはオフラインです」というメッセージを強制的に表示させます。これにより、ユーザーは外部ツールや追加手段を利用しなくても、Excelだけでサーバー状態を確認できるようになります。残りのコードについては非常に単純であるため、これ以上詳しく説明する必要はないでしょう。


まとめ

ここまでの説明で、Pythonサーバーに関するパートはひとまず完了です。このサーバーの目的は、できるだけ教育的かつシンプルであることです。Pythonの標準インストールに含まれるパッケージのみを使用し、理解しやすい形で動作することを重視しています。しかし読者自身は、Excelファイルを扱うための他のパッケージやコンポーネントを利用することで、より複雑かつ実用的なシステムを構築することも可能です。場合によっては、ExcelワークブックそのものをPython側で完全に生成することもできますし、それ以外にもさまざまな機能を実装できます。

ただし私は、特定のPythonパッケージを優遇することで話を複雑にしたくはありません。Excelを扱うための優れたパッケージが多数存在し、それらを使えばExcel自体を使わずに同等以上のことを実現できる場合もあります。しかし本連載で一貫しているように、この解説の目的は、Excelだけで完結させたいユーザーに対応することです。つまり、特定銘柄のファンダメンタル分析用スプレッドシートを作成し、特定の価格帯で売買できるようにすることが目的です。ここで一部の方は「なぜ希望する価格位置に直接MetaTrader 5のチャート上で注文しないのか。その方がExcelを使う必要がなくなるのではないか。」と考えるかもしれません。

この考えは非常によく理解できます。しかし一方で、チャートを見たり、注文を出したり取り消したりする作業に時間や労力をかけたくない人も存在します。彼らはすでに使い慣れた複数のプログラム上で分析手法を構築しており、それを手放したくありません。そのため、その環境のまま注文の送信やポジションの新規建てや決済をおこないたいと考えます。したがって、これらの人々は、プログラマーであるあなた方に、特定のプログラム(この場合はExcel)を使用して、特定の価格範囲内で注文を送信したり、ポジションを決済や新規建てしたりするための何らかの方法または手段を作成してほしいと考えています。

しかし同時に、その仕組みがどのように実現されているのかを理解したいとすら思っていません。彼らは単純に「依頼し、支払い、すべてを実現してもらう」ことを求めます。これこそが、ここで私が示している内容です。つまり、その仕組みを少なくとも部分的に実装する方法です。プログラマーであるあなた自身は、別の方法や少し異なる設計で実装するかもしれません。それは問題ではありません。私にとって重要なのは、この記事を通じて「不可能だと思っていたことでも実現できる」ということを理解してもらうことです。学習し、時間をかければ、さまざまなことを実現できるようになります。次回の記事では、ExcelのVBA (Visual Basic for Applications)部分について説明し、このサーバーとExcelをどのように連携させるかを解説します。それでは次回の記事でお会いしましょう。

ファイル 説明
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/MarketReplay.mq5 市場リプレイ/シミュレーションサービス(システム全体のメインファイル)を作成および維持する
VS Code C++ Server.cpp C++で作成されたソケットサーバーを作成および維持する(ミニチャット版)
Code in Python\Server.py MetaTrader 5とExcel間の通信用のPythonソケットを作成および維持する
Scripts\CheckSocket.mq5 外部ソケットとの接続を確認する
Indicators\Mini Chat.mq5 インジケーターを介してミニチャットを実装する(サーバーが動作している必要がある)
Experts\Mini Chat.mq5 EAを介してミニチャット機能を実装する(サーバーが動作している必要がある)

MetaQuotes Ltdによりポルトガル語から翻訳されました。
元の記事: https://www.mql5.com/pt/articles/12827

添付されたファイル |
Anexo.zip (560.03 KB)
初級から中級まで:構造体(IV) 初級から中級まで:構造体(IV)
本記事では、いわゆる構造化プログラミングにおけるコードの作り方について解説します。構造体の中に、変数や情報を操作するためのコンテキストおよびメソッドをすべて配置し、あらゆるコードを実装するための適切な文脈を構築する方法を扱います。そのため、公開すべき内容とそうでない内容を分離するためにprivateセクションを使用する必要性について検討します。これによりカプセル化の原則が守られ、データ構造が本来意図されたコンテキストが維持されることになります。
取引におけるニューラルネットワーク:周波数領域における異常検出(CATCH) 取引におけるニューラルネットワーク:周波数領域における異常検出(CATCH)
CATCHフレームワークは、フーリエ変換と周波数パッチングを組み合わせることで、従来手法では捉えきれない市場異常を高精度に検出します。本記事では、このアプローチが金融データに潜む隠れたパターンをどのように明らかにするのかを解説します。
バトルロイヤル最適化(BRO) バトルロイヤル最適化(BRO)
本記事では、Battle Royale Optimizer(バトルロイヤル最適化アルゴリズム)について解説します。このアルゴリズムは、各解が近傍解と競合し、「ダメージ」を蓄積し、ある閾値を超えた場合に置き換えられ、さらに現在の最良解の周囲へと探索空間を周期的に縮小していくというメタヒューリスティックです。あわせて、擬似コードおよびCAOBROクラスのMQL5実装も紹介します。また、近傍探索、最良解への移動、適応的なデルタ区間といった主要な処理も含まれています。テスト結果としては、Hilly関数、Forest関数、Megacity関数における評価が示されており、本手法の強みと限界が明らかにされています。さらに、popSizeやmaxDamageといった重要パラメータを調整しながら実験し、検証できる基盤も提供されています。
リスク管理(第5回):リスク管理システムをエキスパートアドバイザーに統合する リスク管理(第5回):リスク管理システムをエキスパートアドバイザーに統合する
本記事では、これまで開発したリスク管理システムを実装し、さらに別記事で解説したOrder Blocksインジケーターを追加します。加えて、バックテストを実行し、リスク管理システムの有無による結果の違いを比較することで、動的リスク管理の影響を評価します。