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

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

MetaTrader 5 |
24 0
Daniel Jose
Daniel Jose

はじめに

前回の「市場シミュレーション(第13回):ソケット(VII)」では、ソケットのアクティビティがなくてもコードを実行し続けるシンプルなPythonサーバの作成方法について紹介しました。この実装の興味深い点は、監視対象のソケットにアクティビティがなくてもサーバーが実行を継続でき、スレッドを使用する必要がないことです。

とはいえ、前回の記事で紹介した内容と、以前学んだ内容を組み合わせることは可能です。以前の記事では、クライアントが接続するとスレッドを使用して同様のサーバーを作成する方法を示しました。どちらの方法も、接続されているクライアント数に関係なくソケットの監視方法に焦点を当てているため、機能するのは当然ですが、スレッドを使用するモデルも、select関数を使用するモデルも、今回の実装には適していません。

これらの方法が不完全であったり、動作しなかったりするわけではありません。問題は、コードの書き方によってExcelと干渉してしまうことです。この干渉により、ExcelとPythonスクリプトがCPU使用率を奪い合うことになり、Excelは非常に使いづらくなってしまいます。

多くのプログラマは、Excelの使用をやめてPythonに直接移行し、PythonでExcelファイルを生成して後から結果を分析できるパッケージを利用すべきだと考えるかもしれません。しかし、このような場合、常に正しいのはユーザーです。私たちプログラマは、すべてをうまく機能させる方法を見つけなければなりません。目標を達成できないのであれば、それはまだ必要な知識レベルに達していないということです。学び続け、自分の知識の基盤となっている原理をさらに深く理解するよう努めてください。

基礎知識だけでは高度なプログラマにはなれません。平均的なレベルのプログラマのままです。知識は、誰もが平均的な成果を示すことで進歩するのではなく、突出した人々がいることで進歩するのです。本日の記事では、ExcelとPythonの間にある問題をどのように解決するかをお見せしたいと思います。それでは、ExcelとPythonがCPU使用率を奪い合うことなく協調して動作する方法を見ていきましょう。


原点に立ち返る

皆さんの中には、Pythonを使い始めてまだ間もない方もいれば、また、長年使用している方もいるでしょう。しかし、多くのプログラマは人気のあるパッケージを積極的に利用しているため、Pythonをどのように、そしてなぜ使うのかを本当に理解している人は少ないのではないかと思います。ここでそれを説明するつもりはありません。それは本連載の範囲を超えているからです。本連載の目的は、MetaTrader 5におけるレプリケーション/モデリングシステムの開発方法を示すことにあります。しかし、そのシステムをより有効に活用するためには、いくつかのリソースを利用する必要があります。そのため、一見すると無関係に思えるものの実際には関連している別のトピックを説明するために、開発を一時中断しました。

さて、私たちの目標(Excel内でサーバーを実行し、ExcelとMetaTrader 5の間で情報を転送すること)を達成するために、VBAを使用することも可能です。しかし、VBAでそのようなサーバーを作成するのは非常に手間がかかります。問題は、そのサーバーが作成されたスプレッドシートに完全に組み込まれてしまうことです。しかし、私たちはそれを複数の異なるスプレッドシートで利用できるようにする必要があります。その理由は後述します。とはいえ、VBAでサーバーを作成すること自体は複雑ではありません。実際には単純ですが、先ほど述べたように、コードを毎回繰り返さなければならないため煩雑なのです。

一方で、Pythonを使用すれば、VBAと同じサーバーを簡単に作成できます。さらに、以前の記事で示したように、C/C++を使用することも可能です。間違いなく、Pythonを使うのが最も簡単な方法です。しかし、これまでの記事で示したとおり、人気のあるパッケージを用いた単純なプログラミング方法は実用的ではありません。主な理由は、サーバーを起動するとExcelとCPU使用率を奪い合ってしまうからです。競合の度合いを減らすためにスレッドを使用する方法も紹介しました。しかし、VBAでスレッドを作成しようとすると、コードを新しいスプレッドシートごとに繰り返す必要があり、非常に煩雑になります。

