ボリンジャー・ブレイクアウト
タートルズ流 投資の魔術 からの引用
このシステムは、1992年に出版されたチャック・ルボーとデビット・ルーカスの共著『マーケットのテクニカル秘録』で説明されている(チャネル幅にさまざまな日数の移動平均とさまざまな標準偏差を用いている)。
ボリンジャー・バンドはジョン・ボリンジャーによって考案された変動性チャネルだ。これは、終値の350日移動平均に標準偏差の2.5倍を加算・減算したもので、前日の終値がチャネルの上限を超えたら、寄り付きから買い持ちのトレードを仕掛け、前日の終値がチャネルの下限を下回れば、売り持ちとなる。終値が移動平均値とクロスして下へ抜けたら、取引は手じまいだ。
ストラテジーを作成
https://gyazo.com/5caac7b94d8bb7f7cb9bc8d0f21b4d61
※ 同じ期間と銘柄でチャートを表示。ほぼ同じ形に。
エントリーとイグジット
https://gyazo.com/73b2cd7c51f9176833ba47ee973259aa
https://gyazo.com/0ad8bc1c4064c599dc407eba3db4aaad
バックテスト
期間
2005年1月1日 ~ 2017年12月31日
12年間
銘柄
為替(5):
USDJPY、EURJPY、GBPJPY、CHFJPY、CADJPY
株価指数(5):
NKY 日経225、DJI NYダウ、DAX ドイツ、UKX イギリス、HSI 香港ハンセン
日本株(5):
6098リクルート、4452花王、5711三菱マテリアル、7201日産、9984ソフトバンクグループ
米株(5):
AAPLアップル、AXPアメリカン・エクスプレス、BAボーイング、JNJジョンソン・エンド・ジョンソン、MCDマクドナルド
海外商品(5):
金、白金、原油、コーン、大豆
その他
資金管理:単利
各主要な市場から5銘柄ずつピックアップしてテスト。
テスト1
table:テスト1設定
MA Stdev upper Stdev lower Losscut Pyramiding
350 2.5 2.5 None None
本に掲載されていたものとまったく同じテスト(と思われる)
table:テスト1結果
損益 最大DD 取引数 勝数 勝率 RR比 勝ち保有 負け保有
USDJPY 48.64 4.98 5 3 60.00 5.889 600 167
EURJPY 15.68 25.32 8 3 37.50 2.462 393 125
GBPJPY 141.55 5.22 5 4 80.00 7.028 509 124
CHFJPY 2.72 14.57 7 2 28.57 2.729 512 98
CADJPY -0.21 9.52 9 4 44.44 1.236 265 90
NKY 11027.16 1409.97 6 4 66.67 2.620 385 157
DJI 5444.31 3114.88 8 4 50.00 2.127 433 71
DAX -443.16 2306.59 5 2 40.00 1.212 424 143
UKX 125.80 1186.90 7 3 42.86 1.419 439 87
HSI -13836.28 20811.90 8 1 12.5 2.346 446 119
6098 1208.00 0 1 1 100.00 - 471 -
4452 2316.00 878.00 7 3 42.86 3.168 516 111
5711 -3385.00 4845.00 8 2 25.00 1.049 286 139
7201 -211.00 392.00 5 1 20.00 2.61 377 140
9984 4306.00 183.00 6 4 66.67 8.329 285 205
AAPL 61.69 6.79 6 5 83.33 2.017 330 160
AXP 32.89 5.79 6 3 50.00 3.157 485 103
BA 164.40 52.29 8 4 50.00 3.591 420 186
JNJ 14.70 21.36 7 2 28.57 3.851 520 110
MCD 33.60 16.15 7 4 57.14 1.947 406 48
GOLD 78130.00 21370.00 5 3 60.00 3.104 604 120
PLATINUM 16365.00 27100.00 4 2 50.00 1.604 558 44
WTI -3380.00 48590.00 7 3 42.86 1.260 302 171
CORN -2900.00 8700.00 8 3 37.50 1.336 320 115
SOY BEANS 5212.50 18325.00 6 3 50.00 1.198 378 101
TOTAL 159 73 45.91 2.95
破産の確率 0%
期待値/リスク 0.81
損益の見込み 128.79
※ 破産の確率は損失の許容=2%で算出
※ TOTALのRR比は「6098」を除いて算出
テスト1考察
勝率高め、RRもかなり優秀
ATRーCBよりもかなり優秀
日本の個別株は苦手そう
その他はほぼプラス以上
破産の確率も0%
期待値の計算式
$ WIN \times RR- | 1-WIN|
テスト2
table:テスト2設定
MA Stdev upper Stdev lower Losscut Pyramiding ATR-N (Pyramiding)
350 2.5 2.5 None 4 10
ピラミッティングを加えてみる
table:テスト2結果
損益 最大DD 取引数 勝数 勝率 RR比 勝ち保有 負け保有
USDJPY 116.30 6.89 10 7 70.00 4.233 650 141
EURJPY 12.59 24.44 13 5 38.46 2.030 357 148
GBPJPY 170.97 31.56 16 9 56.25 2.403 484 181
CHFJPY 10.95 36.26 12 5 41.67 1.699 496 110
CADJPY -23.47 33.34 14 5 35.71 0.825 268 128
NKY 19069.57 3866.40 15 11 73.33 1.335 384 149
DJI 8957.34 5238.15 19 11 57.89 1.366 367 112
DAX 2373.58 2306.59 8 6 62.50 1.217 466 143
UKX 946.90 1482.00 12 6 50.00 1.387 433 147
HSI -3980.33 20811.90 11 4 36.36 1.421 291 119
6098 3030.00 0 4 4 100.00 - 382 -
4452 7300.00 2524.00 13 6 46.15 3.167 615 118
5711 -4005.00 6155.00 12 3 25.00 1.156 278 162
7201 -830.00 830.00 8 1 12.50 2.261 377 131
9984 409.00 3192.00 15 6 40.00 1.585 293 150
AAPL -28.54 118.87 21 8 38.10 1.294 317 151
AXP 34.42 21.04 12 6 50.00 1.849 403 136
BA 400.47 55.42 17 10 58.82 4.32 371 178
JNJ 37.73 21.36 12 6 50.00 1.932 418 105
MCD 16.91 26.95 16 8 50.00 1.285 380 147
GOLD 174830.00 29490.00 12 8 66.67 3.232 548 208
PLATINUM 79885.00 27100.00 9 6 66.67 1.787 535 95
WTI -87820.00 145190.00 14 5 35.71 0.846 321 135
CORN -34387.00 34887.50 15 4 26.67 0.744 301 135
SOY BEANS 32000.00 18325.00 9 6 66.67 1.109 322 101
TOTAL 319 156 48.90 1.95
破産の確率 0%
期待値/リスク 0.44
※ 破産の確率は損失の許容=2%で算出
※ TOTALのRR比は「6098」を除いて算出
テスト2考察
期待値がかなり減少
とはいえ、ほぼ勝率50%でRR比2倍弱、これはすごい
テスト3
table:テスト3設定
MA Stdev upper Stdev lower Losscut Pyramiding
350 2 2 None None
標準偏差を2倍にしてみる
table:テスト3結果
損益 最大DD 取引数 勝数 勝率 RR比 勝ち保有 負け保有
USDJPY 42.51 17.00 8 3 37.50 5.622 615 99
EURJPY 26.78 13.37 10 4 40.00 2.990 364 127
GBPJPY 149.08 12.61 6 4 66.67 6.409 517 186
CHFJPY 23.67 8.65 8 3 37.50 4.493 459 124
CADJPY -17.13 22.36 13 5 38.46 0.968 281 70
NKY 9443.43 2747.39 8 4 50.00 3.004 393 158
DJI 6484.98 2765.62 10 4 40.00 3.290 441 79
DAX 3520.08 868.84 7 5 71.43 1.449 376 138
UKX -555.80 1940.80 11 4 36.36 1.443 423 88
HSI 2364.60 8764.19 9 2 22.22 4.444 455 150
6098 1173.00 142.00 2 1 50.00 9.261 539 28
4452 2145.00 1319.00 9 3 33.33 3.979 518 94
5711 -2080.00 3880.00 9 3 33.33 1.102 345 106
7201 -521.00 521.00 9 1 11.11 3.405 378 127
9984 4062.00 585.00 8 5 62.50 2.500 312 118
AAPL 93.63 15.31 7 5 71.43 2.320 456 169
AXP 50.06 8.10 7 4 57.14 3.861 487 46
BA 219.82 40.31 8 5 62.50 3.293 473 133
JNJ 15.68 21.91 8 2 25.00 4.454 561 107
MCD 31.99 30.18 11 4 36.36 3.119 437 94
GOLD 98100.00 9880.00 5 3 60.00 7.286 613 187
PLATINUM 530.00 45625.00 7 3 42.86 1.347 511 114
WTI 10690.00 74140.00 9 4 44.44 1.461 332 118
CORN 362.50 13462.50 9 4 44.44 1.277 294 95
SOY BEANS 19837.50 11825.00 6 3 50.00 2.062 385 123
TOTAL 204 88 43.14 3.05
破産の確率 0%
期待値/リスク 0.75
※ 破産の確率は損失の許容=2%で算出
テスト3考察
標準偏差を調節してみたが、2.5倍の方が良い
テスト4
table:テスト4設定
MA Stdev upper Stdev lower Losscut Pyramiding ATR-N (Pyramiding)
350 2 2 None 4 10
ピラミッティングを導入して、少し攻撃的に。
table:テスト4結果
損益 最大DD 取引数 勝数 勝率 RR比 勝ち保有 負け保有
USDJPY 119.77 17.00 14 8 57.14 5.070 622 107
EURJPY 12.36 28.94 18 7 38.89 1.873 354 143
GBPJPY 237.82 32.55 17 11 64.71 2.803 458 182
CHFJPY 33.24 30.34 14 6 42.86 2.464 475 123
CADJPY -42.18 50.42 19 6 31.58 0.888 285 114
NKY 17695.86 6599.18 18 11 61.11 1.695 390 165
DJI 12927.77 454.2 22 11 50.00 2.232 384 109
DAX 4252.88 3569.55 15 8 53.33 1.649 447 160
UKX -936.20 4056.80 18 8 44.44 1.029 426 106
HSI 3241.96 22692.00 17 6 35.29 2.060 376 141
6098 3528.00 142.00 5 4 80.00 6.461 418 28
4452 7513.00 -2688.00 15 6 40.00 3.876 621 112
5711 -2480.00 6110.00 14 5 35.71 1.149 317 122
7201 -1829.00 1829.00 15 2 13.33 1.404 293 114
9984 2331.00 3423.00 18 8 44.44 1.635 309 126
AAPL 197.42 44.93 21 14 66.67 2.207 401 177
AXP 56.20 14.78 13 4 53.85 2.195 422 104
BA 597.56 42.44 20 13 65.00 4.362 408 143
JNJ 47.36 21.91 15 6 40.00 2.710 492 98
MCD 44.37 40.00 21 10 47.62 1.788 382 129
GOLD 213750.00 18000.00 12 9 75.00 4.310 558 256
PLATINUM 66845.00 45625.00 13 7 53.85 1.820 536 134
WTI -54260.00 130270.00 17 7 41.18 0.909 321 135
CORN -36750.00 40962.50 18 5 27.78 0.857 285 128
SOY BEANS 11362.50 40075.00 12 6 50.00 1.227 322 125
TOTAL 401 188 46.88 2.41
破産の確率 0%
期待値/リスク 0.6
※ 破産の確率は損失の許容=2%で算出
テスト2考察
期待値は下がったが、取引回数が増えた分で総利益がどうなるか
ピラミッティングを用いる場合は、2.5倍よりも2倍の方が良さそう
一番優秀
考察
期待値が下がった 0.75 → 0.6
取引回数が増えた 204 → 401 ほぼ倍
ざっくり総利益を算出
計算式 $ Risk \times Edge \times Num
Risk:1トレードのリスク
Edge:期待値
Num:取引回数
元金100万円、1トレードのリスク2万円
テスト1
$ 20,000 \times 0.75 \times 204 = 3,060,000
テスト2
$ 20,000 \times 0.6 \times 401 = 4,812.000
期待値は下がったが、手法としてはテスト2の方が儲かる
1トレードのリスクを上げる(取引量を増やす)と、あっという間に破産してしまう手法であると考えられる(どんな手法でもそうだけど)。注意が必要。
Pineスクリプト
code:Pineスクリプト(js)
//@version=3
strategy("Strategy Turtle BB 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")
up_n = input(2 ,minval=1 ,title="stdev upper n")
low_n = input(2 ,minval=1 ,title="stdev lower n")
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)
SMA = sma(close ,len)
STD = stdev(close ,len)
UPPER = SMA + STD * up_n
LOWER = SMA - STD * 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
S_EntrySig = close <= LOWER
if(strategy.position_size != 0)
L_ExitSig = (close <= SMA or S_EntrySig) and strategy.position_size > 0
S_ExitSig = (close >= SMA 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)
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 isWork 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 ,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(losscut ,title="losscut" ,color=red ,transp=0 ,style=linebr)
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(SMA ,color=red ,title="EMA" ,style=line ,linewidth=2 ,transp=0)
fill(p1 ,p2 ,color=#2196F3 ,title="fill" ,transp=60)