Reputation: 445
I am creating OHLC graphs using plotly with and add line chart to the same plot to showcase Moving averages & RSI which can be enabled or disabled by clicking on legend.
I am using tutorial provided in the below link Below code creates the required charts
#https://chart-studio.plotly.com/~jackp/17421/plotly-candlestick-chart-in-python/#/
import time
Mstart = time.process_time()
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.io as pio
from plotly.offline import iplot
# Calling Numpy package to manipulate numbers
import numpy as np
# Calling Pandas to create dataframe
import pandas as pd
#importing ta-lib to calculate Technical indicators
import talib as ta
import datetime
from datetime import date as dt
# ----------------------- Loading data from csv file --------------------------------
VipData = pd.read_csv(r"C:\xxxxxxxx\data.csv")
# --------------------------- Generating Technical indicator features --------------------------
VipData['RSI7']= ta.RSI(VipData['Close'].values, timeperiod=7)
def bbp(price):
#print(price)
up, mid, low = ta.BBANDS(price, timeperiod=20, nbdevup=2, nbdevdn=2, matype=0)
bbp = (VipData['Close'] - low) / (up - low)
return up, mid, low, bbp
VipData['BB_up'],VipData['BB_mid'],VipData['BB_low'],VipData['BBP']=bbp(VipData.Close)
VipData['AD']=ta.AD(VipData.High, VipData.Low, VipData.Close, VipData.Volume)
VipData['OBV'] = ta.OBV(VipData.Close, VipData.Volume)
VipData['EMA12']=ta.EMA(VipData.Close, timeperiod=12)
VipData['EMA26']=ta.EMA(VipData.Close, timeperiod=26)
VipData['MA10'] = ta.MA(VipData.Close, timeperiod=10, matype=0)
VipData['MA50'] = ta.MA(VipData.Close, timeperiod=50, matype=0)
VipData['MP'] = ta.MIDPOINT(VipData.Close, timeperiod=14)
VipData['SMA10']= ta.SMA(VipData.Close, timeperiod=10)
VipData['SMA42']= ta.SMA(VipData.Close, timeperiod=42)
VipData['ADX'] = ta.ADX(VipData.High, VipData.Low, VipData.Close, timeperiod=14)
VipData['CCI'] = ta.CCI(VipData.High, VipData.Low, VipData.Close, timeperiod=14)
def macd(close):
macd, macdsignal, macdhist = ta.MACD(close, fastperiod=12, slowperiod=26, signalperiod=9)
return macd, macdsignal, macdhist
VipData['MACD'],VipData['MACDSig'],VipData['MACDHist'] = macd(VipData.Close)
VipData['MDI'] = ta.MINUS_DI(VipData.High, VipData.Low, VipData.Close, timeperiod=14)
VipData['PDM'] = ta.PLUS_DM(VipData.High, VipData.Low, timeperiod=14)
VipData['ATR'] = ta.ATR(VipData.High, VipData.Low, VipData.Close, timeperiod=14)
#--------------------------- Creating Chart ------------------------------------------------------
Cstart = time.process_time()
fig = make_subplots(specs=[[{"secondary_y": True}]])
INCREASING_COLOR = '#90ee90'
DECREASING_COLOR = '#ff0000'
#Create the layout object
annotations = []
annotations.append(go.layout.Annotation(x= VipData['Datetime'].iloc[VipData['Close'].idxmin()],
y=VipData['Close'].iloc[VipData['Close'].idxmin()],
showarrow=True,
arrowhead=1,
arrowcolor="purple",
arrowsize=2,
arrowwidth=2,
text="Low"))
annotations.append(go.layout.Annotation(x= VipData['Datetime'].iloc[VipData['Close'].idxmax()],
y=VipData['Close'].iloc[VipData['Close'].idxmax()],
showarrow=True,
arrowhead=1,
arrowcolor="purple",
arrowsize=2,
arrowwidth=2,
text="High"))
layout = dict(
title="VIP Chart",
xaxis=go.layout.XAxis(title=go.layout.xaxis.Title( text="Time (IST)"), rangeslider=dict (visible = True)),
yaxis=go.layout.YAxis(title=go.layout.yaxis.Title( text="Price - Indian Rupees"),domain = [0, 0.2]),
yaxis2 = go.layout.YAxis(domain = [0.2, 0.8],title=go.layout.yaxis.Title( text="Indicator Values")),
legend = dict(orientation = 'h', y=0.9, x=0.3, yanchor='bottom'),
margin = dict( t=29, b=20, r=20, l=20 ),
width=800,
height=600,
annotations=annotations
)
#Creating OHLC Chart
data = [ dict(
type = 'ohlc',
open = VipData.Open,
high = VipData.High,
low = VipData.Low,
close = VipData.Close,
x = VipData.Datetime,
yaxis = 'y2',
name = 'OHLC',
increasing = dict( line = dict( color = INCREASING_COLOR ) ),
decreasing = dict( line = dict( color = DECREASING_COLOR ) ),
) ]
layout=dict()
fig = dict( data=data, layout=layout )
#Adding moving average
fig['data'].append( dict( x=list(VipData.Datetime), y=list(VipData.MA10), type='scatter', mode='lines',
line = dict( width = 1 ),
marker = dict( color = '#E377C2' ),
yaxis = 'y2', name='Moving Average' ) )
#Add RSI chart
fig['data'].append( dict( x=VipData.Datetime, y=VipData.RSI7,
marker=dict( color='#000' ),
type='scatter', yaxis='y', secondary_y=True, name='RSI' ) )
#Add volume bollinger bands
fig['data'].append( dict( x=VipData.Datetime, y=VipData.BB_up, type='scatter', yaxis='y2',
line = dict( width = 1 ),
marker=dict(color='#b41c1c'), hoverinfo='none',
legendgroup='Bollinger Bands', name='Bollinger Bands'))
fig['data'].append( dict( x=VipData.Datetime, y=VipData.BB_low, type='scatter', yaxis='y2',
line = dict( width = 1 ),
marker=dict(color='#b41c1c'), hoverinfo='none',
legendgroup='Bollinger Bands', showlegend=False ))
CRstart = time.process_time()
pio.renderers.default = "browser"
iplot( fig, filename = 'candlestick-test-3', validate = False )
#iplot( fig, validate = False )
Cend = time.process_time()
CRtime = Cend - CRstart
CTime = Cend-Cstart
print(f'Chart rendered in {CRtime} secs')
print(f'Chart created in {CTime} secs')
The charts are getting created but I am getting two problems:
Both Y axis values are coming on the same side, left of the plot how show secondary y axis on the right. Adding image for your reference.
Since this is a intraday data with 1min intervals hence will be dense so when I zoom into the same the candlesticks becomes extremely small. how to increase the size of the same. I understand the OHLC are very near to each other but still, i want to have higher sized candlesticks for better visibility. How can I go about doing the same. Image for your reference
Thanks for your time & efforts for helping me.
Regards Sudhir
Upvotes: 1
Views: 3252
Reputation: 35115
It's an interesting question, so I've added a second y-axis setting and a moving average, referring to the official plotly reference. Limiting the period with the slider also expands the candlestick; I didn't see a setting to make the box larger on the plotly candlestick.
import plotly.graph_objects as go
import numpy as np
import pandas as pd
import pandas_datareader.data as web
import datetime
from plotly.subplots import make_subplots
start = datetime.datetime(2018, 1, 1)
end = datetime.datetime(2019, 1, 1)
df = web.DataReader("MSFT", 'yahoo', start, end)
df.reset_index(inplace=True)
# moving average
exp12 = df['Close'].ewm(span=12, adjust=False).mean()
exp26 = df['Close'].ewm(span=26, adjust=False).mean()
macd = exp12 - exp26
signal = macd.ewm(span=9, adjust=False).mean()
# Create figure with secondary y-axis
fig = make_subplots(specs=[[{"secondary_y": True}]])
fig.add_trace(go.Candlestick(x=df['Date'], open=df['Open'], high=df['High'], low=df['Low'], close=df['Close'],
yaxis='y1', name='Cnadlestick'))
fig.add_trace(go.Scatter(x=df['Date'], y=exp12, name='Moving Avg 12',
line=dict(color='royalblue',width=2)))
fig.add_trace(go.Scatter(x=df['Date'], y=exp26, name='Moving Avg 26',
line=dict(color='firebrick',width=2)))
fig.add_trace(go.Bar(x=df['Date'], y=df['Volume'], yaxis='y2', name='Volume'))
# Add figure title
fig.update_layout(
width=1100,
height=600,
title_text="Microsoft Stock",
yaxis_tickformat='M'
)
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1
))
# Set x-axis title
fig.update_xaxes(title_text="Date")
# Set y-axes titles
fig.update_yaxes(title_text="<b>primary</b> Close", secondary_y=False)
fig.update_yaxes(title_text="<b>secondary</b> Volume", range=[0, 300000000], secondary_y=True)
fig.show()
Upvotes: 4