したがって、解決策は、コードの大部分をPythonで実装し、VBAの使用を最小限に抑えることです。そして、はい、それは可能ですし、まさにこれからおこなおうとしていることです。ただし、ここから先に示す内容はかなり混乱を招く可能性があります。そのため、落ち着いて学習することをお勧めします。ここで示すコードを本番環境で使用しないでください。使用することは可能ですが、提供するコードはあくまで教育目的であることを忘れないでください。


COMとは何か理解するために少し時間を取る

はじめにいくつか質問があります。COMが何かご存じですか。OLEについて読んだことや、それを使ってプログラミングをしたことはありますか。.NETについて何か理解していますか。これらの質問のいずれかに対する答えが「いいえ」であれば、あなたはまだプログラミングの第一歩を踏み出したばかりということになります。しかし、ここでの目的においては、基本的な概念を理解し、COMを扱えることができれば十分です。

COMは「Component Object Model」の略です。これは1990年代初頭にMicrosoftによって、プロセス間通信を容易にするために作られました。COMはソケットに似ていますが、いくつかの利点があります。これは、使用する言語やアーキテクチャ、デバイスに依存することなく通信を実装できるようにした技術です。さらに、開発者である私たちは内部実装がどのように動作しているかを理解する必要がありません。共通で明確に定義されたインターフェースを使用するだけでよいからです。

以上がCOMを扱うための基本です。では、なぜ現段階の開発においてこれが重要なのでしょうか。その理由は、この技術を使用することで、PythonとExcelを完全に調和させ、データ交換の際にCPU使用率を巡る競合や衝突を起こすことなく連携させることができるということです。

では、COM技術はPythonで使用できるのでしょうか。はい、可能です。そして驚くことに、パッケージをインストールする必要はありません。Pythonの仕組みを少し理解していれば十分です。しかし、このCOM技術を理解すれば、すべてがはるかに簡単になります。この記事の最後には、COMの学習を始めるためのリンクと、今回取り上げているテーマについてさらに知識を深めるためのリンクが用意されています。


ではPythonでプログラミングを始めましょう

まず最初におこなうことは、とてもシンプルです。同じことは他のPythonパッケージを使ってもできる、と言う人も多いでしょう。そして実際、その意見は間違っていません。確かに、他のパッケージでも同じことは可能です。しかし、物事が実際にどのように動いているのかを理解する必要があります。私たちは、理解すべき内容を隠すようなテクニックは使いません。そのため、できるだけシンプルな形のPythonを使用します。つまり、追加のパッケージを一切インストールせずに、Pythonをダウンロードしてインストールするだけで、ここで紹介する内容を実行できます。なお、Excelがコンピュータにインストールされている必要がありますが、これは念のための注意です。おそらく当然のことだと思います。

それでは、このCOM技術を使って最初のPythonコードを書いてみましょう。具体的には、PythonスクリプトからExcelを起動し、特定のセルにいくつかの情報を書き込みます。追加のパッケージなしでこれを実現するのは難しそうに思えますか。もしそう思ったのであれば、それはまだPython学習の第一歩を踏み出したばかりだからかもしれません。実際には可能であり、特定のパッケージの使用に煩わされることもありません。それでは、まさにそれを実行するスクリプトのソースコードをご覧ください。以下が完全なコードです。

1. from win32com import client as win32
2. 
3. excel = win32.Dispatch('Excel.Application')
4. excel.Visible = True
5. 
6. while True:
7.     pass

Pythonコード

上記のスクリプトを実行すると、次の結果が得られます。

ここで、スプレッドシートはどこにあるのかと疑問に思われるかもしれません。ご安心ください。私たちは単にExcelを起動しただけです。ただし、その方法に注目してください。スクリプトの01行目では、使用するものを指定しています。03行目では、Excelアプリケーションを作成するリクエストを送っています。ただし、この時点では作成されても表示はされません。表示させるために、04行目を使用しています。もし06行目のループを使用しなければ、アプリケーションは起動してすぐに閉じてしまいます。07行目は、ループの中身が空であることに対してPythonがエラーを出さないようにするためのものです。

