政府の市場介入

スイスフランショック

政府の市場介入は価格形成に歪みを与える。その歪みを利用して利益を上げることも可能ではある。だが、恐ろしいのは政府が方針を変更したときである。2015年1月15日に起きたスイスフランショックは記憶に新しい。

スイスフラン高を嫌ったスイス中銀は2011年9月、ユーロスイスの下限を1.2スイスフランに設定して無制限介入を開始した。ユーロスイスが1.2スイスフランを割ることはないとスイス中銀が保証してくれたわけだ。これをバックにして買えば低リスクで利益を上げられると考えたトレーダーも少なくなかっただろう。

かく言う私もスイス中銀の介入をバックにして下がったら買う逆張り戦略をブログで記事にした。ただ、スイス中銀が無制限介入を行ったときにユーロスイスが暴騰したことを挙げて、スイス中銀が方針を変換したら逆のことが起きると警告した。また、1.2スイスフランを割ったら損切りすべきだとも書いた。だが、私の認識は甘すぎた。

スイス中銀が下限を撤廃したことが伝わると、スプレッドが大きく広がり、そしてレート配信が止まった。運よく損切りできても想定以上の損失を受けただろうし、損切りできず、ロスカットすらできずに全資金を失い、さらにはFX会社に対して負債すら抱えてしまったトレーダーも少なくなかった。FX会社が負債を回収できずに倒産するというケースもあった。幸い、私は記事にしただけで実際には運用しなかった。だが、いい加減な記事を書いてはいけないと痛感した。

一時的には勝てるが…

政府の介入によって歪められた市場のデータを使ってバックテストしても、その寿命はその介入が継続している間だけに限られる。そして、介入は何のアナウンスもなく突然撤廃され、後は阿鼻叫喚の地獄がやってくるのである。

例として直近安値をバックにしてユーロスイスを買う戦略を考えてみる。具体的には

  • 終値が直近安値*(1+エントリー閾値/100)以下になったら買いエントリー、
  • 終値が直近安値*(1+(エントリー閾値+エグジット閾値)/100)以上になったら買いエグジット、

という売買ルールである。2012年1月1日から2014年12月31日までのデータを使って最適化すると、以下のようなパフォーマンスになる。

シャープレシオはそれほど高くはないが、資産曲線は比較的きれいな右肩上がりとなっている。

地獄は突然やってくる

2015年でも同様のパフォーマンスを期待したいが、残念ながらスイス中銀は1月15日、突如としてスイスフランの下限を撤廃する。では、すでに最適化されたパラメータを使い、期間を2015年12月31日まで延長したデータでどうなるかを見てみる。

一体何が起きたのか、という感じである。3年もかけてコツコツと積み上げた利益など一瞬で消えてしまい、約10%以上の負けとなっている。

しかも、これはレバレッジが1倍ならの話である。もしレバレッジが10倍だったら、全資金を失うばかりか、負債まで抱えることとなっていただろう。実際にはスプレッドは広がるし、レート配信は停止するしで、バックテストよりもっとひどいことになっていたかもしれない。

トレードで利益を上げるには単に市場の歪みを捉えるだけではなく、それが継続性のあるものでなければならない。政府によって一時的に作られた歪みによって利益を得ようとすることは後々とんでもないしっぺ返しを受けることになる。

サンプルプログラム

①以下のプログラムをSpyderの「エディタ」にコピー&ペーストし、ファイル名を「swiss_franc_shock.py」として「~/py」フォルダーに保存する。

# coding: utf-8

import forex_system as fs

LOTS = 0.1

# パラメータの設定
PERIOD = 1500
ENTRY_THRESHOLD = 0.002
PROFIT_THRESHOLD = 0.08
PARAMETER = [PERIOD, ENTRY_THRESHOLD, PROFIT_THRESHOLD]

# 最適化の設定
START_PERIOD = 250
END_PERIOD = 2500
STEP_PERIOD = 250
START_ENTRY_THRESHOLD = 0.001
END_ENTRY_THRESHOLD = 0.01
STEP_ENTRY_THRESHOLD = 0.001
START_PROFIT_THRESHOLD = 0.01
END_PROFIT_THRESHOLD = 0.1
STEP_PROFIT_THRESHOLD = 0.01
RRANGES = (
    slice(START_PERIOD, END_PERIOD, STEP_PERIOD),
    slice(START_ENTRY_THRESHOLD, END_ENTRY_THRESHOLD, STEP_ENTRY_THRESHOLD),
    slice(START_PROFIT_THRESHOLD, END_PROFIT_THRESHOLD, STEP_PROFIT_THRESHOLD),
)

def strategy(parameter, symbol, timeframe):
    '''戦略を記述する。
    Args:
        parameter: パラメーター。
        symbol: 通貨ペア。
        timeframe: 期間。

    Returns:
        シグナル。
    '''
    # パラメータを格納する。
    period = int(parameter[0])
    entry_threshold = float(parameter[1])
    profit_threshold = float(parameter[2])
    # 戦略を記述する。
    close1 = fs.i_close(symbol, timeframe, 1)
    hl_band1 = fs.i_hl_band(symbol, timeframe, period, 1)
    buy_entry = close1 <= hl_band1['low'] * (1 + entry_threshold / 100)
    buy_exit = (close1 >= hl_band1['low'] *
                (1 + (entry_threshold + profit_threshold) / 100))
    sell_entry = close1 != close1  # 売りはやらないので無意味な条件を与える。
    sell_exit = close1 != close1  # 同上。
    return (symbol, timeframe, buy_entry, buy_exit, sell_entry, sell_exit,
            LOTS, 0, 0)

②以下のコマンドをSpyderの「IPython console」にコピー&ペーストして「Enter」キーを押す。

%run -t ~/py/backtest.py --ea1 swiss_franc_shock --symbol1 EURCHF --spread1 2.0 --position1 0 --min_trade1 0 --timeframe 5 --start 2012.01.01 --end 2014.12.31

③以下のコマンドをSpyderの「IPython console」にコピー&ペーストして「Enter」キーを押す。

%run -t ~/py/backtest.py --ea1 swiss_franc_shock --symbol1 EURCHF --spread1 2.0 --position1 0 --min_trade1 0 --timeframe 5 --start 2012.01.01 --end 2015.12.31
(2017/02/27更新)

コメント

非公開コメント