2023年10月以降の運用実績については「投資でニート生活」で更新しています。

Python 株式投資

【コード解説】Pythonでエンベロープを計算してPlotlyで可視化する

2022年7月6日

こんにちは。TATです。

今日のテーマは「【コード解説】Pythonでエンベロープを計算してPlotlyで可視化する」です。

 

テクニカル分析ツールの1つであるエンベロープについて、Pythonを使って計算する方法を解説しつつ、Ploltyでチャートで描画していきます。

エンベロープは、移動平均線から上下に一定に乖離させた線のことで、移動平均線からどれくらい乖離しているのかを一目で確認することができます。

移動平均線から乖離しすぎた株価は最終的には移動平均線に収束するという特性があるので、この特性を利用して反転のポイントを見つけたり、支持線や抵抗線として利用することもできます。

 

また、エンベロープを利用するにあたって、どれくらい乖離させたものを利用するべきか、という疑問もあります。

この疑問については、簡単な統計学を使っていい感じの数字を見つけていきます。

 

エンベロープとは?

エンベロープとは?

まずはエンベロープについて簡単に解説しておきます。

 

エンベロープは、2本の線から構成されており、それぞれ移動平均線から上下に一定の割合で乖離させたものです。

エンベロープとは

  • エンベロープとは、移動平均線から上下に一定の割合で乖離させた線
  • 移動平均線からどれくらい乖離しているのかを確認することができる

 

一定の乖離率が表示されるので、チャートを見ただけで現在の価格が移動平均線からどれくらい乖離しているのかを簡単に把握することができます。

 

エンベロープの使い方

エンベロープはいろいろは用途に活用できます。

 

移動平均線から乖離しすぎた株価は最終的には移動平均線に収束する、という特徴を利用して、たとえば次の用途に利用できます。

エンベロープの用途

  • 株価反転のポイントして売買に利用する
  • 上値抵抗線、下値指示線として利用する

 

特にボックス相場ではうまく機能します。

強いトレンドが発生している相場では、エンベロープ線を超えてもすぐには回帰せず、そのまま上昇あるいは下落が続くこともあります。

状況によってうまく使い分けることが重要になります。

 

エンベロープの計算方法は?

次にエンベロープの計算方法です。

移動平均線から一定の割合で乖離すればOKなので、次の計算式で計算できます。

 

エンベロープの計算方法

  • 移動平均線 ± (移動平均線×乖離率)
  • あるいは、移動平均線×(1 ± 乖離率)

 

上記の計算式でエンベロープを計算できます。

乖離率が5%としたら、移動平均線 ± (移動平均線×0.05)になります。

 

乖離の目安はどれくらいか?

最後に乖離の目安についてです。

どれくらいの乖離にすればいいのでしょうか?

 

一般的には、3%とか5%がよく利用される印象があります。

エンベロープでググったりするとこれらの数字がよく登場します。

 

統計学を使って効果的な数字を弾き出すことも可能です。

過去データから移動平均線の乖離率をヒストグラムにすると正規分布になります。

これを特性を利用して、平均と標準偏差からいい感じの乖離率を求めることができます。

こちらについては、後ほどPythonを使って計算・可視化していきます。

 

エンベロープをPythonで計算する

エンベロープをPythonで計算する

ここからはPythonを使ってエンベロープを実装していきます。

 

株価データを用意する

まずは株価データの準備です。

 

今回は例として日経平均株価を利用します。

yahoo_finance_api2を使って、過去3年分の日経平均株価の日足データを取得します。

 

import sys
from yahoo_finance_api2 import share
from yahoo_finance_api2.exceptions import YahooFinanceError
import pandas as pd
 
my_share = share.Share('^N225')
symbol_data = None
 
try:
    symbol_data = my_share.get_historical(
        share.PERIOD_TYPE_YEAR, 3,
        share.FREQUENCY_TYPE_DAY, 1)