それでは、このスクリプトにもう少しコードを追加してみましょう。もう少し手早く進めることもできますが、何が起こっているのかをきちんと理解していただきたいと思います。そのため、急がずに進めていきましょう。以下に示すのが、そのスクリプトです。

1. from win32com import client as win32
2. 
3. excel = win32.Dispatch('Excel.Application')
4. excel.Visible = True
5. wb = excel.Workbooks.Add()
6. wb.Activate()
7. 
8. while True:
9.     pass

Pythonコード

結果は下の画像に示されています。

ご覧のとおり、05行目と06行目の2行を追加しました。この時点で、私たちはCOM技術を使用しています。記事の最後に記載されているリンクから、これらの呼び出しについて復習・学習し、ここで示している内容を超えてCOMプログラミング技術をさらに活用することも可能です。繰り返しますが、ここでは次の段階で混乱しないようにするための基礎のみを紹介します。Excelを起動し、表示状態にし、スプレッドシートを追加し、それをアクティブにしました。すべてはまだ非常にシンプルです。

では、その同じスプレッドシートの名前を変更したい場合はどうすればよいでしょうか。Pythonを通じてCOMを使用しておこなう方法は、実はとても簡単です。次のようにスクリプトを修正するだけです。

01. from win32com import client as win32
02. 
03. excel = win32.Dispatch('Excel.Application')
04. excel.Visible = True
05. wb = excel.Workbooks.Add()
06. wb.Activate()
07. ws = wb.Sheets('Sheet1').Name = "New Name"
08. 
09. while True:
10.     pass

Pythonコード

結果は下の画像に示されています。

ご覧のとおり、Pythonスクリプトに追加したのはわずか1行(07行目)だけです。その結果は、まさに期待どおりのものでした。しかし、まだスプレッドシートには何の情報も入力していません。では、どのように入力すればよいのでしょうか。これもまた非常にシンプルで分かりやすいものです。単に場所を指定し、そこに情報を書き込めばよいのです。この部分は、何を実現したいかによって書き方が変わる可能性がありますので、ここでは数ある方法のうちの一例をご紹介します。おおよそ次のような形になります。

01. from win32com import client as win32
02. 
03. excel = win32.Dispatch('Excel.Application')
04. excel.Visible = True
05. wb = excel.Workbooks.Add()
06. wb.Activate()
07. wb.Sheets('Sheet1').Name = "New Name"
08. ws = wb.Sheets('New Name')
09. ws.Range('E6').Value = 'Checking.'
10. 
11. while True:
12.     pass

Pythonコード

その結果、図に示すとおりの結果が得られます。

これは興味深いです。数式を入力すると、それが自動的に計算される点にも注目してください。ここで次の点に注意してください。08行目と09行目が追加されています。08行目を追加することで、シート名を何度も繰り返し記述する必要がなくなります。なお、08行目と09行目は1行にまとめることも可能です。

「ちょっと待ってください。前のスクリプトで見たコード、とても見覚えがあるのですが」と思われたかもしれません。もしそう感じたのであれば、それは偶然ではありません。実際、Excelを起動して表示させると、実行している内容はVBAのコードと非常によく似ています。これこそがCOMインターフェースの魅力です。私たちはPythonでスクリプトを作成していますが、その多くの処理はVBAスクリプトと非常によく似ています。これにより、ここまでに見てきた以上のことを実現できる可能性が広がります。

「それは素晴らしいですが、ここでおこなったことはすべて、Pythonにインストールできる他のパッケージでも実現できますよね」と思われるかもしれません。はい、その通りです。しかし、この方法でおこなうと、VBAでもそのまま使えるような構造のPythonスクリプトを書くことができる点に気づくでしょう。「そうですね、空白のスプレッドシートを開きたいときにその方法を知っています。「空白のスプレッドシートを開く方法は分かりました。でも、Excelがすでに開いている場合はどうすればよいのでしょうか。」その場合、手順はさらに簡単で分かりやすくなります。Excelに接続し、どこに変更を加えるのかを指定するだけです。コードは次のようになります。

