見出し画像

主要テクニカル説明とpine scriptコード

まえがき

本書では、チャート分析の基本である主要なテクニカル指標の説明と、
Tradingviewでストラテジー検証をするためのpine scriptコードを紹介します。また、ボリンジャーバンド、ストキャスティクス、MACDについては、各指標を使った売買ストラテジーを作成し、その効果を検証しています。
もちろんストラテジーのソースコードも本文に載せています。
※Tradingviewで検証した後にpythonに変換して自動売買BOTを作成することを見越して、ソースコードは極力pine scriptの組み込み関数(pythonに同じ関数がないもの)を使用せずに組んでいます。

本書で紹介するテクニカル指標は以下の通りです。

・移動平均

・ボリンジャーバンド

・ストキャスティクス

・MACD

+おまけ(Tradingviewの動的ロット計算)

また、本書を執筆する中でなかなか筋のいいストラテジーもできました。
もちろんこのストラテジーの詳細とコードも本書の中に載せています。

画像1


移動平均線

移動平均線は以下の目的で使用されることが多いです。
 ・売買のタイミングをつかむ
 ・支持線・抵抗線として使用する
 ・値動きの中心線として使用する(その名の通り)

テクニカル指標としての名前が有名すぎて、あまり意識されていない性質として、単純移動平均線は、移動平均を算出して期間の市場参加者の損益分岐点になるというものがあります。心理的に、負けていた人は最悪プラスマイナス0できればよいと考えて、手仕舞いしたくなりますし、逆に買っていた人はマイナスに転じるのを嫌がって手仕舞いしたくなります。結果的に、移動平均線は上昇トレンドにおける支持線、下降トレンドにおける抵抗線として機能します。

こう聞くと単純移動平均線が最も意味のある平均線に感じますが、弱点もあります。それは「算出期間に価格が入った瞬間と、算出期間から出ていく瞬間の2度。同じ強さで影響を与える」ことです。
下の図はBTCの1分足です。ローソクとしては、①の足は大幅な下落、②の足では少しの上昇です。しかし、移動平均をみると、①で下落したのと同じぐらい②で上昇しています。②で大幅に上昇しているのは、大きく下落した足が移動平均の算出期間から抜けたためです。つまり単純移動平均は、新しい足が大きく上昇したことと、過去に大きく下落した足が期間から抜けたことが等しく扱われます。これが上述した弱点です。
これを回避するために、加重移動平均や、指数平滑移動平均が作られたのでしょう。よって、使い分けとしては支持線・抵抗線として使用したいのであれば単純移動平均、相場の動きをとらえ、売買のタイミングを掴むためには加重移動平均や指数平滑移動平均を使うのがよいでしょう。

画像2

・単純移動平均線

式:

画像3

pine script:

//@version=3
study("pine_sma", overlay=true)
pine_sma(x, y) =>
    sum = 0.0
    for i = 0 to y - 1
        sum := sum + x[i] / y
    sum
plot(pine_sma(close, 14))

xにclose(終値)の配列が格納されているので、直近の終値(close[0])から順番に値を加算していき、最後に足の数で割る。
小数の計算なので、sumは0.0で初期化しておく。

・加重移動平均線

式:

画像4

pine script:

//@version=3
study("pine_wma", overlay=true)
pine_wma(x, y) =>
    norm = 0.0
    sum = 0.0
    for i = 0 to y - 1
        weight = y - i
        norm := norm + weight
        sum := sum + x[i] * weight
    sum / norm
plot(pine_wma(close, 14))

・指数平滑移動平均線

式:

画像5

pine script:


//@version=3
study("pine_ema", overlay=true)
pine_ema(x, y) =>
    alpha = 2 / (y + 1)
    sum = 0.0
    sma = 0.0
    for i = 0 to y - 1
        sma := sma + x[i] / y
    sum := nz(sma[1]) + alpha * (x - nz(sma[1]))
plot(pine_ema(close, 14))

すべて描画したものがこちら。

画像6


ボリンジャー・バンド

ボリンジャー・バンドは以下の目的で使用されることが多いです。
 ・短期的な価格変動における現在値の位置づけを知る
 ・相場の反転を判断する

移動平均についで、こちらも有名な指標です。
ボリンジャー・バンドは、移動平均線の上下にバンドを作り、現在の値がバンドのどの位置にいるのかを見る指標です。
バンドは通常、移動平均を中心に算出期間の価格の標準偏差分プラスマイナスした1σ(シグマ)線と、標準偏差の2倍分プラスマイナスした2σ線を描画します。描画すると以下のようになります。

