リプレイシステムの開発(第42回):Chart Traderプロジェクト(I)
はじめに
前回の「リプレイシステムの開発(第41回):第2段階の開始(II)」では、マウスで使用する指標の作成方法を紹介しました。こんなことはナンセンスで、長い目で見れば何の意味もないと思う読者もいるかもしれません。もしそうだとしたら、それはその読者が何が起こっているのか理解できなかったからに他なりません。
何か新しいものを作成するたびに、一連のテストを実施し、あるプログラムやプロセスが他のものと共存できるように条件を整えなければなりません。この条件を満たすかどうかで、あなたが自分自身をプロフェッショナルとして宣言する準備ができているかどうかが示されます。
初心者はしばしば、あるプログラムまたはプロセスが他のプログラムまたはプロセスと競合すると問題に遭遇します。その場合、奇妙なことが起こるかもしれません。初心者がこのような問題を解決するのは難しいか不可能かもしれませんが、プロならこのような状況にも対処できるはずです。
私が言いたいのは、千差万別の操作を実行できるエキスパートアドバイザー(EA)をプログラミングしたり、一連の指標やグラフィカルな要素を用意したり、マーケットで働くための多くのプログラムやプロセスを用意したりしても、それらを1つのチャート上で組み合わせようとしたときに、互いに衝突し始めたら意味がないということです。
さらに悪いことに、非常に信頼性が高く安定したプログラムを1つ作成した後、最初のプログラムの機能の一部を使用する別のプログラムを開発する必要が生じることがあり、その際に、特に他のプロセスと一緒に配置した場合に、新しいプログラムで一連のエラーや障害が発生し始めることがあります。これらの不具合のトラブルシューティングには、単純なものもあれば非常に複雑なものもあり、時間がかかることは間違いありません。
なぜこんなことを言うのかというと、すでにマウス用の指標を作成しているからです。MetaTrader 5プラットフォームには、私たちをの役に立つ様々なツールがあります。中にはもっとシンプルなものもあり、個々のニーズに合わせて改良が必要なものもあります。市場で使用する完璧なライフルと完璧な武器を手に入れるために様々なプログラムを作成することで、これをおこなうことができます。でも、考えてほしいのはこれです。完璧な武器を作ろうとするのではなく、様々な互換性のある部品やコンポーネントを作り始め、それを組み合わせることで、その都度、遭遇する事態に特化して設計された武器を作ることができるとしたらどうでしょうか。
いい解決策だと思いませんか。そして、それこそがマウス指標を作ったときにおこなったことなのです。この指標に基づいて、多くの役立つ一連の部品やコンポーネントを作り始めます。
リプレイ/シミュレーターシステムの開発に関する本連載の最初の段階から、私は、開発中のシステムと実際の市場の両方で同じようにMetaTrader 5プラットフォームを使用することがアイディアであると述べてきました。これが適切におこなわれることが重要です。ある道具を使用して訓練して戦い方を学んだ末、戦いの最中に別の道具を使用しなければならないというようなことは誰もしたくありません。リプレイやシミュレーターを使用するのは勉強になりますが、実際の口座での取引が本当の戦いです。本当の戦いでは、訓練で学び、慣れたことを使用する必要があります。
マウス指標の次に、できるだけ早く作らなければならないツールがあと2つあります。1つはシンプルで、もう1つはデータシミュレーションを扱わなければならないため、かなり複雑です。まずは簡単に慣れられるものから始めましょう。もっと複雑なものに移ったときに、すべてがどのように機能するかをよく理解しているはずです。
そのシンプルなツールがChart Tradeです。その最新版は、「一からの取引エキスパートアドバイザーの開発(第30部):指標としてのCHART TRADE?」稿で紹介されています。これからやろうとしていることに比べれば、この指標はとてもシンプルで非普遍的であるため、子供のおもちゃのように思えるでしょう。すでに作成されている指標、すなわちマウス指標とうまく共存できる新しいChart Tradeを作成しましょう。
新しいChart Trade
上記の記事で取り上げたChart Tradeが基となりますが、そのコードやテンプレートは使用しません。もっと成熟した、ニーズに合った別のものを作成します。
これから紹介する新しいコードは、よりシンプルでコンパクトになっています。つまり、変更や修正が容易になります。このアイデアは、マウス指標を使用してチャート上のあらゆる要素を移動、クリック、操作することです。そのためには、ちょっと変わったコードを書く必要があります。MetaTrader 5で見慣れ、使い慣れているものとは大きく異なるため、何がどのようにおこなわれているのかを簡単に追えるよう、すべてを少しずつ実演していきます。プログラミングというと、最初は理解できない人が多いかもしれません。
まず、Chart Tradeが最近紹介した概念を使用しているという事実から始めましょう。RADプログラミングです。RADとはRapidAapplicationDevelopment.の略です。私がこの概念を知ったのは、Windowsシステムのプログラミングを始めた何年も前のことです。アプリケーションの効率的な作成に大いに役立ち、プログラムの外観を気にする代わりに、コードに直接触れる作業に多くの時間を費やすことができます。「単一チャート上の複数指標(第06部):MetaTrader 5をRADシステムに変える (II)」稿では 、MetaTrader 5で似たようなものを使用する方法を紹介しました。
ここでも同じ概念を使用しますが、改良版としてです。正しいスタートを切りたいのであれば、前述の記事と前回の記事をお読みください。これは、これからおこなうことを理解する上でも重要です。これがその記事です。「単一チャート上の複数指標(第05部):MetaTrader 5をRADシステムにする (I)」。そこで説明されていることを理解することが非常に重要です。現在のトピックはより豊かで複雑なものになるでしょうが、この指標は将来私たちを待ち受けているものに比べれば最も簡単な部分です。
新しいテンプレートは以下の図01のようになります。
図01:RADテンプレート
図01は、Chart Tradeで実際に表示されるビューを示しています。これはChart Tradeのテンプレートであり、Chart Tradeそのものではありません。後者は、すぐ下のビデオ01で見ることができます。マウス指標との相互作用が実演されています。ビデオを見て、それがどのように機能するかに注目してください。このビデオでは、この記事で説明することがすべて明確に紹介されているので、ぜひご覧ください。
ビデオ01:デモビデオ
ビデオ01をご覧になったことを考慮して、Chart Trade指標コードを見てみましょう。しかしその前に、次のスニペットに示すように、C_Terminalクラスのコードにちょっとした追加をおこなう必要があります。
Chart Trade指標のソースコード
156. //+------------------------------------------------------------------+ 157. bool IndicatorCheckPass(const string szShortName) 158. { 159. string szTmp = szShortName + "_TMP"; 160. 161. if (_LastError != ERR_SUCCESS) return false; 162. IndicatorSetString(INDICATOR_SHORTNAME, szTmp); 163. if (ChartWindowFind(m_Infos.ID, szShortName) != -1) 164. { 165. ChartIndicatorDelete(m_Infos.ID, 0, szTmp); 166. Print("Only one instance is allowed..."); 167. 168. return false; 169. } 170. IndicatorSetString(INDICATOR_SHORTNAME, szShortName); 171. ResetLastError(); 172. 173. return true; 174. } 175. //+------------------------------------------------------------------+
C_Terminalクラスの一部
このコードは珍しいものではないかもしれません。このコードは以前にも見たことがありますが、現在はC_Terminalクラスの一部なので、このクラスを使用するすべてのクラスや指標はこのコードを利用します。このコードは、指標がチャート上に複数回配置されるのを防ぎます。これを回避する方法があり、将来的にはそれを使用することになるでしょうが、今はそんな細かいことは気にしなくて大丈夫です。このコードでは、2つの同じ指標が同時にチャートに表示されないようにしていることに留意してください。
Chart Tradeをサポートするソースクラスに進む前に、まず指標のコードを見てみましょう。クラスでの説明をより適切なものにするため、記載の順番を変えています。完全な指標コードは以下で見ることができます。
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. #property description "Base version for Chart Trade (DEMO version)" 04. #property version "1.42" 05. #property link "https://www.mql5.com/pt/articles/11652" 06. #property indicator_chart_window 07. #property indicator_plots 0 08. //+------------------------------------------------------------------+ 09. #include <Market Replay\Chart Trader\C_ChartFloatingRAD.mqh> 10. //+------------------------------------------------------------------+ 11. C_ChartFloatingRAD *chart = NULL; 12. //+------------------------------------------------------------------+ 13. int OnInit() 14. { 15. chart = new C_ChartFloatingRAD("Indicator Chart Trade", new C_Mouse("Indicator Mouse Study")); 16. if (_LastError != ERR_SUCCESS) 17. { 18. Print("Error number:", _LastError); 19. return INIT_FAILED; 20. } 21. 22. return INIT_SUCCEEDED; 23. } 24. //+------------------------------------------------------------------+ 25. int OnCalculate(const int rates_total, const int prev_calculated, const int begin, const double &price[]) 26. { 27. return rates_total; 28. } 29. //+------------------------------------------------------------------+ 30. void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) 31. { 32. (*chart).DispatchMessage(id, lparam, dparam, sparam); 33. 34. ChartRedraw(); 35. } 36. //+------------------------------------------------------------------+ 37. void OnDeinit(const int reason) 38. { 39. delete chart; 40. 41. ChartRedraw(); 42. } 43. //+------------------------------------------------------------------+
上に示したように、この指標のコードは非常にシンプルです。もちろん、もっと情報を追加して適切な説明をするつもりですが、今のところ、必要な情報はこれで十分です。
ここでおこなっているのは、07行目にデータが表示されないことを指定しているだけです。残りの作業は、チャートからの取引をサポートするクラスを使用するためのポインタを初期化し、同じポインタを破棄することです。ビデオ01でその動作を実演する予定です。
指標のコードを理解するのに難しいことはないと思います。おそらく、もう少し作業が必要なのは15行目だけですが、それも非常にシンプルです。両方のクラスを初期化するために2つのnew演算子を使用します。
文字列変数の形で渡される情報に注意してください。最初の文字列変数は、指標がチャート上にあるときにMetaTrader 5が認識する名前を指します。2番目はマウス指標の名前です。これはマウス指標コードで定義されています。より詳細な情報については、「リプレイシステムの開発(第41回):第2段階の開始(II)」をご覧ください。
Chart Trade指標のコードがいかにシンプルであるかがお分かりいただけたと思います。表示されるコードはオリジナルのコードであり、指標を真に機能させるために追加要素が加えられることを覚えておいてください。
C_ChartFloatingRADクラス
名前とは裏腹に、このクラスは主にChart Trade指標と連動するように設計されています。現在の開発段階では、ビデオ01のような動作を実現するために必要なロジックはすでにすべて含まれています。つまり、調査している場合、ウィンドウをクリックしてマウスをドラッグしても、ウィンドウを動かすことはできません。調査が実行されている場合、ウィンドウを移動することはできません。
これを達成するためには、複雑な図を作成する必要があり、ビデオの画像もすでに指標の最終的な外観を示しているように見えるかもしれません。これが本当かどうか見てみましょう。クラスコードを見てください。その全コードは以下の通りです。
C_ChartFloatingRADクラスのソースコード
01. //+------------------------------------------------------------------+ 02. #property copyright "Daniel Jose" 03. //+------------------------------------------------------------------+ 04. #include "../Auxiliar/C_Terminal.mqh" 05. #include "../Auxiliar/C_Mouse.mqh" 06. //+------------------------------------------------------------------+ 07. class C_ChartFloatingRAD : private C_Terminal 08. { 09. private : 10. struct st00 11. { 12. int x, y, cx, cy; 13. string szObj_Chart; 14. long WinHandle; 15. }m_Info; 16. //+------------------------------------------------------------------+ 17. C_Mouse *m_Mouse; 18. //+------------------------------------------------------------------+ 19. void CreateWindowRAD(int x, int y, int w, int h) 20. { 21. m_Info.szObj_Chart = (string)ObjectsTotal(GetInfoTerminal().ID); 22. ObjectCreate(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJ_CHART, 0, 0, 0); 23. ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_XDISTANCE, m_Info.x = x); 24. ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_YDISTANCE, m_Info.y = y); 25. ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_XSIZE, w); 26. ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_YSIZE, h); 27. ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_DATE_SCALE, false); 28. ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_PRICE_SCALE, false); 29. m_Info.WinHandle = ObjectGetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_CHART_ID); 30. m_Info.cx = w; 31. m_Info.cy = 26; 32. }; 33. //+------------------------------------------------------------------+ 34. inline void UpdateChartTemplate(void) 35. { 36. ChartApplyTemplate(m_Info.WinHandle, "IDE_RAD.tpl"); 37. ChartRedraw(m_Info.WinHandle); 38. } 39. //+------------------------------------------------------------------+ 40. public : 41. //+------------------------------------------------------------------+ 42. C_ChartFloatingRAD(string szShortName, C_Mouse *MousePtr) 43. :C_Terminal() 44. { 45. if (!IndicatorCheckPass(szShortName)) SetUserError(C_Terminal::ERR_Unknown); 46. m_Mouse = MousePtr; 47. CreateWindowRAD(0, 0, 170, 240); 48. UpdateChartTemplate(); 49. } 50. //+------------------------------------------------------------------+ 51. ~C_ChartFloatingRAD() 52. { 53. ObjectDelete(GetInfoTerminal().ID, m_Info.szObj_Chart); 54. delete m_Mouse; 55. } 56. //+------------------------------------------------------------------+ 57. void DispatchMessage(const int id, const long &lparam, const double &dparam, const string &sparam) 58. { 59. static int sx = -1, sy = -1; 60. int x, y, mx, my; 61. 62. switch (id) 63. { 64. case CHARTEVENT_MOUSE_MOVE: 65. if ((*m_Mouse).CheckClick(C_Mouse::eClickLeft)) 66. { 67. x = (int)lparam; 68. y = (int)dparam; 69. if ((x > m_Info.x) && (x < (m_Info.x + m_Info.cx)) && (y > m_Info.y) && (y < (m_Info.y + m_Info.cy))) 70. { 71. if (sx < 0) 72. { 73. ChartSetInteger(GetInfoTerminal().ID, CHART_MOUSE_SCROLL, false); 74. sx = x - m_Info.x; 75. sy = y - m_Info.y; 76. } 77. if ((mx = x - sx) > 0) ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_XDISTANCE, m_Info.x = mx); 78. if ((my = y - sy) > 0) ObjectSetInteger(GetInfoTerminal().ID, m_Info.szObj_Chart, OBJPROP_YDISTANCE, m_Info.y = my); 79. } 80. }else if (sx > 0) 81. { 82. ChartSetInteger(GetInfoTerminal().ID, CHART_MOUSE_SCROLL, true); 83. sx = sy = -1; 84. } 85. break; 86. } 87. } 88. //+------------------------------------------------------------------+ 89. }; 90. //+------------------------------------------------------------------+ 91.
これだけですか。オブジェクトの作成コードはどこにありますか?マウス操作は?
このシンプルな2つのコードで、ビデオ01にあるようなことができるなんて信じられません。冗談に思えますが、私は冗談を言っているのではありません。この数行で、図01のウィンドウを動画01のように動作させることができます。
このコードだけで、マウスを使用してチャートを見たり、Chart Tradeウィンドウをクリックしたりドラッグしたりできます。ウィンドウを機能的にし、アセットを表示できるようにするために、このクラスコードにさらにいくつかのことが追加されます。ボタンが機能するようになり、まだ表示されていない値を編集できるようになります。実際には、さらにいくつかの微調整が必要ですが、ここでそれらのオブジェクトが作成されるとは思わないでください。ウィンドウを機能的にするために別の方法を使用しているので、次回の記事で紹介しましょう。
しかし、まだ終わっていありません。何が起こっているのかを本当に理解するために、クラスコードの説明と、なぜその特定のコードが含まれているのかを見てみましょう。
07行目から始めます。C_ChartFloatingRADクラスはC_Terminalクラスを継承しています。継承には常に最低限の特権を与えなければならないので、継承はprivateとします。こうすれば、少なくともC_ChartFloatingRADクラスを通じては、他のコードがC_Terminalクラスにアクセスすることはありません。指標コードにはC_Terminalのクラスコードが記述されていないので、これは問題ではありません。
この点を理解したなら、コンストラクタに進むことができます。そうすることで、実行プロセスが理解しやすくなります。
コンストラクタは42行目から始まります。マウス指標を参照するには、文字列とオブジェクト(実際にはポインタ)を取ります。43行目では、C_Terminalクラスの必要な初期化をおこなっています。コンストラクタコードの45行目から、Chart Trade指標がチャート上にないことを確認するために検証コードを呼び出しています。このチェックに失敗した場合は、SetUserErrorを呼び出して、_LastError定数にそのことを示します。
以下の点に注意してください。これから説明することが理解できないと、本連載の続きがまったくわからなくなってしまいます。私の言うことには細心の注意を払ってください。
46行目では、new演算子呼び出しで渡されたポインタを格納しています。これは、Chart Trade指標のコードで発生します。この呼び出しは、指標コードの15行目にあります。46行目が実行された時点でマウス指標がチャート上に存在するかどうかは重要でありません。重要なことなので繰り返します。 46行目が実行された時点で指標が存在するかどうかは重要でありません.。
本当に重要なのは(多くの人は理解していないかもしれませんが)、Chart Trade指標コードの15行目に表示されている呼び出しで渡される名前です。C_Mouseクラスのコンストラクタに渡されるこの文字列変数が重要なのです。チャート上の指標の有無は関係ありません。
意味がないように思えるかもしれませんが、意味があるのです。それを理解するためには、前回の「リプレイシステムの開発(第41回):第2段階の開始(II)」に戻って、C_Mouseクラスのコードの169行目に注目してください。この行によってのみ、C_ChartFloatingRADクラスで示されるコードの正しい動作が保証されます。したがって、C_Mouseクラスの169行目を実行する必要があるときに、MetaTrader 5プラットフォームがマウス指標を見つけられるように、マウス指標の名前を正しく指定する必要があります。
これでもまだ分かりにくいと思われるかもしれないので、コードがどのように機能するかの説明に移りましょう。この点については、後ほど改めて明確にします。
47行目では、19行目の関数を呼び出しています。この19行目の関数は、単にチャート上にOBJ_CHARTオブジェクトを作成するプロシージャです。これだけです。しかし29行目では、このオブジェクトのIDを保存し、後で非常に特殊な方法で使用できるようにしています。この手順の残りの行を理解するのに苦労する人はいないと思います。
コンストラクタのコードに戻ると、48行目にも呼び出しがあります。この呼び出しによって、34行目に示されていることが実行されます。現時点では、36と37の2行があります。36行目は指定したテンプレートを探しますが、これはまさに図01に示したものです。37行目では、テンプレートが表示されるようにMetaTrader 5にOBJ_CHARTオブジェクトを更新させます。
そこで、Chart Tradeを紹介します。まだ機能ませんが、マウス指標とChart Trade指標の相互作用を理解するために、いくつかの「操作」をおこなうことができます。
デストラクタのコードは非常にシンプルで、あまり説明の必要はありません。メッセージ処理コードを詳しく見てみましょう。DispatchMessageプロシージャは57行目から始まります。2つの指標の相互作用はここで起こります。
基本的に、今は64行目から始まるマウス移動イベントだけを処理します。注意:これは通常の方法ではおこないません。マウスの移動イベントはまったく別の方法で処理します。ある方法でプログラミングをすることに慣れている人にとっては、これは「めちゃくちゃ」です。
よりよく理解するためには(これがこの記事で他のことを紹介しない理由でもある)、以前の「リプレイシステムの開発(第41回):第2段階の開始(II)」をご覧ください。ここでは1つではなく、同時に2つの指標を扱っているのです。これらは相互作用して調和して共存し、ユーザーはビデオ01に示されていることを実行できます。
このChart Trade指標のメッセージ処理コードでは、マウス指標について一度だけ触れます。これは65行目で言及されています。何が起きているのかを理解しようとしてください。これを理解していれば、あとは簡単です。
ここでは2つの状況が考えられます。1つ目はマウス指標がチャート上にある場合、2つ目は指標がチャート上にない場合です。指標は、C_ChartFloatingRADクラスのコンストラクタで指定した名前を持たなければならないことに注意してください。名前が異なる場合、MetaTrader 5は助けてくれず、指標がチャート上にない状況に直面することになります。この細部に注目してください。
これがはっきりし、読者がこの2つの状況を明確に認識できたら、さらに説明を始めます。
こうなると、65行目の呼び出しは、C_Mouseクラス(前回の記事)の158行目の呼び出しをおこなうことになります。Chart Trade指標のコードの15行目では、C_Mouseクラスのコンストラクタに、トランスレータとしてC_Mouseクラスを使用することを伝えています。C_Mouseクラスの158行目は163行目を呼び出し、C_ChartFloatingRADクラスの65行目で指定されたボタンがクリックされたかどうかを確認します。
C_Mouseクラスで165行目が実行された瞬間、コードはトランスレータを使用していることを理解します。次に169行目を実行し、マウス指標ハンドルをキャプチャします。この時、MetaTrader 5に助けを求めるので、提供された名前は一致しなければなりません。MetaTrader 5が参照する指標を見つけると、ハンドルは指標のバッファにアクセスするためのインデックスを受け取ります。バッファを読み取ることができれば、172行目でマウスポインタのデータが取り込まれます。バッファが読み込めなければ、この関数は失敗し、158行目の関数も失敗します。これは、C_ChartFloatingRADクラスの65行目に存在するチェックが失敗する原因になります。従って、クリックが起こらなかったという表示を受け取ることになります。
このロジックは2つの状況で機能します。
- マウスの指標がチャートから消えた場合:MetaTrader 5がそれを見つけるためには、指定されたものと同じ名前でなければならないことを覚えておいてください。
- マウス指標を使用してチャート上で調査する場合
これら2つの状況のいずれにおいても、C_ChartFloatingRADクラスの65行目はマウスクリックの失敗を示します。
この部分はわかりにくいですかもしれませんが、ご心配なく、ここからさらに面白くなります。
では、MetaTrader 5がマウス指標を見つけ、チャート上のChart Trade指標を動かしたい状況を、ビデオ01のように分析してみましょう。このことを理解するためには、以下の記事を理解する必要があります。
- リプレイシステムの開発(第37回):道を切り開く(I)
- リプレイシステムの開発(第38回):道を切り開く(II)
- リプレイシステムの開発(第39回):道を切り開く(III)
- リプレイシステムの開発(第40回):第2段階の開始(I)
- リプレイシステムの開発(第41回):第2段階の開始(II)
これらの記事の1つ1つが、これから起こることへの準備なのです。もし読んでいなかったり、内容を理解していないのであれば、もう一度読み返して、コミュニケーションがどのように起こるのかを理解することをお勧めします。簡単なことのように思えるかもしれませんが、これらの概念は、特にそのような方法を適用していない人にとっては、実際に理解するのが非常に難しくなります。
ここでお見せするのは、最も簡単な部分です。次に来ることに比べれば、幼稚園のように思えるでしょう。したがって、このコードがどのように機能するかを理解することは非常に重要です。
ある時点で、65行目のC_ChartFloatingRADの呼び出しが、181行目のC_Mouseの呼び出しに遭遇します。こうなると、C_Mouseクラスの160行目は、渡されたボタンコードをチェックします。渡されたコードと一致すれば、関数はtrueを返します。この瞬間、そしてマウスボタンが押されている間、67行目から79行目までのコードが実行されます。
このコードには小さな欠陥がありますが、このコードはデモなので、今は無視して構いません。
67行目と68行目では、なぜマウス指標ではなく、MetaTrader 5が提供する値を使用しているのでしょうか。もちろん、その方がきれいだからとか、シンプルだからという理由ではありません。指標の値ではなく、MetaTrader 5が提供する値を使用するのには理由があります。これを理解するには、C_Mouseクラスの203行目から206行目までのコードを見る必要があります。これらの行では、マウスの座標の変換と調整をおこないます。この場合、マウス座標は画面上(xとy)でなくなり、アクティブ(価格と時間)になります。
これは、ある種の問題を扱うには非常に有効ですが、それとは異なる作業が必要な場合には問題にあります。C_ChartFloatingRADクラスの67行目と68行目に、以下のようなコードを使用します:
x = (*m_Mouse).GetInfoMouse().Position.X; y = (*m_Mouse).GetInfoMouse().Position.Y;
OBJ_CHARTオブジェクトの動きを、あたかも資産座標(価格と時間)に紐付いているかのように取得します。しかし実際には、このようなオブジェクトは画面座標(x、y)を使用するため、動きはかなり奇妙で、ビデオ01のようにスムーズではありません。オブジェクトの種類によっては、マウス指標が提供する座標を使用することが望ましい場合もあります。
結論
この記事では、Chart Tradeの指標を作成する第一段階について見てきました。私たちが作成しているChart Trade指標と完全に調和してマウス指標を使用する方法を示しました。ただし、チャート上でドラッグ&ドロップする機能以外にはまだ機能がありません。
次回は、Chart Tradeの機能拡張に着手します。
MetaQuotes Ltdによりポルトガル語から翻訳されました。
元の記事: https://www.mql5.com/pt/articles/11652
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索