1. from win32com import client as win32
2. 
3. excel = win32.GetActiveObject('Excel.Application')
4. excel.Worksheets('Sheet1').Range('D5').Value = "Cool..."

Pythonコード

このスクリプトを実行した結果は以下の通りです。

ご覧のとおり、最初に思っていたよりも、すべてははるかにシンプルで簡単です。03行目では、この場合Excelであるアプリケーションを操作するためのオブジェクトをインターフェースに要求しています。04行目では、何をどこで操作するのかを指定しています。とても簡単です。しかし、ここまでに見てきた内容は、あくまで基本の中の基本にすぎません。私たちの目的は、多数のPythonパッケージをダウンロードしてインストールする必要はない、ということを理解していただくことです。必要なのは、標準で含まれているものをどのように使うかを知ることだけです。そしてもちろん、長年存在してきた技術やテクニックについて、少し理解を深めることも大切です。

さて、これが、Excelで作業しているユーザーの操作を妨げることなくサーバーを実行するために必要な中核部分でした。次に理解すべきことは、Excel内の特定の要素をどのように操作するかという点です。ただし、数式などの話をしているわけではありません。PythonのCOM技術を使えば、通常のPythonの使い方をはるかに超えることが可能であるということを理解していただきたいのです。ただし、考え方を整理し、これから説明する内容をより理解しやすくするために、新しいトピックへ進みましょう。


イベントの後にまたイベント

多くのユーザーは、実際のところ多くのプログラムが「イベントに応答するシステム」であることを知りません。これらのイベントは、マウスクリック、テキスト入力、あるいはプロセス間やプログラム間のデータ交換に関連するものなど、あらゆる種類のものが含まれます。マルチタスクOSにおいて、イベントは最も重要な要素です。

そして今回のケースも例外ではありません。PythonサーバーがCPU使用率を競合させることなくExcelとやり取りするためには、最初はそれほど多くのことは必要ありません。しかし、Excel内で発生するイベントをPythonが監視する方法を理解する必要があります。実際のところ、サーバーはExcelが何をしているのかを把握し、いつ終了すべきか、あるいはいつアクティブになるべきかを判断できなければなりません。

忘れないでください。目的は、Excelを開いたままにし、MetaTrader 5からリアルタイムデータを受信することです。これはRTDやDDEを通じて実現できます。同時に、ExcelからMetaTrader 5へコマンドを送信できるようにしたいのです。つまり、トレーダーがExcelを「見る」だけで注文を送信できるようにするということです。そして、MetaTrader 5はExcelで作成された注文をエキスパートアドバイザー(EA)に解釈させます。こうしてEAは、トレーダーが要求した取引を実行できるようになります。しかも、MetaTrader 5をトレーダーの画面に表示する必要はありません。トレーダーはExcelだけを見て、ファンダメンタル分析やその他の分析に基づいて、チャートに関係なく任意の銘柄をExcelから直接売買できるのです。

では、PythonスクリプトにExcel上でのユーザーの操作をどのように認識させればよいのでしょうか。ここではExcelを例として使用していますが、説明する内容はCOM技術を使用するあらゆるプログラムに適用できます。

方法自体は非常にシンプルです。ただし、監視したいプログラムがどのように動作しているかを理解する必要があります。そのために、リンクから関連資料にアクセスできるようにしています。ここで示している内容に関連する他の処理をおこなうために必要な情報が含まれています。安易に「これはどうやるのか」と尋ねる前に、必ず資料を学習してください。仕組みを理解すれば、用意された答えを求めるだけでなく、さらに多くのことができるようになります。COM経由で使用したいプログラムの資料やドキュメントを必ず学習してください。