画像7

ボリンジャーバンド
式:

画像8

basisは単純移動平均。devは算出期間の値の標準偏差です。
n: データの総数
xi: i番目の値
X: xの平均値

pine script:

//@version=3
study(title="Bollinger Bands", overlay=true)

//sma算出
pine_sma(x, y) =>
    sum = 0.0
    for i = 0 to y - 1
        sum := sum + x[i] / y
    sum

dev = stdev(close,20)
basis = pine_sma(close,20)
upper_1 = basis + dev
lower_1 = basis - dev
upper_2 = basis + dev * 2
lower_2 = basis - dev * 2

plot(basis, color=red)
u1 = plot(upper_1, color=blue)
l1 = plot(lower_1, color=blue)
u2 = plot(upper_2, color=green)
l2 = plot(lower_2, color=green)
fill(u2,l2, color=green)

標準偏差の算出はpythonでも普通に使用できるため、組み込み関数のstdevを使用しています。
fill関数は、指定した二つの値の間の色塗りをしてくれる関数です。
pine_smaは前述の関数をそのまま使用しています。

一般論の検証

「データが正規分布ならば、平均値ー標準偏差の2倍~平均値+標準偏差の2倍の幅にデータが収まる可能性は95%である。」
これは、ボリンジャー・バンドを語る際によく引用される事実です。
これをもって、2σ線を超えた場合逆張りする。あるいは、2σ線付近まで来たら逆張りするという手法が提案されています。
一方で、ボリンジャー・バンドを算出するデータの個数は通常高々20~40個程度しかないため、そもそも正規分布することは少なく、逆にトレンドの発生とみて2σ付近から順張りするという手法も提案されています。
BTCにおいては、どちらが正しいでしょうか。pine scriptができているため、簡単にできます。やってみましょう。

検証方法:
・ボリンジャー・バンドの2σを超えた足で順張り・逆張りのそれぞれを実行し、1・3・5足(→以降決済閾値と記載する)先で決済した場合の損益を比較する。

順張り検証:
決済閾値=1

画像9

決済閾値=3

画像10

決済閾値=5

画像11

どの閾値でも利益が出ていますね。
閾値5が一番プロフィットファクターが大きく、利益も200%程度出ています。筋がいい手法ですね。
pine script:

//@version=3
strategy(title="Bollinger Bands", overlay=true)

//sma算出
pine_sma(x, y) =>
    sum = 0.0
    for i = 0 to y - 1
        sum := sum + x[i] / y
    sum

dev = stdev(close,20)
basis = pine_sma(close,20)
upper_1 = basis + dev
lower_1 = basis - dev
upper_2 = basis + dev * 2
lower_2 = basis - dev * 2

plot(basis, color=red)
u1 = plot(upper_1, color=blue)
l1 = plot(lower_1, color=blue)
u2 = plot(upper_2, color=green)
l2 = plot(lower_2, color=green)
fill(u2,l2, color=green)

//追加部分↓
count = 0
threshold = 5

if strategy.position_size > 0
    count := nz(count[1]) + 1

if strategy.position_size < 0
    count := nz(count[1]) - 1

if crossover(close,upper_2) and strategy.position_size == 0
    strategy.entry("Long", strategy.long,100)

if crossunder(close,lower_2) and strategy.position_size == 0
    strategy.entry("Short", strategy.short,100)

if count == threshold
    strategy.close_all()
    count := 0

if count == threshold*-1
    strategy.close_all()
    count := 0

逆張り検証:

決済閾値=1

画像12

決済閾値=3

画像13

決済閾値=5

画像14

順張りと逆のことをするので、当然利益はでません。損しかしないですね。
pine script:

//@version=3
strategy(title="Bollinger Bands", overlay=true)

//sma算出
pine_sma(x, y) =>
    sum = 0.0
    for i = 0 to y - 1
        sum := sum + x[i] / y
    sum

dev = stdev(close,20)
basis = pine_sma(close,20)
upper_1 = basis + dev
lower_1 = basis - dev
upper_2 = basis + dev * 2
lower_2 = basis - dev * 2

plot(basis, color=red)
u1 = plot(upper_1, color=blue)
l1 = plot(lower_1, color=blue)
u2 = plot(upper_2, color=green)
l2 = plot(lower_2, color=green)
fill(u2,l2, color=green)

//追加部分↓
count = 0
threshold = 5

if strategy.position_size > 0
    count := nz(count[1]) + 1

