Skip to content

Commit 2960904

Browse files
first draft test_fill_between.py
1 parent f02ca53 commit 2960904

File tree

3 files changed

+300
-0
lines changed

3 files changed

+300
-0
lines changed
22.9 KB
Loading
23.2 KB
Loading

tests/test_fill_between.py

Lines changed: 300 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,300 @@
1+
#!/usr/bin/env python
2+
# coding: utf-8
3+
import os
4+
import os.path
5+
import glob
6+
import mplfinance as mpf
7+
import matplotlib.pyplot as plt
8+
from matplotlib.testing.compare import compare_images
9+
10+
print('mpf.__version__ =',mpf.__version__) # for the record
11+
print("plt.rcParams['backend'] =",plt.rcParams['backend']) # for the record
12+
13+
base='fill_between'
14+
tdir = os.path.join('tests','test_images')
15+
refd = os.path.join('tests','reference_images')
16+
17+
globpattern = os.path.join(tdir,base+'*.png')
18+
oldtestfiles = glob.glob(globpattern)
19+
20+
for fn in oldtestfiles:
21+
try:
22+
os.remove(fn)
23+
except:
24+
print('Error removing file "'+fn+'"')
25+
26+
# IMGCOMP_TOLERANCE = 7.0 # this works fine for linux
27+
IMGCOMP_TOLERANCE = 11.0 # required for a windows pass. (really 10.25 may do it).
28+
29+
def _get_scaled_down_dataset(bolldata):
30+
start = int(0.2*len(bolldata))
31+
end = 2*start
32+
df = bolldata.iloc[start:end]
33+
scaled_down_data = df/df['Close'].mean()
34+
scaled_down_data -= 0.9*scaled_down_data['Low'].min()
35+
return scaled_down_data
36+
37+
38+
def test_fill_between01(bolldata):
39+
40+
scaled_down_data = _get_scaled_down_dataset(bolldata)
41+
42+
fname = base+'01.png'
43+
tname = os.path.join(tdir,fname)
44+
rname = os.path.join(refd,fname)
45+
46+
mpf.plot(scaled_down_data,figscale=0.7,
47+
fill_between=scaled_down_data['Close'].values,
48+
savefig=tname)
49+
50+
tsize = os.path.getsize(tname)
51+
print(glob.glob(tname),'[',tsize,'bytes',']')
52+
53+
rsize = os.path.getsize(rname)
54+
print(glob.glob(rname),'[',rsize,'bytes',']')
55+
56+
result = compare_images(rname,tname,tol=IMGCOMP_TOLERANCE)
57+
if result is not None:
58+
print('result=',result)
59+
assert result is None
60+
61+
def test_fill_between02(bolldata):
62+
63+
scaled_down_data = _get_scaled_down_dataset(bolldata)
64+
65+
fname = base+'02.png'
66+
tname = os.path.join(tdir,fname)
67+
rname = os.path.join(refd,fname)
68+
69+
mpf.plot(scaled_down_data,figscale=0.7,
70+
fill_between={'y1':scaled_down_data['Close'].values,'alpha':0.75},
71+
savefig=tname)
72+
73+
tsize = os.path.getsize(tname)
74+
print(glob.glob(tname),'[',tsize,'bytes',']')
75+
76+
rsize = os.path.getsize(rname)
77+
print(glob.glob(rname),'[',rsize,'bytes',']')
78+
79+
result = compare_images(rname,tname,tol=IMGCOMP_TOLERANCE)
80+
if result is not None:
81+
print('result=',result)
82+
assert result is None
83+
84+
85+
## import pandas as pd
86+
##
87+
## # ### Read in daily data for the S&P 500 from November of 2019
88+
##
89+
## daily = pd.read_csv('data/SP500_NOV2019_Hist.csv',index_col=0,parse_dates=True)
90+
## daily.index.name = 'Date'
91+
## daily.shape
92+
## daily.head(3)
93+
##
94+
## import mplfinance as mpf
95+
## mpf.__version__
96+
##
97+
## print('''
98+
##
99+
## A single y-value or series **assumes** we fill between ZERO and that single y-value or series.
100+
##
101+
## Therefore, scale down the data, close to zero, so that we can demonstrate specifying
102+
## a single y-value, or single y-series for fill_between:
103+
##
104+
## ''')
105+
## scaled_down_data = (daily/3000)-1.0
106+
##
107+
## mpf.plot(scaled_down_data,figscale=0.7)
108+
## mpf.plot(scaled_down_data,figscale=0.7,fill_between=0.03)
109+
## mpf.plot(scaled_down_data,figscale=0.7,fill_between=scaled_down_data['Close'].values)
110+
##
111+
## print('''
112+
##
113+
## Use a dict to specify two y values, or two series, (y1 and y2) for `fill_between`:
114+
##
115+
## ''')
116+
##
117+
## mpf.plot(daily,figscale=0.7,fill_between=dict(y1=3090,y2=3120))
118+
## mpf.plot(daily,figscale=0.7,fill_between=dict(y1=3100,y2=daily['Close'].values))
119+
## mpf.plot(daily,figscale=0.7,fill_between=dict(y1=daily['Low'].values,y2=daily['High'].values))
120+
##
121+
## print('''
122+
##
123+
## Use a dict to specify other attributes (kwargs) for `fill_between`:
124+
##
125+
## To demonstrate use of the `where` kwarg to display a holding period,
126+
## we convert the datetime index into a dataframe, and use that to generate a boolean array:
127+
##
128+
## `where_values = pd.notnull(dates_df[ (dates_df>=buy_date) & (dates_df <= sell_date) ])['Date'].values`
129+
##
130+
## ''')
131+
##
132+
## dates_df = pd.DataFrame(daily.index)
133+
## buy_date = pd.Timestamp('2019-11-06')
134+
## sell_date = pd.Timestamp('2019-11-19')
135+
##
136+
## where_values = pd.notnull(dates_df[ (dates_df>=buy_date) & (dates_df <= sell_date) ])['Date'].values
137+
##
138+
## y1values = daily['Close'].values
139+
## y2value = daily['Low'].min()
140+
##
141+
## mpf.plot(daily,figscale=0.7,
142+
## fill_between=dict(y1=y1values,y2=y2value,where=where_values,alpha=0.5,color='g')
143+
## )
144+
##
145+
## print('''
146+
##
147+
## Use `panel=` in the `fill_between` dict to place the fill_between on a panel other than panel 0:
148+
##
149+
## In this example, we `fill_between` on the volume panel,
150+
## filling between the volume and the average volume.
151+
##
152+
## ''')
153+
##
154+
## mpf.plot(daily,volume=True,panel_ratios=(1.1,1),
155+
## type='candle',tight_layout=True,figratio=(1,1),
156+
## fill_between=dict(y1=daily['Volume'].values,
157+
## y2=daily['Volume'].mean(),
158+
## panel=1,alpha=0.5,color='lime'))
159+
##
160+
## print('''
161+
##
162+
## There are two ways to do multiple `fill_betweens`:
163+
## (1) Specify a list of `fill_between` dicts.
164+
## (2) Specify a fill_between (or list of fill_betweens) for each `mpf.make_addplot()`
165+
##
166+
## Here, for example, we specify a `fill_between=` a list of fill between dicts:
167+
##
168+
## ''')
169+
##
170+
## fb1 = dict(y1=daily['Open'].values , y2=daily['Close'].values , panel=0, alpha=0.3, color='magenta')
171+
## fb2 = dict(y1=daily['Volume'].values, y2=daily['Volume'].mean(), panel=1, alpha=0.5, color='lime')
172+
##
173+
## mpf.plot(daily,volume=True,panel_ratios=(1.1,1),
174+
## type='candle',tight_layout=True,figratio=(1,1),
175+
## fill_between=[fb1,fb2])
176+
##
177+
## print('''
178+
##
179+
## We can accomplish the same thing by specifying one fill_between in `mpf.plot()`
180+
## and the other in `mpf.make_addplot()`. This is useful if we are already using
181+
## `make_addplot()` to plot some additional data.
182+
##
183+
## NOTE: Since make_addplot() accepts a panel argument, one should NOT specify
184+
## panel in the fill_between dict used by make_addplot.
185+
##
186+
## ''')
187+
##
188+
## fb1 = dict(y1=daily['Open'].values , y2=daily['Close'].values , alpha=0.4, color='magenta')
189+
## fb2 = dict(y1=daily['Volume'].values, y2=daily['Volume'].mean(), alpha=0.5, color='lime')
190+
##
191+
## avol = [daily['Volume'].mean()]*len(daily)
192+
##
193+
## ap = mpf.make_addplot(avol,panel=1,fill_between=fb2,color='k',linestyle='-.',width=0.25)
194+
##
195+
## mpf.plot(daily,volume=True,panel_ratios=(1.1,1),
196+
## type='candle',tight_layout=True,figratio=(1,1),
197+
## fill_between=fb1,addplot=ap)
198+
##
199+
## print('''
200+
##
201+
## We can specify effectively a "multi-color" fill_between, by breaking it into
202+
## two separate fill_betweens, with two separate colors, each with a "where" clause to
203+
## indicate where the fill_between color should and should not appear along the datetime axis.
204+
##
205+
## This is useful, for example, if we want to highlight where a given value is
206+
## above or below the average value.
207+
##
208+
## Notice that when using multiple where clauses like this, it is helpful
209+
## to set `interpolate=True` in the `fill_between` dict, so that the space
210+
## between True values and False values also gets filled.
211+
##
212+
## ''')
213+
##
214+
## fb_above = dict(y1=daily['Volume'].values,
215+
## y2=daily['Volume'].mean(),
216+
## alpha=0.4, color='lime',
217+
## interpolate=True,
218+
## where=(daily['Volume'] > daily['Volume'].mean()).values)
219+
##
220+
## fb_below = fb_above.copy()
221+
## fb_below['color'] = 'magenta'
222+
## fb_below['where'] = (daily['Volume'] < daily['Volume'].mean()).values
223+
##
224+
## avol = [daily['Volume'].mean()]*len(daily)
225+
## ap = mpf.make_addplot(avol,panel=1,fill_between=[fb_above,fb_below],color='k',linestyle='-.',width=0.25)
226+
##
227+
## mpf.plot(daily,volume=True,panel_ratios=(0.8,1),
228+
## type='candle',tight_layout=True,figratio=(1,1),addplot=ap)
229+
##
230+
## print('''
231+
##
232+
## Here, as an additional example, we create "multi-color" fill_between for both panels:
233+
##
234+
## ''')
235+
##
236+
## fbvolume_above = dict(y1=daily['Volume'].values,
237+
## y2=daily['Volume'].mean(),
238+
## alpha=0.4, color='lime',
239+
## interpolate=True,
240+
## where=(daily['Volume'] > daily['Volume'].mean()).values)
241+
##
242+
## fbvolume_below = fbvolume_above.copy()
243+
## fbvolume_below['color'] = 'magenta'
244+
## fbvolume_below['where'] = (daily['Volume'] < daily['Volume'].mean()).values
245+
##
246+
## avol = [daily['Volume'].mean()]*len(daily)
247+
## ap = mpf.make_addplot(avol,panel=1,fill_between=[fbvolume_above,fbvolume_below],color='k',linestyle='-.',width=0.25)
248+
##
249+
## fbclose_above = dict(y1=daily['Open'].values , y2=daily['Close'].values , alpha=0.4,
250+
## interpolate=True,
251+
## color='lime',
252+
## where=(daily['Close']>daily['Open']).values
253+
## )
254+
##
255+
## fbclose_below = fbclose_above.copy()
256+
## fbclose_below['color'] = 'magenta'
257+
## fbclose_below['where'] = (daily['Close']<daily['Open']).values
258+
##
259+
## mpf.plot(daily,volume=True,panel_ratios=(1,1),
260+
## type='candle',tight_layout=True,figratio=(1,1),
261+
## fill_between=[fbclose_above,fbclose_below],
262+
## addplot=ap)
263+
##
264+
## print('''
265+
##
266+
## Finally, as a more pratical example, we use `fill_between` to color a MACD plot:
267+
##
268+
## ''')
269+
##
270+
## df = pd.read_csv('data/SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True).loc['2011-07-01':'2011-12-30',:]
271+
##
272+
## # =======
273+
## # MACD:
274+
##
275+
## exp12 = df['Close'].ewm(span=12, adjust=False).mean()
276+
## exp26 = df['Close'].ewm(span=26, adjust=False).mean()
277+
## macd = exp12 - exp26
278+
## signal = macd.ewm(span=9, adjust=False).mean()
279+
## histogram = macd - signal
280+
##
281+
## fb_green = dict(y1=macd.values,y2=signal.values,where=signal<macd,color="#93c47d",alpha=0.6,interpolate=True)
282+
## fb_red = dict(y1=macd.values,y2=signal.values,where=signal>macd,color="#e06666",alpha=0.6,interpolate=True)
283+
## fb_green['panel'] = 1
284+
## fb_red['panel'] = 1
285+
## fb = [fb_green,fb_red]
286+
##
287+
## apds = [mpf.make_addplot(exp12,color='lime'),
288+
## mpf.make_addplot(exp26,color='c'),
289+
## mpf.make_addplot(histogram,type='bar',width=0.7,panel=1,
290+
## color='dimgray',alpha=1,secondary_y=True),
291+
## mpf.make_addplot(macd,panel=1,color='fuchsia',secondary_y=False),
292+
## mpf.make_addplot(signal,panel=1,color='b',secondary_y=False)#,fill_between=fb),
293+
## ]
294+
##
295+
## s = mpf.make_mpf_style(base_mpf_style='classic',rc={'figure.facecolor':'lightgray'})
296+
##
297+
## mpf.plot(df,type='candle',addplot=apds,figscale=1.6,figratio=(6,5),title='\n\nMACD',
298+
## style=s,volume=True,volume_panel=2,panel_ratios=(3,4,1),fill_between=fb)
299+
##
300+
## def test_fill_between02(bolldata):

0 commit comments

Comments
 (0)