except YahooFinanceError as e:
    print(e.message)
    sys.exit(1)

df = pd.DataFrame(symbol_data)
df["datetime"] = pd.to_datetime(df.timestamp, unit="ms")

 

取得できたデータがこちらです。

 

参考記事
【Pythonコード解説】yahoo_finance_api2で日本株の株価データを取得する
【Pythonコード解説】yahoo_finance_api2で日本株の株価データを取得する

続きを見る

 

エンベロープを計算する

株価データが用意できたので、早速エンベロープを計算します。

 

例として、移動平均線の期間を25日乖離率は5%で計算してみます。

 

# 移動平均線
df["SMA25"] = df["close"].rolling(window=25).mean()

# エンベロープ
deviation = 0.05

df["upper"] = df["SMA25"] + df["SMA25"] * deviation
df["lower"] = df["SMA25"] - df["SMA25"] * deviation

 

これでエンベロープが計算できます。

 

rolling関数を使うと移動平均線が計算できます。

あとは先ほどご紹介した計算式をPythonで実装すればOKです。

上限をupper、下限をlowerとしました。

 

過去の移動平均線乖離率から効果的な乖離を割り出す

上記の例では乖離率を5%としましたが、この数字が果たして妥当なのか、過去データを使ってみてみましょう。

 

移動平均線との乖離率を計算してヒストグラムで可視化しつつ、平均値標準偏差などを確認していきます。

 

ちょっと左に伸びていますが、正規分布になっていることが確認できます。

正規分布の特性から、平均値をm標準偏差をσとすれば、データの割合を出すことができます。

正規分布

  • m±1σ:  68.2689492%
  • m±2σ:  95.4499736%
  • m±3σ:  99.7300204%

 

これを利用すれば、どれくらいの乖離率にすればいいか、目星をつけることができます。

m±1σで見ると、-3.378508 ~ 4.238182になります。

m±2σなら-7.186853 ~ 8.046527です。

 

この辺りの数値を使って、エンベロープの乖離を決めると良いです。

ゆるく設定するなら3とか4で、厳しめなら7とか8あたりでしょうか。

 

これは銘柄によって値が変わってくるので、都度都度適切な値を決めていくのもいいかと思います。

 

エンベロープをPlotlyで可視化する

エンベロープをPlotlyで可視化する

エンベロープの計算が完了したところで、ここからはPlotlyで可視化していきます。

 

Plotlyを使うとインタラクティブなチャートが簡単に描けます。

Plotlyを使った株価チャートの作成については過去記事で解説しているのでご参考ください。

本記事ではコードの細かい説明は省いてサクッといきます。

PythonのPlotlyでインタラクティブな株価のローソク足チャートを描く【コード解説】

続きを見る

 

また、Plotlyのほかにも、mplfinanceとかmpl_financeなどがあります。

Pythonのmplfinanceで株価のローソク足チャートを描く方法【コード解説】

続きを見る

Pythonのmpl_financeで株価のローソク足チャートを描く方法【コード解説】

続きを見る

 

ローソク足チャートを描く

まずはローソク足チャートを描いてみます。

移動平均線も加えます。

 

import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 非表示にする日付をリストアップ
d_all = pd.date_range(start=df['datetime'].iloc[0],end=df['datetime'].iloc[-1])
d_obs = [d.strftime("%Y-%m-%d") for d in df['datetime']]
d_breaks = [d for d in d_all.strftime("%Y-%m-%d").tolist() if not d in d_obs]

# figを定義
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_width=[0.2, 0.7], x_title="Date")
 
# Candlestick 
fig.add_trace(
    go.Candlestick(x=df["datetime"], open=df["open"], high=df["high"], low=df["low"], close=df["close"], name="OHLC", showlegend=False),
    row=1, col=1
)
 
# Volume
fig.add_trace(
    go.Bar(x=df["datetime"], y=df["volume"], name="Volume", showlegend=False),
    row=2, col=1
)

