本ページはプロモーションが含まれています

EAプログラミング

MT4(MQL4) EAのトレーリングストップのソースコード紹介

トム

・本業エンジニア/EAのFX自動売買歴7年/ブログ歴6年
・首都圏在住30代
・MT4 EAを使った FXの自動売買で年間10万円の利益達成

トレーリングストップは、相場が思惑通りに進んだ際に利益を確保しつつ、逆行時の損失を自動で抑える便利な手法です。

この記事では、MT4(MQL4)でEAを自作する際に役立つ、トレーリングストップのソースコードを網羅的に紹介しています。

具体的には、固定幅方式、ATRベースの可変方式、一定期間の高安値を利用した方法、そして移動平均を活用した動的調整まで、複数のアルゴリズムをケース別に解説。

さらに、それぞれの戦略が有効な相場環境(トレンド・レンジ・高ボラティリティ)も明示しています。

この記事を読むことで、EAに最適なトレーリングストップ手法を選択・実装できるようになり、自動売買の精度と収益性の向上が目指せるでしょう。

価格 時間 価格線 トレーリングストップ

一般的なトレーリングストップ

まずは、一般的なトレーリングストップのソースコードを紹介します。

void orderTrailingStopGeneral(double startPips, double stopPips){
   // 選択した注文の約定価格を指定した少数点以下の桁数で四捨五入(例:110.1118⇒110.112)
   double orderPrice     = NormalizeDouble(OrderOpenPrice(), (int)MarketInfo(OrderSymbol(), MODE_DIGITS));
   // 選択した注文の損切り価格を指定した少数点以下の桁数で四捨五入
   double orderStopLoss  = NormalizeDouble(OrderStopLoss(), (int)MarketInfo(OrderSymbol(), MODE_DIGITS));
   if(OrderType() == OP_BUY) {
      // 最新のレートを取得
      RefreshRates();
      // トレール損切価格(現在価格からトレールストップ幅を引いた値を損切価格とする)
      double modifyStopLoss = Bid - stopPips;
      // 現在価格が注文約定価格とトレール開始値幅の合計以上の場合
      if(Bid >= orderPrice + startPips) {
         commonTrailingStop(modifyStopLoss, orderStopLoss);
      }
   }
   else if(OrderType() == OP_SELL) {
      // 最新のレートを取得
      RefreshRates();
      // トレール損切価格(現在価格からトレールストップ幅を足した値を損切価格とする)
      double modifyStopLoss = Ask + stopPips;
      if(Ask <= orderPrice - startPips) {
         commonTrailingStop(modifyStopLoss, orderStopLoss);
      }
   }
}
void commonTrailingStop(double modifyStopLoss, double stopLoss) {
   if (OrderType() == OP_BUY) {
      // 比較するときに微小の誤差が発生する場合があるため誤差を消すために0.5*Pointを引く
      if (modifyStopLoss  - 0.5 * Point > stopLoss) {
         // 新しいSLを設定
         orderModifyReliable(OrderTicket(), 0.0, modifyStopLoss, 0.0, 0, clrYellow);
      }
   }
   else if(OrderType() == OP_SELL){
      // 比較するときに微小の誤差が発生する場合があるため誤差を消すために0.5*Pointを引く
      if (modifyStopLoss < stopLoss - 0.5 * Point || stopLoss == 0.0) {   
         // 新しいSLを設定
         orderModifyReliable(OrderTicket(), 0.0, modifyStopLoss, 0.0, 0, clrYellow);
      }
   }
}
double currencyUnitPerPips(string symbol){
   // 通貨ペアに対応する小数点数を取得
   double digits = MarketInfo(symbol, MODE_DIGITS);
   // 通貨ペアに対応するポイント(最小価格単位)を取得
   // 3桁/5桁のFX業者の場合、0.001/0.00001
   // 2桁/4桁のFX業者の場合、0.01/0.0001
   double point = MarketInfo(symbol, MODE_POINT);
   // 価格単位の初期化
   double currencyUnit = 0.0;
   // 3桁/5桁のFX業者の場合
   if (digits == 3.0 || digits == 5.0) {
      // 10倍する
      currencyUnit = point * 10.0;
   // 2桁/4桁のFX業者の場合
   } else {
      currencyUnit = point;
   }
   return(currencyUnit);
}

ATRを使う


相場のボラティリティに応じて損切り位置を柔軟に調整したい場合、ATRを使ったトレーリングストップは非常に有効です。

