はじめに
FXでは、ポジションを保有した後に相場が有利な方向へ動いた場合、当初設定した損切りラインや利益確定ラインを相場状況に応じて変更させたいことがよくあります。
例えば、含み益が大きくなったタイミングで損切りラインを引き上げたり、さらに利益が伸びそうな場合には利益確定ラインをより遠くへ移動させたりというような場合です。
このように一定の条件に従って保有中のポジションの決済ラインを自動的に更新する仕組みが「トレーリングストップ」です。
MT4では保有中のポジションに設定されている指値(TP)や逆指値(SL)を変更する際は、一般的にOrderModify()関数が使われます。
この記事では、オリジナルのサンプルプログラムを使いながら、OrderModify()関数の基本的な使い方と、条件に応じて損切りラインを変更するトレーリングストップの仕組みについて解説していきます。
プログラムについて
サンプルプログラム(クリックして開く)
//+------------------------------------------------------------------+
//| test.mq4 |
//| Copyright 2026, MetaQuotes Ltd. |
//| https://www.mql5.com |
//+------------------------------------------------------------------+
#property copyright "Copyright 2026, MetaQuotes Ltd."
#property link "https://www.mql5.com"
#property version "1.00"
#property strict
//変数定義
extern double Lots=0.01; //ロット数設定
int modify=0; //ポジション修正管理用変数
//+------------------------------------------------------------------+
//| Expert initialization function |
//+------------------------------------------------------------------+
int OnInit()
{
//---
//---
return(INIT_SUCCEEDED);
}
//+------------------------------------------------------------------+
//| Expert deinitialization function |
//+------------------------------------------------------------------+
void OnDeinit(const int reason)
{
//---
}
//+------------------------------------------------------------------+
//| Expert tick function |
//+------------------------------------------------------------------+
void OnTick()
{
//利食い損切りラインの設定
double buy_tp=Ask+0.5;
double buy_sl=Ask-0.5;
double sell_tp=Bid-0.5;
double sell_sl=Bid+0.5;
if(OrdersTotal()==0) //ポジション持っていない場合
{
modify=0;
if(/*買いエントリー条件*/)
{
OrderSend(Symbol(),OP_BUY,Lots,Ask,10,buy_sl,buy_tp,NULL,0,0,clrNONE);
}
else return;
if(/*売りエントリー条件*/)
{
OrderSend(Symbol(),OP_SELL,Lots,Bid,10,sell_sl,sell_tp,NULL,0,0,clrNONE);
}
else return;
}
else //ポジションを持っている場合
{
if(OrderSelect(0,SELECT_BY_POS,MODE_TRADES))
{
if(OrderType()== OP_BUY)
{
if(Bid>=OrderOpenPrice()+0.3 && modify==0) //買いポジション修正条件①
{
double new_sl=OrderOpenPrice()-0.3;
OrderModify(OrderTicket(),OrderOpenPrice(),new_sl,OrderTakeProfit(),OrderExpiration(),clrNONE);
modify=1;
}
else if(Bid>=OrderOpenPrice()+0.4 && modify==1) //買いポジション修正条件②
{
double new_sl=OrderOpenPrice()-0.2;
OrderModify(OrderTicket(),OrderOpenPrice(),new_sl,OrderTakeProfit(),OrderExpiration(),clrNONE);
modify=2;
}
else if(/*買いポジション決済条件*/)
{
OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),10,clrNONE);
}
else return;
}
else if(OrderType()==OP_SELL)
{
if(Ask<=OrderOpenPrice()-0.3 && modify==0) //売りポジション修正条件①
{
double new_sl=OrderOpenPrice()+0.3;
OrderModify(OrderTicket(),OrderOpenPrice(),new_sl,OrderTakeProfit(),OrderExpiration(),clrNONE);
modify=-1;
}
else if(Ask<=OrderOpenPrice()-0.4 && modify==-1) //売りポジション修正条件②
{
double new_sl=OrderOpenPrice()+0.2;
OrderModify(OrderTicket(),OrderOpenPrice(),new_sl,OrderTakeProfit(),OrderExpiration(),clrNONE);
modify=-2;
}
else if(/*売りポジション決済条件*/)
{
OrderClose(OrderTicket(),OrderLots(),OrderClosePrice(),10,clrNONE);
}
else return;
}
else return;
}
else return;
}
return;
}
//+------------------------------------------------------------------+
ご自身のメタエディターに貼り付けて、このページを参考にしながら、理解を進めていくことをおすすめします。(基本的なEAファイルの作成方法についてはこちらをご覧ください。)
また、エントリー条件や決済条件を書くところは「/*買いエントリー条件*/」のように説明コメントになっていますので、ご自身で考えたロジックをここに書くことで、簡単にトレーリングストップを含むプログラムの作成が可能です。
それではプログラムの内容説明に移っていきます。
EA概要
- USD/JPYを想定して作成。
- 最大保有ポジション数は1。
- エントリーすると、買いポジション・売りポジションそれぞれ、±0.5円のラインに利食い損切りラインが自動で設定される。
- +0.3円分の含み益が出ると、損切りラインをエントリー価格から0.3円の位置に変更し、+0.4円分の含み益が出ると、損切りラインをエントリー価格から0.2円の位置に変更される。
- else if を増やすことで、これらの指値/逆指値決済とは別の決済条件を指定することもできる。
<買いポジションの場合>

