ホーム » FX自動売買基礎と応用 » 【MT5 API 応用編②】システムトレードのための損切りルール

【MT5 API 応用編②】システムトレードのための損切りルール


この記事では、MT5 API 応用編②として、システムトレードにおける損失管理の重要性に焦点を当て、損切りの基本的な考え方から具体的なルールの作り方、そして戦略への組み込み方法までを解説します。

損切りとは何か

トレードにおける損切り(ストップロス)とは、一定以上の損失が出る前にポジションを決済することをいい、その目的は「損をすること」ではなく、「損失を限定すること」にあります。

【MT5 API 応用編②】システムトレードのための損切りルール_01

長期の現物株投資では、資産配分などを管理することでリスクを調整するのが一般的であり、短期的な値動きに対して機械的な損切りを置かない運用も多いです。

一方でFXのようなレバレッジをかけたトレードでは、短時間の価格変動で大きな損失が発生する危険性も高いため、損切りルールを戦略に組み込むことが重要になります。

とはいえ、実際のトレードでは損切りを行わない方が良かったという場面も少なくありません。

損切りをすることが必ずしも戦略の期待値向上につながるわけではない点を頭に入れておきましょう。

【MT5 API 応用編②】システムトレードのための損切りルール_02

期待値の観点ではメリットにならないですが、損失を限定させることには大きな意味があります。

運用する戦略が優秀なものであっても、突発的な経済ニュースなどによって事故のような形で大きな損失を負うこともあります。

運用期間が長くなるほど、避けようのない大損失に見舞われる可能性も高くなります。

それまでに積み上げてきた利益を守るためにも、損切りルールを構築しておきましょう。

逆指値を使った損切り

システムトレードでは、プログラムに相場を常に監視させて、あらかじめ決めた損切りの水準に達したら自動的に決済注文を送信する仕組みを作ることができます。

このような仕組みはヒューマンエラーの発生の余地がなく、手動決済による損切りよりも安全に実行することが可能です。

しかし、より安全な体制をとるのであれば、逆指値注文を入れて損切りを行うのが望ましいです。

プログラムによる損切りは、何かしらのトラブルでプログラムが停止することがあります。

例えば、「WindowsのPCで気づかないうちにOSのアップデートによってPCが再起動されており、システムトレードのプログラムが停止していた」というような事態も考えられます。

もし、ポジションを保有したままプログラムが停止すれば、「損切りの水準を超えているのに決済されず、大きな損失が発生してしまう」といった危険もあります。

これが逆指値注文による損切りであれば、PC内で何かしらのトラブルがあっても、事前に取引先のブローカーに予約注文が通っていることになるので、損切りの水準に達した時点で問題なく決済されるのです。

【MT5 API 応用編②】システムトレードのための損切りルール_03

MT5の取引では、注文時に「SL」というパラメーターを設定することができます。

SLは逆指値決済注文と同じで、事前にブローカーに通す予約注文になります。

また、SLと同様に「TP」というパラメーターも用意されており、こちらは指値注文(利益確定水準)となります。


trade_request = {
    "action": mt5.TRADE_ACTION_DEAL,
    "symbol": symbol,
    "volume": 0.1,
    "type": mt5.ORDER_TYPE_BUY,
    "price": price,
    "sl": sl_price,   # 損切り価格
    "tp": tp_price,   # 利確価格
    "deviation": 20,
    "magic": 123456789,
    "type_time": mt5.ORDER_TIME_GTC,
    "type_filling": mt5.ORDER_FILLING_IOC
}

Python側から注文を送信するコード内で”sl”と”tp”に任意の価格を入れてから注文することで、決済の指値・逆指値を設定可能です。

損切りルールの作成

損切りルールは、システムトレード戦略の一部として考え、あらかじめロジックに組み込んでからバックテストを行うようにします。

バックテスト済みの戦略に後から損切りルールを追加すると、戦略の評価が全く違うものになってしまう恐れがあるため、損切りも戦略の一部としてバックテストで評価することが重要です。

ここではシンプルな損切りルールを3つ紹介します。

固定pips

最初に紹介するアプローチは、損切り幅をpipsで決める最もシンプルな方法です。

例えば、「新規注文価格から20pips逆行したら損切りする」というように、あらかじめpips幅を決めておき、毎回のトレードでその幅に達したら損切りするアプローチになります。

固定リターン

2つ目のアプローチは、「価格が〇〇%逆行したら損切りする」といったリターンに基づく損切り方法です。

例えば、「エントリ―価格から1%逆行した時点で損切りする」というような損切りルールになります。

固定リターンで損切りを行う意味を、米ドル/円のレートを例に考えてみましょう。

1ドル150円のとき、1%の変動は1.5円(150pips)に相当します。

一方、1ドル100円のとき、1%の変動は1円(100pips)となります。

このように、同じ1%の変動でも、そのときのレート水準によって何pipsになるかは変わるのです。

バックテストする過去データに1ドル150円以上の時期もあれば、1ドル100円以下の時期もあるとすると、一貫した基準で損切りを行うには固定pipsよりも固定リターンで損切りする方が適していると考えることができます。

固定ボラティリティ

金融市場には、「大きな値動きの後には大きな値動きが続きやすく、小さな値動きの後には小さな値動きが続きやすい」といったボラティリティ・クラスタリングと呼ばれる現象があります。

固定pipsや固定リターンの欠点は、ボラティリティの変化に対応できないところです。

  • ●ボラティリティが低い相場のときには損切り位置が遠すぎる
  • ●ボラティリティが高い相場のときには損切り位置が近すぎる

といった状態に陥りやすくなります。

そこで変化するボラティリティに応じて損切り幅を調整するルールを考えます。

