市場シミュレーション(第23回):ポジション表示(I)
はじめに
皆さん、こんにちは。これはリプレイ/シミュレーションシステムの作成方法に関する連載の続きです。
前回の「市場シミュレーション(第22回):SQL入門(V)」では、これからの記事の内容を理解するために必要となるすべての説明を終えました。前回までの記事で扱った内容全体は、初めて学ぶ場合、それほど簡単に理解できるものではなかったと思います。そして、多くの方は、MQL5上でこのようなことが実現できるとは、おそらく想像もしていなかったのではないでしょうか。しかし、ここまで見てきた内容は、巨大な氷山のほんの一角にすぎません。なぜなら、これまで私はソケットについて少し、そしてSQLについて少し説明しただけだからです。
私の考えでは、この期間に得た知識は、これから先の段階で非常に役立つものになります。ここからは、さらに複雑なテーマに取り組んでいくことになります。それでも、読者の皆さんが困難を感じないように、できる限り分かりやすく説明していきます。同時に、これから紹介する内容について、さらに深く学び、掘り下げていく意欲を持っていただきたいと本当に思っています。
一度深呼吸して準備してください。これから、リプレイ/シミュレーションシステムの核心部分へと、一気に踏み込んでいきます。このシステムの開発について私が計画していた内容は、すでに最終段階に近づいています。つまり、紹介すべき内容は残りわずかになっています。しかし、理論的な内容が非常に複雑になるため、できる限り簡単に説明していきます。プログラミングそのものは、非常に単純で分かりやすいものです。しかし、その背後にある理論を理解していなければ、ここで紹介するものとは異なるタスクに対して、リプレイ/シミュレーションシステムを改良したり応用したりするための実践的な基盤を得ることはできません。
私が提示するコードを単にコンパイルして利用するだけになってほしくはありません。学び、理解し、可能であれば、さらに優れたものを自分自身で作成できるようになってほしいのです。なお、私はいくつかの方法については紹介しません。なぜなら、それらは私が実際の運用で使用しているモデルであり、あるいは実際にトレードシステム、つまり時間とともに学習するエキスパートアドバイザー(EA)を作成するために特別に開発したモデルだからです。そのEAは時間の経過とともに独自の取引方法を発展させ、実際の人間の運用者が行う判断や対応に近づいていくことを目指しています。
以前の「市場シミュレーション(第5回):C_Ordersクラスの作成(II)」では、リプレイ/シミュレーションシステムについて説明した部分で、以前に開発したChart Tradeプログラムと連携できる小さなEAを作成しました。それはかなり前のことになります。そのため、コードが最終的にどのような形になったのか覚えていない方もいると思います。そこで、まず簡単に振り返ってみましょう。ここから始めます。その時点から現在までに開発してきたすべてのものは、まもなく利用することになります。しかしその前に、以前どのように構築されていたのかを確認しておきましょう。
これまで開発してきたリプレイ/シミュレーションシステムの振り返り
これは重要なポイントです。なぜなら、これまでに何が開発され、どこまで完成しているのかを理解していなければ、すでに完全に機能していて見直す必要のない部分へ戻ってしまうことになるからです。もちろん、特定の機能については後ほど説明する予定です。しかし、それについてはまた別の機会に扱います。今は、すでに完全に動作している部分を確認していきましょう。
リプレイ/シミュレーションシステムは、複数の独立したアプリケーションによって構成されています。しかし、それらを組み合わせることで、まるでMetaTrader 5がデモ口座やリアル口座に接続されているかのように操作できる環境を実現できます。その構成要素として、まずマウスポインタがあります。これは、チャート上に分析用の描画を作成したり、チャート上の要素と対話したりすることを可能にします。また、Chart Tradeも重要な要素です。Chart Tradeは、EAを介して、成行注文や成行執行リクエストを送信することができます。これは、マウスポインタとChart Trade(こちらもインジケータです)を使用することで、チャート上に配置されたEAとメッセージングプロトコルを通じて通信できるためです。
これら3つのアプリケーションは、それぞれ単独ではあまり実用的ではありません。しかし、チャート上に配置することで、MetaTrader 5と簡単に対話し、市場注文を送信できるようになります。ただし、ポジションを開いたり閉じたりした場合、その結果はまだチャート上に表示されません。もっとも、これは完全には正しくありません。MetaTrader 5が表示する標準的な視覚表示を利用することは可能です。しかし、クロスオーダーシステムを使用する場合、つまり現在表示しているチャートとは異なる銘柄に対して注文を出す場合、この視覚表示は十分なものではありません。なぜなら、クロスオーダーを使用するとき、私たちは現在観察している銘柄のチャートを見ています。しかし、注文や取引リクエストは、別の銘柄に対して送信されます。その銘柄のチャートが開かれていない場合、MetaTrader 5が提供する標準の視覚表示システムでは、もはや十分な情報を得ることができません。
リプレイ/シミュレーションサービスを使用する場合も同じことが起こります。現在でも、リプレイ/シミュレーションシステム内で取引操作を視覚化することは可能です。そして近いうちに、そのための仕組みも実装する予定です。しかし現時点では、まだ適切な視覚表示システムを持っていません。理由は単純です。この特定の銘柄に存在する可能性のある注文やポジションと対話するための視覚表示システムが存在しないからです。それが実際の銘柄であっても、シミュレーションされた銘柄、つまりデータを再生している対象銘柄であっても同じです。
したがって、リプレイ/シミュレーションシステムはすでにその役割を果たせる状態にはありますが、まず最初に、この取引対象に存在する可能性のあるポジションや注文を視覚化し、操作できる仕組みを実装する必要があります。なぜなら、これがなければ、リプレイ/シミュレーションシステム内で分析を支援するための注文システムを作成しても、まったく意味がないからです。その銘柄に存在する注文やポジションと対話することができないからです。
したがって、この部分の作成が最優先事項になります。心配する必要はありません。まずは、比較的単純なシステムを作成します。リプレイ/シミュレーションシステムを開発していく過程で、作業を制御できる程度に十分シンプルな解決策です。それでは、さっそく始めましょう。そのために、新しいテーマを作成して進めていきます。
シンプルなポジション表示インジケータの作成
まず、以下のことから始めます。現在のChart Tradeインジケータは、未約定注文を扱うことを目的としておらず、即時注文の発注だけに焦点を当てています。そのため、最初に作成するものは、未決済ポジションを表示する基本的なインジケータになります。つまり、この段階では未約定注文は扱いません。対象とするのは、未決済ポジションのみです。そして、それらをどのようにチャート上へ表示するかについて考えていきます。ここで改めて強調しておきたいことがあります。今回の目的は、MetaTrader 5がすでに表示しているものを再現することではありません。目的は、MetaTrader 5が表示してくれないものを表示することです。これは、特に、クロスオーダーシステムを使用する場合に重要になります。
実装するコードを見る前に、この段階での目的について少し説明しておきたいと思います。現時点で目指しているのは、単純に価格ラインを表示する機能を実装することだけです。ここで完成版の実用ツールを作ろうとしているわけではありません。つまり、まずは1つだけ未決済ポジションが存在する場合に、その価格ラインを表示できるようにすることが目標です。現段階では、多数の未決済ポジションを管理することには注目しません。そのため、すぐに高度な機能を期待している読者の方には、もう少しだけ待っていただきたいと思います。ここでの目的は、初心者や興味を持って学んでいる方に、どのようにして物事を動作させるのかを説明することです。
まず、新しいファイルを作成します。ここで、「取引サーバー上に存在する可能性のあるポジションを扱うのだから、EAのファイルを作成するべきではないか」と考えるかもしれません。しかし、今回はEAは作成しません。インジケータを作成します。ソースコードは以下のとおりです。
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. #property description "Indicator for tracking an open position on the server." 04. #property version "1.00" 05. #property indicator_chart_window 06. #property indicator_plots 0 07. //+------------------------------------------------------------------+ 08. int OnInit() 09. { 10. return INIT_SUCCEEDED; 11. } 12. //+------------------------------------------------------------------+ 13. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 14. { 15. return rates_total; 16. } 17. //+------------------------------------------------------------------+ 18. void OnDeinit(const int reason) 19. { 20. } 21. //+------------------------------------------------------------------+
ソースコード
これを見ると、「正気なのですか。完全に何かを間違えているのではありませんか。こんなことにインジケーターを使うなんて不可能でしょう。」と思うかもしれません。落ち着いてください、読者の皆さん。少しだけ待ってください。お願いです。今まで見たことがないという事実は、それが実現できない、あるいは存在しないという意味ではありません。この作業にインジケータを使用することには、いくつかの利点があります。もちろん、多くの人はこの方法を推奨しないでしょう。しかし、コードがどのように構築されていくのかを見ていけば、最終的には、なぜここでEAではなくインジケータを使用するのか、その理由を理解できるようになります。これまで何度も述べてきたように、このリプレイ/シミュレーションシステムに関する連載の内容は、これからますます複雑になっていきます。しかし私は、可能な限り、すべてをシンプルで理解しやすい形に保つよう努力しています。
インジケータを使用する場合の問題点は、コードの実装方法を誤ると、チャートの動作そのものを完全に妨げてしまう可能性があることです。これは、MetaTrader 5ではすべてのインジケータが同じ実行スレッド上で動作するためです。そのため、1つのインジケータが一時的に停止したり、応答しなくなったりすると、そのインジケータが配置されているチャートも同じ問題の影響を受けます。多くの人は、ときどき1つのチャート上に大量のインジケータを配置します。一見すると問題ないように見えるかもしれません。しかし、これは推奨されません。なぜなら、それらはすべて同じスレッド上で実行されるからです。1つのインジケータが、ほかのインジケータに悪影響を与える可能性があります。その結果、プラットフォーム全体のパフォーマンスが危険にさらされることになります。
しかし、今回の私たちの考え方は、まさにその逆です。ここでの目的は、インジケータをチャート上に配置し、そのまま放置することです。つまり、このインジケータは更新処理をおこないません。たとえ手動でテイクプロフィットやストップロスの価格を変更したとしても、この段階ではインジケータはその変更を表示しません。この更新処理については後ほど説明します。そのとき、どのように正確に更新を実行するのかを詳しく解説します。ですから、急がないでください。まず最初におこなうべきことは、価格ラインを表示することです。今は、それ以外のことはすべて忘れてください。なぜなら、ここでは最も単純で、そして学習しやすい方法で実装していくからです。私が皆さんに学んでほしいのは、単にここで教えるものを利用して終わることではありません。そうではなく、自分自身のプロジェクトに必要な変更を作成できるようになってほしいのです。そうしなければ、後になって完全に制限されてしまいます。どこへ進めばよいのか分からず、ただ与えられたものを使うだけになってしまうからです。
よろしいでしょう。それでは、先ほど確認したコードを少し変更し、いくつかのテストをおこなえるようにします。新しいコードは以下のようになります。
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. #property description "Indicator for tracking an open position on the server." 04. #property version "1.00" 05. #property indicator_chart_window 06. #property indicator_plots 0 07. //+------------------------------------------------------------------+ 08. #include <Market Replay\Auxiliar\C_Terminal.mqh> 09. //+------------------------------------------------------------------+ 10. C_Terminal *Terminal; 11. //+------------------------------------------------------------------+ 12. int OnInit() 13. { 14. Terminal = new C_Terminal(); 15. if (!PositionSelect((*Terminal).GetInfoTerminal().szSymbol)) return INIT_FAILED; 16. Print ( 17. "Position Ticket: ", PositionGetInteger(POSITION_TICKET), " ", 18. "Opening Price: ",PositionGetDouble(POSITION_PRICE_OPEN), " ", 19. "Stop Position: ", PositionGetDouble(POSITION_SL), " ", 20. "Take Position: ", PositionGetDouble(POSITION_TP) 21. ); 22. 23. return INIT_SUCCEEDED; 24. } 25. //+------------------------------------------------------------------+ 26. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 27. { 28. return rates_total; 29. } 30. //+------------------------------------------------------------------+ 31. void OnDeinit(const int reason) 32. { 33. delete Terminal; 34. } 35. //+------------------------------------------------------------------+
基本的なポジション表示インジケーターのソースコード
このコードは非常にシンプルなので、どのように動作するのか理解してもらうために、簡単に説明していきます。おそらく、コードを見ただけでは理解できないと思います。8行目では、リプレイ/シミュレーションシステムですでに使用されているファイルを追加しています。このファイルは、本連載内で最後に更新した時点から変更されていません。10行目では、ヘッダーファイル内に存在するクラスへ、ポインタを通じてアクセスすることを指定しています。14行目で、クラスを初期化しています。15行目では、MetaTrader 5に対して、この銘柄に未決済ポジションが存在するかどうかを問い合わせています。存在しない場合は、エラーを報告してインジケータを終了します。
ここで注意してください。15行目の処理が実行され、true(存在する)が返された場合、要求した取引対象のポジションに関するデータが利用可能になります。それまでは、信頼できるデータは一切取得できません。この点を覚えておいてください。15行目が正常に実行された場合、16行目が実行されます。この行では、15行目の呼び出しによって取得されたポジションデータを、ターミナルへ出力します。最後に23行目で、インジケータの初期化が正常に完了したことを示す値を返します。
このインジケータ内部では、何らかの理由でチャートから削除されるまで、それ以外の処理は何もおこなわれません。削除された場合、33行目でクラスを破棄し、確保していたメモリをシステムへ返します。
非常にシンプルです。その結果、ターミナルには次の画像に示されているポジションから、以下のようなデータが表示されます。

