下準備
サンプルデータの作成
np.random.seed(9)
from randomwalk import randomwalk
df = randomwalk(60 * 24 * 90, freq='T', tick=0.01, start=pd.datetime(2017, 3, 20)
).resample('B').ohlc() + 115 # 90日分の1分足を日足に直す
ランダムウォークの作成。
詳しくはpythonでローソク足(candle chart)の描画をご覧ください。
pd.DataFrame型をStockDataFrame型に変換
from stockstats import StockDataFrame
sdf = StockDataFrame(df.copy())
StockPlotクラスの使用方法
stockplot.pyのインポート
from stockplot import StockPlot
# StockPlotクラスのインスタンス化
x = StockPlot(sdf)
# キャンドルチャートのプロット
x.candle_plot()
キャンドルチャートが描かれました。
plotlyは基本的に画像をhtml形式で吐き出します。
マウスオーバーすると値が表示されたり、拡大縮小ができます。
わざわざgifファイルを作るのが面倒だったので、ここではpng形式で貼り付けております。
plotlyでぐりぐり動かせるグラフを見たい方は参考までにこちらをご覧ください。
Qiita - inoory様 - [Python] Plotlyでぐりぐり動かせるグラフを作る
指標
指標の追加
指標の追加はリスト型と同様にappend
メソッドを使います。
# 終値25日移動平均線追加
x.append('close_25_sma')
2017-03-20 114.850000
2017-03-21 114.805000
2017-03-22 114.886667
2017-03-23 114.912500
2017-03-24 114.912000
2017-03-27 114.940000
2017-03-28 115.010000
2017-03-29 115.016250
2017-03-30 115.062222
2017-03-31 115.063000
2017-04-03 115.066364
2017-04-04 115.082500
2017-04-05 115.093846
2017-04-06 115.075714
2017-04-07 115.093333
2017-04-10 115.111250
2017-04-11 115.097059
2017-04-12 115.071111
2017-04-13 115.041579
2017-04-14 115.037000
2017-04-17 115.039048
2017-04-18 115.047273
2017-04-19 115.042609
2017-04-20 115.075417
2017-04-21 115.117200
2017-04-24 115.165600
2017-04-25 115.194000
2017-04-26 115.216800
2017-04-27 115.247600
2017-04-28 115.262800
...
2017-05-08 115.319600
2017-05-09 115.306800
2017-05-10 115.313600
2017-05-11 115.328400
2017-05-12 115.315600
2017-05-15 115.297600
2017-05-16 115.297600
2017-05-17 115.314800
2017-05-18 115.337600
2017-05-19 115.330000
2017-05-22 115.317200
2017-05-23 115.296000
2017-05-24 115.308800
2017-05-25 115.302000
2017-05-26 115.282800
2017-05-29 115.256800
2017-05-30 115.254000
2017-05-31 115.238000
2017-06-01 115.245200
2017-06-02 115.272800
2017-06-05 115.289600
2017-06-06 115.318400
2017-06-07 115.366000
2017-06-08 115.425600
2017-06-09 115.508400
2017-06-12 115.579200
2017-06-13 115.636800
2017-06-14 115.686800
2017-06-15 115.736000
2017-06-16 115.798000
Freq: B, Name: close_25_sma, dtype: float64
add_indicator
関数の戻り値はStockDataFrame
クラスでget
メソッドを使った時と同じ結果が返ってきます。
裏でplotly形式に直され、インスタンス変数self._figに追加されます。
# キャンドルチャートと追加された指標のプロット
x.candle_plot()
終値25日移動平均線が追加されました。
# 終値25日指数移動平均線の追加とプロット
x.append('close_25_ema')
x.candle_plot()
先ほど追加された終値25日移動平均線に加え、終値25日指数移動平均線が追加されました。
指標の削除
指標の削除はリストの削除と同様に'remove'メソッドを使います。
y = StockPlot(sdf)
# 10,11,12,13足移動平均線
for i in range(10, 14):
y.append('close_{}_sma'.format(i))
y.candle_plot()
新たなインスタンスを作成し、10, 11, 12, 13足移動平均線を追加しました。
ここでは省略されていますが、remove
戻り値は削除したStockDataFrameのカラムです。
# 10, 12足移動平均線の削除
for i in (10, 12):
y.remove('close_{}_sma'.format(i))
y.candle_plot()
10足、12足移動平均線だけを指定して削除しました。
ファイルへのエクスポート
StockPlotクラスはPlotlyのhtmlエクスポートするplotly.offline.iplot
(Jupyter Notebook形式)で図を吐き出します。
つまり、ファイルへのエクスポートがされません。
ファイルとして吐き出したいときは以下のメソッドを使います。
- html形式:
plotly.offline.plot(figure_or_data, filename=<拡張子htmlにしないとワーニング(勝手に拡張子つけられちゃう)>, )
- png, svg, jpeg, webp形式:
plotly.offline.plot(figure_or_data, image=<png|svg|jpeg|webp>, imagefilename=<拡張子抜きのファイル名>)
import plotly.offline as pyo
pyo.plot(y._fig, filename='candle_y.html', validate=False) # 新しいタブを開いてhtml表示します
pyo.plot(y._fig, image='png', image_filename='candle_y')
# 新しいtmpタブを開いて
# imageに指定した拡張子として
# デフォルトのダウンロードディレクトリに保存します
パッケージ紹介
Plotly
グラフ描画はPlotlyに行わせます。
簡単なことだったら無料で使えます。
インストールは
conda install plotly
または
pip install plotly
有名だと思うのでここでは言及しません。
stockstats
データ操作はstockstatsというパッケージを使います。
インストールは
pip install stockstats
stockstats
は金融指標を簡単に取得できる改造pandas.DataFrameクラスです。
# 使い方
np.random.seed(2)
df = pd.DataFrame(np.random.randn(10,4), columns=['open', 'high', 'low', 'close'])
from stockstats import StockDataFrame
sdf = StockDataFrame(df) # pandasデータフレームをStockDataFrameに入れてあげる
sdf
open | high | low | close | |
---|---|---|---|---|
0 | -0.416758 | -0.056267 | -2.136196 | 1.640271 |
1 | -1.793436 | -0.841747 | 0.502881 | -1.245288 |
2 | -1.057952 | -0.909008 | 0.551454 | 2.292208 |
3 | 0.041539 | -1.117925 | 0.539058 | -0.596160 |
4 | -0.019130 | 1.175001 | -0.747871 | 0.009025 |
5 | -0.878108 | -0.156434 | 0.256570 | -0.988779 |
6 | -0.338822 | -0.236184 | -0.637655 | -1.187612 |
7 | -1.421217 | -0.153495 | -0.269057 | 2.231367 |
8 | -2.434768 | 0.112727 | 0.370445 | 1.359634 |
9 | 0.501857 | -0.844214 | 0.000010 | 0.542353 |
見た目に変化はありませんが金融指標をstockstats
の文法に従ってget
メソッド、またはディクショナリの取得をすると、金融指標のカラムが追加されます。
sdf.get('close_5_sma'); sdf
open | high | low | close | close_5_sma | |
---|---|---|---|---|---|
0 | -0.416758 | -0.056267 | -2.136196 | 1.640271 | 1.640271 |
1 | -1.793436 | -0.841747 | 0.502881 | -1.245288 | 0.197491 |
2 | -1.057952 | -0.909008 | 0.551454 | 2.292208 | 0.895730 |
3 | 0.041539 | -1.117925 | 0.539058 | -0.596160 | 0.522758 |
4 | -0.019130 | 1.175001 | -0.747871 | 0.009025 | 0.420011 |
5 | -0.878108 | -0.156434 | 0.256570 | -0.988779 | -0.105799 |
6 | -0.338822 | -0.236184 | -0.637655 | -1.187612 | -0.094264 |
7 | -1.421217 | -0.153495 | -0.269057 | 2.231367 | -0.106432 |
8 | -2.434768 | 0.112727 | 0.370445 | 1.359634 | 0.284727 |
9 | 0.501857 | -0.844214 | 0.000010 | 0.542353 | 0.391392 |
close_5_sma: 終値の5足移動平均線が追加されました。
sdf['close_5_sma']; sdf
open | high | low | close | close_5_sma | |
---|---|---|---|---|---|
0 | -0.416758 | -0.056267 | -2.136196 | 1.640271 | 1.640271 |
1 | -1.793436 | -0.841747 | 0.502881 | -1.245288 | 0.197491 |
2 | -1.057952 | -0.909008 | 0.551454 | 2.292208 | 0.895730 |
3 | 0.041539 | -1.117925 | 0.539058 | -0.596160 | 0.522758 |
4 | -0.019130 | 1.175001 | -0.747871 | 0.009025 | 0.420011 |
5 | -0.878108 | -0.156434 | 0.256570 | -0.988779 | -0.105799 |
6 | -0.338822 | -0.236184 | -0.637655 | -1.187612 | -0.094264 |
7 | -1.421217 | -0.153495 | -0.269057 | 2.231367 | -0.106432 |
8 | -2.434768 | 0.112727 | 0.370445 | 1.359634 | 0.284727 |
9 | 0.501857 | -0.844214 | 0.000010 | 0.542353 | 0.391392 |
sdf.get('close_5_sma')
と全く同じです。
getの方がありえない指標を打ち込んだときエラーが発生しません。
どちら良いかは用途次第でしょう。
指標できる指標は以下の通りです。
- change (in percent)
- delta
- permutation (zero based)
- log return
- max in range
- min in range
- middle = (close + high + low) / 3
- SMA: simple moving average
- EMA: exponential moving average
- MSTD: moving standard deviation
- MVAR: moving variance
- RSV: raw stochastic value
- RSI: relative strength index
- KDJ: Stochastic oscillator
- Bolling: including upper band and lower band.
- MACD: moving average convergence divergence. Including signal and histogram.
- CR:
- WR: Williams Overbought/Oversold index
- CCI: Commodity Channel Index
- TR: true range
- ATR: average true range
- line cross check, cross up or cross down.
- DMA: Different of Moving Average (10, 50)
- DMI: Directional Moving Index, including
- +DI: Positive Directional Indicator
- -DI: Negative Directional Indicator
- ADX: Average Directional Movement Index
- ADXR: Smoothed Moving Average of ADX
- TRIX: Triple Exponential Moving Average
- VR: Volatility Volume Ratio
詳しくは公式をご覧ください。
stockplot
私が作ったやつです。
stockstatsを楽にplotするためのクラスStockPlotを作成しました。
stockplot.pyのソースコード
import numpy as np
import pandas as pd
# ----------User Module----------
from randomwalk import randomwalk
import stockstats as ss
# ----------Plotly Module----------
from plotly.tools import FigureFactory as FF
import plotly.offline as pyo
import plotly.graph_objs as go
pyo.init_notebook_mode(connected=True)
class StockPlot:
"""StockDataFrameの可視化ツール
# TODO
* heikin_plot
* pop
* subplot
"""
def __init__(self, sdf: ss.StockDataFrame):
self.StockDataFrame = sdf
self._fig = FF.create_candlestick(self.StockDataFrame.open,
self.StockDataFrame.high,
self.StockDataFrame.low,
self.StockDataFrame.close,
dates=self.StockDataFrame.index)
def candle_plot(self, filebasename='candlestick_and_trace'):
"""StockDataFrameをキャンドルチャート化する
引数: dfs: StockDataFrame
戻り値: plotly plot"""
self._fig['layout'].update(xaxis={'showgrid': True})
ax = pyo.iplot(self._fig, filename=filebasename + '.html', validate=False)
# pyo.plot(self._fig, image='png', image_filename=filebasename, validate=False)
return ax
def append(self, indicator):
indi = self.StockDataFrame.get(indicator)
plotter = go.Scatter(x=indi.index, y=indi,
name=indicator.upper().replace('_', ' ')) # グラフに追加する形式変換
self._fig['data'].append(plotter)
return indi
def remove(self, indicator):
indi = indicator.lower().replace(' ', '_')
INDI = indicator.upper().replace('_', ' ')
rem = self.StockDataFrame.pop(indi)
for dicc in self._fig['data']:
if dicc['name'] == INDI:
self._fig['data'].remove(dicc)
return rem
github
u1and0/stockplot