This is a continuation of Qiita --u1and0 / Creating a currency chart that can be moved around with Plotly (1). You can now add / delete / initialize indicators.
Import the required modules.
# ----------General Module----------
import numpy as np
import pandas as pd
# ----------User Module----------
from randomwalk import randomwalk
import stockplot as sp
# ----------Hide General Module----------
import stockstats
import plotly
stock plot
.conda install plotly
pip install stockstats
# Make sample data
np.random.seed(10)
df = randomwalk(60 * 60 * 24 * 90, freq='S', tick=0.01, start=pd.datetime(2017, 3, 20))\
.resample('T').ohlc() + 115 #1 minute for 90 days,Initial value is 115
Create a random exchange chart. Create a 1-minute bar from 2017/3/20 for 90 days ** with the randomwalk function.
# Convert DataFrame as StockPlot
fx = sp.StockPlot(df)
Instantiate with the StockPlot class.
Convert the timeframe once instantiated with fig = sp.StockPlot (sdf)
.
Use the resample
method when converting.
fx.resample('4H').head()
close | open | high | low | |
---|---|---|---|---|
2017-03-20 00:00:00 | 115.34 | 115.00 | 115.98 | 114.79 |
2017-03-20 04:00:00 | 116.03 | 115.34 | 116.48 | 115.16 |
2017-03-20 08:00:00 | 116.31 | 116.03 | 116.75 | 115.76 |
2017-03-20 12:00:00 | 115.92 | 116.32 | 116.87 | 115.62 |
2017-03-20 16:00:00 | 114.36 | 115.92 | 116.12 | 113.85 |
After setting the timeframe, try plotting.
fx.plot(start_view='first', end_view='last')
fx.show('png', filebasename='png1')
This is the review of Last article.
Let's plot the index. Plot the most popular Simple Moving Average. Use the ʻappend` method to add it.
fx.append('close_25_sma')
fx.stock_dataframe.head()
close | open | high | low | close_25_sma | |
---|---|---|---|---|---|
2017-03-20 00:00:00 | 115.34 | 115.00 | 115.98 | 114.79 | 115.340000 |
2017-03-20 04:00:00 | 116.03 | 115.34 | 116.48 | 115.16 | 115.685000 |
2017-03-20 08:00:00 | 116.31 | 116.03 | 116.75 | 115.76 | 115.893333 |
2017-03-20 12:00:00 | 115.92 | 116.32 | 116.87 | 115.62 | 115.900000 |
2017-03-20 16:00:00 | 114.36 | 115.92 | 116.12 | 113.85 | 115.592000 |
fx.plot(start_view='first', end_view='last')
fx.show('png', filebasename='png2')
close_25_sma (25-legged simple moving average) has been added. If you execute the ʻappend` method alone on Jupyter Notebook or Ipython, the value of close_25_sma will be displayed as the return value.
Even if the added index changes the timeframe, the value will change according to the timeframe.
fx.resample('15T')
fx.plot(start_view='first', end_view='last')
fx.show('png', filebasename='png3')
After changing to 15 minutes with the resample
method, close_25_sma
is still added without using the ʻappend` method.
This is because the index is added to the graph when the plot
method is executed, not when the ʻappend` method is executed.
The ʻappend method only stores the values in
self._indicators`.
self.append()
# ========self._Store indicators in indicator==========
def append(self, indicator):
indicator_value = self.stock_dataframe[indicator]
self._indicators[indicator] = indicator_value # self._In indicators format in dictionary format
return indicator_value
self.plot()
# =======self when executing plot method._The indicator stored in the indicator_append_Pass to graph==========
def plot(self, (Abbreviation)):
# (Omission)
# ---------Append indicators----------
for indicator in self._indicators.keys():
self._append_graph(indicator, start_plot, end_plot) # Re-append indicator in graph
# (Omission)
return self._fig
self._append_graph()
# =======self._The indicator stored in the indicator is self._Add to the data part of fig==========
def _append_graph(self, indicator, start, end):
graph_value = self._indicators[indicator].loc[start:end]
plotter = go.Scatter(x=graph_value.index, y=graph_value,
name=indicator.upper().replace('_', ' ')) #Format conversion to add to the graph
self._fig['data'].append(plotter)
Use the pop
method to delete the metric.
fx.pop('close_25_sma')
fx.stock_dataframe.head()
open | high | low | close | |
---|---|---|---|---|
2017-03-20 00:00:00 | 115.00 | 115.26 | 114.87 | 115.11 |
2017-03-20 00:15:00 | 115.11 | 115.21 | 114.85 | 115.01 |
2017-03-20 00:30:00 | 115.01 | 115.49 | 114.90 | 115.47 |
2017-03-20 00:45:00 | 115.47 | 115.50 | 115.24 | 115.26 |
2017-03-20 01:00:00 | 115.25 | 115.49 | 115.10 | 115.27 |
fx.plot(start_view='first', end_view='last')
fx.show('png', filebasename='png3_1')
close_25_sma has been removed.
I will also draw indicators other than the simple moving average.
fx.append('close_20_ema') #Exponential moving average of closing price
fx.append('boll') #Bollinger band middle(close_20_Same as sma)
fx.append('boll_ub') #On Bollinger Bands
fx.append('boll_lb') #Under Bollinger Bands
fx.append('high_0~20_max') #The highest value of movement 20 feet ago
fx.append('low_0~20_min') #The lowest price to move 20 feet ago
fx.plot(start_view='first', end_view='last')
fx.show('png', filebasename='png4')
Was plotted.
If you don't know the name of the index you added, you can access it from the instance variable.
fx._indicators.keys()
dict_keys(['low_0~20_min', 'boll', 'high_0~20_max', 'boll_ub', 'close_20_ema', 'boll_lb'])
ʻWhen the appendmethod is used, the argument is key and the return value is value, and it is saved in the
_indicatorsin dictionary format. Therefore, you can call the index name added by the
keys` method.
You can also view it with
fx.stock_dataframe.columns
, but it is not recommended.stockstats.StockDataFrame
also raises ancillary columns when generating metrics. Therefore, auxiliary indicators (data not plotted in the graph) are also mixed, and it is difficult to distinguish which is plotted.
fx.stock_dataframe.columns
Index(['open', 'high', 'low', 'close', 'close_20_ema', 'close_20_sma',
'close_20_mstd', 'boll', 'boll_ub', 'boll_lb', 'high_0_s', 'high_1_s',
'high_2_s', 'high_3_s', 'high_4_s', 'high_5_s', 'high_6_s', 'high_7_s',
'high_8_s', 'high_9_s', 'high_10_s', 'high_11_s', 'high_12_s',
'high_13_s', 'high_14_s', 'high_15_s', 'high_16_s', 'high_17_s',
'high_18_s', 'high_19_s', 'high_20_s', 'high_0~20_max', 'low_0_s',
'low_1_s', 'low_2_s', 'low_3_s', 'low_4_s', 'low_5_s', 'low_6_s',
'low_7_s', 'low_8_s', 'low_9_s', 'low_10_s', 'low_11_s', 'low_12_s',
'low_13_s', 'low_14_s', 'low_15_s', 'low_16_s', 'low_17_s', 'low_18_s',
'low_19_s', 'low_20_s', 'low_0~20_min'],
dtype='object')
When displaying the index by fx.stock_dataframe.columns
, the index name that has not been added is also displayed.
Since it has been messed up, delete high_20_max and low_20_min.
fx.pop('high_0~20_max')
fx.pop('low_0~20_min')
fx.plot(start_view='first', end_view='last')
fx.show('png', filebasename='png5')
Only high_20_max and low_20_min have been removed from the graph.
Follow the steps below for the pop
method.
self._indicator
. from
self.stock_dataframe`.self._indicators
again.self.pop()
def pop(self, indicator):
popper = self._indicators.pop(indicator) # (1)
self.stock_dataframe = reset_dataframe(self.stock_dataframe) # (2)
for reindicator in self._indicators.keys():
self.stock_dataframe.get(reindicator) # (3)
return popper
The indicators contained in self.stock_dataframe
are a mixture of auxiliary columns depending on the added indicators.
Therefore, it is difficult to identify "only columns created by a certain index" and remove them from self.stock_dataframe
.
Therefore, once self.stock_dataframe
is returned to the state where resample
is applied (2), the index is added again (3).
(3) is almost the same as the ʻappend method, but it does not add to
self._indicators. Since the extra indicators have not been removed from
self._indicators in step (1), there is no need to add them to
self._indicators` again.
Use the clear
method to erase all the added indicators.
fx.clear()
fx.stock_dataframe.head()
open | high | low | close | |
---|---|---|---|---|
2017-03-20 00:00:00 | 115.00 | 115.26 | 114.87 | 115.11 |
2017-03-20 00:15:00 | 115.11 | 115.21 | 114.85 | 115.01 |
2017-03-20 00:30:00 | 115.01 | 115.49 | 114.90 | 115.47 |
2017-03-20 00:45:00 | 115.47 | 115.50 | 115.24 | 115.26 |
2017-03-20 01:00:00 | 115.25 | 115.49 | 115.10 | 115.27 |
fx.plot(start_view='first', end_view='last')
fx.show('png', filebasename='png6')
self.stock_dataframe
).self._fig
).self._indicators
).fx.clear (hard = True)
) (hard reset).self.stock_dataframe
reverts to None
.resample
method.self.clear()
def clear(self, hard=False):
self._fig = None # <-- plotly.graph_objs
self._indicators = {}
if hard:
self.stock_dataframe = None
self.freq = None #Foot time width
else:
self.stock_dataframe = reset_dataframe(self.stock_dataframe)
The clear
method is almost the same as the __init __
method,
That is, there is no need to use the
resample
method when plotting again
Is different from __init__
.
The order of use of each method is as shown in the flowchart below.
The left side shows Add and Show, and the right side shows Delete and Reset.
In stockstats
, the movement interval used in Bollinger Bands and $ \ sigma $ are defined as class variables.
BOLL_PERIOD = 20
BOLL_STD_TIMES = 2
Now try changing the travel section to 5, $ \ sigma $ to 1.
sp.ss.StockDataFrame.BOLL_PERIOD = 5 #Bollinger Bands movement section setting
sp.ss.StockDataFrame.BOLL_STD_TIMES = 1 #Bollinger band σ setting
boll = sp.StockPlot(df)
boll.resample('4H')
boll.append('boll') #Bollinger band middle(close_5_Same as sma)
boll.append('boll_ub') #On Bollinger Bands
boll.append('boll_lb') #Under Bollinger Bands
boll.plot(start_view='first', end_view='last')
boll.show('png', filebasename='png7')
It's a pity that $ \ sigma_1 $ and $ \ sigma_2 $ cannot be drawn at the same time.
Since BOLL_PERIOD
and BOLL_STD_TIMES
are class variables of stockstats
,
It should be redefined as stockplot.stockstats.BOLL_STD_TIMES = 2
.
However, when stockstats
adds an metric, it uses the _get
method, so the metric once added will be overwritten.
If you just draw it on a graph, it seems that you can do something, but it will be a future task.
stockstats supports the output of many indicators, but many indicators require subcharts. (MACD, RSI, ADX ...) The subcharts have not been touched in this release. When I try using Cufflinks, I feel that subplots can be easily done.
The first gif image shows the chart being interactively output as html from ipython.
./bin/stockplot_quickset.py
, which runs from importing modules to changing to daily bars./bin/stockplot_quickset.py
# ----------General Module----------
import numpy as np
import pandas as pd
# ----------User Module----------
from randomwalk import randomwalk
import stockplot as sp
# ----------Plotly Module----------
import plotly.offline as pyo
pyo.init_notebook_mode(connected=True)
# Make sample data
np.random.seed(1)
#Change 1 second tick for 90 days to 1 minute
df = randomwalk(60 * 60 * 24 * 90, freq='S', tick=0.01, start=pd.datetime(2017, 3, 20)).resample('T').ohlc() + 115
# Convert StockDataFrame as StockPlot
fx = sp.StockPlot(df)
# Resample as Day OHLC
fx.resample('H')
I uploaded the source code to github. github - u1and0/stockplot
Recommended Posts