インジケータが処理を完了した後、その動作結果を次の画像のように確認できます。

ここで注目してください。私たちは、このデータを正常に取得することができました。一般的な認識とは異なり、インジケータから直接ポジションや未約定注文のデータを取得することは可能です。必ずしもEAを使用する必要はありません。しかし、ポジションや未約定注文のデータを取得できるという事実は、インジケータを使ってポジションや未約定注文を送信したり変更したりできる、という意味ではありません。この2つの概念を混同しないでください。ポジションや未約定注文の送信、変更を担当するコンポーネントは、つまりその役割を持つものは、EAです。これらの処理をインジケータで実行しようとしないでください。できません。
さて、すべて問題ありません。むしろ非常に良い状態です。しかし、私たちが本当に実装する必要があるものには、まだ遠く及びません。とはいえ、多くの人が次のように言うでしょう。
賢者には一言で十分だ。
つまり、すでにチャート上へオブジェクトを追加する方法を知っている人であれば、おそらくここで私が何を考えているのか理解できるでしょう。しかし、もしまだ分からなかったとしても、落胆する必要はありません。これから、実装すべき次のステップへ進みます。この次のステップは、少し規模が大きくなります。それでも、開発の過程をできる限り楽しいものにしていきたいと思います。なぜなら、この先には多くの可能性が広がっているからです。ただし、いきなり最終的な結果へ進むことはしません。段階的に進めていきます。なぜなら、プログラム量を最小限に抑えるためには、考慮しなければならない重要なポイントがいくつも存在するからです。忘れないでください。私たちはすでに、Chart Trade、マウスインジケータ、そして基本的なEAなど、複数の完成済みアプリケーションを持っています。
ここからは、ポジション表示インジケータを作成する必要があります。理想的には、ほかの3つのアプリケーションが配置されている状態で、このインジケータもチャート上へ配置されるべきです。しかし、現時点ではそのことについては気にしません。まずは、MetaTrader 5が標準機能としてクロスオーダーをサポートしていた場合に表示されるはずの同じ情報を確認できるように、チャート上へ配置するいくつかのオブジェクトを作成してみましょう。それでは、作業を始めましょう。
チャート上へのオブジェクト配置
MQL5を使用してチャート上へ直接オブジェクトを配置することについて、皆さんは「非常に難しい」と考えるかもしれませんし、逆に「とても簡単」と考えるかもしれません。ある意味では、すべてはどのような方法で作業したいのか、そしてその機能に何を期待しているのかによって変わります。しかし、MetaTrader 5のターミナル上でチャートへオブジェクトを配置すること自体は難しくありません。実際には非常に簡単です。MQL5のコードを使用して配置することもできますし、MetaTrader 5から直接配置することもできます。MetaTrader 5には、メニュー内に[挿入]という項目があり、その中の[オブジェクト]サブメニューから、いくつかのオブジェクトを非常に簡単かつ直感的な方法でチャート上へ配置できます。次の画像で確認できます。