例えば、「年率ボラティリティが10%なら、そこに0.1をかけた1%を損切り幅に設定する」といった考え方です。

値動きの激しい相場では損切り幅を広めに、穏やかな相場では狭めに設定できる点が特徴です。

【MT5 API 応用編②】システムトレードのための損切りルール_04

ただし、0.1という係数に絶対的な正解があるわけではありません。

損切り幅を狭めに設定する方が良い戦略の場合は、より小さい値(0.05、0.03、0.01など)を使い、逆に損切り幅を広くしたい場合は、より大きな値に調整する必要があります。

【MT5 API 応用編②】システムトレードのための損切りルール_05

損切りルールを戦略に組み込む

ここでは、下記のシンプルな戦略にどのように損切りルールを組み込んでいくかを考えていきましょう。

※コード内では、ロンドン時間を示す数値を「lon_hour」、年率ボラティリティを「annual_vol」としてデータフィードで追加済みであることを前提としています。


class EurUsdIntradayPattern(bt.Strategy):
    def __init__(self):
        # データに含まれるロンドン時間の hour 列を参照
        self.lon_hour = self.datas[0].lon_hour

    def next(self):
        # 現在バーのロンドン時間
        hour = int(self.lon_hour[0])

        # ロンドン時間11時に、未保有なら新規ショート
        if hour == 11 and not self.position:
            self.sell(size=1)

        # ロンドン時間15時に、保有中なら決済
        elif hour == 15 and self.position:
            self.close()

戦略の基本ルール

  • ●ユーロ/米ドル(EURUSD)をロンドン時間の11時にショートする
  • ●ショートしたポジションをロンドン時間の15時に決済する

この戦略に「年率ボラティリティに0.1をかけた値を損切り幅に設定する」というルールを追加します。


class EurUsdIntradayPattern(bt.Strategy):
    params = (
        ("stop_vol_mult", 0.1),  # 最適化可能なパラメーターとしておく
    )

    def __init__(self):
        # データフィードの追加列
        self.lon_hour = self.datas[0].lon_hour
        self.annual_vol = self.datas[0].annual_vol

        # 損切り価格を保持
        self.stop_price = None

    def next(self):
        hour = int(self.lon_hour[0])
        annual_vol = float(self.annual_vol[0])

        # ロンドン時間11時に、未保有なら新規ショート
        if hour == 11 and not self.position:
            self.sell(size=1)

            # 損切り幅 = 年率換算ボラティリティ × 係数
            stop_width = annual_vol * self.p.stop_vol_mult

            # ショートなので損切りはエントリーより上
            self.stop_price = self.data.close[0] + stop_width

        # 保有中に損切り価格へ到達したら決済
        elif self.position and self.stop_price is not None:
            if self.data.high[0] >= self.stop_price:
                self.close()
                self.stop_price = None

        # ロンドン時間15時に、保有中なら決済
        elif hour == 15 and self.position:
            self.close()
            self.stop_price = None

係数の0.1は戦略クラスの最初にパラメーターとして設定しています。

これを戦略パラメーターとすることで、0.1という数値を最適化できるので、「この戦略にとってどのくらいの損切り幅が適切か」を調整することが可能になります(オーバーフィッティングには注意が必要です)。


# 損切り幅 = 年率換算ボラティリティ × 係数
stop_width = annual_vol * self.p.stop_vol_mult

# ショートなので損切りはエントリーより上
self.stop_price = self.data.close[0] + stop_width

このコードで「stop_width」に損切り幅の計算結果を入れ、現在の終値にプラスして損切り価格を計算しています。

ポジションがロングのときは、損切り幅の分を現在の終値から引いて計算します。

バックテスト用のコードなので、保有中に損切り価格へ到達したら決済するコードも書いていますが、MT5に注文を出すときには、上記のように計算した損切り価格をSLに入れて注文を送信するだけで良いことになります。

この記事では、シンプルな損切りルールを紹介しましたが、損切りルールに明確な正解はありません。

大切なのは、レバレッジをかけたトレード戦略において、損失を限定する仕組みが組み込まれていることです。

「戦略本来の優位性を損なうことなく損失額を限定する」ことを追求し、さまざまな損切りルールを考察・検証してみてください。

【MT5 API 応用編】

本記事の執筆者:藍崎@システムトレーダー

               
本記事の執筆者:藍崎@システムトレーダー 経歴
藍崎@システムトレーダー個人投資家としてEA開発&システムトレード。
トレードに活かすためのデータサイエンス / 統計学 / 数理ファイナンス / 客観的なデータに基づくテクニカル分析 / 機械学習 / MQL5 / Python

EA(自動売買)を学びたい方へオススメコンテンツ

EA運用の注意点

OANDAではEA(自動売買)を稼働するプラットフォームMT4/MT5の基本的な使い方について、画像や動画付きで詳しく解説しています。MT4/MT5のインストールからEAの設定方法までを詳しく解説しているので、初心者の方でもスムーズにEA運用を始めることが可能です。またOANDAの口座をお持ちであれば、独自開発したオリジナルインジケーターを無料で利用することもできます。EA運用をお考えであれば、ぜひ口座開設をご検討ください。


本ホームページに掲載されている事項は、投資判断の参考となる情報の提供を目的としたものであり、投資の勧誘を目的としたものではありません。投資方針、投資タイミング等は、ご自身の責任において判断してください。本サービスの情報に基づいて行った取引のいかなる損失についても、当社は一切の責を負いかねますのでご了承ください。また、当社は、当該情報の正確性および完全性を保証または約束するものでなく、今後、予告なしに内容を変更または廃止する場合があります。なお、当該情報の欠落・誤謬等につきましてもその責を負いかねますのでご了承ください。

この記事をシェアする