一からの取引エキスパートアドバイザーの開発(第29部):おしゃべりプラットフォーム
はじめに
エキスパートアドバイザー(EA)をもっと楽しくしたらどうでしょうか。金融市場の取引は退屈で単調すぎることがよくありますが、私たちはこの仕事の疲れを軽減することができます。依存症などの問題を経験している方にとってはこのプロジェクトは危険な場合があるのでご注意ください。ただし、一般的には、それは退屈を軽減するだけです。
警告:非常に大きな損失のリスクがあるため、市場をギャンブルと見なしている方はこの記事に記載されている変更を使用しないでください。
上記の警告は冗談のように聞こえますが、実際に、EAにいくつかの変更を加えると、一般的にギャンブル中毒者にとって危険になります。
ここでおこなわれる変更のいくつかは、EAの全体的な安定性とパフォーマンスを改善することを目的としています。この記事で削除したものを部分的に保持したい場合は、難しくありません。作成され、EAに存在する発注システムのおかげで、ダメージを与えることなくいくつかのものを削除できます。したがって、何かを受け入れて使用するか、それらを削除するかはあなた次第です。
2.0.Chart Tradeの削除
Chart Tradeは、EAで使用されているものほど複雑ではない単純な発注システムでも意味をなすものです。しかし、開発の現在の段階にある私たちのEAでは、Chart Tradeをチャートで使う意味がないため、削除できます。1つのコマンドを編集するだけで、必要に応じて保持できます。確かに、私は物事を単純に保つのが好きです。そうすれば、後で非常に迅速に変更できる(または変更しない)ため、変更による問題や重要な点での壊滅的な障害などのストレスが発生しなくなります。
コントロールを非常に高速にすると同時に安全にするために、次の定義がEAコードに追加されました。
#define def_INTEGRATION_CHART_TRADER // Chart trader integration with the EA ...
この定義が存在しないかコメントアウトされると、Chart TradeはEAでコンパイルされません。この定義によって影響を受ける点を見てみましょう。最初の最も明白なものには、次のものが含まれます。
#ifdef def_INTEGRATION_CHART_TRADER #include <NanoEA-SIMD\SubWindow\C_TemplateChart.mqh> #endif
上記のコードはEAファイルではなく、C_IndicatorTradeView.mqhファイルにありますが、定義はコードのどこでもコンパイラに表示されるため、コードの修正について心配する必要はありません。ここでは、簡単にアクセスできる場所(この場合はEAコード)に定義を作成し、必要に応じて使用します。
C_IndicatorTradeView.mqhファイルを続けましょう。Chart TradeなしでEAをコンパイルできるため、EA初期化メッセージボックスで定義されたデータへのアクセスを実装する必要があります。これは下の画像で確認できます。
このデータにアクセスする必要があることを忘れないでください。以前はChart Tradeに渡し、それらを知る必要がある場合はChart Tradeに聞きました。しかし、Chart Tradeがなくなった今、同じデータにアクセスするには別の方法を取らなければなりません。
C_IndicatorTradeView.mqhファイルでは、これらの値は、未決注文が配置される場所を示す指標0を作成するときに1つの場所でのみ使用されます。この場所はDispatchMessage関数内にあります。以下のコードに示します。
// ... Previous code ... case CHARTEVENT_MOUSE_MOVE: Mouse.GetPositionDP(dt, price); mKeys = Mouse.GetButtonStatus(); bEClick = (mKeys & 0x01) == 0x01; //Left mouse click bKeyBuy = (mKeys & 0x04) == 0x04; //SHIFT pressed bKeySell = (mKeys & 0x08) == 0x08; //CTRL pressed if (bKeyBuy != bKeySell) { if (!bMounting) { #ifdef def_INTEGRATION_CHART_TRADER m_Selection.bIsDayTrade = Chart.GetBaseFinance(m_Selection.vol, valueTp, valueSl); #else m_Selection.vol = EA_user20 * Terminal.GetVolumeMinimal(); valueTp = EA_user21; valueSl = EA_user22; m_Selection.bIsDayTrade = EA_user23; #endif valueTp = Terminal.AdjustPrice(valueTp * Terminal.GetAdjustToTrade() / m_Selection.vol); valueSl = Terminal.AdjustPrice(valueSl * Terminal.GetAdjustToTrade() / m_Selection.vol); m_Selection.it = IT_PENDING; m_Selection.pr = price; } // ... The rest of the code...
強調表示された行に注意してください。これらのEA_userXX値をファイル内で検索する必要はありません。次のようにEAコードから来ているため、そこにはありません。
#ifdef def_INTEGRATION_CHART_TRADER input group "Chart Trader" #else input group "Base Operacional do EA" #endif input int EA_user20 = 1; //Levering factor input double EA_user21 = 100; //Take Profit (financial) input double EA_user22 = 81.74; //Stop Loss (financial) input bool EA_user23 = true; //Day Trade ?
これだけでも、チャート上にChart Tradeがあるのと同様のコントロールがすでに提供されています。実質的にコードでは何も変更していません。ユーザーが定義した必要なデータを正しい場所に移動するだけです。EAを読み込むときにトレーダー側でこの構成が不要であることに気付いた方もいらっしゃるかもしれません。発注システムではすべての変数を問題なく構成できるため、これはある意味では真実です。したがって、レバレッジファクターとストップロスとテイクプロフィットの最小値を0に設定し、初期操作をデイトレードとして設定するだけです。これは、C_IndicatorTradeViewクラスのDispatchMessage関数でおこないます。トレーダーはチャートで注文を変更してサーバーに送信できるため、システムにはまったく影響がありません。この種の変更は非常に個人的なものであるため、あなた次第です。
2.0.1.いくつかの調整
Chart Tradeを削除する部分に戻る前に、EA全体の安定性を向上させるためにもう1つ何かをする必要があります。
次をおこないましょう。C_IndicatorTradeViewクラスで、以下に示すprivateデータ構造体を定義します。
struct st01 { bool ExistOpenPosition, SystemInitilized; }m_InfoSystem;
次のコードで初期化する必要があります。
void Initilize(void) { static int ot = 0, pt = 0; m_InfoSystem.ExistOpenPosition = false; m_InfoSystem.SystemInitilized = false; ChartSetInteger(Terminal.Get_ID(), CHART_SHOW_TRADE_LEVELS, false); ChartSetInteger(Terminal.Get_ID(), CHART_DRAG_TRADE_LEVELS, false); if ((ot != OrdersTotal()) || (pt != PositionsTotal())) { ObjectsDeleteAll(Terminal.Get_ID(), def_NameObjectsTrade); ChartRedraw(); for (int c0 = ot = OrdersTotal(); c0 >= 0; c0--) IndicatorAdd(OrderGetTicket(c0)); for (int c0 = pt = PositionsTotal(); c0 >= 0; c0--) IndicatorAdd(PositionGetTicket(c0)); } m_InfoSystem.SystemInitilized = true; }
ここでこのデータを作成して初期化するのはなぜでしょうか。MetaTrader 5はイベントをEAに送信し、イベントの1つがOnTickであることを思い出してください。シンプルなシステムには多くの問題はありませんが、システムが複雑になるにつれて、すべてが機能することを確認する必要があります。EAがこれらのイベントを処理する準備が整う前に、MetaTrader 5がイベントをEAに送信する可能性があるため、EAの準備ができていることを確認する必要があります。EAの準備状態を示すいくつかの変数を作成します。まだ準備が整っていない場合、EAがイベントに適切に応答できるようになるまで、MetaTrader 5のイベントを無視します。
最も重要な点は次のコードで確認できます。
inline double SecureChannelPosition(void) { static int nPositions = 0; double Res = 0; ulong ticket; int iPos = PositionsTotal(); if (!m_InfoSystem.SystemInitilized) return 0; if ((iPos != nPositions) || (m_InfoSystem.ExistOpenPosition)) { m_InfoSystem.ExistOpenPosition = false; for (int i0 = iPos - 1; i0 >= 0; i0--) if (PositionGetSymbol(i0) == Terminal.GetSymbol()) { m_InfoSystem.ExistOpenPosition = true; ticket = PositionGetInteger(POSITION_TICKET); if (iPos != nPositions) IndicatorAdd(ticket); SetTextValue(ticket, IT_RESULT, PositionGetDouble(POSITION_VOLUME), Res += PositionGetDouble(POSITION_PROFIT), PositionGetDouble(POSITION_PRICE_OPEN)); } nPositions = iPos; } return Res; };
以前は強調表示された点が存在しなかったため、奇妙なことが起こる場合がありましたが、異常が見過ごされないようにするために必要な確認がおこなわれるようになりました。
複数の確認をおこなうとシステムが非常に安定しますが、コードのメンテナンスと変更も複雑になる可能性があるため、すべてを確認するというこの問題は非常に複雑です。一部の確認は、実際に有効にするには論理的な順序で実行する必要がありますが、これにはかなりコストがかかります。
ただし、EAによって監視されている銘柄のポジションがあるかどうかを確認するときは、アジリティを与えることができます。EAに表示される特定の数のポジションを持つ複数の資産を取引する場合はなおさらです。ここでこれをフィルタリングすることにより、ループを排除し、本当に必要なときにのみEAがループ内のコードを実行するようにします。それ以外の場合は、EAが消費する処理時間を少し短縮します。長くはありませんが、非常に極端な場合には、大きな違いが生じる可能性があります。
2.0.2.EAからのChart Tradeの削除
C_IndicatorTradeViewクラスに変更を加えたので、EAコードに注目してそこからChart Tradeを削除できます。最初におこなうことは、OnInitコードから削除することです。
int OnInit() { Terminal.Init(); #ifdef def_INTEGRATION_WITH_EA WallPaper.Init(user10, user12, user11); VolumeAtPrice.Init(user32, user33, user30, user31); TimesAndTrade.Init(user41); EventSetTimer(1); #endif Mouse.Init(user50, user51, user52); #ifdef def_INTEGRATION_CHART_TRADER static string memSzUser01 = ""; if (memSzUser01 != user01) { Chart.ClearTemplateChart(); Chart.AddThese(memSzUser01 = user01); } Chart.InitilizeChartTrade(EA_user20 * Terminal.GetVolumeMinimal(), EA_user21, EA_user22, EA_user23); TradeView.Initilize(); OnTrade(); #else TradeView.Initilize(); #endif return INIT_SUCCEEDED; }
緑のコードは青のコードに置き換えられます。Chart Tradeを使用しない場合、違いは小さく、実行ファイルサイズの変更にすぎないように見えるかもしれませんが、それだけではありません。Chart Tradeコードに加えて、OnTradeイベントも削除されていることに注意してください。EAはこのイベントを処理しなくなります。
私に何か問題があると思うかもしれません。EAからOnTradeイベントを削除するにはどうすればよいでしょうか。取引イベントをどのように処理しますか。これらのイベントは、OnTradeTransactionイベントによって処理されます。処理方法はOnTradeよりも効率的になります。つまり、EAはよりシンプルで信頼性が高くなります。
変更がおこなわれている別の瞬間があります。
void OnChartEvent(const int id, const long &lparam, const double &dparam, const string &sparam) { Mouse.DispatchMessage(id, lparam, dparam, sparam); #ifdef def_INTEGRATION_WITH_EA switch (id) { case CHARTEVENT_CHART_CHANGE: Terminal.Resize(); WallPaper.Resize(); TimesAndTrade.Resize(); break; } VolumeAtPrice.DispatchMessage(id, sparam); #endif #ifdef def_INTEGRATION_CHART_TRADER Chart.DispatchMessage(id, lparam, dparam, sparam); #endif TradeView.DispatchMessage(id, lparam, dparam, sparam); }
EA内に統合がない場合、コンパイルされる唯一の行は強調表示された行になります。これらのイベントはかなり一定である傾向があるため(これらのイベントの処理が効率的であるほど良い)、EAが処理するためにMetaTrader 5がトリガーする別のイベントと競合することがよくあります。この他のイベントを以下に示します。
void OnTick() { #ifdef def_INTEGRATION_CHART_TRADER Chart.DispatchMessage(CHARTEVENT_CHART_CHANGE, 0, TradeView.SecureChannelPosition(), C_Chart_IDE::szMsgIDE[C_Chart_IDE::eRESULT]); #else TradeView.SecureChannelPosition(); #endif #ifdef def_INTEGRATION_WITH_EA TimesAndTrade.Update(); #endif }
通常、このようなイベントは複数回呼び出され、場合によっては1秒未満で複数回呼び出される可能性があるため、非常に悪夢です。しかし、C_IndicatorTradeViewクラスのコードに加えられた変更のおかげで、このイベントの処理は少し効率的になりました。後でこの効率をさらに改善しますが、今のところはこれで十分です。
さて、これらすべての変更の後、Chart TradeはEAに統合されません。Chart Tradeを指標に変えることができます。これにより、EA操作をメインのアクティビティ(発注システムの処理、ポジショニング、サポート)に集中させながら、いくつかの利点が得られます。しかし、Chart Tradeを指標に移動するには、いくつかの追加の変更が必要なので、今はその方法を示しません。後でやります。しかし、一般的には、Chart Tradeを指標に移動し、それでも注文を送信することができます。
3.0.音声の追加
多くの場合、私たちはチャートを見ませんが、現時点で何が起こっているかを知りたいと思っています。何かについて通知を受け取る方法の1つは、音声アラートを受信することです。これはすぐに注意を引くため、最高のアラートタイプの1つです。アラートを聞くだけで、他のメッセージを確認する必要がなく、なにをするべきかがすでに分かる場合があります。
それでは、基本的な音声アラートの設定方法を学びましょう。場合によっては、これは特定の何かを伝える文になります。私が今示しているものと添付ファイルで利用できるものは基本的な機能しか提供していませんが、メッセージを読む時間を無駄にする必要がないように、既存のアラートと警告の量を増やす動機になるかもしれません。音声は、特定の取引の瞬間に敏捷性を高める特定のイベントを示すことができます。私を信じてください、これは多くの違いをもたらします。
最初におこなうことは、新しいクラスを含み、音声システムをサポートおよび分離する新しいファイルを作成することです。これが完了すると、非常に安定した方法で生産を開始できます。クラス全体は、以下のコードで確認できます。
class C_Sounds { protected: enum eTypeSound {TRADE_ALLOWED, OPERATION_BEGIN, OPERATION_END}; public : //+------------------------------------------------------------------+ inline bool PlayAlert(const int arg) { return PlaySound(StringFormat("NanoEA-SIMD\\RET_CODE\\%d.wav", arg)); } //+------------------------------------------------------------------+ inline bool PlayAlert(const eTypeSound arg) { string str1; switch (arg) { case TRADE_ALLOWED : str1 = def_Sound00; break; case OPERATION_BEGIN : str1 = def_Sound01; break; case OPERATION_END : str1 = def_Sound02; break; default : return false; } PlaySound("::" + str1); return true; } //+------------------------------------------------------------------+ };
このコードは非常に単純ですが、興味深い点があります。PlayAlert関数を書き換えていることに注意してください。そのため、同じ関数の2つのバージョンがあります。何のためにでしょう。音声システムが機能する方法には、2つのバリエーションが必要です。関数の最初のバージョンではファイルから音声を再生します。2番目のバージョンではEA関数の一部である音声を再生します。多くの方はオーディオファイルから直接音声を再生する方法をご存じでないかもしれませんが、心配無用です。その方法も紹介します。最初のバージョンの理由は、自分の声やその他の音をアラートとして入れて、EAを再コンパイルせずにいつでも変更したいという人もいるからです。実際、EAがMetaTrader 5で実行されている場合でも、これらの音声を変更できます。音声を再生する必要がある瞬間から、EAは最新バージョンを使用するため、1つのオーディオファイルを別のオーディオファイルに置き換えるだけで済みます。EAは違いにも気付かないため、これは非常に役立ちます。しかし、EAコードからわかる別の理由があります。
実際、最初のオプションはかなり特定の場所で使用されています。これは、以下で強調表示されているクラスコードで確認できます。
class C_Router { protected: private : MqlTradeRequest TradeRequest; MqlTradeResult TradeResult; //+------------------------------------------------------------------+ inline bool Send(void) { if (!OrderSend(TradeRequest, TradeResult)) { if (!Sound.PlayAlert(TradeResult.retcode))Terminal.MsgError(C_Terminal::FAILED_ORDER, StringFormat("Error Number: %d", TradeResult.retcode)); return false; } return true; } // ... The rest of the class code....
取引サーバーから返される可能性のあるすべてのエラーを処理するために必要な作業量を想像してみてください。しかし、音声ファイルを録音し、取引サーバーが返す値に従って名前を付けると、EAはどちらのファイルを再生するかを認識し、作業が大幅に簡素化されます。ここでは、サーバーから返された値に基づいて使用するファイルを指定するだけでよいため、EAはこのファイルを見つけて再生し、音声警告または音声メッセージを提供して、何が起こったのかを正確に把握できるようにします。素晴らしいでしょう。たとえば、注文が拒否された場合、プラットフォームは何が起こったのか何が問題なのかを非常に明確な方法で知らせてくれます。これは、あなたに特有のもの、つまりあなたが市場でどう取引して行動するかに排他的でユニークなものを表す非常に適切な方法でおこなわれます。同じ音声ファイルで問題の解決方法を明確にできるため、どの程度の敏捷性が得られるかを確認してください。
ただし、音声が実行可能なEAファイル内に保存される2番目の操作モードもあります。これは同じ関数の2番目のバージョンであり、この段階では3つの異なる場所で3つの異なるタイプのイベントを示すために使用されます。最初の場所は、以下のコードで確認できます。
int OnInit() { if (!TerminalInfoInteger(TERMINAL_TRADE_ALLOWED)) { Sound.PlayAlert(C_Sounds::TRADE_ALLOWED); return INIT_FAILED; } Terminal.Init(); // ... The rest of the code...
このコードは、プラットフォームでアルゴリズム取引が有効になっているかどうかを確認します。有効にされていない場合、EAは取引に利用できないことを通知します。オプションが有効になっているかどうかを確認するには、次の図に示すように、プラットフォームでマーカーを見てください。
補助音を使用する2番目の場所を以下に示します。
void CreateIndicator(ulong ticket, eIndicatorTrade it) { string sz0; switch (it) { case IT_TAKE : macroCreateIndicator(it, clrForestGreen, clrDarkGreen, clrNONE); break; case IT_STOP : macroCreateIndicator(it, clrFireBrick, clrMaroon, clrNONE); break; case IT_PENDING: macroCreateIndicator(it, clrCornflowerBlue, clrDarkGoldenrod, def_ColorVolumeEdit); m_BtnCheck.Create(ticket, sz0 = macroMountName(ticket, it, EV_CHECK), def_BtnCheckEnabled, def_BtnCheckDisabled); m_BtnCheck.SetStateButton(sz0, true); macroInfoBase(IT_PENDING); break; case IT_RESULT : macroCreateIndicator(it, clrSlateBlue, clrSlateBlue, def_ColorVolumeResult); macroInfoBase(IT_RESULT); Sound.PlayAlert(C_Sounds::OPERATION_BEGIN); m_InfoSystem.ExistOpenPosition = true; break; } m_BtnClose.Create(ticket, macroMountName(ticket, it, EV_CLOSE), def_BtnClose); }
ポジション指標が作成されるたびに、音声が再生されます。これにより、未決注文がポジションになり、注意を払う必要があることがわかるので、ずっと楽になります。
補助音が鳴る3番目の最後の点は、何らかの理由でポジションが決済されたときです。これは非常に特定の場所でおこなわれます。
inline void RemoveIndicator(ulong ticket, eIndicatorTrade it = IT_NULL) { ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, false); if ((it == IT_NULL) || (it == IT_PENDING) || (it == IT_RESULT)) { if (macroGetPrice(ticket, IT_RESULT, EV_LINE) > 0) Sound.PlayAlert(C_Sounds::OPERATION_END); ObjectsDeleteAll(Terminal.Get_ID(), StringFormat("%s%c%llu%c", def_NameObjectsTrade, def_SeparatorInfo, ticket, (ticket > 1 ? '*' : def_SeparatorInfo))); } else ObjectsDeleteAll(Terminal.Get_ID(), StringFormat("%s%c%llu%c%c", def_NameObjectsTrade, def_SeparatorInfo, ticket, def_SeparatorInfo, (char)it)); ChartSetInteger(Terminal.Get_ID(), CHART_EVENT_OBJECT_DELETE, true); m_Selection.ticket = 0; Mouse.Show(); ChartRedraw(); }
EAを削除するとポジション決済音が鳴ると思われるかもしれませんが、そうではありません。価格ラインはシステムにまだ存在するため、これは発生しません。しかし、ポジションが決済されると、何か別のことが起こり、ポジションの価格ラインは価格レベル0になります。この時点で、ポジションが決済されたことを示す音が再生されます。
EAのリソースであるこれらの音声は、コードを再コンパイルしないと変更できないためより制限されますが、同時に、実行可能ファイルがどこに行こうとも付いていくため、EAを別の場所に移動するときにオーディオファイルを一緒に移動しなくてすむので、役立ちます。
しかし、障害やエラーを警告するために使用される音声の場合は、ロジックが異なります。必要なときに機能するように、これらは別々に移動して所定の場所に配置する必要があります。
添付ファイルには、SOUNDSというフォルダが含まれています。このフォルダに含まれる音声は再生されないため、このフォルダをコードと同じフォルダに置かないでください。簡単に見つけられる別の場所に移動します。どこにあるかわからなくても、心配しないでください。後で確認します。
#property copyright "Daniel Jose" //+------------------------------------------------------------------+ void OnStart() { Print(TerminalInfoString(TERMINAL_PATH)); } //+------------------------------------------------------------------+
このスクリプトを実行すると、使用する場所を示す情報がツールバーに表示されます。実行結果の例を以下の画像に示します。
次のことをおこなう必要があります。
- 添付ファイルを開きます。
- ファイルエクスプローラーを開きます。
- 上の図に示されているフォルダに移動します。
- SOUNDSフォルダの内容を添付ファイルから上記のフォルダにコピーします。
- これら3つのファイル(WARRING、BEGIN、END)はEAと共にコンパイルされるため、必要に応じて削除できます。
- 必要に応じて、.WAVの内容を好きなものに変更できます。名前を変更しないように注意してください。
- MetaTrader 5プラットフォームでEAを使用します。
結論
この記事では、カスタム音声をEAシステムに追加する方法を学びました。ここでは、これがどのようにおこなわれるかを示すために非常に単純なシステムを使用しましたが、EAだけに限定されず、指標やスクリプトでも使用できます。
素晴らしいことに、ここで提案されているのと同じ概念とアイデアを使用すると、何かについて言ったり警告したりする音声メッセージを録音できます。そして、EA、またはMetaTrader 5によって実行され、音声システムを使用するその他のプロセスが、記事に示されているトリガーを介してアクティブ化されると、すでに予見していて、しなければならないある種の行動について、伝えたり警告したりするような音のメッセージを受け取ります。
また、これはテキストではなく音声メッセージなので、システムを使用している人に何をすべきか、またはそのようなメッセージが生成された原因は何かをすばやく説明できて、はるかに効果的です。
このシステムはこのスキームに限定されず、ここで実証されたものを越えて使用できます。ユーザーがプラットフォームに味方を持つことができるようにすることが、まさにそのアイデアです。トレーダーと音声でやり取りすることで、プレーンテキストよりも理解しやすいメッセージを伝えることができます。ここであなたを制限しているのは、あなたの創造性だけです。
MetaQuotes Ltdによりポルトガル語から翻訳されました。
元の記事: https://www.mql5.com/pt/articles/10664
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索