それでは、実際にどのように動作するのかを見ていきましょう。そのために、これまでに示したスクリプトを少し修正します。説明をできるだけ分かりやすく、かつ実践的にするために、Pythonスクリプト実行時にはExcelがすでに起動しているものと仮定します。こうすることで作業量が減り、何が起きているのかをより簡単に理解・説明できるようになります。

メインのスクリプトは以下のとおりです。

01. from win32com import client as win32
02. import pythoncom as pyCOM
03. import time
04. 
05. class AppEvents:
06.     def OnSheetActivate(self, *arg):
07.         print('Tab ' +  str(arg[0].Name) + ' selected...')
08. 
09. class SheetEvent:
10.     def OnSheetSelectionChange(self, *args):
11.         print(args[1].Address)
12.         args[0].Cells(1, 1).Value = "Select " + str(args[1].Address)
13. 
14. excel = win32.GetActiveObject('Excel.Application')
15. 
16. win32.WithEvents(excel, AppEvents)
17. win32.WithEvents(excel.Workbooks('Book1'), SheetEvent)
18. 
19. print("Enter in loop...")
20. while True:
21.     pyCOM.PumpMessages()
22.     print('ping...')
23.     time.sleep(1)

Pythonコード

実行すると、2つのことに気付くでしょう。最初のものは、次の図に示すように、Excelに直接表示されます。

2番目は、スクリプトが実行されているターミナルで観察されます。今回の例では、私たちはVisual Studio Codeを使用しています。そのため、通常コマンドラインで表示される内容を模したエリアには、次のようなデータが表示されます。

ご注意ください。これはExcelで実行された内容を示しています。どうしてこんなことが可能なのかと思われるかもしれません。このコードはあくまで教育目的のためのものです。ここで示した以上のことも可能ですが、まず何が起こったのかを分解して理解することで、この知識を使って本当に面白いことができるようになります。

まず、コードのある部分に注目していただきたいと思います。特定の箇所を指摘しますが、この考え方は、スクリプトに新しいポイントを作成する場合でも、既存の箇所を扱う場合でも共通です。ここでは06行目について説明しますが、同じ考え方は10行目にも適用されます。

この記事の参考資料のドキュメントで「Excelアプリケーションのイベント」を検索すると、Application.SheetActivateイベントが見つかります。では、なぜこれを話すのかというと、理由は単純です。Pythonスクリプト内でイベントを参照する際、任意の名前は使えないからです。名前を間違えると、イベントを捕捉する際にスクリプトは正しく動作しません。

コードに注目してください。05行目でクラスを定義しています。このクラスは、私たちがインターセプトしたいすべてのアプリケーションイベントを格納します。同様に、09行目で別のクラスを作成して異なるタイプのイベントを処理しています。この場合、スプレッドシート自体に関連するイベントを扱っています。これら2つの活動は別々であり、目的も異なります。クラス名は有効な名前であれば何でも構いません。しかし、手続き名はこのルールに従いません。イベントに手続きを関連付けるには、決められた名前を使用する必要があります。

ドキュメントに戻ると、Application.SheetActivateイベントをPythonスクリプトで使う場合、捕捉したいイベントの名前は「On」で始まり、その直後にイベント名が続く必要があります。今回のケースではイベント名がSheetActivateです。したがって、手続き名はOnSheetActivateとなります。また、各イベントで使用される引数やパラメータの数にも注意する必要があります。ここで示す構造を使えば、Pythonは実際の引数をタプルに変換し、Python内部で利用可能にします。もしタプルの使い方が分からなければ、Pythonの公式ドキュメントを参照してください。Pythonでプログラミングするうえで最も基本的な資料です。

コードに戻ると、この仕組みがどのように動くかがすでに見えてきます。ターミナルの例では、メッセージが多すぎて分かりにくくなるため、22行目は削除しています。しかし教育目的では、21行目を最初から有効にしておくことをおすすめします。21行目の呼び出しはコードをブロックしませんが、イベントに関連するクラスがイベントを受け取れるようにするためのものです。はっきりしないかもしれないので、はっきりさせましょう。

