「投資苑2に書いてあるシステムをTradingViewで再現し、投資戦略を作り、バックテストを行う」
これを目標に少しずつトレードシステムを作っています。
前回はオートエンベロープの計算式などを解説しました。
今回は、実装編ということでプログラムに落とし込んでいきます。
オートエンベロープがどういうものか知りたい方や、どういった計算で導き出される指標なのかを知りたい方は、前回の記事を読んでからのほうがより理解しやすいかと思います。
>>TradingViewのトップページへ行く価格とEMAとの距離の計算
その時の価格とEMA(指数移動平均線)との距離を計算して、新しく用意した変数”distance”に入れておきます。
distance = math.max(math.abs(high - long_ema), math.abs(low - long_ema)
math.max()は引数のうち値が高いものを選ぶ関数です。
math.abs()は絶対値を返してくれます。
long_emaは前回作った変数で、中にはEMA(26)が入っています。
式の意味としては、中心となるEMAとの差を高値と安値両方で計算します。
中心との距離を出したいので、絶対値で計算します。
math.max()により、EMAから、より離れている価格を採用するようになっています。
σ(標準偏差)を計算する
前回も書きましたが、上が標準偏差を計算する式です。
使用する値を変数に入れて確認します。
long_ema // "平均"となる長期のemaが入っています
distance = math.max(math.abs(high - long_ema), math.abs(low - long_ema) // 使用する価格とemaとの差
lookback = 100 // 参照する期間(値は好みです)
lookbackの値は、決まった値はないので自由ですが、あまり小さい値にすると、標準偏差の意味がなくなってしまうので注意してください。
材料はそろったので、標準偏差を計算していきます。
正直に、平均や累乗、平方根を計算しても良いのですが、Pine Scriptには標準偏差を計算する関数がすでに用意されています!
それがta.stdev()です。
sigma = ta.stdev(distance, lookback) // 標準偏差の計算
これだけで、1標準偏差の計算ができてしまいました。
計算結果は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 × 1標準偏差
下側のチャネル = EMA - 2 × 1標準偏差
プログラムに直してグラフにします。
upper = long_ema + 2 * sigma
lower = long_ema - 2 * sigma
plot(upper, color = color.aqua)
plot(lower, color = color.aqua)
デフォルトだと移動平均線の色と同じになってしまい、わかりづらいので、エンベロープには色を付けました。
オートエンベロープの実装結果

//@version=5
indicator("マイ移動平均線", overlay = true)
long_ema = ta.ema(close, 26)
// 指数移動平均線
plot(ta.ema(close, 13), color = color.red)
plot(long_ema, color = color.blue)
// オートエンベロープ
// 使用する価格
distance = math.max(math.abs(high - long_ema), math.abs(low - long_ema))
// 参照する期間
lookback = 100
sigma = ta.stdev(distance, lookback)
upper = long_ema + (2 * sigma)
lower = long_ema - (2 * sigma)
plot(upper, color = color.aqua)
plot(lower, color = color.aqua)
ようやくオートエンベロープを実装できました。
実は、線の更新回数を5期間に1回だけなどにして、
もう少し線の幅を安定させたかったのですが、まずは完成ということにします。
次はオシレーターの定番、MACDに進みたいと思います。
MACDが追加されると、チャートとしても普通に使えるようになりそうです!
コメント
こんにちは!
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の場合はその辺り自分で細かく設定を変えて試せるので良いですよね。