一般的な固定幅のトレーリングストップでは対応しきれない相場の変動に対応できるため、不必要な損切りを回避しやすいのが最大の利点です。

ここでは、2種類のATR期間を使い、大きい方の値を基準としてトレール幅を決定する手法を紹介します。

なぜATRを使うのか?

ATRを使う理由は以下です。

  • 相場が活発なとき:トレール幅を広げることで、ノイズによる早すぎる損切りを防ぐ
  • 相場が静かなとき:トレール幅を狭めて、利益確定を迅速に行う

結果として、市場の状況に応じた合理的なトレーリングが可能になります。

以下の関数は、2つのATR期間を使用し、大きい方に倍率をかけた値をトレール幅とする設計です。

void trailingStopATR(int ATRPeriod1, int ATRPeriod2, double ATRMulti) {
   // 選択した注文の損切り価格を指定した少数点以下の桁数で四捨五入
   double orderStopLoss  = NormalizeDouble(OrderStopLoss(), (int)MarketInfo(OrderSymbol(), MODE_DIGITS));
   double ATR1 = iATR(OrderSymbol(), 0, ATRPeriod1, 1);
   double ATR2 = iATR(OrderSymbol(), 0, ATRPeriod2, 1);
   // ATR1,2で大きいほうを損切り価格とする
   double ATR  = MathMax(ATR1,ATR2);
   double stop = ATR * ATRMulti;
   if (OrderType() == OP_BUY) {
      // モディファイSL(1つ前の高値 - ATR*倍率)
      double modifyStopLoss = iHigh(OrderSymbol(), 0, 1) - stop; 
      commonTrailingStop(modifyStopLoss, orderStopLoss);
   }
   else if(OrderType() == OP_SELL) {
      double lowPrice = iLow(OrderSymbol(), 0, 1) + MarketInfo(OrderSymbol(), MODE_SPREAD) * currencyUnitPerPips(Symbol()); 
      double modifyStopLoss  = lowPrice + stop;
      commonTrailingStop(modifyStopLoss, orderStopLoss);
   }
}

補足:トレール幅の計算方法

パラメータ説明
ATRPeriod1短期のボラティリティを測る期間
ATRPeriod2長期のボラティリティを測る期間
ATRMultiATRに掛ける倍率(調整用)

2つのATRを計算し、大きい方に倍率を掛けることで、相場が急変したときでも柔軟に対応可能になります。

注意点

・相場が極端に荒れているときはトレール幅が広がりすぎて利益確定が遠のく可能性もあるため、ATRMultiは適度に調整する必要があります。
・ATRの期間設定は、戦略や取引スタイル(スキャルピング・デイトレ・スイング)によって最適な値が変わります。

一定期間内の最高値/最安値を用いたトレーリングストップ

一定期間の高値や安値を基準に損切り価格を動かすトレーリングストップ手法です。

相場の「反転しやすいポイント」を活用することで、より自然なトレンドフォローとリスク管理が可能になります。

この方法の最大の特徴は、直近のローソク足における高値・安値を参照し、それを基準に動的に損切り位置(ストップロス)を調整できる点です。

つまり、過去の値動きを踏まえながら、今の相場に沿った位置へ損切りラインを追従させていきます。

void trailingStopHL(int candleNum) {
   // 選択した注文の損切り価格を指定した少数点以下の桁数で四捨五入
   double orderStopLoss = NormalizeDouble(OrderStopLoss(), (int)MarketInfo(OrderSymbol(), MODE_DIGITS));
   if (OrderType() == OP_BUY) {
      double modifyStopLoss = iLow(OrderSymbol(), 0, iLowest(OrderSymbol(), 0, MODE_LOW, candleNum, 1)) + MarketInfo(OrderSymbol(), MODE_SPREAD) * currencyUnitPerPips(Symbol());
      commonTrailingStop(modifyStopLoss, orderStopLoss);
   }
   else if (OrderType() == OP_SELL) {
      double modifyStopLoss = iHigh(OrderSymbol(), 0, iHighest(OrderSymbol(), 0, MODE_HIGH, candleNum, 1));
      commonTrailingStop(modifyStopLoss, orderStopLoss);
   }
}

BUYポジションの場合

買い注文では、指定期間の最安値+スプレッド分を新たな損切りライン候補とします。

