どんな記事
ありきたりな移動平均線のゴールデンクロスとデットクロスを使った手法でも、長期で運用すると(統計的には)利益がでます。この記事では、その結論にいたる〝バックテストの結果〟をご紹介 します。
タートルズ流 投資の魔術 からの引用
まずは、「ダブル移動平均」について書かれている箇所を、書籍「伝説のトレーダー集団 タートルズ流投資の魔術」から引用します。
100日移動平均が、それより動きの遅い350日移動平均とクロスして上に抜いたときに売買を行うという非常に単純なシステムだ。他のシステムと異なり、このシステムは、買い持ち売り持ちにかかわらず、つねに市場にあらわれる。唯一の退出時は、動きの速いほうの移動平均が遅いほうの移動平均とクロスして下に抜いたときで、この時点で手じまいし、逆方向に新しい取引を仕掛けることになる。
(中略)
おそらくおわかりだろうが、このシステムは非常に長期のトレンドフォロー・システムで、他の大半のシステムのように頻繁にトレードが行われるわけではない。
「このシステムは、買い持ち売り持ちにかかわらず、つねに市場にあらわれる」
つまり、常に「何かしらのポジションを保有するシステム」であるということです。この記事は、上記の手法を TradingView で再現することを目的としたものです。
ストラテジーを作成
エントリーとイグジット
非常にシンプルなスキームです。ゴールデンクロスとデットクロスで途転どてん(決済して反対の方向のエントリー)して常に市場にポジションを保有し続けます。
買いエントリー
- 「EMA100 と EMA350 のゴールデンクロス(上抜け)」で買いエントリー
- 「EMA100 と EMA350 のデッドクロス(下抜け)」で決済
※ EMA●●:●●日指数平滑移動平均
売りエントリー
- 「EMA100 と EMA350 のデッドクロス(下抜け)」で売りエントリー
- 「EMA100 と EMA350 のゴールデンクロス(上抜け)」で決済
バックテスト
同じ条件で手法を比べるために、以下の「基本条件」でテストしていきます。
バックテストの基本条件
期間
- 2005年1月1日 ~ 2017年12月31日(12年間)
資金管理
- 単利
銘柄
為替 | USDJPY、EURJPY、GBPJPY、CHFJPY、CADJPY |
株価指数 | NKY日経225、DJI NYダウ、DAXドイツ、UKXイギリスFTSE、HSI香港ハンセン |
日本株 | 6098リクルート、4452花王、5711三菱マテリアル、7201日産、9984ソフトバンクグループ |
米株 | AAPLアップル、AXPアメリカン・エクスプレス、BAボーイング、JNJジョンソン・エンド・ジョンソン、MCDマクドナルド |
海外商品 | 金、白金、原油、コーン、大豆 |
手法は、市場との相性があるケースも多いので、主要な各市場から5銘柄ずつピックアップしてテストしています。
テスト1
まずは、本に掲載されていたものと同じ設定でバックテストをしてみます。
テスト1 設定
EMA-m | EMA-l | Pyramiding |
---|---|---|
100 | 350 | None |
テスト1 結果
損益 | 最大DD | 取引数 | 勝数 | 勝率 | RR比 | |
---|---|---|---|---|---|---|
Total | 226 | 85 | 37.61 | 2.977 | ||
USDJPY | 41.34 | 15.34 | 8 | 3 | 37.50 | 4.385 |
EURJPY | 49.40 | 13.25 | 10 | 4 | 40.00 | 6.943 |
GBPJPY | 153.82 | 4.68 | 5 | 4 | 80.00 | 8.474 |
CHFJPY | 9.71 | 15.31 | 11 | 4 | 36.36 | 2.603 |
CADJPY | 13.42 | 9.42 | 7 | 5 | 71.43 | 0.713 |
NKY | 7866.50 | 3678.93 | 8 | 3 | 37.50 | 3.779 |
DJI | 4054.13 | 4339.95 | 8 | 3 | 37.50 | 2.869 |
DAX | 4927.09 | 1897.55 | 9 | 4 | 44.44 | 3.318 |
UKX | 286.50 | 1842.60 | 9 | 5 | 55.56 | 0.908 |
HSI | 4145.36 | 4376.54 | 7 | 3 | 42.86 | 2.596 |
6098 | -171.50 | 171.50 | 1 | 0 | 0.00 | - |
4452 | 2072.00 | 973.00 | 8 | 3 | 37.50 | 3.813 |
5711 | -2560.00 | 4980.00 | 13 | 3 | 23.08 | 1.644 |
7201 | -604.50 | 984.50 | 15 | 4 | 26.67 | 1.423 |
9984 | 3873.00 | 1417.00 | 9 | 5 | 55.56 | 2.217 |
AAPL | 39.72 | 17.66 | 6 | 3 | 50.00 | 2.077 |
AXP | 63.67 | 0.00 | 4 | 4 | 100.00 | - |
BA | 55.69 | 24.89 | 6 | 3 | 50.00 | 2.339 |
JNJ | -13.11 | 51.69 | 13 | 2 | 15.38 | 4.348 |
MCD | 45.26 | 10.85 | 12 | 5 | 41.67 | 5.900 |
GOLD | 92450.00 | 33150.00 | 7 | 3 | 42.86 | 4.120 |
PLATINUM | 3530.00 | 17745.00 | 7 | 3 | 42.86 | 1.459 |
WTI | -30520.00 | 65700.00 | 15 | 3 | 20.00 | 2.569 |
CORN | -1587.50 | 11587.50 | 11 | 3 | 27.27 | 2.496 |
SOY BEANS | -105862.50 | 105862.50 | 17 | 3 | 17.65 | 0.732 |
※「勝ち保有」「負け保有」は、保有期間(日)の平均。※ RR比はGBPJPYと6098、AXPを除いた数値。
結果の良し悪しの差が激しいですね。大きく長期のトレンドが発生すると、かなり良い成績になるようです。
- 「勝率」も「RR比」も、わりと良い
- 保有期間が長い(4年近いものも)
- 取引回数はボリンジャーの方が少なかった
テスト1 統計
破産の確率 | 期待値/リスク | 収益の見込み |
---|---|---|
0.00% | 0.496 | 112.064 |
破産の確率は、損失の許容=2%で算出しています。期待値と収益の見込みは以下の計算式で算出しています。
期待値も6098とAXPのRR比が含まれていないことに注意が必要ですが、おおむね良い数値であることには間違いなさそうです。ただの移動平均のクロスですが、超長期で用いるとわりと優秀な手法であることがわかります。
短期で用いた場合はさておき、超長期の移動平均の手法は有効そうです。
テスト2
次に、ピラミッティングを試してみます。
テスト2 設定
EMA-m | EMA-l | Pyramiding |
---|---|---|
100 | 350 | 1-ATR 上限4 |
初回を含めて、4回エントリーします。
テスト2 結果
損益 | 最大DD | 取引数 | 勝数 | 勝率 | RR比 | |
---|---|---|---|---|---|---|
Total | 728 | 303 | 41.62% | 2.340 | ||
USDJPY | 185.72 | 45.90 | 24 | 11 | 45.83 | 4.477 |
EURJPY | 162.18 | 35.78 | 28 | 16 | 57.14 | 3.544 |
GBPJPY | 566.60 | 27.47 | 20 | 16 | 80.00 | 5.407 |
CHFJPY | -1.85 | 82.78 | 36 | 9 | 25.00 | 2.946 |
CADJPY | 31.48 | 38.78 | 25 | 14 | 56.00 | 1.210 |
NKY | 28636.40 | 13861.20 | 28 | 12 | 42.86 | 2.981 |
DJI | 24690.41 | 10433.16 | 20 | 12 | 60.00 | 2.072 |
DAX | 15342.12 | 8051.42 | 32 | 16 | 50.00 | 2.119 |
UKX | -160.40 | 6821.70 | 30 | 17 | 56.67 | 0.748 |
HSI | -1763.40 | 32369.11 | 28 | 10 | 35.71 | 1.703 |
6098 | -591.50 | 591.50 | 4 | 0 | 0.00 | - |
4452 | 10964.00 | 1255.00 | 22 | 12 | 54.55 | 4.204 |
5711 | -9635.00 | 17335.00 | 40 | 9 | 22.50 | 1.540 |
7201 | -2599.40 | 4017.40 | 48 | 13 | 27.08 | 1.217 |
9984 | 12229.00 | 5325.00 | 33 | 20 | 60.61 | 1.528 |
AAPL | 134.06 | 81.18 | 22 | 12 | 54.55 | 1.537 |
AXP | 225.01 | 0.00 | 16 | 16 | 100.00 | - |
BA | 166.51 | 138.68 | 22 | 12 | 54.55 | 1.580 |
JNJ | -24.16 | 190.22 | 41 | 8 | 19.51 | 3.653 |
MCD | 179.66 | 20.20 | 25 | 13 | 52.00 | 5.224 |
GOLD | 388110.00 | 103960.00 | 22 | 12 | 54.55 | 3.645 |
PLATINUM | -6890.00 | 89870.00 | 24 | 12 | 50.00 | 0.953 |
WTI | -144590.00 | 286560.00 | 45 | 9 | 20.00 | 2.320 |
CORN | -26737.50 | 52500.00 | 40 | 12 | 30.00 | 1.742 |
SOY BEANS | -331950.00 | 331950.00 | 53 | 10 | 18.87 | 0.666 |
- 「取引回数」 226 → 728
- 「勝率」 37.61% → 41.62%
- 「RR比」 2.977 → 2.340
勝率が改善したものの、RR比は悪化。期待値にしてみないとわからないですね。
テスト2 統計
破産の確率 | 期待値/リスク | 収益の見込み |
---|---|---|
0.00% | 0.390 | 284.052 |
破産の確率は、損失の許容=2%で算出しています。期待値と収益の見込みは以下の計算式で算出しています。
- 「期待値」 0.496 → 0.390
- 「見込み収益」 112.064 → 284.052
期待値としては悪化しましたが、取引回数が増加しているため「見込み収益」は大きく改善。ピラミッティングは良い施策であると言えそうです。これで破産の確率が上昇していたら問題ですが、それもなし。
テスト3
さて、最後に EMA の期間をかえて試してみたいと思います。
テスト3 設定
EMA-m | EMA-l | Pyramiding |
---|---|---|
50 | 350 | None |
EMA100 を「50」に。ピラミッティングも「None」にします。
テスト3 結果
損益 | 最大DD | 取引数 | 勝数 | 勝率 | RR比 | |
---|---|---|---|---|---|---|
Total | 315 | 91 | 28.89% | 3.361 | ||
USDJPY | 28.45 | 23.15 | 12 | 3 | 25.00 | 5.249 |
EURJPY | 46.07 | 19.08 | 13 | 6 | 46.15 | 2.358 |
GBPJPY | 170.22 | 10.85 | 9 | 4 | 44.44 | 12.471 |
CHFJPY | 11.70 | 21.77 | 15 | 4 | 26.67 | 3.498 |
CADJPY | 12.42 | 29.89 | 15 | 4 | 26.67 | 3.433 |
NKY | 8839.93 | 5606.54 | 10 | 3 | 30.00 | 5.220 |
DJI | 1870.67 | 4827.98 | 10 | 4 | 40.00 | 1.902 |
DAX | 1770.71 | 3561.47 | 11 | 4 | 36.36 | 2.263 |
UKX | -961.90 | 2739.30 | 13 | 4 | 30.77 | 1.594 |
HSI | 6376.26 | 6779.19 | 13 | 4 | 30.77 | 4.353 |
6098 | -105.00 | 105.00 | 1 | 0 | 0.00 | - |
4452 | 1806.00 | 1501.00 | 12 | 3 | 25.00 | 4.982 |
5711 | -440.00 | 3740.00 | 17 | 3 | 17.65 | 4.251 |
7201 | -1097.00 | 1403.00 | 29 | 4 | 13.79 | 2.587 |
9984 | 1277.00 | 2587.00 | 15 | 5 | 33.33 | 2.526 |
AAPL | 50.79 | 16.15 | 6 | 3 | 50.00 | 2.783 |
AXP | 84.01 | - | 4 | 4 | 100.00 | - |
BA | 71.02 | 20.43 | 6 | 4 | 66.67 | 1.581 |
JNJ | -9.44 | 50.25 | 19 | 3 | 15.79 | 4.529 |
MCD | 30.53 | 10.85 | 8 | 3 | 37.50 | 4.196 |
GOLD | 103450.00 | 17030.00 | 7 | 4 | 57.14 | 3.145 |
PLATINUM | 20530.00 | 23090.00 | 10 | 4 | 40.00 | 2.464 |
WTI | -42390.00 | 91150.00 | 20 | 4 | 20.00 | 2.448 |
CORN | -1175.00 | 9100.00 | 17 | 3 | 17.65 | 4.473 |
SOY BEANS | -86150.00 | 86350.00 | 23 | 4 | 17.39 | 1.263 |
- 「取引回数」 226 → 315
- 「勝率」 37.61% → 28.89%
- 「RR比」 2.977 → 3.361
今度は、勝率が悪化して、RR比が改善。「期待値」を算出してみます。
テスト3統計
破産の確率 | 期待値/リスク | 収益の見込み |
---|---|---|
0.07% | 0.260 | 81.835 |
破産の確率は、損失の許容=2%で算出しています。期待値と収益の見込みは以下の計算式で算出しています。
期待値と見込み収益ともに大きく悪化。取引回数が増えたもののカバーできず。破産の確率も、まだ問題のない範囲ではありますが悪化しています。やはり勝率とRR比だけではなかなか判断がつかないですね。
考察
- コモディティは超長期の手法に向いていないのかもしれない
- 超長期で EMA のクロスがワークするのは、競合が少なく、価格操作が容易ではないためか
ここ最近、超長期のバックテストを行っていて、ふとこんなことを考えていました。
コモディティは超長期の手法に向いていない
これは、とくに「WTI、Corn、SoyBeans」あたりです。
このあたりのコモディティって、わりと「適正価格」というものがあって、そこから大きく乖離することが少ないです。例えば原油は今「数十ドル」ですが、この価値が半分や倍になるなんてことはあまり起きないわけです。「これはコモディティならではなのかな」なんて思います。
あとは、わりと日本株も負けがち。米株はよく勝てるのに。
超長期でEMAのクロスがワークするのは何故か
最初はとくに不思議には思わなかったのですが、よくよく考えてみると疑問をもちます。
「なぜ、短期でワークしない EMA のクロスが長期では有効なのか――」
いくつか思い当たる理由があります。
一つは、競合が少ないということです。
一般的によくトレードされる足種、日足とか4時間足、1時間足などは投資家がたくさんいます。投資家がたくさんいるということは、彼らをだまそうとする動きも多くでてくるはずです。
今回は行っていませんが、1980年あたりの価格でバックテストすると単純なブレイクアウトの手法が非常に有効だったりします。しかし、ここ最近では優位性が大きく損なわれています。何が原因なのか明確にはわかりませんが、投資家が多い時間軸において、そういう 〝だまし〟のような値動きが多い ことは間違いないと思います。
もう一つは、価格操作が容易ではないということです。
超長期の価格を操作しようと考えたときに、膨大な資金力がないとなし得ないことは簡単に想像ができます。例えファンドであっても、長期間にわたって価格に影響をあたえ続けることは困難です。ファンドの影響の少ない安全圏であるのではないかと考えています。
とはいえ、超長期の手法は「すぐに結果がでない」「損失を長く放置しなくてはいけない」など、ハードルが非常に高いです。だからこそ競合が少ないのだと思います。
(筆者は実践してみていますが、)安易にできる手法ではないので、導入する際には注意が必要です。
Pineスクリプト
今回行ったバックテストに用いたストラテジーのコード(Pineスクリプト)を公開します。販売や二次配布以外は自由にご利用いただいて差し支えありません。ご自由にお使いください!
strategy("Strategy Turtle Double EMA"
,default_qty_type=strategy.fixed
,default_qty_value=1
,pyramiding=4
,overlay=true)
src = close
M = input(50 ,minval=1 ,title="middle_")
L = input(350 ,minval=1 ,title="long_")
MAX_N = input(1 ,type=integer ,minval=1 ,maxval=4 ,title="maximun num of unit")
LO_len = input(20 ,type=integer ,minval=1 ,title="pyramiding ATR length")
LO_N = input(1 ,type=float ,minval=0.5 ,title="pyramiding ATR*N")
fromYear = input(2005 ,type=integer ,minval=1900 ,title="test start")
endYear = input(2017 ,type=integer ,minval=1900 ,title="test end")
isWork = timestamp(fromYear ,1 ,1 ,00 ,00) <= time and time < timestamp(endYear+1 ,1 ,1 ,00 ,00)
M_ = ema(close ,M)
L_ = ema(close ,L)
atr_LO_ = ema(tr ,LO_len)
atr_LO = atr_LO_*LO_N
countTradingDays = na
countNonTradingDays = na
countTradingDays := strategy.position_size==0 ? 0 : countTradingDays[1] + 1
countNonTradingDays := strategy.position_size!=0 ? 0 : countNonTradingDays[1] + 1
entry1 = close
entry2 = close
entry3 = close
entry4 = close
entry1 := strategy.position_size==0 ? na : entry1[1]
entry2 := strategy.position_size==0 ? na : entry2[1]
entry3 := strategy.position_size==0 ? na : entry3[1]
entry4 := strategy.position_size==0 ? na : entry4[1]
lo2 = close
lo3 = close
lo4 = close
lo2 := strategy.position_size==0 ? na : lo2[1]
lo3 := strategy.position_size==0 ? na : lo3[1]
lo4 := strategy.position_size==0 ? na : lo4[1]
L_EntrySig = M_ >= L_
S_EntrySig = M_ <= L_
lo_sig2 = strategy.position_size>0 ? lo2 < high : strategy.position_size<0 ? lo2 > low : na
lo_sig3 = strategy.position_size>0 ? lo3 < high : strategy.position_size<0 ? lo3 > low : na
lo_sig4 = strategy.position_size>0 ? lo4 < high : strategy.position_size<0 ? lo4 > low : na
if(strategy.position_size != 0)
L_ExitSig = S_EntrySig and strategy.position_size > 0
S_ExitSig = L_EntrySig and strategy.position_size < 0
strategy.close_all(when = L_ExitSig or S_ExitSig)
if(L_ExitSig or S_ExitSig)
entry1 := na
entry2 := na
entry3 := na
entry4 := na
lo2 := na
lo3 := na
lo4 := na
if(strategy.position_size > 0)
if(lo_sig2 and MAX_N >= 2)
lo2 := na
strategy.entry("L-Entry2" ,strategy.long ,comment="L-Entry2")
if(lo_sig3 and MAX_N >= 3)
lo3 := na
strategy.entry("L-Entry3" ,strategy.long ,comment="L-Entry3")
if(lo_sig4 and MAX_N >= 4)
lo4 := na
strategy.entry("L-Entry4" ,strategy.long ,comment="L-Entry4")
if(strategy.position_size < 0)
if(lo_sig2 and MAX_N >= 2)
lo2 := na
strategy.entry("S-Entry2" ,strategy.short ,comment="S-Entry2")
if(lo_sig3 and MAX_N >= 3)
lo3 := na
strategy.entry("S-Entry3" ,strategy.short ,comment="S-Entry3")
if(lo_sig4 and MAX_N >= 4)
lo4 := na
strategy.entry("S-Entry4" ,strategy.short ,comment="S-Entry4")
if((L_EntrySig or S_EntrySig) and isWork and strategy.position_size==0)
countTradingDays := 0
entry1 := close
if(L_EntrySig)
strategy.entry("L-Entry1" ,strategy.long ,comment="L-Entry1")
lo2 := MAX_N >= 2 ? close + atr_LO : na
lo3 := MAX_N >= 3 ? close + atr_LO * 2 : na
lo4 := MAX_N >= 4 ? close + atr_LO * 3 : na
if(S_EntrySig)
strategy.entry("S-Entry1" ,strategy.short ,comment="S-Entry1")
lo2 := MAX_N >= 2 ? close - atr_LO : na
lo3 := MAX_N >= 3 ? close - atr_LO * 2 : na
lo4 := MAX_N >= 4 ? close - atr_LO * 3 : na
plot(strategy.position_size ,transp=0 ,title="保有ポジションの数")
plot(strategy.openprofit ,transp=0 ,title="未決済の損益")
plot(strategy.netprofit ,transp=0 ,title="決済済みの損益")
plot(strategy.closedtrades ,transp=0 ,title="決済済み取引数")
plot(countTradingDays ,transp=0 ,title="取引日数")
plot(countNonTradingDays ,transp=0 ,title="ノンポジ日数")
plot(entry1 ,title="entry1" ,color=blue ,transp=0 ,style=linebr)
plot(lo2 ,title="lo2" ,color=red ,transp=0 ,style=linebr)
plot(lo3 ,title="lo3" ,color=red ,transp=0 ,style=linebr)
plot(lo4 ,title="lo4" ,color=red ,transp=0 ,style=linebr)
plot(atr_LO ,transp=0 ,title="ATR_LO")
plot(L_ ,color=#303F9F ,title="長期EMA" ,style=line ,linewidth=2, transp=0)
plot(M_ ,color=#4CAF50 ,title="中期EMA" ,style=line ,linewidth=2, transp=0)
TradingViewでも公開しています!
TradingView のインジケーターの検索で「Turtle Double」と検索するとでてきます。上記のコードと同じストラテジーを使用することができます。
バックテストならTradingView
TradingViewのテストは大変便利で、
- かなり自由の効くバックテストを
- 短時間で簡単に、
- 価格データを用意することなく
- 豊富な銘柄と足種を対象に
行うことができます。
一方で、その簡便さと引き換えに「TradingViewではできないバックテスト」も多くあります。
たとえば「分散投資」や「資金管理」があげられますが、これらは投資において非常に重要な要素でもあり、これらを含めたバックテストをするならリアルさが不可欠です。こういったバックテストをするためには、やはりPythonなどのプログラミング言語で自作していくしかないと考えています。
とはいえ、TradingViewが便利であることは間違いなく、最近では、手法の検証はTradingViewで行い、良い手法が見つかったら更に詳細なテストをPythonで行うようにしています。できるものはTradingViewでサクサクやってしまいます。
わりと、30分くらいあればインジケーターを作成することもできます。便利。

- 記事をシェア