「投資苑2に書いてあるシステムをTradingViewで再現し、投資戦略を作り、バックテストを行う」
これを目標に少しずつトレードシステムを作っています。
前回はオートエンベロープの計算式などを解説しました。
今回は、実装編ということでプログラムに落とし込んでいきます。
過去記事
第1回 テンプレート解説
第2回 移動平均線を描く
第3回 オーバーレイと色分け
第4回 オートエンベロープ解説編
価格とEMAとの距離の計算
max(abs(high - long_ema), abs(low - long_ema)
max()は引数のうち値が高いものを選ぶ関数です。
abs()は絶対値を返してくれます。
long_emaは前回作った変数で、中にはEMA(26)が入っています。
式の意味としては、中心となるEMAとの差を高値と安値両方で計算します。
中心との距離を出したいので、絶対値で計算します。
max()により、中心から離れている価格を採用するようになっています。
abs(close - long_ema)
σ(標準偏差)を計算する
前回も書きましたが、上が標準偏差を計算する式です。
使用する値を変数に入れて確認します。
distance = max(abs(high - long_ema), abs(low - long_ema) //使用する価格とemaとの差 lookback = 64 //参照する期間 long_ema //平均となるemaを前回入れました
どういう計算式なのかコメントを使ってメモしておくと見直すときに、とても役立ちます。
材料はそろったので、標準偏差を計算していきます。
sigma = sqrt(sma(pow(distance, 2), lookback)) //標準偏差の計算
新しい関数を3つ使いました。
pow()は、累乗を計算する関数です。
上のコードでは、distanceを2乗しています。
sma()は単純移動平均線(simple movineg average)を計算する関数です。
ema()と同じように使います。
ここでは、単純移動平均線を計算するというよりも、
画像の黄色い部分であるn個合計してnで割る部分を意味しています。
sma()はその時その時の平均の計算結果です。
つまり平均を計算するのにも使えます。
n個合計してnで割るというのは平均を出しているわけです。
sqrt()は平方根を計算する関数です。
計算結果はsigmaという変数に入れておきます。
1標準偏差と2標準偏差
ようやく標準偏差をプログラムで計算できました。
標準偏差はσ(シグマ)という文字であらわされることが一般的なようです。
確率が正規分布の場合、平均を0(中心)とすると、
- -1σ~1σの範囲には約68%のデータ
- -2σ~2σの範囲には約95%のデータ
- -3σ~3σの範囲には約99.7%のデータ
が含まれます(と、物の本に書いてありました)。
データが偏っている場合はそれぞれの範囲の確率が変動します。
1σから2σを求める計算は簡単で、見た目の通り2倍すれば大丈夫です。
2 * sigma // 1σを2σにした
チャネルの描画
標準偏差が計算できたので、満足しかけましたが、チャネルを描画するために計算していたのを思い出しました。
上側のチャネルと下側のチャネルの2本の線を引きます。
チャネルの描画にはいつも通りplot()を使います。
前回の記事ではチャネルの計算式を
上側のチャネル = EMA + EMA × チャネル係数 下側のチャネル = EMA - EMA × チャネル係数
と紹介しました。
チャネル係数は価格の約95%を含むように調節すると投資苑2には書いてあります。
自動で調節できるように標準偏差を計算したので、
チャネルの計算は次のようになります。
上側のチャネル = EMA + 2 × 標準偏差 下側のチャネル = EMA - 2 × 標準偏差
プログラムに直してグラフにします。
upper = long_ema + 2 * sigma lower = long_ema - 2 * sigma plot(upper) plot(lower)
オートエンベロープの実装結果
//@version=3 study(title="トレーディングシステムを作る第5回", shorttitle="auto envelope", overlay=true) long_ema = ema(close, 26) //指数移動平均 plot(ema(close, 13), color=red) plot(long_ema, color=blue) //オートエンベロープ distance = max(abs(high - long_ema), abs(low - long_ema)) //使用する価格 lookback = 64 //参照する期間 sigma = sqrt(sma(pow(distance, 2), lookback)) upper = long_ema + (2 * sigma) lower = long_ema - (2 * sigma) plot(upper) plot(lower)
ようやくオートエンベロープを実装できました。
インジケーターのタイトル部分を少し変えましたが、プログラムに大きな違いはありません。
実は、線の更新回数を5期間に1回だけなどにして、
もう少し線の幅を安定させたかったのですが、まずは完成ということにします。
次はオシレーターの定番、MACDに進みたいと思います。
MACDが追加されると、チャートとしても普通に使えるようになりそうです!

よりシンプルな実装方法
この記事では、少しややこしい標準偏差を計算するために、説明を交えながら、いくつか式を書いてきましたが、Pine Scriptではstdev()という関数を使うと、簡単に標準偏差を実装できるということをコメント欄で教えていただきました。
ありがとうございます!
標準偏差の計算にstdev()を使うとこのようになります。
//@version=3 study(title="トレーディングシステムを作る第5回", shorttitle="auto envelope", overlay=true) long_ema = ema(close, 26) //指数移動平均 plot(ema(close, 13), color=red) plot(long_ema, color=blue) //オートエンベロープ distance = max(abs(high - long_ema), abs(low - long_ema)) //使用する価格 lookback = 64 //参照する期間 sigma = stdev(distance, lookback) //←この行だけ変更 upper = long_ema + (2 * sigma) lower = long_ema - (2 * sigma) plot(upper) plot(lower)
どういう計算をやっているかというは、知っておくと線の意味などの理解が深まりますが、実際のコードはなるだけ用意された関数などを使用したほうが、バグがあった場合やコードを改修したいときなどに、都合が良いです。
>>TradingViewのトップページへ行く
コメント
こんにちは!
PineScriptに関する数少ない記事でとても参考になりました。
一ヶ月くらい触ってスクリプトの仕様がわかってきたこともあり、一点気になったことがあったのでコメントさせてください。
distance = max(abs(high – long_ema), abs(low – long_ema)) //使用する価格
lookback = 64 //参照する期間
sigma = sqrt(sma(pow(distance, 2), lookback))
標準偏差を計算していますが、seriesとして、highやlow以外にもlong_emaも同様にseriesなので
sma()関数で計算すると、high[i]-long_ema[i]として計算(iは0~lookback-1まで)されてしまうと思われます。
何が言いたいかといいますと、標準偏差の平均値xがhighやlowと同様に過去の値を参照してしまうため
正しい標準偏差が計算できていないのではないかな?と思っています。
PineScriptには標準でstdev()があるのでそれを用いるのが素直に良さそうかなと思いました。
sigma = stdev(distance, lookback)
ちなみに、この計算の場合、エルダー博士は2.7標準偏差とすると(2.7*sigma)とすると良いと言われてました。
SK 様
コメントありがとうございます!
返信遅くなってしまってすいません。
おっしゃる通りstdev()を使うほうがシンプルかつ間違いがないですね。
stdev()を使っていない理由は単純に知らなかったからです(もうちょっとドキュメントを読めば良かった・・・)。
せっかくなので、参考にさせていただいて、記事の一部を修正しようと思います。
ありがとうございます。
投資苑2には価格の「だいたい95%を含むように」というように書かれていたので、とりあえず2sigmaにしています。
2.7sigmaという話は知りませんでした(少し調べてみます)。
TradingViewの場合はその辺り自分で細かく設定を変えて試せるので良いですよね。