@@ -119,7 +119,17 @@ def _valid_plot_kwargs():
119
119
'mav' : { 'Default' : None ,
120
120
'Description' : 'Moving Average window size(s); (int or tuple of ints)' ,
121
121
'Validator' : _mav_validator },
122
+
123
+ 'ema' : { 'Default' : None ,
124
+ 'Description' : 'Exponential Moving Average window size(s); (int or tuple of ints)' ,
125
+ 'Validator' : _mav_validator },
122
126
127
+ 'mavcolors' : { 'Default' : None ,
128
+ 'Description' : 'color cycle for moving averages (list or tuple of colors)' +
129
+ '(overrides mpf style mavcolors).' ,
130
+ 'Validator' : lambda value : isinstance (value ,(list ,tuple )) and
131
+ all ([mcolors .is_color_like (v ) for v in value ]) },
132
+
123
133
'renko_params' : { 'Default' : dict (),
124
134
'Description' : 'dict of renko parameters; call `mpf.kwarg_help("renko_params")`' ,
125
135
'Validator' : lambda value : isinstance (value ,dict ) },
@@ -450,6 +460,13 @@ def plot( data, **kwargs ):
450
460
else :
451
461
raise TypeError ('style should be a `dict`; why is it not?' )
452
462
463
+ if config ['mavcolors' ] is not None :
464
+ config ['_ma_color_cycle' ] = cycle (config ['mavcolors' ])
465
+ elif style ['mavcolors' ] is not None :
466
+ config ['_ma_color_cycle' ] = cycle (style ['mavcolors' ])
467
+ else :
468
+ config ['_ma_color_cycle' ] = None
469
+
453
470
if not external_axes_mode :
454
471
fig = plt .figure ()
455
472
_adjust_figsize (fig ,config )
@@ -528,8 +545,10 @@ def plot( data, **kwargs ):
528
545
529
546
if ptype in VALID_PMOVE_TYPES :
530
547
mavprices = _plot_mav (axA1 ,config ,xdates ,pmove_avgvals )
548
+ emaprices = _plot_ema (axA1 , config , xdates , pmove_avgvals )
531
549
else :
532
550
mavprices = _plot_mav (axA1 ,config ,xdates ,closes )
551
+ emaprices = _plot_ema (axA1 , config , xdates , closes )
533
552
534
553
avg_dist_between_points = (xdates [- 1 ] - xdates [0 ]) / float (len (xdates ))
535
554
if not config ['tight_layout' ]:
@@ -595,6 +614,13 @@ def plot( data, **kwargs ):
595
614
else :
596
615
for jj in range (0 ,len (mav )):
597
616
retdict ['mav' + str (mav [jj ])] = mavprices [jj ]
617
+ if config ['ema' ] is not None :
618
+ ema = config ['ema' ]
619
+ if len (ema ) != len (emaprices ):
620
+ warnings .warn ('len(ema)=' + str (len (ema ))+ ' BUT len(emaprices)=' + str (len (emaprices )))
621
+ else :
622
+ for jj in range (0 , len (ema )):
623
+ retdict ['ema' + str (ema [jj ])] = emaprices [jj ]
598
624
retdict ['minx' ] = minx
599
625
retdict ['maxx' ] = maxx
600
626
retdict ['miny' ] = miny
@@ -1129,10 +1155,7 @@ def _plot_mav(ax,config,xdates,prices,apmav=None,apwidth=None):
1129
1155
if len (mavgs ) > 7 :
1130
1156
mavgs = mavgs [0 :7 ] # take at most 7
1131
1157
1132
- if style ['mavcolors' ] is not None :
1133
- mavc = cycle (style ['mavcolors' ])
1134
- else :
1135
- mavc = None
1158
+ mavc = config ['_ma_color_cycle' ]
1136
1159
1137
1160
for idx ,mav in enumerate (mavgs ):
1138
1161
mean = pd .Series (prices ).rolling (mav ).mean ()
@@ -1147,6 +1170,42 @@ def _plot_mav(ax,config,xdates,prices,apmav=None,apwidth=None):
1147
1170
mavp_list .append (mavprices )
1148
1171
return mavp_list
1149
1172
1173
+
1174
+ def _plot_ema (ax ,config ,xdates ,prices ,apmav = None ,apwidth = None ):
1175
+ '''ema: exponential moving average'''
1176
+ style = config ['style' ]
1177
+ if apmav is not None :
1178
+ mavgs = apmav
1179
+ else :
1180
+ mavgs = config ['ema' ]
1181
+ mavp_list = []
1182
+ if mavgs is not None :
1183
+ shift = None
1184
+ if isinstance (mavgs ,dict ):
1185
+ shift = mavgs ['shift' ]
1186
+ mavgs = mavgs ['period' ]
1187
+ if isinstance (mavgs ,int ):
1188
+ mavgs = mavgs , # convert to tuple
1189
+ if len (mavgs ) > 7 :
1190
+ mavgs = mavgs [0 :7 ] # take at most 7
1191
+
1192
+ mavc = config ['_ma_color_cycle' ]
1193
+
1194
+ for idx ,mav in enumerate (mavgs ):
1195
+ # mean = pd.Series(prices).rolling(mav).mean()
1196
+ mean = pd .Series (prices ).ewm (span = mav ,adjust = False ).mean ()
1197
+ if shift is not None :
1198
+ mean = mean .shift (periods = shift [idx ])
1199
+ emaprices = mean .values
1200
+ lw = config ['_width_config' ]['line_width' ]
1201
+ if mavc :
1202
+ ax .plot (xdates , emaprices , linewidth = lw , color = next (mavc ))
1203
+ else :
1204
+ ax .plot (xdates , emaprices , linewidth = lw )
1205
+ mavp_list .append (emaprices )
1206
+ return mavp_list
1207
+
1208
+
1150
1209
def _auto_secondary_y ( panels , panid , ylo , yhi ):
1151
1210
# If mag(nitude) for this panel is not yet set, then set it
1152
1211
# here, as this is the first ydata to be plotted on this panel:
0 commit comments