Deus EAの実装:MQL5におけるRSIと移動平均を使った自動売買
はじめに
この記事では、取引ロジック、パラメータ設定、実装に必要なMQL5コードなど、Deusエキスパートアドバイザー(EA)の重要な要素について解説します。この記事の目的は、読者が取引アルゴリズムを開発し、強化するために必要な知識とツールを提供することです。Deus EAを活用することで、自動売買の世界を探求し、新たな取引機会を見つけることが可能になります。
MQL5を使用して構築された自動売買手法、Deus EAの機能を検証します。このディスカッションでは、Deus EAが移動平均と相対力指数(RSI)をどのように組み合わせて取引選択をおこなうかに焦点を当てます。これらの指標を分析することで、EAはマーケットにおける最適なエントリポイントとエグジットポイントを特定し、リスクを最小限に抑えつつ取引の収益性を最大化します。
Deus EAは、移動平均と相対力指数(RSI)に基づいて売買シグナルを生成する、MetaTrader5プラットフォーム用に設計された自動売買システムです。市場のトレンドを見極め、買われすぎや売られすぎの状態を検出することで、取引判断を強化します。また、ストップロス(損切り)注文、テイクプロフィット(利食い)注文、トレーリングストップなどのリスク管理ツールも備えています。
Deus EAの概要
Deus EAは、相対力指数(RSI)や移動平均などの指標を使用して、取引決定を自動化します。このEAの目的は、これらの指標を用いて実用的な売買推奨をおこなうことで、取引パフォーマンスを向上させ、リスクを効果的に管理することです。
以下はDeus EAの主な要素です。
- 技術的対策
- 相対力指数(RSI):このモメンタムオシレーターは、価格の動きの速さを測定し、市場が買われ過ぎか売られ過ぎかを判断するのに役立ちます。これにより、市場の動きに迅速に対応することが可能です。Deus EAでは、7日間のRSIを採用し、買われ過ぎの閾値を35、売られ過ぎの閾値を15に設定しています。
- 移動平均(MA):移動平均は、一定期間のトレンドを把握するために価格データを平滑化します。Deus EAでは、25期間の単純移動平均(SMA)を用いて売買シグナルをフィルタリングし、市場の大まかな方向性を確認します。
- 買いシグナル:価格が移動平均線とRSIの上にある場合、売られすぎの状態(15以下)を示し、価格が上昇する可能性があることを示唆します。この状況下では、買い注文が出されます。
- 売りシグナル:価格が移動平均線とRSIの下にある場合、買われすぎの状態(35以上)を示し、価格が下降する可能性があることを示唆します。この状況下では、売り注文が出されます。
3. リスク管理
- ストップロスとテイクプロフィット:このEAでは、リスク管理と利益確定を助けるために、ストップロスとテイクプロフィットをそれぞれ50ポイントに設定したカスタマイズ可能なパラメータを含んでいます。
- トレーリングストップ:25ポイントのトレーリングストップを使い、相場が有利に動くにつれてストップロスレベルを調整することで、利益を確保しつつ、相場が望ましい方向に動く限り、取引の継続を目指します。
4. 注文管理
- ポジション管理:取引シグナルに基づき、新規ポジションを建てる前に既存のポジションをクローズすることで、一度に1つのポジションしかないようにします。
Deus EAには、初期化、ティック処理、ポジションのオープンとクローズ、トレーリングストップ調整の機能が備わっています。これらは、MetaTrader 5で使用されるスクリプト言語MQL5で実装されています。プログラムによって、リスク管理ガイドラインが遵守され、取引シグナルが効果的に処理されます。
Deusはこれらの機能を活用することで、取引手順の自動化、感情的な意思決定の削減、そして取引結果の改善を支援します。この記事では、Deus EAの設計思想と機能性についての基礎を提供します。
MQL5での実装
まず、取引ポジションを建てる必要があります。ポジションを建てるための専用ファイルをインクルードして、取引ポジションを建てます。
#include <Trade\Trade.mqh>
CTrade trade;
ここでは、インクルードファイルを用いて取引ライブラリを組み込みます。これにより、Deus EAは取引操作に必要な機能にアクセスできるようになります。この時点で、CTradeクラスも定義され、取引活動を行うための高いレベルの抽象化を提供します。このファイルがインクルードされていることで、EAはCTradeクラスを使用して取引を管理できます。EAを通じて、このオブジェクトはポジションのオープン、変更、クローズなど、さまざまな取引タスクを実行するために活用されます。
このセクションでは、Deus EAの重要な入力パラメータについて説明します。Deus EAは移動平均とRSI指標を用いて取引チャンスを見つける高度な取引アルゴリズムです。これらのパラメータを調整することで、トレーダーはEAを自分の独自の取引戦略やリスク許容度に最も適した形で動作させることができます。
入力パラメータは以下の通りです。
input double Lots = 0.1; // Lot size input double StopLoss = 50; // Stop loss in points input double TakeProfit = 50; // Take profit in points input double TrailingStop = 25; // Trailing stop in points
- Lots(取引量)
input double Lots = 0.1; // Lot size
各取引のサイズはLotsオプションで指定します。この例では、EAは各取引で 0.1ロットを取引するように設定されています。トレーダーはロットサイズを変えることで、市場リスクへのエクスポージャーを管理できます。ロットサイズを小さくすると、起こりうるリスクと利益の両方が低くなり、ロットサイズを大きくすると、起こりうる利益が高くなるだけでなく、リスクも高くなります。リスクと利益のバランスを取るには、適切なロットを選ぶことが不可欠です。
2. StopLoss(ポイント単位のストップロス)
input double StopLoss = 50; // Stop loss in points
取引ごとの最大許容損失はStopLossオプションによって定義され、このケースでは50ポイントに設定されています。将来の損失を阻止するため、市場がこのポイントを超えて取引に不利になると、ポジションは自動的に閉じられます。これにより、大きな損失から取引口座を守ることができます。
3. TakeProfit(ポイント単位のテイクプロフィット)
input double TakeProfit = 50; // Take profit in points
TakeProfitパラメータを使って、すべての取引の利益目標を50ポイントに設定します。利益を確保するため、市場が取引に有利な方向にこれだけシフトすると、ポジションは自動的に閉じられます。市況が反転する可能性がある場合に先回りして利益を確保できるため、収益性が高まります。
4. TrailingStop(トレーリングストップのポイント)
input double TrailingStop = 25; // Trailing stop in points
TrailingStopパラメータでストップロスを導入し、取引に有利な方向にシフトします。相場が有利な方向に振れると、最初はエントリ価格から25ポイントに設定されているトレーリングストップが調整され、利益が確定されます。この機能により、トレーダーは利益を守りながら、長引く相場変動から利益を得ることができます。
RSI指標のパラメータ:
input int RSI_Period = 7; // RSI period input double RSI_Overbought = 35.0; // RSI overbought level input double RSI_Oversold = 15.0; // RSI oversold level
5. RSI_Period(RSI算出期間)
input int RSI_Period = 7; // RSI period
相対力指数(RSI)を生成するために使用する期間数は、RSI_Periodパラメータによって指定され、この場合は7に設定されています。RSIは、値動きの速度と変動を測定するモメンタムオシレーターです。RSIは7など短い期間の直近の値動きに反応しやすく、買われすぎや売られすぎの状況を素早く見極めるのに役立ちます。
6. RSI_Overbought(RSI買われすぎレベル)
input double RSI_Overbought = 35.0;
買われすぎを判断する基準値はRSI_Overboughtパラメータで定義され、35.0に設定されています。一般的な買われすぎのレベルは70かもしれませんが、この手法では35.0でより積極的な売りポジションを示します。RSIがこの閾値を上回ると、EAは売り行動をトリガーし、相場の下方反転が迫っている可能性を示します。
7. RSI_Oversold(RSIの売られすぎレベル)
input double RSI_Oversold = 15.0; // RSI oversold level
売られ過ぎの閾値はRSI_Oversoldパラメータで定義され、その値は15.0です。このアプローチでは、買いの可能性を示すためにより保守的なレベルを採用していますが、典型的な売られすぎのレベルは30かもしれません。EAは、RSIがこの閾値を下回ると、相場反転の可能性があると判断し、買いのアクションをトリガーします。
移動平均パラメータ
input int MA_Period = 25; // Moving Average period input ENUM_MA_METHOD MA_Method = MODE_SMA; // Moving Average method input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied price for MA
8. MA_Period(移動平均期間)
input int MA_Period = 25; // Moving Average period
移動平均(MA)の計算期間はMA_Periodパラメータで決定され、その値は25です。価格データはトレンドを把握するためにMAによって平滑化されます。25期間のウィンドウを用いることで、市場の動向について包括的な視点を得ることができます。短期的なノイズを取り除くだけでなく、重要な価格変動にも対応することが可能です。
9. MA_Method(移動平均法)
Moving Average period input ENUM_MA_METHOD MA_Method = MODE_SMA; // Moving Average method
この場合に使用される移動平均のタイプである単純移動平均(SMA)は、MA_Method オプションによって指定されます。SMAは、一定期間の終値の平均を計算する単純なトレンド指標です。様々な感応度については、指数移動平均(EMA)のような代替手法を採用することもできますが、単純移動平均(SMA)は信頼できる安定したトレンド指標です。
10. MA_Price(MAに適用される価格)
input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied price for MA
移動平均の計算に使用される価格タイプは、価格PRICE_CLOSEに設定されているMA_Priceオプションによって指定されます。これは、MAが終値を使って決定されることを示しており、終値は取引セッションの終値を表すため、頻繁に採用されます。このように判断することで、MAは一般的な市場トレンドの信頼できる指標を提供することが保証されます。
Deus EAの取引動作とリスク管理は、主に入力パラメータによって決まります。トレーダーは、取引量、リスクコントロール、指標の継続時間、閾値などのパラメータを調整することで、独自の取引目的や現在の市場状況により適したEAに調整することができます。自動売買でDeus EAを十分に活用するには、これらの設定を理解し、 適切に変更することが不可欠です。
次に、移動平均とRSI指標に基づくEAの新しい変数について説明します。これらの要素を理解することで、EAがどのように取引執行を処理し、市場データを分析するかを知ることができます。
//--- Variables double rsiValue; // RSI value double maValue; // Moving Average value double Ask; double Bid; double Close; // Initializing Close array with two elements
RSIの値:
double rsiValue; // RSI value
相対力指数(RSI)の現在値はrsiValue変数に格納されます。モメンタムオシレーターとして、RSIは価格変動の速度と変動を計算することで、市場が買われすぎ、売られすぎのタイミングを判断するのに役立ちます。
価格の種類と指定されたRSI期間は、RSI値を決定するために使用されます。ユーザー定義のパラメータと最新の価格データは、Deus EAがRSIを計算するために使用します。
RSI値がRSI_Oversoldレベルを下回ると、EAはこれを買いシグナルと解釈します。このことは、市場が売られすぎ、反転上昇する可能性があることを示唆しています。
一方、RSIの値がRSI_買われすぎのレベルを上回れば、売りシグナルとなります。つまり、相場は買われすぎ、下降に転じる可能性があるということです。
移動平均の値:
double maValue; // Moving Average value
移動平均(MA)の現在値はmaValue変数に格納されます。この指標は、あらかじめ決められた時間枠の価格データを平滑化することで、トレンドの識別を容易にします。
移動平均は、手法、価格タイプ、選択した期間を使用して計算されます。指定された期間の終値は、EAでMAを計算するために使用されます。
トレンド:現在の市場トレンドはMA値によって支えられています。価格がMAの上にあるとき、EAは市場が上昇トレンドにあると考え、MAの下にあるとき、EAは市場が下降トレンドにあると考えます。
エントリシグナル:売買シグナルの生成は、RSIとMAの値の関係に依存します。例えば、直前の終値がMA値より高く、RSIがRSI_Oversoldレベル以下であれば、買いシグナルは正当と判断されます。RSIとMAの値は、Deus EAが賢明な取引判断を下すために組み合わされます。
double Ask;
資産の現在の売値はAsk変数に格納されます。これはトレーダーにとっての資産の購入価格です。OpenPosition関数で買い注文のエントリ価格を設定します。Ask価格とは、その資産を買うためにその時点で見つけることができる最大の価格です。このコストを正確に監視することで、買い注文が適切に出されることが保証されます。
double Bid;
資産の現在の買値はBid変数に記録されます。これはトレーダーにとっての資産の販売価格です。OpenPosition関数で売り注文のエントリ価格を設定します。資産を売るために得られる最良の価格がBid価格に反映されます。
double Close[];
ある期間の資産の終値は、Close配列に格納されます。このEAでは、最新の使用状況の値を保存するために拡大されています。この配列は、売買シグナルの生成と値動きの分析に使用されます。買いシグナルを出すか売りシグナルを出すかを決定するために、以前の期間の終値(Close[1])と直近の終値(Close[0])を比較します。この比較によって、価格が上昇傾向にあるのか下降傾向にあるのかを判断することができます。
void ApplyTrailingStop();
この関数は、トレーリングストップの仕組みの導入に役立ちます。現在の市場価格がポジションのストップロスより有利に動いた場合、この関数はすべてのポジションを反復処理して、ストップロスを修正します。この関数は、トレーリングストップを設定することで、市場価格が取引に不利に変化しても、ストップロスが最も有利な位置に留まることを保証します。
void OpenPosition(CTrade trade, int orderType);
このメソッドは注文タイプに基いて新しい取引ポジションを建てることを意図しています。この関数は、注文タイプに基づいて、テイクプロフィット、ストップロス、エントリ価格を決定します。取引はCTradeオブジェクトを使って計算されたパラメータを使っておこなわれます。これは、EAが市場で取引を開始するために不可欠なシグナルを生成するのに役立ちます。
void ClosePositions(int orderType);
この関数により、特定の注文タイプの取引ポジションは決済されます。すべてのポジションが反復処理され、指定された注文タイプに適合するものが、関数によってクローズされます。これにより、取引戦略や市場の状況に合わなくなったポジションを排除することができ、取引管理が強化されます。
//--- Function prototypes void ApplyTrailingStop(); void OpenPosition(CTrade trade, int orderType);
次に、これらの関数のプロトタイプを組み合わせることで、EAが効果的に取引ポジションを処理できるようにします。OpenPositionメソッドは市況に基づいて取引を開始し、ClosePositions関数は必要に応じて取引を制御し決済し、ApplyTrailingStop関数はストップロスを修正することで取引管理を改善します。これらすべての機能を組み合わせることで、EAは市場の変化に素早く反応し、効果的に取引をおこなうことができます。
次にOnInit関数に移りましょう。Deus EAはOnInit関数を使用して取引を開始します。移動平均とRSI指標に基づいて取引をおこなうことを目的としています。
//+------------------------------------------------------------------+ //| Expert initialization function . | //+------------------------------------------------------------------+ int OnInit() { Print("Deus EA initialized successfully."); return(INIT_SUCCEEDED); }
端末が起動したとき、またはEAがチャートにロードされたとき、OnInit関数が一度だけ呼び出されます。ここでは、変数の初期化、指標ハンドルの確立、その他、この関数の使用が必要な設定操作をおこないます。そして、その部分を以下のように分割します。
Print("Deus EA initialized successfully.");
このコードの目的は、初期化が正常に完了したことを確認するメッセージをEAのログに出力することです。すべてのEAに欠かせないのがロギングです。EAが問題なくロードされ、初期化されたことを確認することができます。また、デバッグの際や、EAがマーケットデータの処理と取引の実行を開始する準備ができていることを確認する際にも役立ちます。
return(INIT_SUCCEEDED); }
このreturnステートメントは、初期化プロセスが完了したことをMetaTraderプラットフォームに通知する役割を果たします。EAが次のステージに進むには、INIT_SUCCEEDEDを返す必要があります。例えば、OnTick関数は主要な取引ロジックが実行される場所です。何らかの理由で初期化に失敗した場合、この関数はINIT_FAILEDを返し、EAの動作を停止させ、動作中の潜在的な不具合を回避します。
次に、OnDeinit関数を見てみましょう。この関数は、EAの信頼性と完全性を維持するために非常に重要です。この関数の役割について説明します。EAが再コンパイルされると、チャートから削除されます。このアクションはOnDinit関数をアクティブにし、クリーンアップタスクを実行し、リソースが適切に解放され、最後のステップが完了したことを確認する機会を提供します。
//+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Print("Deus EA deinitialized. Reason: ", reason); }
初期化解除の根拠は、OnDeinit関数のreasonパラメータによって提供されます。これは、デバッグや、EAがなぜ初期化されたのかを解明するのに役立ちます。Deus EAでPrint関数を使って、この理由を記録します。
void OnDeinit(const int reason) { Print("Deus EA deinitialized. Reason: ", reason); }
EAが明示的に削除されたのか、再コンパイルされたのか、あるいは端末のシャットダウンの結果なのかは、このわかりやすいログを見れば判断できます。開発段階でもテスト段階でも有益な情報を得ることができます。
現在のOnDeinitの実装では、初期化解除の理由のみがログに記録されていますが、この関数は必要なクリーンアッププロシージャまで拡張することが可能です。たとえば、開いているリソースを閉じたり、ファイルハンドルを解放したり、現在の状態を保存する必要があるかもしれません。これによりリソースのリークを防ぎ、EAのクリーンな再初期化が適切なクリーンアップによって保証されます。これは、信頼性と安定性が重要なリアルタイムの取引状況において非常に重要です。正しいハンドリングにより、以前の実行によるパフォーマンスの問題がEAのリロードや再スタートの能力を妨げないことが保証されます。
次に、EAのリアルタイムの意思決定に不可欠なOnTick関数に移ります。新しい価格ティックを受信するたびに、この関数が呼び出され、EAに市場の状態を評価する機能を与え、事前に確立されたテクニックを使用して取引を実行します。OnTick関数の主な機能と、Deus EAのストラテジーコンポーネントをどのように 組み合わせるかを説明します。
- 市場情報の入手
OnTick関数が最初に起動するとき、それは最も多くの市場データを取得するのに役立ちます。
Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); ArrayResize(Close, 2); Close[0] = iClose(_Symbol, _Period, 0); Close[1] = iClose(_Symbol, _Period, 1);
このコードでは、直近の終値を保存し、Ask価格とBid価格を取得します。Close配列に直近の終値を格納する十分なスペースを確保するために、ArrayResizeが使用されます。
- テクニカル指標の計算
移動平均と相対力指数はアルゴリズムによって計算されます。
//--- Calculate RSI value rsiValue = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE, 0); if (rsiValue == WRONG_VALUE) { Print("Error calculating RSI"); return; } //--- Calculate Moving Average value maValue = iMA(_Symbol, _Period, MA_Period, 0, MA_Method, MA_Price, 0); if (maValue == WRONG_VALUE) { Print("Error calculating Moving Average"); return; }
MA値がトレンドの方向性を判断するのに役立つのに対して、RSI値は買われすぎ、売られすぎの状態を示します。チェックを続ける前に、数字が正確であることを確認します。
- 売買シグナルの生成:指標を計算した後、売買シグナルを探します。
//--- Check for Buy Signal if(rsiValue < RSI_Oversold && Close[1] > maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_SELL); OpenPosition(ORDER_TYPE_BUY); } } //--- Check for Sell Signal if(rsiValue > RSI_Overbought && Close[1] < maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_BUY); OpenPosition(ORDER_TYPE_SELL); } }
現在の終値が移動平均線を上回り、RSIが売られ過ぎの基準値を下回った場合、買いシグナルが出されます。この状況は、上昇反転の可能性を示唆しています。
終値が移動平均線を下回り、RSIが買われすぎの基準値を上回った場合、売りシグナルが出されます。この状況は、下降反転の可能性を示唆しています。
- トレーリングストップの適用:損失を最小限に抑え、利益を守るために、OnTick関数にはトレーリングストップを適用するロジックが組み込まれています。
//--- Apply trailing stop if specified if (TrailingStop > 0) { ApplyTrailingStop(); }
トレーリングストップパラメータが設定されている場合、このセクションはトレーリングストップ機構が確実に作動するようにします。賞金を確定するために、ApplyTrailingStop関数は、価格が希望する方向に動くとストップロスレベルを変更します。
- ポジションの開閉:OpenPosition関数は、エントリ価格、ストップロス、テイクプロフィットレベルを決定した後、ポジションを建てようとします。ポジションのクローズ:すべてのポジションはClosePositions関数によって繰り返し処理され、指定された注文タイプに対応するポジションがクローズされます。
ここでは、Deus EAがどのように動的に市況に適応するかを、OnTick関数を用いて説明します。この機能は、RSIとMA指標を使用して、取引シグナルとトレーリングストップを生成し、利益を保護します。この戦略では、EAは利益を守り、市場の変化にも対応することが保証されています。以下はOnTick関数の全コードです。
//+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); ArrayResize(Close, 2); Close[0] = iClose(_Symbol, _Period, 0); Close[1] = iClose(_Symbol, _Period, 1); //--- Calculate RSI value rsiValue = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE, 0); if (rsiValue == WRONG_VALUE) { Print("Error calculating RSI"); return; } //--- Calculate Moving Average value maValue = iMA(_Symbol, _Period, MA_Period, 0, MA_Method, MA_Price, 0); if (maValue == WRONG_VALUE) { Print("Error calculating Moving Average"); return; } //--- Check for Buy Signal if(rsiValue < RSI_Oversold && Close[1] > maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_SELL); OpenPosition(ORDER_TYPE_BUY); } } //--- Check for Sell Signal if(rsiValue > RSI_Overbought && Close[1] < maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_BUY); OpenPosition(ORDER_TYPE_SELL); } } //--- Apply trailing stop if specified if (TrailingStop > 0) { ApplyTrailingStop(); }
OnTick関数の説明は終わったので、次はEAのユーティリティ関数を自由に見てみましょう。Deus EAがRSI および移動平均指標からのシグナルに基づいて取引を実行するには、オープン関数が不可欠です。この機能により、リスク管理要因を考慮した正確な売買注文がおこなわれます。
void OpenPosition(int orderType)
出される注文のタイプは、OpenPosition関数が受け付ける唯一のパラメータであるorderTypeによって決定されます。買い注文の場合はORDER_TYPE_BUY、売り注文の場合はORDER_TYPE_SELLとなります。注文タイプによって、注文価格が決定されます。
double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid;
買い注文にはAsk価格を使い、売り注文にはBid価格を使います。
リスクをコントロールし、利益を確保するために、ストップロス(SL)とテイクプロフィット(TP)の閾値を決めます。
double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point; double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point;
買い注文の場合、テイクプロフィットは注文価格より上に、ストップロスは注文価格より下に設定されます。売り注文のテイクプロフィットとストップロスは、それぞれ注文価格の下と上に置かれます。CTrade{クラスのPositionOpen関数を使用して、実際のポジションを建てます。
bool result = trade.PositionOpen(_Symbol, orderType, Lots, price, sl, tp, "Deus EA");
このテクニックにはいくつかのパラメータが必要です。
- Symbol:EURUSDなどの取引に使用される銘柄
- orderType:注文の種類(売りまたは買い)
- Lots:注文のロットサイズ
- price:注文の買値または売値
- sI:ストップロス計算のレベル
- tp:決定されたテイクプロフィットの閾値
- Deus EA:注文に関連するステートメント
ポジションを建てようとし、その結果を確認し、必要に応じてメッセージを記録します。
if(result) { Print("Order opened successfully. Type: ", orderType, ", Price: ", price); } else { Print("Failed to open order. Error code: ", GetLastError()); } }
注文が正常に出されると、確認通知が印刷されます。注文が出せない場合、GetLastErrorを使用して問題コードを取得し、トラブルシューティングのためにそれを記録します。
ポジションを建てる関数の完全なコードは以下の通りです。
//+------------------------------------------------------------------+ //| Function to open a position | //+------------------------------------------------------------------+ void OpenPosition(int orderType) { double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid; double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point; double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point; bool result = trade.PositionOpen(_Symbol, orderType, Lots, price, sl, tp, "Deus EA"); if(result) { Print("Order opened successfully. Type: ", orderType, ", Price: ", price); } else { Print("Failed to open order. Error code: ", GetLastError()); } } )
ユーティリティ関数のひとつは終わったので、次はポジションをクローズする関数を見てみましょう。望ましくないポジションが取引戦略のパラメータによって終了されることを保証するために、Deus EAのClosePositions関数は不可欠です。特定の条件が満たされた場合、この関数は特定の種類のポジション(買いまたは売り)をクローズするためのロジックを管理するものです。この関数の操作内容と、より広範なプランにとっての意義を検証してみましょう。
void OpenPosition(int orderType)
クローズするポジションのタイプは、Closepositions関数によって取得される単一の引数orderTypeによって指定されます。ORDER_TYPE_SELLまたはORDER_TYPE_BUYが、このパラメータに指定できる値です。この関数は、この時点のすべてのポジションをループし、該当するポジションをクローズします。
for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByIndex(i)) { if(PositionGetInteger(POSITION_TYPE) == orderType) { if(!trade.PositionClose(ticket) { Print("Failed to close position. Error code: ", GetLastError()); } } } }
ループは後方に進み、最後のポイントから始まります。ポジションをシャットダウンすると、ポジション全体のカウントが減少するため、順方向の反復ループが中断される可能性があります。そのため、逆方向の反復が必要となります。PositionSelectByIndex(i)は、与えられたインデックス「i」の位置を選択するために使用されます。
この関数は、選択された場所がループ内で与えられたorderTypeと一致するかどうかを検証します。
if(PositionGetInteger(POSITION_TYPE) == orderType)
orderTypeがこの値と等しくない場合、ポジションはクローズされるべきではありません。この関数は、タイプが一致すればポジションをクローズしようとします。
if(!trade.PositionClose(ticket) { Print("Failed to close position. Error code: ", GetLastError()); } } } }
ポジションは、チケット番号trade.PositionClose(ticket)で識別しようとすることによってクローズされます。ポジションのクローズに失敗した場合は、GetLastError()で取得したエラーコードを含むエラーメッセージが出力されます。これにより、ポジションを閉じることができない原因を特定し、トラブルシューティングが容易になります。
Deus EAは、勝ちポジションが一定の利益レベルに達したときにクローズすることで、利益を確定することができます。これは、選択したポジションが特定の条件下でクローズされるようにすることで達成されます。
ポジションをクローズする関数の完全なコードは以下の通りです。
//+------------------------------------------------------------------+ //| Function to close positions | //+------------------------------------------------------------------+ void ClosePositions(int orderType) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByIndex(i)) { if(PositionGetInteger(POSITION_TYPE) == orderType) { if(!trade.PositionClose(ticket) { Print("Failed to close position. Error code: ", GetLastError()); } } } }
最後に、トレーリングストップを適用するユーティリティ関数に移りましょう。負けた取引をクローズすることで、追加の損失を止めることができます。買いポジションと売りポジションの同時保有を控える、ヘッジをおこなうなど、ガイドラインに従ってください。トレーリングストップは、市場価格がポジションに有利な方向に変動した場合に、ストップロス水準を修正します。Deus EAのApplyTrailingStopメソッドは、この機能が効果的に適用されるようにします。トレーリングストップは、潜在的な損失を制限すると同時に、相場の変動に追随して利益を確定します。では、この関数がどのように機能するのかを説明しましょう。
void ApplyTrailingStop()
これは現在の銘柄のすべてのポジションに適用されるため、ApplyTrailingStopメソッドにはパラメータは必要ありません。ClosePositions関数と同様に、この関数はすべてのポジションを反復処理することから始まります。
for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelectByIndex(i) && PositionGetSymbol() == _Symbol)
ループは後方に進み、最後の位置から始まります。
PositionSelectByIndex(i):この関数はインデックス「i」のエントリを選択します。「PositionGetSymbol()==_Symbol」を使用して、ポジションがアクティブな取引銘柄に関連付けられていることを確認します。
この関数は、トレーリングストップの距離と現在の市場価格を使用して、新しいストップレベルを決定します。
double price = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? Bid : Ask; double sl = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? price - TrailingStop * _Point : price + TrailingStop * _Point;
買いポジションのトレーリングストップはBid価格より下に設定されます。トレーリングストップは、売り取引ではAsk価格より上に位置します。そして、この関数は、それが適切かどうかを判断した後、新しいストップロスレベルを適用するためにPositionModifyを使用します。
if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && PositionGetDouble(POSITION_SL) < sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } else if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL && PositionGetDouble(POSITION_SL) > sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } }
新しいストップロスレベル(sI)が既存のストップロスを上回った場合のみ、ポジションのストップロスが変更されます。また、新しいストップロスレベルが既存のストップロスレベルより小さい場合、売りポジションのストップロスが更新されます。
位置変更に失敗した場合は、エラーコードを含むエラーメッセージが表示されます。これはトラブルシューティングに役立ち、トレーリングストップが使用されなかった理由を明確にするのに貢献します。
トレーリングストップを適用する関数の完全なコードは以下の通りです。
//+------------------------------------------------------------------+ //| Function to apply trailing stop | //+------------------------------------------------------------------+ void ApplyTrailingStop() { for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelectByIndex(i) && PositionGetSymbol() == _Symbol) { double price = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? Bid : Ask; double sl = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? price - TrailingStop * _Point : price + TrailingStop * _Point; if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && PositionGetDouble(POSITION_SL) < sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } else if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL && PositionGetDouble(POSITION_SL) > sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } }
記事の全コードは以下の通りです。
//+------------------------------------------------------------------+ //| Deus EA | //| Copyright 2024, MetaQuotes Ltd. | //| https://www.mql5.com | //+------------------------------------------------------------------+ #include <Trade\Trade.mqh> CTrade trade; //--- Input parameters input double Lots = 0.1; // Lot size input double StopLoss = 50; // Stop loss in points input double TakeProfit = 50; // Take profit in points input double TrailingStop = 25; // Trailing stop in points //--- RSI parameters input int RSI_Period = 7; // RSI period input double RSI_Overbought = 35.0; // RSI overbought level input double RSI_Oversold = 15.0; // RSI oversold level //--- Moving Average parameters input int MA_Period = 25; // Moving Average period input ENUM_MA_METHOD MA_Method = MODE_SMA; // Moving Average method input ENUM_APPLIED_PRICE MA_Price = PRICE_CLOSE; // Applied price for MA //--- Variables double rsiValue; // RSI value double maValue; // Moving Average value double Ask; double Bid; double Close[2]; // Initializing Close array with two elements //--- Function prototypes void ApplyTrailingStop(); void OpenPosition(CTrade &trade, int orderType); // Pass CTrade by reference void ClosePositions(int orderType); // pass orderType directly //+------------------------------------------------------------------+ //| Expert initialization function | //+------------------------------------------------------------------+ int OnInit() { Print("Deus EA initialized successfully."); return(INIT_SUCCEEDED); } //+------------------------------------------------------------------+ //| Expert deinitialization function | //+------------------------------------------------------------------+ void OnDeinit(const int reason) { Print("Deus EA deinitialized. Reason: ", reason); } //+------------------------------------------------------------------+ //| Expert tick function | //+------------------------------------------------------------------+ void OnTick() { //--- Update current prices Ask = SymbolInfoDouble(_Symbol, SYMBOL_ASK); Bid = SymbolInfoDouble(_Symbol, SYMBOL_BID); ArrayResize(Close, 2); Close[0] = iClose(_Symbol, Period(), 0); Close[1] = iClose(_Symbol, Period(), 1); //--- Calculate RSI value rsiValue = iRSI(_Symbol, _Period, RSI_Period, PRICE_CLOSE, 0); if (rsiValue == WRONG_VALUE) { Print("Error calculating RSI"); return; //--- Calculate Moving Average value maValue = iMA(_Symbol, _Period, MA_Period, 0, MA_Method, MA_Price, 0); if (maValue == WRONG_VALUE) { Print("Error calculating Moving Average"); return; } //--- Check for Buy Signal if(rsiValue < RSI_Oversold && Close[1] > maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_SELL); OpenPosition(ORDER_TYPE_BUY); } } //--- Check for Sell Signal if(rsiValue > RSI_Overbought && Close[1] < maValue) { if(PositionsTotal() == 0) { ClosePositions(ORDER_TYPE_BUY); OpenPosition(ORDER_TYPE_SELL); } } //--- Apply trailing stop if specified if(TrailingStop > 0) { ApplyTrailingStop(); } } //+------------------------------------------------------------------+ //| Function to open a position | //+------------------------------------------------------------------+ void OpenPosition(int orderType) { //--- Determine price stop loss, and take profit levels double price = (orderType == ORDER_TYPE_BUY) ? Ask : Bid; double sl = (orderType == ORDER_TYPE_BUY) ? price - StopLoss * _Point : price + StopLoss * _Point; double tp = (orderType == ORDER_TYPE_BUY) ? price + TakeProfit * _Point : price - TakeProfit * _Point; bool result = trade.PositionOpen(_Symbol, orderType, Lots, price, sl, tp, "Deus EA"); if(result) { Print("Order opened successfully. Type: ", orderType, ", Price: ", price); } else { Print("Failed to open order. Error code: ", GetLastError()); } } //+------------------------------------------------------------------+ //| Function to close positions | //+------------------------------------------------------------------+ void ClosePositions(int orderType) { for(int i = PositionsTotal() - 1; i >= 0; i--) { if(PositionSelectByIndex(i)) { //--- Check if the positions type matches the order type to be closed if(PositionGetInteger(POSITION_TYPE) == orderType) { ulong ticket = PositionGetInteger(POSITION_TICKET); if(!trade.PositionClose(ticket) { Print("Failed to close position. Error code: ", GetLastError()); } } } } } //+------------------------------------------------------------------+ //| Function to apply trailing stop | //+------------------------------------------------------------------+ void ApplyTrailingStop() { for (int i = PositionsTotal() - 1; i >= 0; i--) { if (PositionSelectByIndex(i) && PositionGetSymbol() == _Symbol) { double price = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? Bid : Ask; double sl = (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY) ? price - TrailingStop * _Point : price + TrailingStop * _Point; //--- Trailing stop logic for buy positions if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_BUY && PositionGetDouble(POSITION_SL) < sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } //--- Trailing stop logic for sell positions else if (PositionGetInteger(POSITION_TYPE) == ORDER_TYPE_SELL && PositionGetDouble(POSITION_SL) > sl) { if (!trade.PositionModify(PositionGetInteger(POSITION_TICKET), sl, PositionGetDouble(POSITION_TP))) { Print("Failed to modify position. Error code: ", GetLastError()); } } } }
お疲れ様です。ここまでで、自動売買のためのDeus EAを実装しました。
テスト結果は以下の通りです。
得られた結果
テストはUSDJPYでおこない、バックテストは1時間足チャートを使用して2024年7月10日から2024年8月6日まで実施しました。モデリングはすべておこないました。使用したパラメータは、実装を研究するために用いたものです。
このタイプの戦略はEUR/USDとUSD/JPYに最適ですが、高い勝率を求めないトレーダーに限ります。以下は、EAのテストを実施するために使用したパラメータです。
結論
Deus EAは、移動平均と相対力指数(RSI)を使用して売買シグナルを生成し、テクニカル指標を統合して市場機会を効果的に活用する高度な取引戦略を提供します。本ガイドでは、取引ロジック、リスク管理、そしてEAの基盤となるMQL5コードについて詳しく説明しました。これにより、取引の決定が自動化され、一貫性が向上し、感情的なバイアスが軽減されます。
グラフからは、最適化のための小さなパラメータがリスクを減少させる一方で、損失を増加させる可能性があることが示されています。したがって、EAをライブ取引に導入する前に、さまざまな銘柄で徹底的なテストと最適化を行うことが重要です。これにより、異なる市場環境においても優れたパフォーマンスを発揮し、特定の取引目標に合致させることができます。
Deus EAおよび同様の自動システムの有効性を維持するには、定期的な監視と調整が欠かせません。この記事では、Deus EAを効果的に実装し、取引のために最適化するための重要な洞察とツールを提供しました。追加のサポートが必要な場合は、MQL5をご利用ください。
MetaQuotes Ltdにより英語から翻訳されました。
元の記事: https://www.mql5.com/en/articles/15431
- 無料取引アプリ
- 8千を超えるシグナルをコピー
- 金融ニュースで金融マーケットを探索