さらに14行目には以前見たことがある内容が含まれています。目的はExcelセッションを取得することですが、私たちが注目するのは変数自体です。この変数は二箇所で使用されます。まず16行目では、どのクラスがアプリケーション関連のイベントを処理するかを指定しています。ここでの第二引数はクラス名です。次に17行目では、特定の接続を使用することに注意してください。この場合、接続はExcelで開いたファイルの名前を指します。異なる名前のファイルを使用する場合は、この箇所を置き換える必要があります。第二引数は、シート上のイベントを処理するクラス名を示しています。

ここは、ぜひ読者の皆さん自身で学習していただきたい部分です。スクリプトがどのようにしてシート名や選択されたセルを記録できるのか、なぜそのように動作するのかを試して理解してください。理解すれば、スクリプトをさらに改良するモチベーションにもつながります。


まとめ

本記事では、多くの人があまり知らないこと、すなわちPythonがCOMインターフェースを通じて情報を処理し、他のプログラムにアクセスできる仕組みについて、わかりやすいように解説しました。この内容が、将来プロのプログラマを目指す皆さんにとって、「仕組みを理解すること」の重要性を感じ、さらに学習意欲を刺激するものになれば幸いです。ここで示したのは、私たちが扱える技術の最も基本的な実装に過ぎません。多くの人は、多数のツールをインストールしたり、複数のプログラムを同時に操作する必要があると考えますが、実際には技術の理解と知識だけで、高品質な成果を十分に生み出すことが可能です。

Pythonがライブサーバーを維持しつつ、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 グラフィカルコントロールとユーザー間のインタラクションを実現する(リプレイおよび実取引の両方で必須)
Servicios\Market Replay.mq5 市場レプリケーション/モデリングサービスを作成および維持する(システム全体のメインファイル)
Code VS C++ Server.cpp C++で作成されたソケットサーバーを作成および維持する(ミニチャット版)
Python Code 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/10683

添付されたファイル |
Anexo.zip (560.03 KB)
カオス理論アプローチによる買われ過ぎと売られ過ぎのトレンド分析 カオス理論アプローチによる買われ過ぎと売られ過ぎのトレンド分析
市場の買われすぎや売られすぎの状態を、カオス理論に基づいて評価します。この手法では、カオス理論、フラクタル幾何学、ニューラルネットワークの原理を統合し、金融市場の予測をおこないます。この研究では、市場のランダム性の尺度として、また売買シグナルの動的適応として、リアプノフ指数を使用する方法を実証しています。市場のランダム性の評価にはリアプノフ指数を用い、売買シグナルの動的適応を実現しています。具体的には、フラクタルノイズ生成アルゴリズム、双曲線正接関数による活性化、モーメント最適化を組み合わせた手法を採用しています。
初級から中級まで:インジケーター(III) 初級から中級まで:インジケーター(III)
本記事では、DRAW_COLOR_LINEやDRAW_FILLINGなど、さまざまなグラフィック表示インジケーターの宣言方法について解説します。さらに、複数のインジケーターを用いてグラフを簡単かつ実践的に、そして高速に描画する方法も学びます。これにより、MetaTrader 5や市場全体の見方が大きく変わることでしょう。
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法 エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
この記事では、MT4において複数のEAの衝突をさける方法を扱います。ターミナルの操作、MQL4の基本的な使い方がわかる人にとって、役に立つでしょう。
ニューロボイド最適化アルゴリズム2 (NOA2) ニューロボイド最適化アルゴリズム2 (NOA2)
新しい独自最適化アルゴリズムNOA2 (Neuroboids Optimization Algorithm 2)は、群知能の原理とニューラルネットワークによる制御を組み合わせています。NOA2は、ニューラルボイド群の動作メカニズムに適応型ニューラルシステムを統合し、探索中にエージェント自身が行動を自己修正できるよう設計されています。現在も開発中のアルゴリズムですが、複雑な最適化問題の解決に有望な結果を示しています。