『矢口新の短期トレード教室』のルールでバックテストをしてみました

『矢口新の短期トレード教室』を読みました。

矢口新さんの本は『実践 生き残りのディーリング』も読んだことがあって、こちらも良い本でした。

エントリーとエグジット

一番具体的で印象に残ったのは次のチャートでした。

では、実際の素のローソク足に番号を振って、エントリーとエグジット(仕込み、利食い、損切り)の詳しい解説を図5-3でいたします[編集部注:ローソク足が1本ずつ進むにつれ、どういう判断(対処)が必要なのかを学んでいただきたいため、次ページ以降、特殊な見せ方にしています。ご理解ください]。

矢口新の短期トレード教室 第5章 素のチャートで転換点を探ることが最も効率の良いやり方 第3節 素のチャートでエントリーとエグジットを考える

「特殊な見せ方」が特に良かったです。 具体的には次のような見せ方になっていました。

下のローソク足を見てください。 4本目の足で、前の2本を上抜けしたところ(点線)でロング(買い持ち)を作りました(3本目は「はらみ線」で様子見)。 買いで保有している状態です。

買った後の次の足(5本目)は前足を高値安値共に切り上げています。 評価益が出ていますね。 高値も安値も切り上げているので、買いポジションはそのままです。

矢口新の短期トレード教室 第5章 素のチャートで転換点を探ることが最も効率の良いやり方 第3節 素のチャートでエントリーとエグジットを考える

リアルタイムでチャートを見ながら解説してもらっている感じがあるので、思った以上に良い見せ方だと感じました。 先が見えた状態で解説されているものよりも(たとえ動画であったとしても)こちらの方が好みです。

基本的なエントリーとエグジットのルールは次のようになっているようです。

なお、ローソク足の基本的な値動きは以下の4つになります。 それを念頭に置いて、次ページ以降、読み進めてみてください。

  1. 前足を高値&安値共に切り上げる→買い(&売りポジションの利確)
  2. 前足の中に高値&安値が収まる(はらみ線)→様子見
  3. 前足を包むように高値&安値が形成される(抱き線)→様子見
  4. 前足を高値&安値共に切り下げる→売り(&買いポジションの利確)

矢口新の短期トレード教室 第5章 素のチャートで転換点を探ることが最も効率の良いやり方 第3節 素のチャートでエントリーとエグジットを考える

でも、解説を見ていくとわかりますけれども、もう少し柔軟にトレードしていました。

バックテスト

Python で次のようなバックテストの関数を作りました。

def test(df, pip=0.01, spread=0.3, unit=10000):
    sp = pip * spread * unit
    df2 = pd.concat([df, df['high'].shift(1), df['high'].shift(2), df['low'].shift(1), df['low'].shift(2)], axis=1)
    bs = pd.Series(np.full(df2.index.size, np.nan), index=df2.index)
    pl = pd.Series(np.full(df2.index.size, np.nan), index=df2.index)
    entry = ls = np.nan
    for row in df2.itertuples():
        time, open_, high, low, close, high1, high2, low1, low2 = row
        if np.isnan([high1, high2, low1, low2]).any():
            continue
        if high2 < high1 and low2 < low1:
            # 前足を高値&安値共に切り上げる
            if ls < 0:
                # 売りポジションの利確
                pl[time] = (open_ - entry) * unit * ls - sp
            if not 0 < ls:
                # 買いポジション以外
                # 買い
                bs[time] = ls = 1
                entry = open_
        if high1 < high2 and low1 < low2:
            # 前足を高値&安値共に切り下げる
            if 0 < ls:
                # 買いポジションの利確
                pl[time] = (open_ - entry) * unit * ls - sp
            if not ls < 0:
                # 売りポジション以外
                # 売り
                bs[time] = ls = -1
                entry = open_
    if not np.isnan(ls):
        pl[time] = (close - entry) * unit * ls - sp
    return bs, pl

ヒストリカルデータはこの記事を書いたときに作ったデューカスコピー・ジャパンのものを使いました。 まず、米ドル/円の日足の 2003/5/5~2018/1/2 までのデータを使ってバックテストをしてみました。 テストした結果は次の通りでした。 損益を折れ線グラフで表示しています。

結果的にマイナスになってしまったようです。

ざっくりと損益を評価してみました。

   
トレード数 1191
勝率(%) 39.46
平均利益 9762
平均損失 6438
平均利益÷平均損失 1.52
1トレード当たりの平均損益 -45
最大損失額 -412600
総損益 -54060

10,000 通貨単位でしかトレードしていないけれども、ドローダウンが 40 万円程度にもなってしまっていました…。

Python ローソク足とフラグを表示してみました」の記事を書いたときのように、売買したところにフラグを表示してみました。

「↑」がロング、「↓」がショートです。 ロングのところはショートのポジションを決済するところでもあり、ショートのところはロングのポジションを決済するところでもあります。

日足のヒストリカルデータを使っているため、ローソク足が確定してからエントリーとエグジットをしています。 高値安値を切り上げたら、次の足の始値でロングのエントリーです。 だからフラグが 1 本ずれたような見え方になっているかもしれません。

21 通貨ペアのバックテスト

