トレーリングストップは、レートが予想通り動き、含み益があるときに、自動で損切りレート、利益確定レートを移動させるための機能です。
トレーリングストップを使えば大きな利益を確保しながら、同時にリスクを最小限に抑えます。投資の世界では「高いリターンを追求し、リスクを最小限に抑える」のが重要なポイントです。高いリターン、最小限のリスクのバランスを取るための大切な道具が、トレーリングストップなのです。
一般的なトレーリングストップ
まずは、一般的なトレーリングストップのソースコードを紹介します。
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という指標を使ったトレーリングストップです。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);
}
}
一定期間内の最高値/最安値を用いたトレーリングストップ
ある一定期間の高値、安値を損切り価格にしながらトレーリングできるのが特徴です。相場の損切り価格になりやすい高値、安値を使ってトレーニングできるのがメリットです。
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);
}
}
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);
}
}
トレーリングストップの使い分け
さまざまなトレーリングストップを紹介しましたが、使い方によっては効果を発揮できません。また、相場状況やトレードスタイルによって、最適な使い方は変わります。
いくつかのシナリオを考え、どのように使い分けると効果的かを考えてみましょう。
トレンドフォロー型の戦略を用いる場合
トレーリングストップは、特にトレンドフォロー型のEAと相性がよいです。市場が一定の方向に動き続ける場合、トレーリングストップを用いると、トレンドを追いかけて利益を得られるからです。
レンジ相場で取引を行う場合
一方、レンジ相場ではトレーリングストップは必ずしも最善の手段とは言えません。なぜなら、価格が一定範囲内で上下に動くため、トレーリングストップが早くに発動してしまい、利益を十分に伸ばせない可能性があるからです。
この場合、固定のストップロスやテイクプロフィットを設定する方が良い結果になることもあります。
高ボラティリティの環境で取引を行う場合
高ボラティリティ(値動きが大きい相場)の環境では、価格が急激に変動するため、トレーリングストップの幅を広く取ることで、一時的な価格変動による損切りを防ぐことが可能です。
市販EAの例
トレーリングストップを使ったEAで有名なので当サイトでも紹介している「一本勝ち」というEAです。
このEAの特徴はトレーリングストップを使うことによって、急激にレートが変化するときに大きな利益を得ることができるのが特徴です。
こちらのEAはトレーリングにより、理論上は無限の利益が狙えます。
実際に私もこのEAのトレーリングストップのおかけで、相場か予想外に急激に動いたときに大きな利益を得た経験があります。
まとめ
今回はMT4のEA作成に使えるトレーリングストップのソースコードについて、いくつか例を挙げて詳しく解説してきました。この記事を読んで、あなたも自分だけのEAを作るためにトレーリングストップを有効に取り入れましょう。