if strategy.position_size < 0
    count := nz(count[1]) - 1

if crossover(close,upper_2) and strategy.position_size == 0
    strategy.entry("Short", strategy.short,100)

if crossunder(close,lower_2) and strategy.position_size == 0
    strategy.entry("Long", strategy.long,100)

if count == threshold
    strategy.close_all()
    count := 0

if count == threshold*-1
    strategy.close_all()
    count := 0


結論として、いままでのBitMEXのBTC相場の1分足においては、ボリンジャー・バンドの2σを上抜く、下抜けるというイベントは、順張りのシグナルとして有用である。ということが言えます。足の長さや、市場が変われば結果も変わりますので、そこはご注意ください。


ストキャスティクス

ストキャスティクスは、以下の目的で使用されることが多いです。
 ・売られすぎ、買われすぎを検知する
 ・相場の反転を判断する

ストキャスティクスは、上述したインジケーター(移動平均、ボリンジャーバンド)とは違い、オシレーターと呼ばれるテクニカル指標です。
オシレーターとは「振り子」を意味し、買われ過ぎや売られ過ぎなどを示す指標として利用します。
通常、0から100、もしくは−100から+100、−1から+1のような範囲で示したり、ゼロラインを挟んで上下に振幅するチャートになります。
描画すると以下のようになります。

画像15

ストキャスティクス
 式:

画像16

%Kは、過去n日間の値動きのレンジの中で、最新の終値が何%の位置にいるかを示しています。最新の終値が今までの最高値であれば100%で、最安値であれば0%となります。
%DとSDは、それぞれ%Kを滑らかにしただけであり、SDは%Dを滑らかにしただけです。
また、mとlには通常3を用います。

pine script:

//@version=3
study(title="Stochastic", overlay = false)

pine_stoch_K(length) =>
    k = 100 * (close - lowest(low, length)) / (highest(high, length) - lowest(low, length))
    
k = pine_stoch_K(18)
d = sma(k,3)
sd = sma(d,3)
plot(d, color=blue)
plot(sd, color=orange)
h0 = hline(70)
h1 = hline(30)
fill(h0, h1, color=purple, transp=75)

ボックス相場であれば、ボックスの中の底、天井を検知するシグナルとして有用なストキャスティクスですが、BTCに関しては、基本的にトレンドが発生しています。よって、長い時間足で使用すると上や下で停滞してしまいます。

画像17

よって、BTCでストキャスティクスを有効利用できるのは、トレンド内での押し目買い、戻り売りをする際の売買シグナルが考えられます。

有効性を確かめるために実験してみましょう。
売買ルールは以下の通り。
・トレンドの判断は現在値が200日単純移動平均の上にある(上昇トレンド)か下にある(下降トレンド)かで判断
・トレンドに従った方向にしかエントリーしない
・%Dが30以下でSDを上抜くか、70以上でSDを下抜いた場合にエントリー
・%DとSDがエントリーと逆向きに交差した際に決済

さて、どんな結果がでるでしょうか。

1分足:

画像18

5分足:

画像19

1時間足:

画像20

1分足では利益がでるストラテジーですが、5分、1時間と足を長くするにつれて利益がでなくなりました。
1時間足を見ると、単調に上がり続けている箇所が全くエントリーできておらず、移動平均付近で一時的にボックス相場になった箇所で多くエントリーが発生しています。単純に期間や閾値のパラメーターがはまらなかったということもありますが、足が長くなるにつれ、単調なトレンドか激しいもみ合いというストキャスティクスと相性の悪い相場に近づいていくのではないかと思います。

上記の実験のscriptはこちら。

//@version=3
strategy(title="Stochastic", overlay = false)

pine_stoch_K(length) =>
    k = 100 * (close - lowest(low, length)) / (highest(high, length) - lowest(low, length))
    
k = pine_stoch_K(18)
d = sma(k,3)
sd = sma(d,3)
plot(d, color=blue)
plot(sd, color=orange)
h0 = hline(70)
h1 = hline(30)
fill(h0, h1, color=purple, transp=75)

//追記部分↓

Sma = sma(close,200)
Buy_allow = 0
Sell_allow = 0

if close > Sma
    Buy_allow  := 1
    Sell_allow := 0
else
    Buy_allow  := 0
    Sell_allow := 1

//エントリー
if Buy_allow == 1  and d < 30 and crossover(d,sd) and strategy.position_size == 0
    strategy.entry("Long", strategy.long,100)