# SMA
fig.add_trace(go.Scatter(x=df["datetime"], y=df["SMA25"], name="SMA25", mode="lines", line=dict(color="orange")), row=1, col=1)

# Layout
fig.update_layout(
    title={
        "text": "日経平均株価の日足チャート",
        "y":0.9,
        "x":0.5,
    }
)
 
# y軸名を定義
fig.update_yaxes(title_text="株価", row=1, col=1)
fig.update_yaxes(title_text="出来高", row=2, col=1)
 
# 不要な日付を非表示にする
fig.update_xaxes(
    rangebreaks=[dict(values=d_breaks)]
)
 
fig.update(layout_xaxis_rangeslider_visible=False)
fig.show()

 

表示されるチャートがこちらです。

 

ローソク足と移動平均線、さらに出来高が表示されました。

ここにエンベロープを加えていきます。

 

エンベロープを加える

それでは先ほどのローソク足チャートエンベロープを加えてみます。

ここでは2つの方法で描画してみます。

エンベロープの描画方法

  • 線だけ描く
  • 帯状で描く

 

線だけ描く

まずはシンプルに線だけ描いてみます。

移動平均線と同じように描くだけです。

 

import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 非表示にする日付をリストアップ
d_all = pd.date_range(start=df['datetime'].iloc[0],end=df['datetime'].iloc[-1])
d_obs = [d.strftime("%Y-%m-%d") for d in df['datetime']]
d_breaks = [d for d in d_all.strftime("%Y-%m-%d").tolist() if not d in d_obs]

# figを定義
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_width=[0.2, 0.7], x_title="Date")
 
# Candlestick 
fig.add_trace(
    go.Candlestick(x=df["datetime"], open=df["open"], high=df["high"], low=df["low"], close=df["close"], name="OHLC", showlegend=False),
    row=1, col=1
)
 
# Volume
fig.add_trace(
    go.Bar(x=df["datetime"], y=df["volume"], name="Volume", showlegend=False),
    row=2, col=1
)

# SMA
fig.add_trace(go.Scatter(x=df["datetime"], y=df["SMA25"], name="SMA25", mode="lines", line=dict(color="orange")), row=1, col=1)

# Layout
fig.update_layout(
    title={
        "text": "日経平均株価の日足チャート",
        "y":0.9,
        "x":0.5,
    }
)
 
# エンベロープ
fig.add_trace(
    go.Scatter(x=df["datetime"], y=df["upper"], name="エンベロープ", line=dict(width=1, color="blue")),
    row=1, col=1
)
fig.add_trace(
    go.Scatter(x=df["datetime"], y=df["lower"], line=dict(width=1, color="blue"), showlegend=False),
    row=1, col=1
)


# y軸名を定義
fig.update_yaxes(title_text="株価", row=1, col=1)
fig.update_yaxes(title_text="出来高", row=2, col=1)
 
# 不要な日付を非表示にする
fig.update_xaxes(
    rangebreaks=[dict(values=d_breaks)]
)
 
fig.update(layout_xaxis_rangeslider_visible=False)
fig.show()

 

完成したチャートがこちらです。

 

移動平均線の上下にエンベロープが描かれていることが確認できます。

色は青で統一しました。

 

この線からはみ出たら、移動平均線に回帰する確率が高い、ということで売買サインとして利用することができます。

ただし、強いトレンドが発生している状況ではうまく機能しない場合もあるので、使い所をうまく見極める必要があります。

 

帯状で描く

次に帯状でエンベロープを描いてみます。

こっちの方がスタイリッシュでかっこいいかもです。

 

import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots

# 非表示にする日付をリストアップ
d_all = pd.date_range(start=df['datetime'].iloc[0],end=df['datetime'].iloc[-1])
d_obs = [d.strftime("%Y-%m-%d") for d in df['datetime']]
d_breaks = [d for d in d_all.strftime("%Y-%m-%d").tolist() if not d in d_obs]