プログラムの内容説明
①変数定義

「Lots」は取引ロット数の設定するための変数です。0.01となっていますが、extern変数なので、MT4のプロパティ画面から値を変更することができます。
→extern変数についてはこちらをご覧ください。
「modify」はポジション修正管理用の変数です。初期値は「0」になっていますが、ポジションが修正されるたびに値が変更されます。各値の意味については以下の通りです。
| modifyの値 | 意味 |
|---|---|
| 0 | 「初期値」 損切りラインの修正がまだ行われていない状態 |
| 1 | 「買いポジション修正①」 損切りラインをエントリー価格の−0.3円に変更 |
| 2 | 「買いポジション修正②」 損切りラインをエントリー価格の−0.2円に変更 |
| −1 | 「売りポジション修正①」 損切りラインをエントリー価格の+0.3円に変更 |
| −2 | 「売りポジション修正②」 損切りラインをエントリー価格の+0.2円に変更 |
②エントリー処理

「利食い損切りラインの設定」では現在価格を基準に、買い・売りそれぞれの利食い価格と損切り価格の取得を行っています。
OrdersTotal関数は現在の保有ポジション数を返す関数で「OrdersTotal()==0」は保有ポジション数が0であることを表しています。このプログラムで保有するポジション数は最大1つなので、ポジションを保有していないときのみ、エントリー処理が行われるようにしています。
modify=0はmodifyの値をリセットする役割を持ちます。ポジションが修正されて、決済されると、modifyの値が1や2のままの状態なので、ポジションが無くなった時点で0にリセットし、次のエントリーで修正処理を最初の段階から行えるようにしています。
その下は実際に注文を行うプログラムです。if内にエントリー条件を入れることで、ご自身の好きなタイミングでのエントリーが可能になります。OrdserSend関数内の指値、逆指値を設定する引数には最上部で取得した利食い損切り価格が代入されています。
③ポジション修正/決済処理
OrderSelect関数でポジション選択した後、OrderType関数でポジション種別を判別しています。買いポジションと売りポジションの構造は損切りラインの修正に関する条件が逆になっているだけで、基本的な構造は同じなので、買いポジションの場合を例に説明していきます。
ポジション修正(トレーリングストップ処理)

まず1つ目のポジション修正は+0.3円分の含み益が出たときです。買いポジションでは売値で決済するため、現在の売値価格であるBidを使って、エントリー価格との差額が0.3円以上かどうかで判定します。
変数「new_sl」に新しい損切りラインの価格を代入し、OrderModify関数を使って、ポジション修正を行います。OrderModify関数の引数の意味については以下の通りです。
| 引数 | 意味と説明 |
|---|---|
| OrderTicket() | 「変更したいポジションのチケット番号」 OrderTicket関数を用いてポジションの チケット番号を取得。 |
| OrderOpenPrice() | 「エントリー価格の変更」 オープンポジションではOrderOpenPrice関数を指定。 |
| new_sl | 「ストップラインの変更」 変更後の損切り価格を指定。変更しない場合は、OrderStopLoss関数を使う。 |
| OrderTakeProfit() | 「テイクプロフィットの変更」 変更しない場合は、OrderTakeProfit関数を用いて、既存の設定を引き継ぐ。 |
| OrderExpiration() | 「有効期限の変更」 オープンポジションではOrderExpiration関数を指定。 |
| clrNONE | 矢印非表示 |
最後に「modify=1」とすることで、同じ修正処理が繰り返されるのを防ぎ、次の修正条件に進めるようにしています。
2つ目のポジション修正も同様に行います。else ifの条件分岐を増やし、modify変数でポジション修正を適切に管理することで、さらにトレーリングストップを増やしたり、利食いラインを変更したりするなど、様々なポジション修正に応用できます。
決済処理

指値・逆指値決済とは別にテクニカルでポジションを決済したい場合は、ここに決済条件を記述します。例えば、移動平均線のクロスやRSIなどの指標を設定することで、相場状況に応じた決済が可能になります。必要ない場合は、else ifの条件分岐をまるごと消して下さい。
一方、複数の決済条件を設定したい場合は、else ifの条件分岐を追加することで対応できます。
まとめ
いかがだったでしょうか。相場状況に応じて、既存の利食い・損切りラインを変更したい場合はOrderModify関数を利用することで簡単に決済ラインの変更を行うことができます。また、条件分岐とmodifyのようなポジションを修正する変数を組み合わせることで、含み益の大きさに応じて損切りラインを段階的に引き上げるなど、トレーリングストップのような仕組みも作ることができます。
今回紹介したプログラムをベースに、自分のトレード手法に合わせて条件を変更・追加し、ポジション管理を組み込んだEAの作成をしてみてください。