これは、最も低い位置まで価格が下がった場合でも、多少のスプレッドを見越して安全圏で逃げられるようにするためです。

SELLポジションの場合

売り注文の場合は、指定期間の最高値を新しい損切り候補とします。

価格が再びその高値を超えるようであれば、下降トレンドが崩れたと判断し、ポジションをクローズします。

注意点

ローソク足の本数(candleNum)の選定が重要:短すぎるとダマシに弱く、長すぎると反応が鈍くなる

MAを使う


移動平均をベースにしたトレーリングストップを実装します。

チャートの一定期間における価格の平均を参照して、損切り位置を動的に調整するため、相場の流れに応じて柔軟な対応が可能です。

void TrailingByMA(int timeFrame, int MAPeriod, int MAShift, int MAMethod, int applPrice, int shift, double indent) {    
   // 選択した注文の損切り価格を指定した少数点以下の桁数で四捨五入
   double orderStopLoss  = NormalizeDouble(OrderStopLoss(), (int)MarketInfo(OrderSymbol(), MODE_DIGITS));
   double dMA            = iMA(Symbol(), timeFrame, MAPeriod, MAShift, MAMethod, applPrice, shift);
   if (OrderType() == OP_BUY) {
      double modifyStopLoss = dMA - indent; 
      commonTrailingStop(modifyStopLoss, orderStopLoss);
   }
   else if(OrderType() == OP_SELL) {
      double modifyStopLoss  = dMA + indent + MarketInfo(OrderSymbol(), MODE_SPREAD) * currencyUnitPerPips(Symbol()); 
      commonTrailingStop(modifyStopLoss, orderStopLoss);
   }
}

BUY注文の場合

MA値からindent分を引いた価格が、トレーリングストップの新しい候補になります。

つまり、現在価格が移動平均よりも上にあることを前提として、下方向に一定の余裕を持たせて損切りラインを設定します。

SELL注文の場合

逆に、MA値にindentとスプレッド(買値と売値の差)を加えた価格が損切りライン候補になります。

価格がMAより下にあることを前提とし、上方向に余裕をもたせて損切りラインを設定します。

注意点

•MAのパラメータ設定(期間・種類)によっては過度に反応が遅くなることもある

トレーリングストップの使い分け

さまざまなトレーリングストップを紹介しましたが、使い方によっては効果を発揮できません。

また、相場状況やトレードスタイルによって、最適な使い方は変わります。

いくつかのシナリオを考え、どのように使い分けると効果的かを考えてみましょう。

トレンドフォロー型の戦略を用いる場合

トレーリングストップは、特にトレンドフォロー型のEAと相性がよいです。

市場が一定の方向に動き続ける場合、トレーリングストップを用いると、トレンドを追いかけて利益を得られるからです。

レンジ相場で取引を行う場合

一方、レンジ相場ではトレーリングストップは必ずしも最善の手段とは言えません。

なぜなら、価格が一定範囲内で上下に動くため、トレーリングストップが早くに発動してしまい、利益を十分に伸ばせない可能性があるからです。

この場合、固定のストップロスやテイクプロフィットを設定する方が良い結果になることもあります。

高ボラティリティの環境で取引を行う場合

高ボラティリティ(値動きが大きい相場)の環境では、価格が急激に変動するため、トレーリングストップの幅を広く取ることで、一時的な価格変動による損切りを防ぐことが可能です。

市販EAの例

トレーリングストップで幸せに一本勝ちトレーリングストップで幸せに一本勝ち | GogoJungle

トレーリングストップを使ったEAで有名なので当サイトでも紹介している「一本勝ち」というEAです。

このEAの特徴はトレーリングストップを使うことによって、急激にレートが変化するときに大きな利益を得ることができるのが特徴です。

こちらのEAはトレーリングにより、理論上は無限の利益が狙えます。

実際に私もこのEAのトレーリングストップのおかけで、相場か予想外に急激に動いたときに大きな利益を得た経験があります。

まとめ

今回はMT4のEA作成に使えるトレーリングストップのソースコードについて、いくつか例を挙げて詳しく解説してきました。

この記事を読んで、あなたも自分だけのEAを作るためにトレーリングストップを有効に取り入れましょう。

  • この記事を書いた人
  • 最新記事

トム

・本業エンジニア/EAのFX自動売買歴7年/ブログ歴6年
・首都圏在住30代
・MT4 EAを使った FXの自動売買で年間10万円の利益達成

-EAプログラミング
-,