# figを定義
fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_width=[0.2, 0.7], x_title="Date")
 
# Candlestick 
fig.add_trace(
    go.Candlestick(x=df["datetime"], open=df["open"], high=df["high"], low=df["low"], close=df["close"], name="OHLC", showlegend=False),
    row=1, col=1
)
 
# Volume
fig.add_trace(
    go.Bar(x=df["datetime"], y=df["volume"], name="Volume", showlegend=False),
    row=2, col=1
)

# SMA
fig.add_trace(go.Scatter(x=df["datetime"], y=df["SMA25"], name="SMA25", mode="lines", line=dict(color="orange")), row=1, col=1)

# Layout
fig.update_layout(
    title={
        "text": "日経平均株価の日足チャート",
        "y":0.9,
        "x":0.5,
    }
)
 
# エンベロープ
fig.add_trace(go.Scatter(x=df["datetime"], y=df["upper"], mode="lines", fill=None, line=dict(width=0, color="lightblue"), showlegend=False), row=1, col=1)
fig.add_trace(go.Scatter(x=df["datetime"], y=df["lower"], mode="lines", fill='tonexty', line=dict(width=0, color="lightblue"), showlegend=False), row=1, col=1)

# y軸名を定義
fig.update_yaxes(title_text="株価", row=1, col=1)
fig.update_yaxes(title_text="出来高", row=2, col=1)
 
# 不要な日付を非表示にする
fig.update_xaxes(
    rangebreaks=[dict(values=d_breaks)]
)
 
fig.update(layout_xaxis_rangeslider_visible=False)
fig.show()

 

完成したチャートがこちらです。

 

エンベロープが帯状で表示されているのできれいですね。

どっちを使うかは好みが分かれるところなので、使い勝手の良い方を選んでいただければと思います。

 

これで、Plotlyでエンベロープを描くことができました。

 

データの分析・可視化にはPythonが最適!

本記事で紹介したコードは、全てPythonを使って書いています。

 

Pythonデータの分析や可視化を得意とするプログラミング言語で、さらにAI関連のライブラリーも豊富で昨今のAIブームで需要が急拡大しています。

【いますぐ始められます】データ分析をするならPythonが最適です。

 

また、Python比較的学びやすい言でもあります。

実際、僕は社会人になってからPythonを独学で習得して転職にも成功し、Python独学をきっかけに人生が大きく変わりました。

【実体験】ゼロからのPython独学を決意してから転職を掴み取るまでのお話。 

 

Python学習方法についてはいろいろな方法があります。

僕はUdemyを選びましたが、書籍プログラミングスクールも選択肢になります。

【決定版】Python独学ロードマップ【完全初心者からでもOKです】

【まとめ】Pythonが学べるおすすめプログラミングスクール

プログラミングの独学にUdemyをおすすめする理由!【僕はUdemyでPythonを独学しました!】

 

まとめ

いかがでしたでしょうか。

ここでは、「【コード解説】Pythonでエンベロープを計算してPlotlyで可視化する」というテーマで、Pythonでエンベロープを計算して、Plotlyで可視化する方法について解説しました。

 

エンベロープを使うと移動平均線からどれくらい乖離しているのかが一目で確認できるのでとても便利です。

うまく活用することができれば、売買サインとして利用したり、上値抵抗線下値指示線として活用することもできます。

簡単な統計学を使えば、いい感じの乖離率を算出することもできます。

 

また、本記事で紹介したコードは自由にコピペしていただければと思います。

ここまで読んでくださり、ありがとうございました。

 

おすすめPython学習法

Udemy:セール中なら90%オフで購入可能。豊富なコースから選べる!

データミックス:Pythonとビジネスについて学べる!起業したい方にもおすすめ!

SAMURAI TERAKOYA:月額2,980円〜利用できるコスパ最強スクール!

 

-Python, 株式投資
-, , ,

© 2023 気ままなブログ