if Sell_allow == 1 and d > 70 and crossunder(d,sd) and strategy.position_size == 0
    strategy.entry("Short", strategy.short,100)

//決済
if strategy.position_size > 0 and crossunder(d,sd)
    strategy.close_all()

if strategy.position_size < 0 and crossover(d,sd)
    strategy.close_all()


MACD

MACDは、以下の目的で使用されることが多いです。
 ・相場の反転を判断する

MACDとは「Moving Average Convergence Divergence(移動平均収束拡散法)」を略したもので、算出期間の違う2つの移動平均を用いたテクニカル指標です。普通は「マックディー」と読みます。
短い期間の移動平均と長い期間の移動平均の差分(乖離)を「MACD」とし、このMACDの移動平均を「シグナル」と呼びます。
シグナルはMACDをスムージングしたものなので、当然価格に対して鋭敏に動くのはMACDです。このMACDがシグナルを上抜いた場合に買いシグナル、下抜いた場合に売りシグナルとするのが通常の使い方です。
描画すると以下のようになります。

画像21

MACD
 式:

画像22

 pine script:

//@version=3
study(title="MACD", overlay = false)

fastMA = ema(close, 5)
slowMA = ema(close, 12)
macd = fastMA - slowMA
signal = ema(macd, 12)
plot(macd, color=blue)
plot(signal, color=orange)


MACDについてもストラテジーを組んで有効性を検証してみます。
売買ルールは以下の通り。
・トレンドの判断は現在値が200日単純移動平均の上にある(上昇トレンド)か下にある(下降トレンド)かで判断
・トレンドに従った方向にしかエントリーしない
・MACDがシグナルを上抜けば買い、下抜けば売りでエントリー
・エントリーの逆向きに交差したら決済

1分足:

画像23


5分足:

画像24


1時間足:

画像25

基本ストラテジー自体は、ストキャスティクスの時と同じなので、足の時間を長くしていった際の利益の減り方は同じですね。
ただし、プロフィットファクターも純利益もMACDの方がかなり成績が良いです。単純な売買シグナルとしてはMACDの方が優秀だと言えますね。


最後に、Tradingviewのプチ情報として、ロットを動的に変更する方法を紹介して本書の結びとします。
本書で今まで紹介したエントリー方法は、すべてロットサイズが固定されています。よって、残高の上昇曲線がどんどん収束していってしまっています。
これでは、後半に相場と相性が合わなかったのか、ロットサイズが小さかっただけで、勝ち方は同じなのか判断できません。よって、検証の際には、残高に対してロットサイズを動的に変えた方が、検証しやすいと思います。

画像26

画像27

ではさっそくコードを見てみましょう。

//@version=3
strategy(title="MACD", overlay = false)

fastMA = ema(close, 5)
slowMA = ema(close, 12)
macd = fastMA - slowMA
signal = ema(macd, 12)
plot(macd, color=blue)
plot(signal, color=orange)

//追記部分↓

lot = 0.0
leverage = 25
lot := strategy.equity * leverage / close

Sma = sma(close,200)
Buy_allow = 0
Sell_allow = 0

if close > Sma
    Buy_allow  := 1
    Sell_allow := 0
else
    Buy_allow  := 0
    Sell_allow := 1

//エントリー
if Buy_allow == 1  and crossover(macd,signal) and strategy.position_size == 0
    strategy.entry("Long", strategy.long,lot)

if Sell_allow == 1 and crossunder(macd,signal) and strategy.position_size == 0
    strategy.entry("Short", strategy.short,lot)

//決済
if strategy.position_size > 0 and crossunder(macd,signal)
    strategy.close_all()

if strategy.position_size < 0 and crossover(macd,signal)
    strategy.close_all()

ちょっと見にくいですが、変更箇所を太字にしました。
何をやっているかというと、随時ロットサイズを計算する式を追加しています。今回はサンプルとして、残高に対して25倍のレバレッジをかけて売買するコードにしました。
このようにロットサイズを可変にした場合の結果を見てみましょう。

画像28

先ほどの固定ロットと違い、増加曲線ほぼ一次関数になっていますね。
これは、遠い過去も近い過去も同様に手法がうまく機能しているということを意味しています。また、レバレッジをかけたことで、純利益が21800%になりました。100万円が2憶1800万ですね。(笑)

本書は以上になります。本書をきっかけに利益を出していただいたり、プログラミング、ストラテジー作成を楽しんでいただけると幸いです。


この記事が気に入ったらサポートをしてみませんか?