#はじめに
こんにちは!くりぷ(@CRYPTANNEWS)です。
「移動平均線がゴールデンクロスで買い!デッドクロスで売り!」
「ボリバン3σで逆張り!」
トレードの話を調べていると、よくこんな売買サインの話しが出てきます。
(特にテクニカルを中心にトレードしている人であれば)自分なりの基準となる売買サインがあるのではないでしょうか。
もし、過去3ヶ月間実際にその売買サインに忠実にトレードしてた場合、どういう結果になったのか気になりませんか?
今日はTradingviewというWEBブラウザチャートツールを使い、「ロジックに忠実にトレードをしたらどういう結果になるのかバックテストする方法」をシェアします!
>>Tradingviewはこちら(無料プランで大丈夫です)
為替・株式・商品・仮想通貨など幅広い市場が用意されています。
(カスタマイズしたTradingViewのスクリーンショット)
#バックテストをするとわかること
バックテストをすると、そのロジックでトレードをした結果を分析することができます。
いちばん注目するところは、勝率とPFです。
この二つを見ることによって、「勝ててるのか、負けてるのか」が分かります。
次にわたしが見るのは最大DDです。
一番損をしたトレードでどのくらい資産が凹むのか、ロスカットする可能性があるのか、が分かります。
他にもいろいろな数値が見れるので分析してみてください。
#そのロジック、本当に勝ててる?
それでは、早速バックテストをしていきましょう!
わたしが普段トレードしている中で意識しているロジックの一つに「半値戻し」があります。
直近X期間の高値と安値のちょうど50%のところが転換地点となりやすい、という基本的なロジックです。
このロジックが本当に効くのか、早速バックテストをしてみました!
エントリーロジックは、『直近4時間の最高値最安値の、50%ラインを上抜けしたら、ロング。下抜けしたら、ショート。』
利確は、ロングの場合:同じ期間の最高値、ショートの場合:同じ期間の最安値、です。
損切は、ロングの場合:同じ期間の最安値、ショートの場合:同じ期間の最高値、に設定しました。
バックテストのコードはこちらです。
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © CRIPU
//@version=3
strategy("backtest", overlay=true)
//バックテストをする期間
fromYear = input(2019 ,type=integer ,minval=1900 ,title="test start")
endYear = input(2020 ,type=integer ,minval=1900 ,title="test end")
isWork = timestamp(fromYear ,1 ,1 ,00 ,00) <= time and time < timestamp(endYear ,8,31 ,00 ,00)
posi = strategy.position_size != 0
no_posi = strategy.position_size == 0
posi_l = strategy.position_size > 0
posi_s = strategy.position_size < 0
//Period
length = 48
h_line = highest(length)
l_line = lowest(length)
diff = h_line - l_line
//Fib
f39 = (diff*0.39) + l_line
f50 = (diff*0.5) + l_line
f61 = (diff*0.61) + l_line
plot(f50,linewidth=1,color=#ffd700,transp=50)
plot(f39,linewidth=1,color=#81d8d0,transp=50)
plot(f61,linewidth=1,color=#ffa594,transp=50)
plot(l_line,linewidth=1,color=#f5f5f5,transp=50)
plot(h_line,linewidth=1,color=#f5f5f5,transp=50)
//entrySignal
entry_l = low < f39 and high > f39 and open > close
entry_s = low < f61 and high > f61 and open < close
//closeSignal
close_l = high == h_line
close_s = low == l_line
//cutSignla
cut_l = low == l_line
cut_s = high == h_line
//trade
//ここから下はストラテジーなので触らない
L_EntrySig = isWork and entry_l and no_posi
S_EntrySig = isWork and entry_s and no_posi
L_CloseSig = isWork and close_l and posi_l
S_CloseSig = isWork and close_s and posi_s
L_CutSig = isWork and cut_l and posi_l
S_CutSig = isWork and cut_s and posi_s
strategy.entry(id = "Long", long = true, when = L_EntrySig)
strategy.close(id = "Long", when = L_CloseSig)
strategy.close(id = "Long", when = L_CutSig)
strategy.entry(id = "Short", long = false, when = S_EntrySig)
strategy.close(id = "Short", when = S_CloseSig)
strategy.close(id = "Short", when = S_CutSig)
bgcolor(color
= not isWork ? #aaaaaa
: na
,transp=70 ,title="背景色")
↑をコピーして、tradingview下部の『pineスクリプト』エリアにペーストしてください。
「保存」をして「チャートに追加」をクリックしてください。
これでオッケーです!
結果はこの通り。
勝率44.74% / PF 0.911
う…これは典型的な負けてる人の損益グラフ…
これを基準にしていたらお金をばら撒いてしまいます。
負け組脱出にむけてこのロジックをどんどん改善していきましょう!
※バックテストの結果は数値だけではなく、チャート上にも表示されるため、視覚的にもロジックチェックができます。
###自分のロジックのバックテストをするには
他のロジックのバックテストをするには、ロジック部分を変更します。
移動平均線やボリンジャーバンド、一目雲などの主要インジのpineスクリプトコードはページ最下部にまとめたので良ければ参考にしてください。
▶︎自分のロジックを入れてコピペしてお使いください
//entrySignal
entry_l = ロングをエントリーする条件
entry_s = ショートをエントリーする条件
//closeSignal
close_l = ロングをクローズする条件
close_s = ショートをクローズする条件
//cutSignla
cut_l = ロングを損切りする条件
cut_s = ショートを損切りする条件
#ロジック改善計画始動
半値戻しは、実際に裁量トレードをしてる時もよく効きます!
何かちょっとしたポイントを効かせればうまくいくはず!!!
ということで、じゃんじゃん改善していきましょう。
##①エントリーラインをちょっとズラす
50%きっちりでエントリーするのではなく、
・ロングならちょっと押した39%ラインに到達
・ショートならちょっと戻した61%ラインに到達
でエントリーするようにしたらどうでしょうか?!
バックテストコードのエントリーロジックの部分を下記のように書き換えます。
▶︎50%でエントリー
//entrySignal
entry_l = low < f50 and high > f50 and open > close
entry_s = low < f50 and high > f50 and open < close
▶︎ちょっとズラしてエントリー
//entrySignal
entry_l = low < f39 and high > f39 and open > close
entry_s = low < f61 and high > f61 and open < close
結果をどん!
うまくいきました!
勝率44.1% / PF 1.119
きっちり半値戻し狙いよりも、ちょっとズラすのが効くようです。
フィボナッチ、有名だしね。
でも、これじゃまだまだ足りません。
##②インジの期間を長くする
何となく効くイメージがある4時間足一本分を期間として設定していましたが、そもそも短すぎるのでは?
ということで、もう少し長くしてみましょう。
6倍の日足1本分(24時間)に設定します。
バックテストコードのフィボナッチ期間設定部分を下記のように書き換えます。
▶︎直近4時間の最高値・最安値から計算する
length = 48
h_line = highest(length)
l_line = lowest(length)
diff = h_line - l_line
▶︎直近24時間の最高値・最安値から計算する
length = 288
h_line = highest(length)
l_line = lowest(length)
diff = h_line - l_line
※これは5分足チャートで表示しているため、1440分の期間を参照にするために288本分を参照しています
(288本*5分足=1440分=24時間)
結果をどん!
おおお!すごい!
勝率54.02% / PF 1.579
何と10パーセント以上の改善です!
損益グラフも右肩上がりでとても良いのですが、トレード回数がとても少なくなることと、DDが大きいことが気になります。
うーん…
#ロジックを自動化して自動売買ボットを動かしてみよう
こんな感じで何週間か改善し続けた結果、ようやく満足できる結果になってきました。
(どこを変えたかは今は秘密です)
少しでも勝率やPFをあげようとアレコレ試していくうちに、トレードに関する新しい発見がたっくさんあり、とても勉強になりました。
トレード上手になった気がする!
やっぱバックテストは大事だと思います。
せっかくいいロジックを作れたら、自動化してみましょう。
わたしはこのロジックを元に実際にFTXという大手仮想通貨取引所で自動売買プログラムを動かしています。
この取引所では環境構築もプログラミングの知識も無しで自動売買ボットをつくるシステムが用意されているので重宝していますが、海外取引所なのでおすすめはしていません。
#主要インジのpineスクリプトコード
最後に、主要なインジケーターのpineスクリプトコードをいくつか置いておきます。
バックテストをする時にお役立てください!
(随時追記していく予定です)
(アラームのつけ方も追記します)
##移動平均線
ave = sma(close,9)
plot(ave,linewidth=1,color=white,transp=0)
##一目雲
tenkanPeriods = input(9, minval=1, title="Tenkan Line Periods")
kijyunPeriods = input(26, minval=1, title="Kijyun Line Periods")
senko2Periods = input(52, minval=1, title="Senko 2 Periods")
diff = input(26, minval=1, title="Difference")
donchian(len) => avg(lowest(len), highest(len))
tenkanLine = donchian(tenkanPeriods)
kijyunLine = donchian(kijyunPeriods)
senko1 = avg(tenkanLine, kijyunLine)
senko2 = donchian(senko2Periods)
plot(tenkanLine,linewidth=1,color=white,transp=0)
plot(kijyunLine,linewidth=1,color=white,transp=0)
plot(senko1,linewidth=1,color=white,transp=0)
plot(senko2,linewidth=1,color=white,transp=0)
##ボリンジャーバンド
dev = stdev(close,20)
basis = pine_sma(close,20)
upper = basis + dev
lower = basis - dev
upper_2 = basis + dev * 2
lower_2 = basis - dev * 2
upper_3 = basis + dev * 3
lower_3 = basis - dev * 3
plot(upper,linewidth=1,color=white,transp=0)
plot(lower,linewidth=1,color=white,transp=0)
##ストキャRSI
smoothK = input(3, minval=1)
smoothD = input(3, minval=1)
lengthRSI = input(14, minval=1)
lengthStoch = input(14, minval=1)
src = input(close, title="RSI Source")
rsi1 = rsi(src, lengthRSI)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)
plot(k,linewidth=1,color=white,transp=0)
plot(d,linewidth=1,color=white,transp=0)