ATRチャネル・ブレイクアウト
タートルズ流 投資の魔術 からの引用
ATRチャネル・ブレイクアウト・システムは、変動性の尺度として真の値幅の平均(ATR)を使用するものだ。チャネルは、350日の終値の移動平均にATRの7倍を加えたものを上限とし、ATRの3倍を引いたものを下限として形成される。前日の終値がチャネルの最高値を超えていたら寄り付きから買い持ちのトレードが仕掛けられ、前日の終値がチャネルの最安値より下回れば、売り持ちとなる。価格が戻して終値が移動平均とクロスしたら、取引は手じまいだ。
ATRチャネル・ブレイクアウト・システムのバリエーションのひとつは、PGO(プリティー・グッド・オシレーター)システムという名称で、チャック・ルボーズ・システムトレーダーズ・クラブ(www.traderclub.com)フォーラムのトレーダー、マーク・ジョンソンが普及させた。これは次に述べるボリンジャー・ブレイクアウト・システムの変形でもある。
ストラテジーを作成
https://gyazo.com/ba8c109b94b1fba004d82bcd699db0e3
※ 同じ期間と銘柄でチャートを出してみたものの、おそらく「つなぎ足と限月の違い」があり、まったく同じチャートにはならなかった
エントリーとイグジット
https://gyazo.com/c9d569e1f4b022c1b61a7d04deb7d46b
https://gyazo.com/6c10230039b5a4b637a3776e055d8633
バックテスト
期間
2005年1月1日 ~ 2017年12月31日
12年間
銘柄
為替(5):
USDJPY、EURJPY、GBPJPY、CHFJPY、CADJPY
株価指数(5):
日経225、NYダウ、ドイツDAX、イギリスFTSE、香港ハンセン
日本株(5):
6098リクルート、4452花王、5711三菱マテリアル、7201日産、9984ソフトバンクグループ
米株(5):
AAPLアップル、AXPアメリカン・エクスプレス、BAボーイング、JNJジョンソン・エンド・ジョンソン、MCDマクドナルド
海外商品(5):
金、白金、原油、コーン、大豆
その他
資金管理:単利
各主要な市場から5銘柄ずつピックアップしてテスト。
テスト1
table:テスト1設定
MA ATR Upper Lower Lossscut Pyramiding
350 20 7 3 None None
本に掲載されていたものとまったく同じテスト(と思われる)
table:テスト1結果
損益 最大DD 取引数 勝数 勝率 RR比 勝ち保有 負け保有
USDJPY 23.8 23.14 15 5 33.33 3.441 421 42
EURJPY 38.13 17.03 16 8 50 1.978 289 34
GBPJPY 162.40 8.92 9 5 55.56 7.959 519 36
CHFJPY 8.12 22.97 15 3 20 4.954 380 70
CADJPY -2.05 19.53 17 5 29.41 2.288 295 53
日経225 8494.24 6386.4 19 5 26.32 5.364 403 60
NYダウ 9202.67 1345.76 13 5 34.46 5.095 368 73
DAX 1688 3206.79 16 6 37.5 1.946 374 53
FTSE -431.4 3254.8 17 4 23.53 3.108 375 73
HSI 2072.38 16969.29 18 5 27.78 3.057 316 57
6098 1179.5 80 2 1 50 15.744 494 39
4452 794 1647 18 4 22.22 4.323 383 53
5711 -1095 3425 20 6 25 2.377 272 68
7201 -2113.2 2113.2 30 1 3.33 5.23 393 51
9984 2703 2070 16 6 37.5 3.018 315 50
AAPL 76.65 30.1 12 5 41.67 3.747 482 80
AXP 73.63 7.64 9 5 55.56 4.362 449 121
BA 186.1 39.07 12 5 41.67 5.994 421 61
JNJ 1.49 49.79 18 3 16.67 5.925 349 63
MCD 57.96 22.34 12 4 33.33 5.72 414 83
GOLD 88610 19470 8 4 50 3.056 587 59
PLATINUM 36915 16315 15 5 33.33 5.796 355 74
WTI 110 61140 19 5 26.32 3.265 264 37
CORN 3287.5 9750 16 4 25 3.948 306 98
SOY BEANS -6425 30412 21 4 19.05 4.026 320 55
TOTAL 383 113 29.5 4.09
破産の確率 0%
期待値/リスク 0.5
見込み損益 191.5
※ 「勝ち保有」「負け保有」は、保有期間(日)の平均
25銘柄12年間のテスト。サンプル数は383トレードと少し心もとない。
破産の確率はゼロ。おおむねほとんどの銘柄でゼロ以上の成績。TradingViewのバックテストには、残念ながら年ごとの統計をとる機能がないため詳細はわからないが、ものの数十分でイチからこれだけのテストができるので非常に優秀だと思う。
日本株が、他の市場と比べると不向きかもしれない。
簡易的に計算した期待値だが、プラスになった。
$ WIN \times RR- | 1-WIN|
WIN: 勝率、RR: RR比率
テスト2
table:テスト2設定
MA ATR Upper Lower Lossscut Pyramiding ATR-N(Pyramiding)
350 20 7 3 None 4 10
ピラミッティングを導入して、少し攻撃的に。
table:テスト2結果
損益 最大DD 取引数 勝数 勝率 RR比 勝ち保有 負け保有
USDJPY 72.78 32.87 20 8 40 3.71 540 72
EURJPY -3.18 32.21 27 10 37.04 1.644 309 95
GBPJPY 327.2 25.43 21 14 66.67 3.689 517 83
CHFJPY 15.12 48.63 22 6 27.27 3.296 458 73
CADJPY -56.29 64.3 28 9 32.14 0.983 283 86
日経225 27987.02 10273.46 29 12 41.38 4.917 371 82
NYダウ 16318.82 6114.77 26 13 50 2.823 315 98
DAX 6360.26 3557.44 25 12 48 2.087 393 87
FTSE -368.5 5365.4 25 9 36 2.199 361 77
HSI 5674.91 39666.1 18 5 27.78 3.057 316 57
6098 4095 80 5 4 80 13.047 207 39
4452 8769 1793 25 9 37.5 5.522 373 57
5711 -3155 8070 29 10 34.48 1.338 240 87
7201 -3057 3057 35 2 5.71 2.597 365 57
9984 2802 4654 27 10 37.04 2.264 305 82
AAPL 252.59 59.72 26 15 57.69 3.034 395 120
AXP 109.16 14.78 17 11 64.71 2.222 368 141
BA 510.62 46.68 24 14 58.33 4.417 357 93
JNJ 48.62 41.33 23 7 30.43 4.188 373 67
MCD 135.3 32.16 21 11 52.38 3.568 321 103
GOLD 259110 19470 15 11 73.33 2.666 552 59
PLATINUM 36540 41000 26 11 42.31 2.078 295 97
WTI -5630 91700 27 8 29.63 2.285 287 69
CORN -22600 33025 23 6 26.09 1.449 321 107
SOY BEANS 16112.5 54475 27 8 29.63 2.875 324 59
Total 591 235 39.76% 3.10
破産の確率 0%
期待値/リスク 0.63
※ 「勝ち保有」「負け保有」は、保有期間(日)の平均
今回のストラテジーには、いくつかよく使う機能を実装したが、その中のピラミッティングを利用。少しだけ攻めのストラテジーにしてみた。
期待値が、「0.5 → 0.63」と上昇した。
考察
単一銘柄だと勝てない。分散投資必要。
その銘柄が悪いわけではない(悪い場合もある)。穀物は季節性があり、価格の変動にも限度があると考える。そういう銘柄は長期のトレンドが出づらく不利かも。こういった特殊な事例を除けば、どんな銘柄でも大きなトレンドが発生する可能性はある。しかし、どれが上がるか、いつ上がるか、予想することはできない。そこで、分散投資が必要なる。
今でも十分通用する
分散投資すれば十分通用する。問題は以下。
勝率が低い。長期間運用する必要がある。トレード数が圧倒的に少ない。
シンプルで堅固なシステムであると考える。
ここではやらないが、他の期間でもプラスになると考える。少なくとも「投資の魔術」で検証していた期間もプラスであった。
Pineスクリプト
code:Pineスクリプト(js)
//@version=3
strategy("Strategy Turtle ATR Chanel Break Out"
,default_qty_type=strategy.fixed
,default_qty_value=1
,pyramiding=4
,overlay=true)
src = close
len = input(350 ,minval=1 ,title="ma length")
atr_len = input(20 ,minval=1 ,title="band atr length")
up_n = input(7 ,minval=1 ,title="atr upper length")
low_n = input(3 ,minval=1 ,title="atr lower length")
SO_bool = input(false,type=bool ,title="loss cut")
SO_len = input(20 ,type=integer ,minval=1 ,title="loss cut ATR length")
SO_N = input(2 ,type=float ,minval=0.5 ,title="loss cut ATR*N")
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(10 ,type=float ,minval=0.5 ,title="pyramiding ATR*N")
Tm_bool = input(false,type=bool ,title="timed exit")
Tm_len = input(80 ,type=integer ,minval=1 ,title="timed exit length")
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)
EMA = ema(close ,len)
ATR = ema(tr ,atr_len)
UPPER = EMA + ATR * up_n
LOWER = EMA - ATR * low_n
atr_SO_ = ema(tr ,SO_len)
atr_LO_ = ema(tr ,LO_len)
atr_SO = atr_SO_*SO_N
atr_LO = atr_LO_*LO_N
countTradingDays = na
countNonTradingDays = na
countTradingDays := strategy.position_size==0 ? 0 : countTradingDays1 + 1 countNonTradingDays := strategy.position_size!=0 ? 0 : countNonTradingDays1 + 1 entry1 = close
entry2 = close
entry3 = close
entry4 = close
entry1 := strategy.position_size==0 ? na : entry11 entry2 := strategy.position_size==0 ? na : entry21 entry3 := strategy.position_size==0 ? na : entry31 entry4 := strategy.position_size==0 ? na : entry41 lo2 = close
lo3 = close
lo4 = close
lo2 := strategy.position_size==0 ? na : lo21 lo3 := strategy.position_size==0 ? na : lo31 lo4 := strategy.position_size==0 ? na : lo41 losscut = close
losscut := strategy.position_size==0 or SO_bool==false ? na : losscut1 L_EntrySig = close >= UPPER and isWork
S_EntrySig = close <= LOWER and isWork
if(strategy.position_size != 0)
L_ExitSig = (close <= EMA or S_EntrySig) and strategy.position_size > 0
S_ExitSig = (close >= EMA or L_EntrySig) and strategy.position_size < 0
TimedSig = countTradingDays > Tm_len and Tm_bool
strategy.close_all(when = L_ExitSig or S_ExitSig or TimedSig or not isWork)
if(L_ExitSig or S_ExitSig)
entry1 := na
entry2 := na
entry3 := na
entry4 := na
lo2 := na
lo3 := na
lo4 := na
losscut := na
if(strategy.position_size > 0)
lo_sig2 = lo2 < high
lo_sig3 = lo3 < high
lo_sig4 = lo4 < high
if(lo_sig2 and MAX_N >= 2)
if(SO_bool)
strategy.entry("L-Entry2" ,strategy.long ,stop=close-atr_SO ,comment="L-Entry2")
strategy.exit("L-Entry1" ,stop=close-atr_SO)
else
strategy.entry("L-Entry2" ,strategy.long ,comment="L-Entry2")
lo2 := na
losscut := SO_bool ? close - atr_SO : na
if(lo_sig3 and MAX_N >= 3)
if(SO_bool)
strategy.entry("L-Entry3" ,strategy.long ,stop=close-atr_SO ,comment="L-Entry3")
strategy.exit("L-Entry2" ,stop=close-atr_SO)
strategy.exit("L-Entry1" ,stop=close-atr_SO)
else
strategy.entry("L-Entry3" ,strategy.long ,comment="L-Entry3")
lo3 := na
losscut := SO_bool ? close - atr_SO : na
if(lo_sig4 and MAX_N >= 4)
if(SO_bool)
strategy.entry("L-Entry4" ,strategy.long ,stop=close-atr_SO ,comment="L-Entry4")
strategy.exit("L-Entry3" ,stop=close-atr_SO)
strategy.exit("L-Entry2" ,stop=close-atr_SO)
strategy.exit("L-Entry1" ,stop=close-atr_SO)
else
strategy.entry("L-Entry4" ,strategy.long ,comment="L-Entry4")
lo4 := na
losscut := SO_bool ? close - atr_SO : na
if(strategy.position_size < 0)
lo_sig2 = lo2 > low
lo_sig3 = lo3 > low
lo_sig4 = lo4 > low
if(lo_sig2 and MAX_N >= 2)
if(SO_bool)
strategy.entry("S-Entry2" ,strategy.short ,stop=close+atr_SO ,comment="S-Entry2")
strategy.exit("S-Entry1" ,stop=close+atr_SO)
else
strategy.entry("S-Entry2" ,strategy.short ,comment="S-Entry2")
lo2 := na
losscut := SO_bool ? close + atr_SO : na
if(lo_sig3 and MAX_N >= 3)
if(SO_bool)
strategy.entry("S-Entry3" ,strategy.short ,stop=close+atr_SO ,comment="S-Entry3")
strategy.exit("S-Entry2" ,stop=close+atr_SO)
strategy.exit("S-Entry1" ,stop=close+atr_SO)
else
strategy.entry("S-Entry3" ,strategy.short ,comment="S-Entry3")
lo3 := na
losscut := SO_bool ? close + atr_SO : na
if(lo_sig4 and MAX_N >= 4)
if(SO_bool)
strategy.entry("S-Entry4" ,strategy.short ,stop=close+atr_SO ,comment="S-Entry4")
strategy.exit("S-Entry3" ,stop=close+atr_SO)
strategy.exit("S-Entry2" ,stop=close+atr_SO)
strategy.exit("S-Entry1" ,stop=close+atr_SO)
else
strategy.entry("S-Entry4" ,strategy.short ,comment="S-Entry4")
lo4 := na
losscut := SO_bool ? close + atr_SO : na
if((L_EntrySig or S_EntrySig) and strategy.position_size==0)
countTradingDays := 0
entry1 := close
if(L_EntrySig)
if(SO_bool)
strategy.entry("L-Entry1" ,strategy.long ,stop=close-atr_SO ,comment="L-Entry1")
else
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
losscut := SO_bool ? close - atr_SO : na
if(S_EntrySig)
if(SO_bool)
strategy.entry("S-Entry1" ,strategy.short ,stop=close+atr_SO ,comment="S-Entry1")
else
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
losscut := SO_bool ? close + atr_SO : 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)
plot(lo2 ,title="lo2" ,color=red ,transp=0)
plot(lo3 ,title="lo3" ,color=red ,transp=0)
plot(lo4 ,title="lo4" ,color=red ,transp=0)
plot(losscut ,title="losscut" ,color=red ,transp=0)
plot(atr_SO ,transp=0 ,title="ATR_SO")
plot(atr_LO ,transp=0 ,title="ATR_LO")
// plot(strategy.max_drawdown ,transp=50 ,title="最大DD")
// plot(strategy.equity, title="equity", color=red, linewidth=2, style=areabr)
p1 = plot(UPPER ,color=#303F9F ,title="UPPER" ,style=line ,linewidth=2, transp=0)
p2 = plot(LOWER ,color=#4CAF50 ,title="LOWER" ,style=line ,linewidth=2, transp=0)
plot(EMA ,color=red ,title="EMA" ,style=line ,linewidth=2 ,transp=0)
fill(p1 ,p2 ,color=#2196F3 ,title="fill" ,transp=60)