QuantFigure() allows you to persist data, setting and technical analysis calculations.
It is still based on the same principles as Cufflinks:
import cufflinks as cf
import pandas as pd
import eikon as ek
ek.set_app_id('AD2833F918E18C4FC866')
Warning: file .portInUse was not found. Is Eikon Scripting Proxy running? Defaulting to port 36036
We will retrieve 7 years of daily data for
gbp=ek.get_timeseries('gbp=',fields='*',start_date='2010-01-01',interval='weekly')
vix=ek.get_timeseries('.vix',fields='*',start_date='2010-01-01',interval='weekly')
spx=ek.get_timeseries('.spx',fields='*',start_date='2010-01-01',interval='weekly')
aapl=ek.get_timeseries('aapl.o',fields='*',start_date='2015-01-01')
aapl.head()
AAPL.O | HIGH | CLOSE | LOW | OPEN | COUNT | VOLUME |
---|---|---|---|---|---|---|
Date | ||||||
2015-01-02 | 111.44 | 109.33 | 107.350 | 111.39 | 287735.0 | 53204626.0 |
2015-01-05 | 108.65 | 106.25 | 105.410 | 108.29 | 318491.0 | 64285491.0 |
2015-01-06 | 107.43 | 106.26 | 104.630 | 106.54 | 364769.0 | 65797116.0 |
2015-01-07 | 108.20 | 107.75 | 106.695 | 107.20 | 222954.0 | 40105934.0 |
2015-01-08 | 112.15 | 111.89 | 108.700 | 109.23 | 305171.0 | 59364547.0 |
We create a new QuantFigure with the GBP data.
qf=cf.QuantFig(gbp,title='USD/GBP',legend='top',name='GBP=')
Below you can see that the structure of the QuantFigure is aligned with the properties/metadata of a Financial chart.
qf
{ "_d": { "close": "CLOSE", "high": "HIGH", "low": "LOW", "open": "OPEN" }, "data": { "kind": "candlestick", "name": "GBP=", "showlegend": true }, "kwargs": {}, "layout": { "annotations": { "params": {}, "values": [] }, "legend": "top", "margin": { "b": 40, "l": 40, "r": 40, "t": 40 }, "rangeselector": { "visible": false }, "rangeslider": false, "shapes": {}, "showlegend": true, "title": "USD/GBP" }, "panels": { "bottom_margin": 0, "min_panel_size": 0.15, "spacing": 0.08, "top_margin": 0.9 }, "studies": {}, "theme": { "down_color": "grey", "theme": "white", "up_color": "java" }, "trendlines": [] }
Plotting our first QuantFigure
qf.iplot()
Below we can see the structure of this Figure. The values are similar to those interpretted by cufflinks rather than
qf
{ "_d": { "close": "CLOSE", "high": "HIGH", "low": "LOW", "open": "OPEN" }, "data": { "kind": "candlestick", "name": "GBP=", "showlegend": true }, "kwargs": {}, "layout": { "annotations": { "params": {}, "values": [] }, "legend": "top", "margin": { "b": 40, "l": 40, "r": 40, "t": 40 }, "rangeselector": { "visible": false }, "rangeslider": false, "shapes": {}, "showlegend": true, "title": "USD/GBP" }, "panels": { "bottom_margin": 0, "min_panel_size": 0.15, "spacing": 0.08, "top_margin": 0.9 }, "studies": {}, "theme": { "down_color": "grey", "theme": "white", "up_color": "java" }, "trendlines": [] }
All values can be overriden on the fly - without affecting the original instance.
qf.iplot(theme='ggplot',up_color='white',down_color='blue',title='OHLC Chart',
showlegend=False,kind='ohlc')
Going back to our original chart - all settings are preserved
qf.iplot()
Aleternatively we could also change an attribute of the figure (serlalized) to make it a permanent change
qf.theme.update(up_color='green')
qf.iplot()
A rangeselector allows us to select different periods on the same chart. This can be any variety of Year, Months, Hours etc.
For example:
steps=['1y','2 months','5 weeks','ytd','2mtd']
rangeselector=dict(steps=['Reset','3Y','2Y','1Y','YTD','6M'],
bgcolor=('lime',.2),
fontsize=12,fontfamily='monospace')
qf.layout.update(rangeselector=rangeselector)
qf.iplot()
qf.layout['annotations']['values']=[]
qf.add_annotations({'2016-06-24':'BREXIT',
'2016-10-07':'Flash Crash'},
arrowhead=6,arrowcolor='green',fontcolor='red',textangle=0)
We will add a support line to indicate where the price has struggled to break (downwards). A support line is a horizontal line. We only need the date as reference.
qf.add_support('2010-03-26',width=2,color='purple')
qf.iplot()
qf.add_support('2016-07-08',width=2,color='purple',mode='toend')
qf.iplot()
qf.iplot(shapes=dict(kind='rect',x0='2017-03-31',x1='2017-04-28',y0=1.2,y1=1.35,
color='magenta',fillcolor='magenta',opacity=0.2))
qf=cf.QuantFig(vix,title='VIX',legend='top',datalegend=False)
qf.iplot()
qf.iplot(hspan=dict(y0=11.5,y1=16,color='mustard',fill=True,opacity=.3,yref='y2'),
rangeslider=True)
A rangeselector allows us to select change the amount of data displayed on the chart.
rangeselector=dict(steps=['Reset','3Y','2Y','1Y','YTD','6M'],
bgcolor=('rgb(150, 200, 250)',.1),
fontsize=12,fontfamily='monospace')
qf=cf.QuantFig(spx,legend='top',datalegend=False,name='SPX',rangeselector=rangeselector)
qf.iplot()
qf.add_rsi()
qf.iplot()
qf.trendlines=[]
qf.add_trendline('07Oct11','06Feb15',on='low',text='SPX Long Term<br>Uptrend',color='purple',
width=2,dash='solid',ay=50,arrowhead=7,arrowcolor='green')
qf.add_trendline('06Feb15','28Apr17',on='low',y1=2600,width=2,dash='dash')
qf.iplot()
qf.add_shapes(shapes=dict(kind='rect',x0='2014-10-17',x1='2016-07-01',y0=1600,y1=2300,
color='grey',fill=True,opacity=.2))
qf.add_annotations(dict(x='2015-10-10',y=1600,text='Head & Shoulders<br>Pattern',
arrowhead=7,arrowcolor='green',ay=50))
qf.iplot()
We can see how the trendlines are always added as metadata
qf.trendlines
[]
qf.add_shapes(vspan=dict(x0='2017-01-27',x1='2017-04-28',color='orange',fill=True,opacity=.1))
qf.add_annotations(dict(x='2017-01-27',y=70,text='RSI<br>Overbought',
arrowhead=7,arrowcolor='green',yref='y3',yanchor='middle',ay=30))
qf.iplot()
qf=cf.QuantFig(aapl,legend='top',name='Apple')
rangeselector=dict(steps=['Reset','2Y','1Y','6M','3M','2MTD'],
bgcolor=('rgb(150, 200, 250)',.1),
fontsize=12,fontfamily='monospace')
qf.layout.update(rangeselector=rangeselector)
qf.iplot()
qf.add_volume(colorchange=True)
qf.iplot(legend='top')
qf.add_sma([21,55,144],colors=['green','orange','blue'],width=1)
qf.iplot()
qf.studies['sma']['display'].update(legendgroup=True)
qf.data.update(showlegend=False)
qf.iplot()
qf.add_bollinger_bands(periods=20,boll_std=2,colors=['magenta','grey'],fill=True)
qf.iplot()
qf.add_rsi(periods=20,rsi_upper=70,rsi_lower=30)
qf.iplot()
qf._get_study_figure('rsi').iplot()
Panels control how multipe charts (studies) are displayed
qf.panels
{'bottom_margin': 0, 'min_panel_size': 0.15, 'spacing': 0.08, 'top_margin': 0.9}
We can change the spacing between panels on the fly
qf.iplot(spacing=.05,theme='ggplot')
qf.add_macd(fast_period=12, slow_period=26, signal_period=9)
qf.iplot(spacing=.05)
qf.theme.update(theme='solar')
qf.iplot()