本記事で公開しているライブラリーは公開当時のままで、古くなっております。最新版のライブラリーはメルマガ登録いただくことでダウンロードできます。
トレイリングストップはトレンドフォローの必需品
トレーダーなら損小利大を狙いたいですよね。それを叶えてくれるのが、皆さんご存じのトレイリングストップ。トレンドフォロー戦略では欠かせない機能です。
トレイリングストップと一言でいってもシンプルなものから複雑なものまで色々ありますが、今回は、仕掛けから特定の値幅だけ進んだらストップの位置を変更していく一般的なトレイリングストップ関数を紹介します。複雑なトレイリングストップは必要になり次第、取り上げるつもりです。
//+------------------------------------------------------------------+
//|【関数】一般的なトレイリングストップ |
//| |
//|【引数】 IN OUT 引数名 説明 |
//| --------------------------------------------------------- |
//| ○ aMagic マジックナンバー |
//| ○ aTS_StartPips トレイリングストップ開始値幅(pips) |
//| ○ aTS_StopPips 損切り値幅(pips) |
//| |
//|【戻値】なし |
//| |
//|【備考】仕掛け位置からaTS_StartPips順行したら、その位置か |
//| aTS_StopPips逆行した位置にストップを設定 |
//+------------------------------------------------------------------+
void trailingStopGeneral(int aMagic, double aTS_StartPips, double aTS_StopPips)
{
for(int i = 0; i < OrdersTotal(); i++){
// オーダーが1つもなければ処理終了
if(OrderSelect(i, SELECT_BY_POS) == false){
break;
}
string oSymbol = OrderSymbol();
// 別EAのオーダーはスキップ
if(oSymbol != Symbol() || OrderMagicNumber() != aMagic){
continue;
}
int oType = OrderType();
// 待機オーダーはスキップ
if(oType != OP_BUY && oType != OP_SELL){
continue;
}
double digits = MarketInfo(oSymbol, MODE_DIGITS);
double oPrice = NormalizeDouble(OrderOpenPrice(), digits);
double oStopLoss = NormalizeDouble(OrderStopLoss(), digits);
int oTicket = OrderTicket();
double start = aTS_StartPips * gPipsPoint;
double stop = aTS_StopPips * gPipsPoint;
if(oType == OP_BUY){
double price = MarketInfo(oSymbol, MODE_BID);
double modifyStopLoss = price - stop;
if(price >= oPrice + start){
if(modifyStopLoss > oStopLoss){
orderModifyReliable(oTicket, 0.0, modifyStopLoss, 0.0, 0, gArrowColor[oType]);
}
}
}else if(oType == OP_SELL){
price = MarketInfo(oSymbol, MODE_ASK);
modifyStopLoss = price + stop;
if(price <= oPrice - start){
// ショートの場合、条件式にoStopLoss == 0.0が必要
// oStopLoss=0は、損切り値を設定していない場合
// その場合、modifyStopLoss < oStopLossの条件は永久に成立しない(※)ため
// ※「modifyStopLoss < 0」でかつ「modifyStopLossは価格なので0以上」のため
if(modifyStopLoss < oStopLoss || oStopLoss == 0.0){
orderModifyReliable(oTicket, 0.0, modifyStopLoss, 0.0, 0, gArrowColor[oType]);
}
}
}
}
}
最初に、オーダーの有無をチェックした上で、別EAの注文や待機注文は対象外なのでスキップするようにしています。

ロングとショートで若干ロジックが異なっています。特にショートのif文の「oStopLoss == 0.0」は重要です。うっかり忘れやすい箇所ですね。これを追加しておかないと、永久に条件が成立しなくなってしまいますので、必ず入れておきましょう!
サンプルEA
関数だけではイメージが沸きづらいと思いますので、サンプルEAを載せておきます。OnTick()に当関数をセットすることで、ティックごとに関数が呼ばれます。OnInit()にセットしてしまうと、EA開始時に一回しか呼ばれないことになり、トレイリングストップの役割を果たしてくれませんので、要注意です。