21 通貨ペアでバックテストしました。 結果は次の通りでした。

  トレード数 勝率(%) 平均利益 平均損失 平均利益÷平均損失 1トレード当たりの平均損益 最大損失額 総損益
AUDJPY 1129 41.28 11593.88 7472.05 1.55 397.50 -479960.0 448780.0
AUDNZD 866 35.45 98.18 63.05 1.56 -5.89 -6747.7 -5101.0
AUDUSD 1156 40.22 100.03 64.76 1.54 1.52 -2649.9 1761.2
CADJPY 991 39.35 12173.13 8307.25 1.47 -247.37 -728370.0 -245140.0
CHFJPY 1156 37.11 10288.90 6570.94 1.57 -314.13 -448850.0 -363130.0
EURAUD 962 40.54 159.25 99.84 1.60 5.20 -3843.1 4999.8
EURGBP 1160 37.50 61.80 41.13 1.50 -2.53 -3479.3 -2934.9
EURJPY 1187 39.26 14300.04 8865.53 1.61 228.96 -304880.0 271770.0
EURUSD 1193 39.73 116.49 81.18 1.44 -2.64 -4722.5 -3147.4
GBPAUD 945 38.10 196.27 141.73 1.38 -12.97 -14125.9 -12252.2
GBPJPY 1144 41.08 20223.09 12029.55 1.68 1221.09 -433420.0 1396930.0
GBPUSD 1125 39.38 149.92 96.51 1.55 0.53 -6696.9 590.9
HKDJPY 865 29.02 1384.50 936.40 1.48 -262.94 -226470.0 -227440.0
NZDJPY 1011 40.95 10478.60 7000.10 1.50 157.35 -423630.0 159080.0
NZDUSD 1139 39.16 96.91 58.30 1.66 2.47 -3759.4 2816.7
SGDJPY 857 37.81 6722.19 4972.74 1.35 -551.32 -506230.0 -472480.0
USDCAD 1176 37.33 100.11 68.67 1.46 -5.66 -8118.6 -6660.2
USDCHF 1149 39.51 105.48 74.47 1.42 -3.37 -5825.7 -3868.4
USDHKD 721 40.92 39.62 21.82 1.82 3.32 -944.8 2392.0
USDJPY 1191 39.46 9762.09 6438.61 1.52 -45.39 -412600.0 -54060.0
USDSGD 1116 37.90 66.01 51.93 1.27 -7.23 -8444.3 -8065.0

総損益は一覧で比較するとあまり参考にはならなくて、決済通貨の単位の金額になっています( 1 米ドルと 100 円だったら数字としては 100 円の方が大きいですよね)。

勝率は 20% 台から 40% 台になっています。 50% を超えるものはありませんでした。

平均利益÷平均損失は 1.0~2.0 の間には収まっているようです。 単純なルールなのに 1.0 以上あることはなかなかいい感じです。

これらの期待値を計算してみました。

   
AUDJPY 0.052640
AUDNZD -0.092480
AUDUSD 0.021588
CADJPY -0.028055
CHFJPY -0.046273
EURAUD 0.054040
EURGBP -0.062500
EURJPY 0.024686
EURUSD -0.030588
GBPAUD -0.093220
GBPJPY 0.100944
GBPUSD 0.004190
HKDJPY -0.280304
NZDJPY 0.023750
NZDUSD 0.041656
SGDJPY -0.111465
USDCAD -0.081682
USDCHF -0.043858
USDHKD 0.153944
USDJPY -0.005608
USDSGD -0.139670

平均しました。

-0.0256

1 ドル賭けると 2 セント程度の損失になります。 10,000 円賭けると 250 円程度の損失になります。 いずれにしてもマイナスなのでトレードする意味がないことになります。

以前から感じていましたが、香港ドルとシンガポールドルが足を引っ張っているような気がします。 あまりテクニカルが効かないのかな? 投機の参加者が少ないとか?

参考程度に、香港ドルとシンガポールドルを除いて平均してみました。

-0.0094

10,000 円賭けると 90 円程度の損失にまで下がりました。 いずれにしてもマイナスのようでした。

考察

バックテストした結果は損失にはなってしまっていますが、以前の記事(これこれ)も踏まえて考えてみると、このトレードの考え方は今まで学んできたことと矛盾しないので、すんなり取り入れていけそうに感じています。

前回の記事でローソク足 1 本のトレンドを学びました。 今回も同じことが言えそうに感じました。 ローソク足2本を合わせて高値安値を切り上げていたらトレンド(トレードするところ)と判断しているように思います。 ダウ理論にも当てはめられそうです。

これを始値、安値、高値、終値の順番に折れ線グラフでつないでみました。

ダウ理論でいうトレンドのような高値安値を切り上げる様子が見えた気がします。 今までローソク足を見るときは始値と終値に注目していて、あまり高値と安値に注目していなかったかもしれません。 高値安値を切り上げる、または切り下げるローソク足を秩序と見る視点ができました。 点から線にスムーズにつながってきたような気がします。

終わり

機械的にルールに従っていたらポジションを常に持っている状態になります。 けれども、トレードをしてはいけないところを判断しないと利益は上げられなそうに思いました。

バックテストをしたときの Jupyter Notebook のファイルを Gist にアップロードしておきました。