しかし、ここには問題があります。以前にもお話ししたかどうか、はっきりとは覚えていません。いずれにせよ、ここから先、読者の皆さんには理解していただきたいことがあります。私たちは、何でも好き勝手にすることはできません。チャートを見た目に美しくするためだけに、あるいは必要だと思うデータや情報を表示するためだけに、何も考えずオブジェクトを追加してはいけません。適切な管理なしにこれをおこなうことは、大きな間違いです。誤解しないでください。なぜなら、多くの人がまったく認識していない問題が存在するからです。そして遅かれ早かれ、その問題に直面することになります。その結果、MetaTrader 5を使用する体験そのものが、文字通り台無しになる可能性があります。
しかし、その問題の原因は本当にMetaTrader 5にあるわけではありません。問題は、チャート上へオブジェクトを作成するさまざまなアプリケーション側にあります。しかも、それらのオブジェクトが画面を過剰に圧迫していなくても、通常のチャート分析を邪魔していなくても、後になって本当の悪夢になる可能性があります。例えるなら、地面に埋まった石のようなものです。最初は小石だと思っています。しかし、それを取り除こうとした瞬間、実際には想像していたよりもはるかに大きな岩だったことに気づくのです。
おそらく、皆さんはこう考えているかもしれません。「分かりました。しかし、それが私にどのような影響を与えるのですか。なぜ気にする必要があるのですか。」もし本当にそのように考えるのであれば、私から言えることはもうありません。幸運を祈るだけです。しかし、チャート上のオブジェクトを扱うアプリケーションを使用する際に、最高の体験を得たいと本当に考えているのであれば、このテーマは非常に興味深いものになるでしょう。この問題は発見するのが難しいものではありません。むしろ、非常にはっきりと現れます。そして、この問題がどのように発生するのかを実際に確認したいのであれば、私が以前公開したコードを使用するだけで十分です。当時の私は、MetaTrader 5が特定の状況をどのように処理しているのか理解していませんでした。しかし、これから私たちがおこなおうとしていることにおいては、MetaTrader 5がいくつかの状況をどのように処理するのかを理解することが非常に重要になります。
たとえば、チャート全体を覆う画像を追加するとします。その結果、画面上には壁紙のようなものが表示されます。 これは、現在表示されているシンボルを素早く識別するための方法として利用できます。さらに、チャート上で画像を使用すれば、単色の背景よりもはるかに魅力的に見えます。簡単に言えば、好みというものに正解はありません。悪くても、単に自分の選択を後悔するだけです。さて、すべて問題ありません。チャート上へオブジェクトを直接配置することで実現できます。または、この目的専用のアプリケーションを使用することもできます。前者の場合、いくつかの要素を制御することはできません。しかし後者の場合、プロセス全体を完全に制御できます。
さて、すべて問題ありません。私の記事を継続的に読んでいる方なら覚えているかと思いますが、これまで説明してきた内容の中で、ある時点でC_DrawImageというクラスを作成しました。このクラスの目的は、ビットマップ画像を内容として持つオブジェクトを配置できるようにすることでした。少なくとも現時点ではそうです。なぜなら、まだほかの画像形式を扱う方法については説明していないからです。しかし、ここで重要なのは画像形式の話ではありません。別の事実が重要になります。つまり、これまで紹介してきたコード全体を利用することで、以下に示すファイルを作成できます。
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. #property description "This indicator allows you to add" 04. #property description "a wallpaper to the chart." 05. #property version "1.00" 06. #property indicator_chart_window 07. #property indicator_plots 0 08. //+------------------------------------------------------------------+ 09. #include <Market Replay\Auxiliar\C_DrawImage.mqh> 10. //+------------------------------------------------------------------+ 11. input string user00 = "WallPaper_1"; //WallPaper 12. input uchar user01 = 60; //Transparency 13. //+------------------------------------------------------------------+ 14. C_DrawImage *Draw; 15. C_Terminal *Terminal; 16. //+------------------------------------------------------------------+ 17. int OnInit() 18. { 19. Terminal = new C_Terminal(); 20. if (!Terminal.IndicatorCheckPass("Indicator WallPaper")) return INIT_FAILED; 21. Draw = new C_DrawImage(Terminal, "WallPaper", 0, "WallPapers\\" + user00 + ".bmp", NULL); 22. 23. return INIT_SUCCEEDED; 24. } 25. //+------------------------------------------------------------------+ 26. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 27. { 28. return rates_total; 29. } 30. //+------------------------------------------------------------------+ 31. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) 32. { 33. switch (id) 34. { 35. case CHARTEVENT_CHART_CHANGE: 36. (*Terminal).DispatchMessage(id, lparam, dparam, sparam); 37. (*Draw).Paint(0, 0, (*Terminal).GetInfoTerminal().Width, (*Terminal).GetInfoTerminal().Height, user01, 0); 38. break; 39. } 40. ChartRedraw((*Terminal).GetInfoTerminal().ID); 41. } 42. //+------------------------------------------------------------------+ 43. void OnDeinit(const int reason) 44. { 45. delete Draw; 46. delete Terminal; 47. } 48. //+------------------------------------------------------------------+
Wallpaper.mq5のソースコード
これは単なるインジケータです。しかし、このファイルは実際には何をしているのでしょうか。答えは簡単です。この小さく控えめなファイルは、実は以前の記事で作成した別のファイルを更新したものです。先ほど説明したように、その当時の私はMetaTrader 5について、いくつか理解していなかったことがありました。
この作業の動機や、全体的なアイデアについてより詳しい情報を知りたい方は、記事「チャートをより面白くする:背景の追加」をご覧ください。コードを比較してみると、完全に異なっていることが分かります。そして、確かに異なっています。しかし、皆さんが想像するほど大きな違いではありません。この記事で紹介したコードには、非常に簡単に解決できる問題が存在していました。このコードをコンパイルし、MetaTrader 5のアプリケーションとしてチャートへ読み込むと、チャート上に背景画像が表示されます。実際には、その画像は背景として機能するはずでした。
しかし、コードをよく見ると分かるように、時間足を変更した場合、実際には正確にそのような動作にはなりません。MetaTrader 5に対して、バー(ローソク足)が前面に表示されるよう指定したとしても、この壁紙画像は依然としてバーを覆ってしまい、場合によってはチャートを完全に隠してしまう可能性があります。しかし、問題はさらに悪化します。そこで作成されたオブジェクトは、ここで紹介している更新版コードとは異なり、クリックイベントを受け取るための優先度が初期状態のままになっています。
では、何が問題なのでしょうか。チャート上に存在するオブジェクトが少なく、それぞれが互いに分離している場合には問題ありません。しかし、チャート全体を覆う壁紙のようなオブジェクトを配置した場合はどうでしょうか。さらに、そのオブジェクトが、チャート上に存在するほかのオブジェクトと同じイベント受信優先度を持っていた場合はどうなるでしょうか。状況は少し複雑になりますよね。なぜなら、その場合MetaTrader 5は、どのオブジェクトへイベントを送信すべきなのか判断できなくなるからです。
ここで次のことを考えてください。現在、チャート上にはすでにいくつかの必要なオブジェクトがあります。それらは、マウスインジケータとChart Tradeインジケータによって作成されています。しかし、マウスインジケータのオブジェクトの優先度は-1に設定されています。一方、Chart Tradeインジケータのオブジェクトの優先度は0です。つまり、マウスインジケータで作成されたオブジェクトへクリックイベントを送ろうとしても、マウスポインタがChart Tradeパネル上のオブジェクトの上にある場合、そのイベントを受け取ることはできません。この問題については、Chart Tradeパネルを実装した際にすでに確認しています。ただし、読者の皆さんがその内容をまだ覚えているかどうかは分かりません。
そして今、新たな複雑化する要素が登場します。私たちは、さらに多くのオブジェクトをチャート上へ作成し、配置することになります。なぜなら、注文およびポジション表示インジケーターを作成するからです。しかし、ここで同じ疑問が残ります。OrderインジケータとPositionインジケータでオブジェクトを作成するとき、どうすればよいのでしょうか。それらがChart Tradeパネルと同じイベント受信優先度を持っていた場合、1つのオブジェクトが別のオブジェクトと重なった際に問題が発生する可能性があります。
皆さんはこう考えるかもしれません。「でも、それは簡単でしょう。前面にあるオブジェクトが優先されるはずです。」はい、その通りです。しかし、もう一度聞きます。どのオブジェクトについて話しているのでしょうか。なぜなら、2つのオブジェクトが同じ優先度で作成され、さらに同じ位置に存在する場合、MetaTrader 5はそれらを配置された順番で描画するからです。つまり、最後に配置されたオブジェクトが、それ以前に作成されたオブジェクトを覆います。しかし、そこが問題なのではありません。本当の問題は、チャートの再描画が必要になるイベントが発生した場合、たとえば、時間足を変更した場合です。その瞬間、オブジェクトが作成された順序が以前とは異なるものになる可能性があります。これにより、すべての管理が非常に困難になります。もし、すべてのオブジェクトが1つのアプリケーションによって作成されているのであれば、この問題は解決できます。しかし、私たちはすべてを1つの巨大なファイルへ集中させる方法を選択しませんでした。そのため、オブジェクトがどのように作成されるのかについて、もう少し制御する必要があります。
最終的な考察
単純に「これからイベントが急速かつ無秩序に展開される」と期待していた方にとって、今回の記事は少し厳しい現実を示すものだったかもしれません。ここでは、注文システムを実装する際に進む方向性について、最初の設計を始めました。まず第一に、システムと対話するために、何らかのインジケータを作成する必要があります。第二に、作成、あるいは正確には実装は、無秩序におこなってはいけません。もしそうしてしまうと、チャート上に存在するオブジェクトを完全に制御できなくなる可能性があります。第三に、これから実装するインジケータは、さらに多くのオブジェクトをチャートへ追加します。そのため、発生する可能性のある相互作用の失敗を避ける方法を見つける必要があります。なぜなら、2つのオブジェクトが同じ場所に存在する場合、片方が覆われていたとしても、単に優先度が高いという理由だけでイベントを受け取る可能性があるからです。
しかし、チャート上で複数の注文やポジションを扱うようになった際に、私は問題を発生させたくありません。なぜなら、実装方法を誤ると、本来維持したかったポジションを決済してしまったり、逆に決済したかったポジションを維持してしまったりする可能性があるからです。私は、このような失敗をどのように防ぐのかを皆さんに示したいと思います。そのため、読者の皆さんには、本当に学ぶ意欲を持っていただきたいと思います。なぜなら、リプレイ/シミュレーションシステムが完成するまでに、これから多くの新しいことを学ぶことになるからです。
| ファイル | 説明 |
|---|---|
| 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 | グラフィカルコントロールとユーザーとの相互作用を実現する(リプレイシステムと実市場での運用の両方に必要) |
| Indicators\Order Indicator.mq5 | 市場における注文の表示、それらとのやり取りや管理を担当する |
| Indicators\Position View.mq5 | 市場におけるポジションの表示、それらとのやり取りや管理を担当する |
| Services\Market Replay.mq5 | 市場リプレイ/シミュレーションサービス(システム全体のメインファイル)を作成および維持する |
MetaQuotes Ltdによりポルトガル語から翻訳されました。
元の記事: https://www.mql5.com/pt/articles/13133
警告: これらの資料についてのすべての権利はMetaQuotes Ltd.が保有しています。これらの資料の全部または一部の複製や再プリントは禁じられています。
この記事はサイトのユーザーによって執筆されたものであり、著者の個人的な見解を反映しています。MetaQuotes Ltdは、提示された情報の正確性や、記載されているソリューション、戦略、または推奨事項の使用によって生じたいかなる結果についても責任を負いません。
初級から中級まで:オブジェクトイベント(III)
エラー 146 (「トレードコンテキスト ビジー」) と、その対処方法
MQL5カスタムシンボル:3Dバー用シンボルの作成
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索