From 3becf41ad7edaba51cdc047c957ed2ca62b67250 Mon Sep 17 00:00:00 2001 From: AurumnPegasus Date: Sun, 3 Oct 2021 15:23:19 +0530 Subject: [PATCH 01/11] Preliminary done --- src/mplfinance/_arg_validators.py | 11 ++++ src/mplfinance/_utils.py | 86 ++++++++++++++++++++++++------- src/mplfinance/plotting.py | 19 +++++-- 3 files changed, 95 insertions(+), 21 deletions(-) diff --git a/src/mplfinance/_arg_validators.py b/src/mplfinance/_arg_validators.py index ef91eb05..4ad370e1 100644 --- a/src/mplfinance/_arg_validators.py +++ b/src/mplfinance/_arg_validators.py @@ -142,6 +142,17 @@ def _valid_mav(value, is_period=True): return True return False +def _colors_validator(value): + if not isinstance(value, list): + return False + + for v in value: + if v: + if not (isinstance(v, dict) or isinstance(v, str)): + return False + + return True + def _hlines_validator(value): if isinstance(value,dict): diff --git a/src/mplfinance/_utils.py b/src/mplfinance/_utils.py index e39b6d05..f640917f 100644 --- a/src/mplfinance/_utils.py +++ b/src/mplfinance/_utils.py @@ -20,7 +20,7 @@ from six.moves import zip -def _check_input(opens, closes, highs, lows): +def _check_input(opens, closes, highs, lows, colors=None): """Checks that *opens*, *highs*, *lows* and *closes* have the same length. NOTE: this code assumes if any value open, high, low, close is missing (*-1*) they all are missing @@ -46,6 +46,10 @@ def _check_input(opens, closes, highs, lows): if not same_length: raise ValueError('O,H,L,C must have the same length!') + if colors: + if len(opens) != len(colors): + raise ValueError('O,H,L,C and Colors must have the same length!') + o = np.where(np.isnan(opens))[0] h = np.where(np.isnan(highs))[0] l = np.where(np.isnan(lows))[0] @@ -85,11 +89,11 @@ def _check_and_convert_xlim_configuration(data, config): return xlim -def _construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style): +def _construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style,colors): collections = None if ptype == 'candle' or ptype == 'candlestick': collections = _construct_candlestick_collections(xdates, opens, highs, lows, closes, - marketcolors=style['marketcolors'],config=config ) + marketcolors=style['marketcolors'],config=config, colors=colors ) elif ptype =='hollow_and_filled': collections = _construct_hollow_candlestick_collections(xdates, opens, highs, lows, closes, @@ -176,16 +180,45 @@ def coalesce_volume_dates(in_volumes, in_dates, indexes): return volumes, dates -def _updown_colors(upcolor,downcolor,opens,closes,use_prev_close=False): - if upcolor == downcolor: - return upcolor - cmap = {True : upcolor, False : downcolor} - if not use_prev_close: - return [ cmap[opn < cls] for opn,cls in zip(opens,closes) ] +def _updown_colors(upcolor,downcolor,opens,closes,use_prev_close=False,colors=None): + if not colors: + if upcolor == downcolor: + return upcolor + cmap = {True : upcolor, False : downcolor} + if not use_prev_close: + return [ cmap[opn < cls] for opn,cls in zip(opens,closes) ] + else: + first = cmap[opens[0] < closes[0]] + _list = [ cmap[pre < cls] for cls,pre in zip(closes[1:], closes) ] + return [first] + _list else: - first = cmap[opens[0] < closes[0]] - _list = [ cmap[pre < cls] for cls,pre in zip(closes[1:], closes) ] - return [first] + _list + cmap = {True: 'up', False: 'down'} + default = {'up': upcolor, 'down': downcolor} + custom = [] + if not use_prev_close: + for i in range(len(opens)): + opn = opens[i] + cls = closes[i] + if colors[i]: + custom.append(colors[i][cmap[opn < cls]]) + else: + custom.append(default[cmap[opn < cls]]) + else: + if color[0]: + custom.append(colors[0][cmap[opens[0] < closes[0]]]) + else: + custom.append(default[cmap[opens[0] < closes[0]]]) + + for i in range(len(closes) - 1): + pre = closes[1:][i] + cls = closes[i] + if colors[i]: + custom.append(colors[i][cmap[pre < cls]]) + else: + custom.append(default[cmap[pre < cls]]) + + return custom + def _updownhollow_colors(upcolor,downcolor,hollowcolor,opens,closes): @@ -525,7 +558,7 @@ def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors= return [rangeCollection, openCollection, closeCollection] -def _construct_candlestick_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None): +def _construct_candlestick_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None, colors=None): """Represent the open, close as a bar line and high low range as a vertical line. @@ -552,8 +585,8 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market ret : list (lineCollection, barCollection) """ - - _check_input(opens, highs, lows, closes) + + _check_input(opens, highs, lows, closes, colors) if marketcolors is None: marketcolors = _get_mpfstyle('classic')['marketcolors'] @@ -581,17 +614,34 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market alpha = marketcolors['alpha'] + candle_c = None + wick_c = None + edge_c = None + if colors: + candle_c = [] + wick_c = [] + edge_c = [] + for color in colors: + if color: + candle_c.append({'up': mcolors.to_rgba(color['candle']['up'], alpha), 'down': mcolors.to_rgba(color['candle']['down'], alpha)}) + wick_c.append({'up': mcolors.to_rgba(color['wick']['up'], 1), 'down': mcolors.to_rgba(color['wick']['down'], 1)}) + edge_c.append({'up': mcolors.to_rgba(color['edge']['up'], 1), 'down': mcolors.to_rgba(color['edge']['down'], 1)}) + else: + candle_c.append(None) + wick_c.append(None) + edge_c.append(None) + uc = mcolors.to_rgba(marketcolors['candle'][ 'up' ], alpha) dc = mcolors.to_rgba(marketcolors['candle']['down'], alpha) - colors = _updown_colors(uc, dc, opens, closes) + colors = _updown_colors(uc, dc, opens, closes, colors=candle_c) uc = mcolors.to_rgba(marketcolors['edge'][ 'up' ], 1.0) dc = mcolors.to_rgba(marketcolors['edge']['down'], 1.0) - edgecolor = _updown_colors(uc, dc, opens, closes) + edgecolor = _updown_colors(uc, dc, opens, closes, colors=edge_c) uc = mcolors.to_rgba(marketcolors['wick'][ 'up' ], 1.0) dc = mcolors.to_rgba(marketcolors['wick']['down'], 1.0) - wickcolor = _updown_colors(uc, dc, opens, closes) + wickcolor = _updown_colors(uc, dc, opens, closes, colors=wick_c) lw = config['_width_config']['candle_linewidth'] diff --git a/src/mplfinance/plotting.py b/src/mplfinance/plotting.py index c6cccc0b..6867aa6d 100644 --- a/src/mplfinance/plotting.py +++ b/src/mplfinance/plotting.py @@ -40,6 +40,7 @@ from mplfinance._arg_validators import _scale_padding_validator, _yscale_validator from mplfinance._arg_validators import _valid_panel_id, _check_for_external_axes from mplfinance._arg_validators import _xlim_validator +from mplfinance._arg_validators import _colors_validator from mplfinance._panels import _build_panels from mplfinance._panels import _set_ticks_on_bottom_panel_only @@ -49,6 +50,8 @@ from mplfinance._helpers import _num_or_seq_of_num from mplfinance._helpers import _adjust_color_brightness +from mplfinance._styles import make_marketcolors + VALID_PMOVE_TYPES = ['renko', 'pnf'] DEFAULT_FIGRATIO = (8.00,5.75) @@ -125,6 +128,9 @@ def _valid_plot_kwargs(): 'marketcolors' : { 'Default' : None, # use 'style' for default, instead. 'Validator' : lambda value: isinstance(value,dict) }, + + 'colors' : { 'Default' : None, # use default style instead. + 'Validator' : lambda value: _colors_validator(value) }, 'no_xgaps' : { 'Default' : True, # None means follow default logic below: 'Validator' : lambda value: _warn_no_xgaps_deprecated(value) }, @@ -391,14 +397,21 @@ def plot( data, **kwargs ): rwc = config['return_width_config'] if isinstance(rwc,dict) and len(rwc)==0: config['return_width_config'].update(config['_width_config']) - + + if config['colors']: + colors = config['colors'] + for c in range(len(colors)): + if isinstance(colors[c], str): + config['colors'][c] = make_marketcolors(up=colors[c], down=colors[c], edge=colors[c], wick=colors[c]) + else: + config['colors'] = None collections = None if ptype == 'line': lw = config['_width_config']['line_width'] axA1.plot(xdates, closes, color=config['linecolor'], linewidth=lw) else: - collections =_construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style) + collections =_construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style,config['colors']) if ptype in VALID_PMOVE_TYPES: collections, calculated_values = collections @@ -858,7 +871,7 @@ def _addplot_collections(panid,panels,apdict,xdates,config): if not isinstance(apdata,pd.DataFrame): raise TypeError('addplot type "'+aptype+'" MUST be accompanied by addplot data of type `pd.DataFrame`') d,o,h,l,c,v = _check_and_prepare_data(apdata,config) - collections = _construct_mpf_collections(aptype,d,xdates,o,h,l,c,v,config,config['style']) + collections = _construct_mpf_collections(aptype,d,xdates,o,h,l,c,v,config,config['style'],config['colors']) if not external_axes_mode: lo = math.log(max(math.fabs(np.nanmin(l)),1e-7),10) - 0.5 From 774a7f1ec5300590d6a7a004003c0c6ad95ab115 Mon Sep 17 00:00:00 2001 From: AurumnPegasus Date: Sun, 3 Oct 2021 16:25:34 +0530 Subject: [PATCH 02/11] Testing done --- src/mplfinance/_utils.py | 64 ++++++++++++++++++++++++++++---------- src/mplfinance/plotting.py | 2 +- 2 files changed, 49 insertions(+), 17 deletions(-) diff --git a/src/mplfinance/_utils.py b/src/mplfinance/_utils.py index f640917f..b742c9ef 100644 --- a/src/mplfinance/_utils.py +++ b/src/mplfinance/_utils.py @@ -97,11 +97,11 @@ def _construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volume elif ptype =='hollow_and_filled': collections = _construct_hollow_candlestick_collections(xdates, opens, highs, lows, closes, - marketcolors=style['marketcolors'],config=config ) + marketcolors=style['marketcolors'],config=config, colors=colors ) elif ptype == 'ohlc' or ptype == 'bars' or ptype == 'ohlc_bars': collections = _construct_ohlc_collections(xdates, opens, highs, lows, closes, - marketcolors=style['marketcolors'],config=config ) + marketcolors=style['marketcolors'],config=config, colors=colors ) elif ptype == 'renko': collections = _construct_renko_collections( dates, highs, lows, volumes, config['renko_params'], closes, marketcolors=style['marketcolors']) @@ -480,7 +480,7 @@ def _valid_lines_kwargs(): return vkwargs -def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None): +def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None, colors=None): """Represent the time, open, high, low, close as a vertical line ranging from low to high. The left tick is the open and the right tick is the close. @@ -505,8 +505,8 @@ def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors= ret : list a list or tuple of matplotlib collections to be added to the axes """ - - _check_input(opens, highs, lows, closes) + + _check_input(opens, highs, lows, closes, colors) if marketcolors is None: mktcolors = _get_mpfstyle('classic')['marketcolors']['ohlc'] @@ -530,13 +530,25 @@ def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors= # we'll translate these to the date, close location closeSegments = [((dt, close), (dt+ticksize, close)) for dt, close in zip(dates, closes)] - if mktcolors['up'] == mktcolors['down']: - colors = mktcolors['up'] - else: - colorup = mcolors.to_rgba(mktcolors['up']) - colordown = mcolors.to_rgba(mktcolors['down']) - colord = {True: colorup, False: colordown} - colors = [colord[open < close] for open, close in zip(opens, closes)] + bar_c = None + if colors: + bar_c = [] + for color in colors: + if color: + bar_up = color['ohlc']['up'] + bar_down = color['ohlc']['down'] + if bar_up == 'k': + bar_up = mktcolors['up'] + if bar_down == 'k': + bar_down = mktcolors['down'] + + bar_c.append({'up': mcolors.to_rgba(bar_up, 1), 'down': mcolors.to_rgba(bar_down, 1)}) + else: + bar_c.append(None) + + uc = mcolors.to_rgba(mktcolors['up']) + dc = mcolors.to_rgba(mktcolors['down']) + colors = _updown_colors(uc, dc, opens, closes, colors=bar_c) lw = config['_width_config']['ohlc_linewidth'] @@ -623,9 +635,29 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market edge_c = [] for color in colors: if color: - candle_c.append({'up': mcolors.to_rgba(color['candle']['up'], alpha), 'down': mcolors.to_rgba(color['candle']['down'], alpha)}) - wick_c.append({'up': mcolors.to_rgba(color['wick']['up'], 1), 'down': mcolors.to_rgba(color['wick']['down'], 1)}) - edge_c.append({'up': mcolors.to_rgba(color['edge']['up'], 1), 'down': mcolors.to_rgba(color['edge']['down'], 1)}) + candle_up = color['candle']['up'] + candle_down = color['candle']['down'] + edge_up = color['edge']['up'] + edge_down = color['edge']['down'] + wick_up = color['wick']['up'] + wick_down = color['wick']['down'] + if candle_up == 'w': + candle_up = marketcolors['candle']['up'] + if candle_down == 'k': + candle_down = marketcolors['candle']['down'] + if edge_up == 'k': + edge_up = candle_up + if edge_down == 'k': + edge_down = candle_down + if wick_up == 'k': + wick_up = candle_up + if wick_down == 'k': + wick_down = candle_down + + candle_c.append({'up': mcolors.to_rgba(candle_up, alpha), 'down': mcolors.to_rgba(candle_down, alpha)}) + edge_c.append({'up': mcolors.to_rgba(edge_up, 1), 'down': mcolors.to_rgba(edge_down, 1)}) + wick_c.append({'up': mcolors.to_rgba(wick_up, 1), 'down': mcolors.to_rgba(wick_down, 1)}) + else: candle_c.append(None) wick_c.append(None) @@ -659,7 +691,7 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market return [rangeCollection, barCollection] -def _construct_hollow_candlestick_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None): +def _construct_hollow_candlestick_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None, colors=None): """Represent today's open to close as a "bar" line (candle body) and high low range as a vertical line (candle wick) diff --git a/src/mplfinance/plotting.py b/src/mplfinance/plotting.py index 6867aa6d..7dfc5156 100644 --- a/src/mplfinance/plotting.py +++ b/src/mplfinance/plotting.py @@ -402,7 +402,7 @@ def plot( data, **kwargs ): colors = config['colors'] for c in range(len(colors)): if isinstance(colors[c], str): - config['colors'][c] = make_marketcolors(up=colors[c], down=colors[c], edge=colors[c], wick=colors[c]) + config['colors'][c] = make_marketcolors(up=colors[c], down=colors[c], edge=colors[c], wick=colors[c], ohlc=colors[c], volume=colors[c]) else: config['colors'] = None From de86b62ea8aeb69aece120efeedd407d7c53b80e Mon Sep 17 00:00:00 2001 From: AurumnPegasus Date: Sun, 3 Oct 2021 16:30:05 +0530 Subject: [PATCH 03/11] Final --- src/trial.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/trial.py diff --git a/src/trial.py b/src/trial.py new file mode 100644 index 00000000..57c5bce4 --- /dev/null +++ b/src/trial.py @@ -0,0 +1,45 @@ +import pandas as pd +import random +from datetime import date, timedelta +from mplfinance.plotting import plot +from mplfinance._styles import make_marketcolors + +dict_data = [] +start_date = date(2019, 1, 1) +end_date = date(2020, 1, 1) +delta = timedelta(days=1) +start = 20 +end = 30 +while start_date <= end_date: + openval = random.randint(start, end) + closeval = random.randint(start, end) + high = random.randint(max(openval, closeval), end) + low = random.randint(start, min(openval, closeval)) + change = random.randint(-5, 5) + volume = random.randint(10000, 20000) + dict_data.append({ + "Open": openval, + "Close": closeval, + "High": high, + "Low": low, + "Date": start_date, + "Volume": volume + }) + start += change + end += change + start_date += delta + +df = pd.DataFrame(dict_data) +df.index = pd.to_datetime(df['Date']) + +# custom_colors = [] +# for i in range(len(df)): +# if i % 3 == 0: +# custom_colors.append(make_marketcolors(up='#29c9ff', down='#f3b5ff', edge='#29c9ff', wick='#29c9ff', ohlc='#32a852', volume='#a89132')) +# elif i%5 == 0: +# custom_colors.append("#000000") +# else: +# custom_colors.append(None) + +# plot(df, type='candle', style='yahoo', colors=custom_colors, volume=True) +plot(df, type='candle', style='yahoo', volume=True) \ No newline at end of file From 71ca40365436fc7753c4f757cdfa55b89cbab8ca Mon Sep 17 00:00:00 2001 From: Shivansh Subramanian <54315149+AurumnPegasus@users.noreply.github.com> Date: Sun, 3 Oct 2021 16:31:09 +0530 Subject: [PATCH 04/11] Delete trial.py --- src/trial.py | 45 --------------------------------------------- 1 file changed, 45 deletions(-) delete mode 100644 src/trial.py diff --git a/src/trial.py b/src/trial.py deleted file mode 100644 index 57c5bce4..00000000 --- a/src/trial.py +++ /dev/null @@ -1,45 +0,0 @@ -import pandas as pd -import random -from datetime import date, timedelta -from mplfinance.plotting import plot -from mplfinance._styles import make_marketcolors - -dict_data = [] -start_date = date(2019, 1, 1) -end_date = date(2020, 1, 1) -delta = timedelta(days=1) -start = 20 -end = 30 -while start_date <= end_date: - openval = random.randint(start, end) - closeval = random.randint(start, end) - high = random.randint(max(openval, closeval), end) - low = random.randint(start, min(openval, closeval)) - change = random.randint(-5, 5) - volume = random.randint(10000, 20000) - dict_data.append({ - "Open": openval, - "Close": closeval, - "High": high, - "Low": low, - "Date": start_date, - "Volume": volume - }) - start += change - end += change - start_date += delta - -df = pd.DataFrame(dict_data) -df.index = pd.to_datetime(df['Date']) - -# custom_colors = [] -# for i in range(len(df)): -# if i % 3 == 0: -# custom_colors.append(make_marketcolors(up='#29c9ff', down='#f3b5ff', edge='#29c9ff', wick='#29c9ff', ohlc='#32a852', volume='#a89132')) -# elif i%5 == 0: -# custom_colors.append("#000000") -# else: -# custom_colors.append(None) - -# plot(df, type='candle', style='yahoo', colors=custom_colors, volume=True) -plot(df, type='candle', style='yahoo', volume=True) \ No newline at end of file From 15e9f98928dce5b9655e4819415ee254d5233e40 Mon Sep 17 00:00:00 2001 From: Shivansh Subramanian Date: Sat, 4 Dec 2021 21:42:36 +0530 Subject: [PATCH 05/11] made changes according to pr --- src/mplfinance/_arg_validators.py | 30 ++--- src/mplfinance/_utils.py | 196 +++++++++++++++--------------- src/mplfinance/plotting.py | 162 ++++++++++++------------ src/trial.py | 45 +++++++ 4 files changed, 239 insertions(+), 194 deletions(-) create mode 100644 src/trial.py diff --git a/src/mplfinance/_arg_validators.py b/src/mplfinance/_arg_validators.py index 4ad370e1..ceb8072b 100644 --- a/src/mplfinance/_arg_validators.py +++ b/src/mplfinance/_arg_validators.py @@ -52,7 +52,7 @@ def _check_and_prepare_data(data, config): columns = ('Open', 'High', 'Low', 'Close', 'Volume') if all([c.lower() in data for c in columns[0:4]]): columns = ('open', 'high', 'low', 'close', 'volume') - + o, h, l, c, v = columns cols = [o, h, l, c] @@ -100,7 +100,7 @@ def _get_valid_plot_types(plottype=None): return _alias_types[plottype] else: return plottype - + def _mav_validator(mav_value): ''' @@ -143,12 +143,12 @@ def _valid_mav(value, is_period=True): return False def _colors_validator(value): - if not isinstance(value, list): + if not isinstance(value, (list, tuple, np.ndarray)): return False for v in value: if v: - if not (isinstance(v, dict) or isinstance(v, str)): + if v is not None and not isinstance(v, (dict, str)): return False return True @@ -204,11 +204,11 @@ def _alines_validator(value, returnStandardizedValue=False): A sequence of (line0, line1, line2), where: linen = (x0, y0), (x1, y1), ... (xm, ym) - + or the equivalent numpy array with two columns. Each line can be a different length. The above is from the matplotlib LineCollection documentation. - It basically says that the "segments" passed into the LineCollection constructor + It basically says that the "segments" passed into the LineCollection constructor must be a Sequence of Sequences of 2 or more xy Pairs. However here in `mplfinance` we want to allow that (seq of seq of xy pairs) _as well as_ just a sequence of pairs. Therefore here in the validator we will allow both: @@ -270,8 +270,8 @@ def _tlines_subvalidator(value): def _bypass_kwarg_validation(value): ''' For some kwargs, we either don't know enough, or the validation is too complex to make it worth while, - so we bypass kwarg validation. If the kwarg is - invalid, then eventually an exception will be + so we bypass kwarg validation. If the kwarg is + invalid, then eventually an exception will be raised at the time the kwarg value is actually used. ''' return True @@ -300,7 +300,7 @@ def _process_kwargs(kwargs, vkwargs): Given a "valid kwargs table" and some kwargs, verify that each key-word is valid per the kwargs table, and that the value of the kwarg is the correct type. Fill a configuration dictionary with the default value - for each kwarg, and then substitute in any values that were provided + for each kwarg, and then substitute in any values that were provided as kwargs and return the configuration dictionary. ''' # initialize configuration from valid_kwargs_table: @@ -327,7 +327,7 @@ def _process_kwargs(kwargs, vkwargs): # --------------------------------------------------------------- # At this point in the loop, if we have not raised an exception, - # then kwarg is valid as far as we can tell, therefore, + # then kwarg is valid as far as we can tell, therefore, # go ahead and replace the appropriate value in config: config[key] = value @@ -346,7 +346,7 @@ def _scale_padding_validator(value): if key not in valid_keys: raise ValueError('Invalid key "'+str(key)+'" found in `scale_padding` dict.') if not isinstance(value[key],(int,float)): - raise ValueError('`scale_padding` dict contains non-number at key "'+str(key)+'"') + raise ValueError('`scale_padding` dict contains non-number at key "'+str(key)+'"') return True else: raise ValueError('`scale_padding` kwarg must be a number, or dict of (left,right,top,bottom) numbers.') @@ -372,9 +372,9 @@ def _yscale_validator(value): def _check_for_external_axes(config): ''' - Check that all `fig` and `ax` kwargs are either ALL None, + Check that all `fig` and `ax` kwargs are either ALL None, or ALL are valid instances of Figures/Axes: - + An external Axes object can be passed in three places: - mpf.plot() `ax=` kwarg - mpf.plot() `volume=` kwarg @@ -391,7 +391,7 @@ def _check_for_external_axes(config): raise TypeError('addplot must be `dict`, or `list of dict`, NOT '+str(type(addplot))) for apd in addplot: ap_axlist.append(apd['ax']) - + if len(ap_axlist) > 0: if config['ax'] is None: if not all([ax is None for ax in ap_axlist]): @@ -416,6 +416,6 @@ def _check_for_external_axes(config): raise ValueError('`volume` must be of type `matplotlib.axis.Axes`') #if not isinstance(config['fig'],mpl.figure.Figure): # raise ValueError('`fig` kwarg must be of type `matplotlib.figure.Figure`') - + external_axes_mode = True if isinstance(config['ax'],mpl.axes.Axes) else False return external_axes_mode diff --git a/src/mplfinance/_utils.py b/src/mplfinance/_utils.py index b742c9ef..e3109aff 100644 --- a/src/mplfinance/_utils.py +++ b/src/mplfinance/_utils.py @@ -85,7 +85,7 @@ def _check_and_convert_xlim_configuration(data, config): xlim = [ _date_to_mdate(dt) for dt in xlim] else: xlim = [ _date_to_iloc_extrapolate(data.index.to_series(),dt) for dt in xlim] - + return xlim @@ -111,7 +111,7 @@ def _construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volume dates, highs, lows, volumes, config['pnf_params'], closes, marketcolors=style['marketcolors']) else: raise TypeError('Unknown ptype="',str(ptype),'"') - + return collections @@ -142,7 +142,7 @@ def combine_adjacent(arr): Returns ------- output: new summed array - indexes: indexes indicating the first + indexes: indexes indicating the first element summed for each group in arr """ output, indexes = [], [] @@ -155,7 +155,7 @@ def combine_adjacent(arr): output.append(sum(arr[:index])) indexes.append(curr_i) curr_i += index - + for _ in range(index): arr.pop(0) return output, indexes @@ -188,7 +188,7 @@ def _updown_colors(upcolor,downcolor,opens,closes,use_prev_close=False,colors=No if not use_prev_close: return [ cmap[opn < cls] for opn,cls in zip(opens,closes) ] else: - first = cmap[opens[0] < closes[0]] + first = cmap[opens[0] < closes[0]] _list = [ cmap[pre < cls] for cls,pre in zip(closes[1:], closes) ] return [first] + _list else: @@ -208,7 +208,7 @@ def _updown_colors(upcolor,downcolor,opens,closes,use_prev_close=False,colors=No custom.append(colors[0][cmap[opens[0] < closes[0]]]) else: custom.append(default[cmap[opens[0] < closes[0]]]) - + for i in range(len(closes) - 1): pre = closes[1:][i] cls = closes[i] @@ -216,9 +216,9 @@ def _updown_colors(upcolor,downcolor,opens,closes,use_prev_close=False,colors=No custom.append(colors[i][cmap[pre < cls]]) else: custom.append(default[cmap[pre < cls]]) - + return custom - + def _updownhollow_colors(upcolor,downcolor,hollowcolor,opens,closes): @@ -232,7 +232,7 @@ def _updownhollow_colors(upcolor,downcolor,hollowcolor,opens,closes): def _date_to_iloc(dtseries,date): - '''Convert a `date` to a location, given a date series w/a datetime index. + '''Convert a `date` to a location, given a date series w/a datetime index. If `date` does not exactly match a date in the series then interpolate between two dates. If `date` is outside the range of dates in the series, then raise an exception . @@ -269,7 +269,7 @@ def _date_to_iloc_linear(dtseries,date,trace=False): i1 = 0.0 i2 = len(dtseries) - 1.0 if trace: print('i1,i2=',i1,i2) - + slope = (i2 - i1) / (d2 - d1) yitrcpt1 = i1 - (slope*d1) if trace: print('slope,yitrcpt=',slope,yitrcpt1) @@ -279,7 +279,7 @@ def _date_to_iloc_linear(dtseries,date,trace=False): print('WARNING: yintercepts NOT equal!!!(',yitrcpt1,yitrcpt2,')') yitrcpt = (yitrcpt1 + yitrcpt2) / 2.0 else: - yitrcpt = yitrcpt1 + yitrcpt = yitrcpt1 return (slope * _date_to_mdate(date)) + yitrcpt def _date_to_iloc_5_7ths(dtseries,date,direction,trace=False): @@ -299,14 +299,14 @@ def _date_to_iloc_5_7ths(dtseries,date,direction,trace=False): return loc_5_7ths def _date_to_iloc_extrapolate(dtseries,date): - '''Convert a `date` to a location, given a date series w/a datetime index. + '''Convert a `date` to a location, given a date series w/a datetime index. If `date` does not exactly match a date in the series then interpolate between two dates. If `date` is outside the range of dates in the series, then extrapolate: Extrapolation results in increased error as the distance of the extrapolation increases. We have two methods to extrapolate: (1) Determine a linear equation based on the data provided in `dtseries`, and use that equation to calculate the location for the date. - (2) Multiply by 5/7 the number of days between the edge date of dtseries and the + (2) Multiply by 5/7 the number of days between the edge date of dtseries and the date for which we are requesting a location. THIS ASSUMES DAILY data AND a 5 DAY TRADING WEEK. Empirical observation (scratch_pad/date_to_iloc_extrapolation.ipynb) shows that @@ -359,7 +359,7 @@ def _date_to_mdate(date): def _convert_segment_dates(segments,dtindex): ''' - Convert line segment dates to matplotlib dates + Convert line segment dates to matplotlib dates Inputted segment dates may be: pandas-parseable date-time string, pandas timestamp, or a python datetime or date, or (if dtindex is not None) integer index A "segment" is a "sequence of lines", @@ -374,7 +374,7 @@ def _convert_segment_dates(segments,dtindex): new_line = [] for dt,value in line: if dtindex is not None: - date = _date_to_iloc(dtseries,dt) + date = _date_to_iloc(dtseries,dt) else: date = _date_to_mdate(dt) if date is None: @@ -385,13 +385,13 @@ def _convert_segment_dates(segments,dtindex): def _valid_renko_kwargs(): ''' - Construct and return the "valid renko kwargs table" for the mplfinance.plot(type='renko') - function. A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are - the valid key-words for the function. The value for each key is a dict containing 2 + Construct and return the "valid renko kwargs table" for the mplfinance.plot(type='renko') + function. A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are + the valid key-words for the function. The value for each key is a dict containing 2 specific keys: "Default", and "Validator" with the following values: "Default" - The default value for the kwarg if none is specified. "Validator" - A function that takes the caller specified value for the kwarg, - and validates that it is the correct type, and (for kwargs with + and validates that it is the correct type, and (for kwargs with a limited set of allowed values) may also validate that the kwarg value is one of the allowed values. ''' @@ -399,7 +399,7 @@ def _valid_renko_kwargs(): 'brick_size' : { 'Default' : 'atr', 'Validator' : lambda value: isinstance(value,(float,int)) or value == 'atr' }, 'atr_length' : { 'Default' : 14, - 'Validator' : lambda value: isinstance(value,int) or value == 'total' }, + 'Validator' : lambda value: isinstance(value,int) or value == 'total' }, } _validate_vkwargs_dict(vkwargs) @@ -408,13 +408,13 @@ def _valid_renko_kwargs(): def _valid_pnf_kwargs(): ''' - Construct and return the "valid pnf kwargs table" for the mplfinance.plot(type='pnf') - function. A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are - the valid key-words for the function. The value for each key is a dict containing 2 + Construct and return the "valid pnf kwargs table" for the mplfinance.plot(type='pnf') + function. A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are + the valid key-words for the function. The value for each key is a dict containing 2 specific keys: "Default", and "Validator" with the following values: "Default" - The default value for the kwarg if none is specified. "Validator" - A function that takes the caller specified value for the kwarg, - and validates that it is the correct type, and (for kwargs with + and validates that it is the correct type, and (for kwargs with a limited set of allowed values) may also validate that the kwarg value is one of the allowed values. ''' @@ -424,7 +424,7 @@ def _valid_pnf_kwargs(): 'atr_length' : { 'Default' : 14, 'Validator' : lambda value: isinstance(value,int) or value == 'total' }, 'reversal' : { 'Default' : 1, - 'Validator' : lambda value: isinstance(value,int) } + 'Validator' : lambda value: isinstance(value,int) } } _validate_vkwargs_dict(vkwargs) @@ -433,14 +433,14 @@ def _valid_pnf_kwargs(): def _valid_lines_kwargs(): ''' - Construct and return the "valid lines (hlines,vlines,alines,tlines) kwargs table" + Construct and return the "valid lines (hlines,vlines,alines,tlines) kwargs table" for the mplfinance.plot() `[h|v|a|t]lines=` kwarg functions. - A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are - the valid key-words for the function. The value for each key is a dict containing 2 + A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are + the valid key-words for the function. The value for each key is a dict containing 2 specific keys: "Default", and "Validator" with the following values: "Default" - The default value for the kwarg if none is specified. "Validator" - A function that takes the caller specified value for the kwarg, - and validates that it is the correct type, and (for kwargs with + and validates that it is the correct type, and (for kwargs with a limited set of allowed values) may also validate that the kwarg value is one of the allowed values. ''' @@ -463,12 +463,12 @@ def _valid_lines_kwargs(): 'Validator' : lambda value: value is None or value in valid_linestyles }, 'linewidths': { 'Default' : None, 'Validator' : lambda value: value is None or - isinstance(value,(float,int)) or + isinstance(value,(float,int)) or all([isinstance(v,(float,int)) for v in value]) }, 'alpha' : { 'Default' : 1.0, 'Validator' : lambda value: isinstance(value,(float,int)) }, - 'tline_use' : { 'Default' : 'close', + 'tline_use' : { 'Default' : 'close', 'Validator' : lambda value: isinstance(value,str) or (isinstance(value,(list,tuple)) and all([isinstance(v,str) for v in value]) ) }, 'tline_method': { 'Default' : 'point-to-point', @@ -502,10 +502,10 @@ def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors= Returns ------- - ret : list + ret : list a list or tuple of matplotlib collections to be added to the axes """ - + _check_input(opens, highs, lows, closes, colors) if marketcolors is None: @@ -618,10 +618,10 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market rangeSegLow = [((date, low), (date, min(open,close))) for date, low, open, close in zip(dates, lows, opens, closes)] - + rangeSegHigh = [((date, high), (date, max(open,close))) for date, high, open, close in zip(dates, highs, opens, closes)] - + rangeSegments = rangeSegLow + rangeSegHigh alpha = marketcolors['alpha'] @@ -657,7 +657,7 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market candle_c.append({'up': mcolors.to_rgba(candle_up, alpha), 'down': mcolors.to_rgba(candle_down, alpha)}) edge_c.append({'up': mcolors.to_rgba(edge_up, 1), 'down': mcolors.to_rgba(edge_down, 1)}) wick_c.append({'up': mcolors.to_rgba(wick_up, 1), 'down': mcolors.to_rgba(wick_down, 1)}) - + else: candle_c.append(None) wick_c.append(None) @@ -670,7 +670,7 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market uc = mcolors.to_rgba(marketcolors['edge'][ 'up' ], 1.0) dc = mcolors.to_rgba(marketcolors['edge']['down'], 1.0) edgecolor = _updown_colors(uc, dc, opens, closes, colors=edge_c) - + uc = mcolors.to_rgba(marketcolors['wick'][ 'up' ], 1.0) dc = mcolors.to_rgba(marketcolors['wick']['down'], 1.0) wickcolor = _updown_colors(uc, dc, opens, closes, colors=wick_c) @@ -694,7 +694,7 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market def _construct_hollow_candlestick_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None, colors=None): """Represent today's open to close as a "bar" line (candle body) and high low range as a vertical line (candle wick) - + If config['type']=='hollow_and_filled' (hollow and filled candles) then candle edge and wick color depend on PREVIOUS close to today's close (up or down), and the center of the candle body (hollow or filled) depends on the today's open to close (up or down). @@ -721,7 +721,7 @@ def _construct_hollow_candlestick_collections(dates, opens, highs, lows, closes, ret : list (lineCollection, barCollection) """ - + _check_input(opens, highs, lows, closes) if marketcolors is None: @@ -742,23 +742,23 @@ def _construct_hollow_candlestick_collections(dates, opens, highs, lows, closes, rangeSegLow = [((date, low), (date, min(open,close))) for date, low, open, close in zip(dates, lows, opens, closes)] - + rangeSegHigh = [((date, high), (date, max(open,close))) for date, high, open, close in zip(dates, highs, opens, closes)] - + rangeSegments = rangeSegLow + rangeSegHigh alpha = marketcolors['alpha'] uc = mcolors.to_rgba(marketcolors['candle'][ 'up' ], alpha) dc = mcolors.to_rgba(marketcolors['candle']['down'], alpha) - + hc = mcolors.to_rgba(marketcolors['hollow']) if 'hollow' in marketcolors else (0,0,0,0) - + colors = _updownhollow_colors(uc, dc, hc, opens, closes) # for candle body. edgecolor = _updown_colors(uc, dc, opens, closes, use_prev_close=True) - + wickcolor = _updown_colors(uc, dc, opens, closes, use_prev_close=True) # For hollow candles, we scale the candle linewidth up a little: @@ -788,19 +788,19 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param --------------------- In the first part of the algorithm, we populate the cdiff array along with adjusting the dates and volumes arrays into the new_dates and - new_volumes arrays. A single date includes a range from no bricks to many - bricks, if a date has no bricks it shall not be included in new_dates, - and if it has n bricks then it will be included n times. Volumes use a + new_volumes arrays. A single date includes a range from no bricks to many + bricks, if a date has no bricks it shall not be included in new_dates, + and if it has n bricks then it will be included n times. Volumes use a volume cache to save volume amounts for dates that do not have any bricks before adding the cache to the next date that has at least one brick. - We populate the cdiff array with each close values difference from the + We populate the cdiff array with each close values difference from the previously created brick divided by the brick size. In the second part of the algorithm, we iterate through the values in cdiff - and add 1s or -1s to the bricks array depending on whether the value is + and add 1s or -1s to the bricks array depending on whether the value is positive or negative. Every time there is a trend change (ex. previous brick is an upbrick, current brick is a down brick) we draw one less brick to account - for the price having to move the previous bricks amount before creating a + for the price having to move the previous bricks amount before creating a brick in the opposite direction. In the final part of the algorithm, we enumerate through the bricks array and @@ -811,7 +811,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param Useful sources: https://avilpage.com/2018/01/how-to-plot-renko-charts-with-python.html https://school.stockcharts.com/doku.php?id=chart_analysis:renko - + Parameters ---------- dates : sequence @@ -836,10 +836,10 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param if marketcolors is None: marketcolors = _get_mpfstyle('classic')['marketcolors'] #print('default market colors:',marketcolors) - + brick_size = renko_params['brick_size'] atr_length = renko_params['atr_length'] - + if brick_size == 'atr': if atr_length == 'total': @@ -860,7 +860,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param dc = mcolors.to_rgba(marketcolors['candle']['down'], alpha) euc = mcolors.to_rgba(marketcolors['edge'][ 'up' ], 1.0) edc = mcolors.to_rgba(marketcolors['edge']['down'], 1.0) - + cdiff = [] # holds the differences between each close and the previously created brick / the brick size prev_close_brick = closes[0] volume_cache = 0 # holds the volumes for the dates that were skipped @@ -887,7 +887,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param last_diff_sign = 0 # direction the bricks were last going in -1 -> down, 1 -> up dates_volumes_index = 0 # keeps track of the index of the current date/volume for diff in cdiff: - + curr_diff_sign = diff/abs(diff) if last_diff_sign != 0 and curr_diff_sign != last_diff_sign: last_diff_sign = curr_diff_sign @@ -900,7 +900,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param new_volumes.pop(dates_volumes_index) continue last_diff_sign = curr_diff_sign - + if diff > 0: bricks.extend([1]*abs(diff)) else: @@ -922,7 +922,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param curr_price += (brick_size * number) brick_values.append(curr_price) - + x, y = index, curr_price verts.append(( @@ -954,41 +954,41 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf --------------------- In the first part of the algorithm, we populate the boxes array along with adjusting the dates and volumes arrays into the new_dates and - new_volumes arrays. A single date includes a range from no boxes to many - boxes, if a date has no boxes it shall not be included in new_dates, - and if it has n boxes then it will be included n times. Volumes use a + new_volumes arrays. A single date includes a range from no boxes to many + boxes, if a date has no boxes it shall not be included in new_dates, + and if it has n boxes then it will be included n times. Volumes use a volume cache to save volume amounts for dates that do not have any boxes before adding the cache to the next date that has at least one box. - We populate the boxes array with each close values difference from the + We populate the boxes array with each close values difference from the previously created brick divided by the box size. The second part of the algorithm has a series of step. First we combine the adjacent like signed values in the boxes array (ex. [-1, -2, 3, -4] -> [-3, 3, -4]). - Next we subtract 1 from the absolute value of each element in boxes except the + Next we subtract 1 from the absolute value of each element in boxes except the first to ensure every time there is a trend change (ex. previous box is - an X, current brick is a O) we draw one less box to account for the price - having to move the previous box's amount before creating a box in the - opposite direction. During this same step we also combine like signed elements - and associated volume/date data ignoring any zero values that are created by - subtracting 1 from the box value. Next we recreate the box array utilizing a - rolling_change and volume_cache to store and sum the changes that don't break + an X, current brick is a O) we draw one less box to account for the price + having to move the previous box's amount before creating a box in the + opposite direction. During this same step we also combine like signed elements + and associated volume/date data ignoring any zero values that are created by + subtracting 1 from the box value. Next we recreate the box array utilizing a + rolling_change and volume_cache to store and sum the changes that don't break the reversal threshold. Lastly, we enumerate through the boxes to populate the line_seg and circle_patches - arrays. line_seg holds the / and \ line segments that make up an X and + arrays. line_seg holds the / and \ line segments that make up an X and circle_patches holds matplotlib.patches Ellipse objects for each O. We start - by filling an x and y array each iteration which contain the x and y + by filling an x and y array each iteration which contain the x and y coordinates for each box in the column. Then for each coordinate pair in - x, y we add to either the line_seg array or the circle_patches array - depending on the value of sign for the current column (1 indicates - line_seg, -1 indicates circle_patches). The height of the boxes take - into account padding which separates each box by a small margin in + x, y we add to either the line_seg array or the circle_patches array + depending on the value of sign for the current column (1 indicates + line_seg, -1 indicates circle_patches). The height of the boxes take + into account padding which separates each box by a small margin in order to increase readability. Useful sources: https://stackoverflow.com/questions/8750648/point-and-figure-chart-with-matplotlib https://www.investopedia.com/articles/technical/03/081303.asp - + Parameters ---------- dates : sequence @@ -1013,7 +1013,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf if marketcolors is None: marketcolors = _get_mpfstyle('classic')['marketcolors'] #print('default market colors:',marketcolors) - + box_size = pointnfig_params['box_size'] atr_length = pointnfig_params['atr_length'] reversal = pointnfig_params['reversal'] @@ -1033,7 +1033,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf if reversal < 1 or reversal > 9: raise ValueError("Specified reversal must be an integer in the range [1,9]") - + alpha = marketcolors['alpha'] uc = mcolors.to_rgba(marketcolors['ohlc'][ 'up' ], alpha) @@ -1044,7 +1044,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf prev_close_box = closes[0] # represents the value of the last box in the previous column volume_cache = 0 # holds the volumes for the dates that were skipped temp_volumes, temp_dates = [], [] # holds the temp adjusted volumes and dates respectively - + for i in range(len(closes)-1): box_diff = int((closes[i+1] - prev_close_box) / box_size) if box_diff == 0: @@ -1062,7 +1062,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf # combine adjacent similarly signed differences boxes, indexes = combine_adjacent(boxes) new_volumes, new_dates = coalesce_volume_dates(temp_volumes, temp_dates, indexes) - + adjusted_boxes = [boxes[0]] temp_volumes, temp_dates = [new_volumes[0]], [new_dates[0]] volume_cache = 0 @@ -1098,7 +1098,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf boxes = [adjusted_boxes[0]] new_volumes = [temp_volumes[0]] new_dates = [temp_dates[0]] - + rolling_change = 0 volume_cache = 0 biggest_difference = 0 # only used for the last column @@ -1106,11 +1106,11 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf #Clean data to account for reversal size (added to allow overriding the default reversal of 1) for i in range(1, len(adjusted_boxes)): - # Add to rolling_change and volume_cache which stores the box and volume values + # Add to rolling_change and volume_cache which stores the box and volume values rolling_change += adjusted_boxes[i] volume_cache += temp_volumes[i] - # if rolling_change is the same sign as the previous box and the abs value is bigger than the + # if rolling_change is the same sign as the previous box and the abs value is bigger than the # abs value of biggest_difference then we should replace biggest_difference with rolling_change if rolling_change*boxes[-1] > 0 and abs(rolling_change) > abs(biggest_difference): biggest_difference = rolling_change @@ -1128,14 +1128,14 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf boxes.append(rolling_change) new_volumes.append(volume_cache) new_dates.append(temp_dates[i]) - + # reset rolling_change and volume_cache once we've used them rolling_change = 0 volume_cache = 0 - + # reset biggest_difference as we start from the beginning every time there is a reversal biggest_difference = 0 - + # Adjust the last box column if the left over rolling_change is the same sign as the column boxes[-1] += biggest_difference new_volumes[-1] += volume_cache @@ -1150,33 +1150,33 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf sign = (difference / abs(difference)) # -1 or 1 start_iteration = 0 if sign > 0 else 1 - + x = [index] * (diff) y = [curr_price + (i * box_size * sign) for i in range(start_iteration, diff+start_iteration)] curr_price += (box_size * sign * (diff)) box_values.append( y ) - + for i in range(len(x)): # x and y have the same length height = box_size * 0.85 width = 0.6 if height < 0.5: width = height - + padding = (box_size * 0.075) if sign == 1: # X line_seg.append([(x[i]-width/2, y[i] + padding), (x[i]+width/2, y[i]+height + padding)]) # create / part of the X line_seg.append([(x[i]-width/2, y[i]+height+padding), (x[i]+width/2, y[i]+padding)]) # create \ part of the X else: # O circle_patches.append(Ellipse((x[i], y[i]-(height/2) - padding), width, height)) - + useAA = 0, # use tuple here - lw = 0.5 + lw = 0.5 cirCollection = PatchCollection(circle_patches) cirCollection.set_facecolor([tfc] * len(circle_patches)) cirCollection.set_edgecolor([dc] * len(circle_patches)) - + xCollection = LineCollection(line_seg, colors=[uc] * len(line_seg), linewidths=lw, @@ -1194,7 +1194,7 @@ def _construct_aline_collections(alines, dtix=None): ---------- alines : sequence sequences of segments, which are sequences of lines, - which are sequences of two or more points ( date[time], price ) or (x,y) + which are sequences of two or more points ( date[time], price ) or (x,y) date[time] may be (a) pandas.to_datetime parseable string, (b) pandas Timestamp, or @@ -1284,7 +1284,7 @@ def _construct_hline_collections(hlines,minx,maxx): #print('hconfig=',hconfig) #print('hlines=',hlines) - + lines = [] if not isinstance(hlines,(list,tuple)): hlines = [hlines,] # may be a single price value @@ -1347,7 +1347,7 @@ def _construct_vline_collections(vlines,dtix,miny,maxy): #print('vconfig=',vconfig) #print('vlines=',vlines) - + if not isinstance(vlines,(list,tuple)): vlines = [vlines,] @@ -1430,7 +1430,7 @@ def _tline_lsq(dfslice,tline_use): https://mmas.github.io/least-squares-fitting-numpy-scipy ''' si = dfslice[tline_use].mean(axis=1) - s = si.dropna() + s = si.dropna() if len(s) < 2: err = 'NOT enough data for Least Squares' if (len(si) > 2): @@ -1467,7 +1467,7 @@ def _tline_lsq(dfslice,tline_use): alines.append((p1,p2)) del tconfig['alines'] - alines = dict(alines=alines,**tconfig) + alines = dict(alines=alines,**tconfig) alines['tlines'] = None return _construct_aline_collections(alines, dtix) @@ -1485,7 +1485,7 @@ class IntegerIndexDateTimeFormatter(Formatter): you would otherwise plot on that axis. Construct this formatter by providing the arrange of datetimes (as matplotlib floats). When the formatter receives an integer in the range, it will look up the - datetime and format it. + datetime and format it. """ def __init__(self, dates, fmt='%b %d, %H:%M'): @@ -1499,7 +1499,7 @@ def __call__(self, x, pos=0): # not sure what 'pos' is for: see # https://matplotlib.org/gallery/ticks_and_spines/date_index_formatter.html ix = int(np.round(x)) - + if ix >= self.len or ix < 0: date = None dateformat = '' diff --git a/src/mplfinance/plotting.py b/src/mplfinance/plotting.py index 7dfc5156..0478e70f 100644 --- a/src/mplfinance/plotting.py +++ b/src/mplfinance/plotting.py @@ -95,7 +95,7 @@ def _valid_plot_kwargs(): 2 specific keys: "Default", and "Validator" with the following values: "Default" - The default value for the kwarg if none is specified. "Validator" - A function that takes the caller specified value for the kwarg, - and validates that it is the correct type, and (for kwargs with + and validates that it is the correct type, and (for kwargs with a limited set of allowed values) may also validate that the kwarg value is one of the allowed values. ''' @@ -107,46 +107,46 @@ def _valid_plot_kwargs(): and all(isinstance(c, str) for c in value) }, 'type' : { 'Default' : 'ohlc', 'Validator' : lambda value: value in _get_valid_plot_types() }, - + 'style' : { 'Default' : None, 'Validator' : _styles._valid_mpf_style }, - + 'volume' : { 'Default' : False, 'Validator' : lambda value: isinstance(value,bool) or isinstance(value,mpl_axes.Axes) }, - + 'mav' : { 'Default' : None, 'Validator' : _mav_validator }, - + 'renko_params' : { 'Default' : dict(), 'Validator' : lambda value: isinstance(value,dict) }, 'pnf_params' : { 'Default' : dict(), 'Validator' : lambda value: isinstance(value,dict) }, - + 'study' : { 'Default' : None, - 'Validator' : lambda value: _kwarg_not_implemented(value) }, - + 'Validator' : lambda value: _kwarg_not_implemented(value) }, + 'marketcolors' : { 'Default' : None, # use 'style' for default, instead. 'Validator' : lambda value: isinstance(value,dict) }, - 'colors' : { 'Default' : None, # use default style instead. + 'override_marketcolors' : { 'Default' : None, # use default style instead. 'Validator' : lambda value: _colors_validator(value) }, - + 'no_xgaps' : { 'Default' : True, # None means follow default logic below: 'Validator' : lambda value: _warn_no_xgaps_deprecated(value) }, - - 'show_nontrading' : { 'Default' : False, + + 'show_nontrading' : { 'Default' : False, 'Validator' : lambda value: isinstance(value,bool) }, - + 'figscale' : { 'Default' : None, # scale base figure size up or down. 'Validator' : lambda value: isinstance(value,float) or isinstance(value,int) }, - + 'figratio' : { 'Default' : None, # aspect ratio; scaled to 8.0 height 'Validator' : lambda value: isinstance(value,(tuple,list)) and len(value) == 2 and isinstance(value[0],(float,int)) and isinstance(value[1],(float,int)) }, - + 'figsize' : { 'Default' : None, # figure size; overrides figratio and figscale 'Validator' : lambda value: isinstance(value,(tuple,list)) and len(value) == 2 @@ -155,32 +155,32 @@ def _valid_plot_kwargs(): 'fontscale' : { 'Default' : None, # scale all fonts up or down 'Validator' : lambda value: isinstance(value,float) or isinstance(value,int) }, - + 'linecolor' : { 'Default' : None, # line color in line plot 'Validator' : lambda value: mcolors.is_color_like(value) }, 'title' : { 'Default' : None, # Figure Title 'Validator' : lambda value: isinstance(value,(str,dict)) }, - + 'axtitle' : { 'Default' : None, # Axes Title (subplot title) 'Validator' : lambda value: isinstance(value,(str,dict)) }, - + 'ylabel' : { 'Default' : 'Price', # y-axis label 'Validator' : lambda value: isinstance(value,str) }, - + 'ylabel_lower' : { 'Default' : None, # y-axis label default logic below 'Validator' : lambda value: isinstance(value,str) }, - - 'addplot' : { 'Default' : None, + + 'addplot' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,dict) or (isinstance(value,list) and all([isinstance(d,dict) for d in value])) }, - - 'savefig' : { 'Default' : None, + + 'savefig' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,dict) or isinstance(value,str) or isinstance(value, io.BytesIO) or isinstance(value, os.PathLike) }, - - 'block' : { 'Default' : None, + + 'block' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,bool) }, - - 'returnfig' : { 'Default' : False, + + 'returnfig' : { 'Default' : False, 'Validator' : lambda value: isinstance(value,bool) }, 'return_calculated_values' : {'Default' : None, @@ -188,29 +188,29 @@ def _valid_plot_kwargs(): 'set_ylim' : {'Default' : None, 'Validator' : lambda value: _warn_set_ylim_deprecated(value) }, - + 'ylim' : {'Default' : None, - 'Validator' : lambda value: isinstance(value, (list,tuple)) and len(value) == 2 + 'Validator' : lambda value: isinstance(value, (list,tuple)) and len(value) == 2 and all([isinstance(v,(int,float)) for v in value])}, - + 'xlim' : {'Default' : None, 'Validator' : lambda value: _xlim_validator(value) }, - + 'set_ylim_panelB' : {'Default' : None, 'Validator' : lambda value: _warn_set_ylim_deprecated(value) }, - - 'hlines' : { 'Default' : None, + + 'hlines' : { 'Default' : None, 'Validator' : lambda value: _hlines_validator(value) }, - - 'vlines' : { 'Default' : None, + + 'vlines' : { 'Default' : None, 'Validator' : lambda value: _vlines_validator(value) }, - 'alines' : { 'Default' : None, + 'alines' : { 'Default' : None, 'Validator' : lambda value: _alines_validator(value) }, - - 'tlines' : { 'Default' : None, + + 'tlines' : { 'Default' : None, 'Validator' : lambda value: _tlines_validator(value) }, - + 'panel_ratios' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,(tuple,list)) and len(value) <= 10 and all([isinstance(v,(int,float)) for v in value]) }, @@ -237,7 +237,7 @@ def _valid_plot_kwargs(): 'Validator' : lambda value: isinstance(value,bool) }, 'fill_between' : { 'Default' : None, - 'Validator' : lambda value: _num_or_seq_of_num(value) or + 'Validator' : lambda value: _num_or_seq_of_num(value) or (isinstance(value,dict) and 'y1' in value and _num_or_seq_of_num(value['y1'])) }, @@ -258,8 +258,8 @@ def _valid_plot_kwargs(): 'saxbelow' : { 'Default' : True, # Issue#115 Comment#639446764 'Validator' : lambda value: isinstance(value,bool) }, - - 'scale_padding' : { 'Default' : 1.0, # Issue#193 + + 'scale_padding' : { 'Default' : 1.0, # Issue#193 'Validator' : lambda value: _scale_padding_validator(value) }, 'ax' : { 'Default' : None, @@ -300,7 +300,7 @@ def plot( data, **kwargs ): # translate alias types: config['type'] = _get_valid_plot_types(config['type']) - + dates,opens,highs,lows,closes,volumes = _check_and_prepare_data(data, config) config['xlim'] = _check_and_convert_xlim_configuration(data, config) @@ -375,7 +375,7 @@ def plot( data, **kwargs ): fmtstring = _determine_format_string(dates, config['datetime_format']) - ptype = config['type'] + ptype = config['type'] if config['show_nontrading']: formatter = mdates.DateFormatter(fmtstring) @@ -398,20 +398,20 @@ def plot( data, **kwargs ): if isinstance(rwc,dict) and len(rwc)==0: config['return_width_config'].update(config['_width_config']) - if config['colors']: - colors = config['colors'] - for c in range(len(colors)): - if isinstance(colors[c], str): - config['colors'][c] = make_marketcolors(up=colors[c], down=colors[c], edge=colors[c], wick=colors[c], ohlc=colors[c], volume=colors[c]) + if config['override_marketcolors']: + override_marketcolors = config['override_marketcolors'] + for c in range(len(override_marketcolors)): + if isinstance(override_marketcolors[c], str): + config['override_marketcolors'][c] = make_marketcolors(up=override_marketcolors[c], down=override_marketcolors[c], edge=override_marketcolors[c], wick=override_marketcolors[c], ohlc=override_marketcolors[c], volume=override_marketcolors[c]) else: - config['colors'] = None + config['override_marketcolors'] = None collections = None if ptype == 'line': lw = config['_width_config']['line_width'] axA1.plot(xdates, closes, color=config['linecolor'], linewidth=lw) else: - collections =_construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style,config['colors']) + collections =_construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style,config['override_marketcolors']) if ptype in VALID_PMOVE_TYPES: collections, calculated_values = collections @@ -498,7 +498,7 @@ def plot( data, **kwargs ): if len(mav) != len(mavprices): warnings.warn('len(mav)='+str(len(mav))+' BUT len(mavprices)='+str(len(mavprices))) else: - for jj in range(0,len(mav)): + for jj in range(0,len(mav)): retdict['mav' + str(mav[jj])] = mavprices[jj] retdict['minx'] = minx retdict['maxx'] = maxx @@ -525,7 +525,7 @@ def plot( data, **kwargs ): tlines = [tlines,] for tline_item in tlines: line_collections.append(_construct_tline_collections(tline_item, dtix, dates, opens, highs, lows, closes)) - + for collection in line_collections: if collection is not None: axA1.add_collection(collection) @@ -561,7 +561,7 @@ def plot( data, **kwargs ): axA1.set_yscale(yscale,**ysd) elif isinstance(ysd,str): axA1.set_yscale(ysd) - + addplot = config['addplot'] if addplot is not None and ptype not in VALID_PMOVE_TYPES: @@ -595,7 +595,7 @@ def plot( data, **kwargs ): for apdict in addplot: - panid = apdict['panel'] + panid = apdict['panel'] if not external_axes_mode: if panid == 'main' : panid = 0 # for backwards compatibility elif panid == 'lower': panid = 1 # for backwards compatibility @@ -606,11 +606,11 @@ def plot( data, **kwargs ): if aptype == 'ohlc' or aptype == 'candle': ax = _addplot_collections(panid,panels,apdict,xdates,config) _addplot_apply_supplements(ax,apdict) - else: + else: apdata = apdict['data'] if isinstance(apdata,list) and not isinstance(apdata[0],(float,int)): raise TypeError('apdata is list but NOT of float or int') - if isinstance(apdata,pd.DataFrame): + if isinstance(apdata,pd.DataFrame): havedf = True else: havedf = False # must be a single series or array @@ -636,7 +636,7 @@ def plot( data, **kwargs ): fb['x'] = xdates ax = panels.at[panid,'axes'][0] ax.fill_between(**fb) - + # put the primary axis on one side, # and the twinx() on the "other" side: if not external_axes_mode: @@ -653,14 +653,14 @@ def plot( data, **kwargs ): # TODO: =========== # TODO: It appears to me that there may be some or significant overlap # TODO: between what the following functions actually do: - # TODO: At the very least, all four of them appear to communicate + # TODO: At the very least, all four of them appear to communicate # TODO: to matplotlib that the xaxis should be treated as dates: # TODO: -> 'ax.autoscale_view()' # TODO: -> 'ax.xaxis_dates()' # TODO: -> 'plt.autofmt_xdates()' # TODO: -> 'fig.autofmt_xdate()' # TODO: ================================================================ - + #if config['autofmt_xdate']: #print('CALLING fig.autofmt_xdate()') @@ -671,7 +671,7 @@ def plot( data, **kwargs ): # for `addplot`, that this IS necessary when the only thing done to the # the axes is .add_collection(). (However, if ax.plot() .scatter() or # .bar() was called, then possibly this is not necessary; not entirely - # sure, but it definitely was necessary to get 'ohlc' and 'candle' + # sure, but it definitely was necessary to get 'ohlc' and 'candle' # working in `addplot`). axA1.set_ylabel(config['ylabel']) @@ -727,7 +727,7 @@ def plot( data, **kwargs ): offset = '\n'+offset vol_label = config['ylabel_lower'] + offset volumeAxes.set_ylabel(vol_label) - + if config['title'] is not None: if config['tight_layout']: # IMPORTANT: `y=0.89` is based on the top of the top panel @@ -747,8 +747,8 @@ def plot( data, **kwargs ): else: title = config['title'] # config['title'] is a string fig.suptitle(title,**title_kwargs) - - + + if config['axtitle'] is not None: axA1.set_title(config['axtitle']) @@ -784,10 +784,10 @@ def plot( data, **kwargs ): if config['closefig']: # True or 'auto' plt.close(fig) elif not config['returnfig']: - plt.show(block=config['block']) # https://stackoverflow.com/a/13361748/1639359 + plt.show(block=config['block']) # https://stackoverflow.com/a/13361748/1639359 if config['closefig'] == True or (config['block'] and config['closefig']): plt.close(fig) - + if config['returnfig']: if config['closefig'] == True: plt.close(fig) return (fig, axlist) @@ -852,7 +852,7 @@ def _addplot_collections(panid,panels,apdict,xdates,config): apdata = apdict['data'] aptype = apdict['type'] external_axes_mode = apdict['ax'] is not None - + #--------------------------------------------------------------# # Note: _auto_secondary_y() sets the 'magnitude' column in the # `panels` dataframe, which is needed for automatically @@ -871,18 +871,18 @@ def _addplot_collections(panid,panels,apdict,xdates,config): if not isinstance(apdata,pd.DataFrame): raise TypeError('addplot type "'+aptype+'" MUST be accompanied by addplot data of type `pd.DataFrame`') d,o,h,l,c,v = _check_and_prepare_data(apdata,config) - collections = _construct_mpf_collections(aptype,d,xdates,o,h,l,c,v,config,config['style'],config['colors']) + collections = _construct_mpf_collections(aptype,d,xdates,o,h,l,c,v,config,config['style'],config['override_marketcolors']) if not external_axes_mode: lo = math.log(max(math.fabs(np.nanmin(l)),1e-7),10) - 0.5 hi = math.log(max(math.fabs(np.nanmax(h)),1e-7),10) + 0.5 secondary_y = _auto_secondary_y( panels, panid, lo, hi ) if 'auto' != apdict['secondary_y']: - secondary_y = apdict['secondary_y'] + secondary_y = apdict['secondary_y'] if secondary_y: - ax = panels.at[panid,'axes'][1] + ax = panels.at[panid,'axes'][1] panels.at[panid,'used2nd'] = True - else: + else: ax = panels.at[panid,'axes'][0] else: ax = apdict['ax'] @@ -908,9 +908,9 @@ def _addplot_columns(panid,panels,ydata,apdict,xdates,config): #print("apdict['secondary_y'] says secondary_y is",secondary_y) if secondary_y: - ax = panels.at[panid,'axes'][1] + ax = panels.at[panid,'axes'][1] panels.at[panid,'used2nd'] = True - else: + else: ax = panels.at[panid,'axes'][0] else: ax = apdict['ax'] @@ -999,7 +999,7 @@ def _plot_mav(ax,config,xdates,prices,apmav=None,apwidth=None): mavgs = mavgs, # convert to tuple if len(mavgs) > 7: mavgs = mavgs[0:7] # take at most 7 - + if style['mavcolors'] is not None: mavc = cycle(style['mavcolors']) else: @@ -1049,8 +1049,8 @@ def _valid_addplot_kwargs(): 'mav' : { 'Default' : None, 'Validator' : _mav_validator }, - - 'panel' : { 'Default' : 0, + + 'panel' : { 'Default' : 0, 'Validator' : lambda value: _valid_panel_id(value) }, 'marker' : { 'Default' : 'o', @@ -1066,7 +1066,7 @@ def _valid_addplot_kwargs(): 'linestyle' : { 'Default' : None, 'Validator' : lambda value: value in valid_linestyles }, - 'width' : { 'Default' : None, # width of `bar` or `line` + 'width' : { 'Default' : None, # width of `bar` or `line` 'Validator' : lambda value: isinstance(value,(int,float)) or all([isinstance(v,(int,float)) for v in value]) }, @@ -1082,12 +1082,12 @@ def _valid_addplot_kwargs(): 'y_on_right' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,bool) }, - + 'ylabel' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,str) }, 'ylim' : {'Default' : None, - 'Validator' : lambda value: isinstance(value, (list,tuple)) and len(value) == 2 + 'Validator' : lambda value: isinstance(value, (list,tuple)) and len(value) == 2 and all([isinstance(v,(int,float)) for v in value])}, 'title' : { 'Default' : None, @@ -1100,7 +1100,7 @@ def _valid_addplot_kwargs(): 'Validator' : lambda value: _yscale_validator(value) }, 'stepwhere' : { 'Default' : 'pre', - 'Validator' : lambda value : value in valid_stepwheres }, + 'Validator' : lambda value : value in valid_stepwheres }, } _validate_vkwargs_dict(vkwargs) @@ -1112,7 +1112,7 @@ def make_addplot(data, **kwargs): ''' Take data (pd.Series, pd.DataFrame, np.ndarray of floats, list of floats), and kwargs (see valid_addplot_kwargs_table) and construct a correctly structured dict - to be passed into plot() using kwarg `addplot`. + to be passed into plot() using kwarg `addplot`. NOTE WELL: len(data) here must match the len(data) passed into plot() ''' if not isinstance(data, (pd.Series, pd.DataFrame, np.ndarray, list)): diff --git a/src/trial.py b/src/trial.py new file mode 100644 index 00000000..d75885ec --- /dev/null +++ b/src/trial.py @@ -0,0 +1,45 @@ +import pandas as pd +import random +from datetime import date, timedelta +from mplfinance.plotting import plot +from mplfinance._styles import make_marketcolors + +dict_data = [] +start_date = date(2019, 1, 1) +end_date = date(2020, 1, 1) +delta = timedelta(days=1) +start = 20 +end = 30 +while start_date <= end_date: + openval = random.randint(start, end) + closeval = random.randint(start, end) + high = random.randint(max(openval, closeval), end) + low = random.randint(start, min(openval, closeval)) + change = random.randint(-5, 5) + volume = random.randint(10000, 20000) + dict_data.append({ + "Open": openval, + "Close": closeval, + "High": high, + "Low": low, + "Date": start_date, + "Volume": volume + }) + start += change + end += change + start_date += delta + +df = pd.DataFrame(dict_data) +df.index = pd.to_datetime(df['Date']) + +custom_colors = [] +for i in range(len(df)): + if i % 3 == 0: + custom_colors.append(make_marketcolors(up='#29c9ff', down='#f3b5ff', edge='#29c9ff', wick='#29c9ff', ohlc='#32a852', volume='#a89132')) + elif i%5 == 0: + custom_colors.append("#000000") + else: + custom_colors.append(None) + +plot(df, type='candle', style='yahoo', override_marketcolors=custom_colors, volume=True) +# plot(df, type='candle', style='yahoo', volume=True) From d653acdb6c95eb53555e358f68a20b2acf531108 Mon Sep 17 00:00:00 2001 From: Shivansh Subramanian Date: Sat, 4 Dec 2021 21:44:04 +0530 Subject: [PATCH 06/11] example --- src/Figure_1.png | Bin 0 -> 59649 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/Figure_1.png diff --git a/src/Figure_1.png b/src/Figure_1.png new file mode 100644 index 0000000000000000000000000000000000000000..062eb929699fec7bc2f16bf363069783a7f67305 GIT binary patch literal 59649 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�jZ4}H!Dd|&QQ4+F^Xy#MV3uCJ6I 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 Gmj4H7in_o6 literal 0 HcmV?d00001 From f06db4b080c6cd2e100a8f14e2cc32570b3b2adb Mon Sep 17 00:00:00 2001 From: Daniel Goldfarb Date: Thu, 9 Dec 2021 12:59:22 -0500 Subject: [PATCH 07/11] simplify marketcolor overrides --- src/mplfinance/_arg_validators.py | 56 +++-- src/mplfinance/_utils.py | 357 ++++++++++++------------------ src/mplfinance/plotting.py | 172 +++++++------- 3 files changed, 258 insertions(+), 327 deletions(-) diff --git a/src/mplfinance/_arg_validators.py b/src/mplfinance/_arg_validators.py index ceb8072b..945f117f 100644 --- a/src/mplfinance/_arg_validators.py +++ b/src/mplfinance/_arg_validators.py @@ -1,4 +1,5 @@ import matplotlib.dates as mdates +import matplotlib.colors as mcolors import pandas as pd import numpy as np import datetime @@ -52,7 +53,7 @@ def _check_and_prepare_data(data, config): columns = ('Open', 'High', 'Low', 'Close', 'Volume') if all([c.lower() in data for c in columns[0:4]]): columns = ('open', 'high', 'low', 'close', 'volume') - + o, h, l, c, v = columns cols = [o, h, l, c] @@ -100,7 +101,7 @@ def _get_valid_plot_types(plottype=None): return _alias_types[plottype] else: return plottype - + def _mav_validator(mav_value): ''' @@ -142,17 +143,6 @@ def _valid_mav(value, is_period=True): return True return False -def _colors_validator(value): - if not isinstance(value, (list, tuple, np.ndarray)): - return False - - for v in value: - if v: - if v is not None and not isinstance(v, (dict, str)): - return False - - return True - def _hlines_validator(value): if isinstance(value,dict): @@ -204,11 +194,11 @@ def _alines_validator(value, returnStandardizedValue=False): A sequence of (line0, line1, line2), where: linen = (x0, y0), (x1, y1), ... (xm, ym) - + or the equivalent numpy array with two columns. Each line can be a different length. The above is from the matplotlib LineCollection documentation. - It basically says that the "segments" passed into the LineCollection constructor + It basically says that the "segments" passed into the LineCollection constructor must be a Sequence of Sequences of 2 or more xy Pairs. However here in `mplfinance` we want to allow that (seq of seq of xy pairs) _as well as_ just a sequence of pairs. Therefore here in the validator we will allow both: @@ -270,8 +260,8 @@ def _tlines_subvalidator(value): def _bypass_kwarg_validation(value): ''' For some kwargs, we either don't know enough, or the validation is too complex to make it worth while, - so we bypass kwarg validation. If the kwarg is - invalid, then eventually an exception will be + so we bypass kwarg validation. If the kwarg is + invalid, then eventually an exception will be raised at the time the kwarg value is actually used. ''' return True @@ -300,7 +290,7 @@ def _process_kwargs(kwargs, vkwargs): Given a "valid kwargs table" and some kwargs, verify that each key-word is valid per the kwargs table, and that the value of the kwarg is the correct type. Fill a configuration dictionary with the default value - for each kwarg, and then substitute in any values that were provided + for each kwarg, and then substitute in any values that were provided as kwargs and return the configuration dictionary. ''' # initialize configuration from valid_kwargs_table: @@ -327,7 +317,7 @@ def _process_kwargs(kwargs, vkwargs): # --------------------------------------------------------------- # At this point in the loop, if we have not raised an exception, - # then kwarg is valid as far as we can tell, therefore, + # then kwarg is valid as far as we can tell, therefore, # go ahead and replace the appropriate value in config: config[key] = value @@ -346,7 +336,7 @@ def _scale_padding_validator(value): if key not in valid_keys: raise ValueError('Invalid key "'+str(key)+'" found in `scale_padding` dict.') if not isinstance(value[key],(int,float)): - raise ValueError('`scale_padding` dict contains non-number at key "'+str(key)+'"') + raise ValueError('`scale_padding` dict contains non-number at key "'+str(key)+'"') return True else: raise ValueError('`scale_padding` kwarg must be a number, or dict of (left,right,top,bottom) numbers.') @@ -370,11 +360,29 @@ def _yscale_validator(value): return True +def _is_marketcolor_object(obj): + if not isinstance(obj,dict): return False + market_colors_keys = ('candle','edge','wick','ohlc') + return all([k in obj for k in market_colors_keys]) + + +def _mco_validator(value): # marketcolor overrides validator + if isinstance(value,dict): # not yet supported, but maybe we will have other + if 'colors' not in value: # kwargs related to mktcolor overrides (ex: `mco_faceonly`) + raise ValueError('`marketcolor_overrides` as dict must contain `colors` key.') + colors = value['colors'] + else: + colors = value + if not isinstance(colors,(list,tuple,np.ndarray)): + return False + return all([(c is None or mcolors.is_color_like(c) or _is_marketcolor_object(c)) for c in colors]) + + def _check_for_external_axes(config): ''' - Check that all `fig` and `ax` kwargs are either ALL None, + Check that all `fig` and `ax` kwargs are either ALL None, or ALL are valid instances of Figures/Axes: - + An external Axes object can be passed in three places: - mpf.plot() `ax=` kwarg - mpf.plot() `volume=` kwarg @@ -391,7 +399,7 @@ def _check_for_external_axes(config): raise TypeError('addplot must be `dict`, or `list of dict`, NOT '+str(type(addplot))) for apd in addplot: ap_axlist.append(apd['ax']) - + if len(ap_axlist) > 0: if config['ax'] is None: if not all([ax is None for ax in ap_axlist]): @@ -416,6 +424,6 @@ def _check_for_external_axes(config): raise ValueError('`volume` must be of type `matplotlib.axis.Axes`') #if not isinstance(config['fig'],mpl.figure.Figure): # raise ValueError('`fig` kwarg must be of type `matplotlib.figure.Figure`') - + external_axes_mode = True if isinstance(config['ax'],mpl.axes.Axes) else False return external_axes_mode diff --git a/src/mplfinance/_utils.py b/src/mplfinance/_utils.py index e3109aff..9f519010 100644 --- a/src/mplfinance/_utils.py +++ b/src/mplfinance/_utils.py @@ -20,7 +20,7 @@ from six.moves import zip -def _check_input(opens, closes, highs, lows, colors=None): +def _check_input(opens, closes, highs, lows): """Checks that *opens*, *highs*, *lows* and *closes* have the same length. NOTE: this code assumes if any value open, high, low, close is missing (*-1*) they all are missing @@ -46,10 +46,6 @@ def _check_input(opens, closes, highs, lows, colors=None): if not same_length: raise ValueError('O,H,L,C must have the same length!') - if colors: - if len(opens) != len(colors): - raise ValueError('O,H,L,C and Colors must have the same length!') - o = np.where(np.isnan(opens))[0] h = np.where(np.isnan(highs))[0] l = np.where(np.isnan(lows))[0] @@ -85,23 +81,23 @@ def _check_and_convert_xlim_configuration(data, config): xlim = [ _date_to_mdate(dt) for dt in xlim] else: xlim = [ _date_to_iloc_extrapolate(data.index.to_series(),dt) for dt in xlim] - + return xlim -def _construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style,colors): +def _construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style): collections = None if ptype == 'candle' or ptype == 'candlestick': collections = _construct_candlestick_collections(xdates, opens, highs, lows, closes, - marketcolors=style['marketcolors'],config=config, colors=colors ) + marketcolors=style['marketcolors'],config=config ) elif ptype =='hollow_and_filled': collections = _construct_hollow_candlestick_collections(xdates, opens, highs, lows, closes, - marketcolors=style['marketcolors'],config=config, colors=colors ) + marketcolors=style['marketcolors'],config=config ) elif ptype == 'ohlc' or ptype == 'bars' or ptype == 'ohlc_bars': collections = _construct_ohlc_collections(xdates, opens, highs, lows, closes, - marketcolors=style['marketcolors'],config=config, colors=colors ) + marketcolors=style['marketcolors'],config=config ) elif ptype == 'renko': collections = _construct_renko_collections( dates, highs, lows, volumes, config['renko_params'], closes, marketcolors=style['marketcolors']) @@ -111,7 +107,7 @@ def _construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volume dates, highs, lows, volumes, config['pnf_params'], closes, marketcolors=style['marketcolors']) else: raise TypeError('Unknown ptype="',str(ptype),'"') - + return collections @@ -142,7 +138,7 @@ def combine_adjacent(arr): Returns ------- output: new summed array - indexes: indexes indicating the first + indexes: indexes indicating the first element summed for each group in arr """ output, indexes = [], [] @@ -155,7 +151,7 @@ def combine_adjacent(arr): output.append(sum(arr[:index])) indexes.append(curr_i) curr_i += index - + for _ in range(index): arr.pop(0) return output, indexes @@ -180,47 +176,38 @@ def coalesce_volume_dates(in_volumes, in_dates, indexes): return volumes, dates -def _updown_colors(upcolor,downcolor,opens,closes,use_prev_close=False,colors=None): - if not colors: - if upcolor == downcolor: - return upcolor - cmap = {True : upcolor, False : downcolor} - if not use_prev_close: - return [ cmap[opn < cls] for opn,cls in zip(opens,closes) ] - else: - first = cmap[opens[0] < closes[0]] - _list = [ cmap[pre < cls] for cls,pre in zip(closes[1:], closes) ] - return [first] + _list +def _updown_colors(upcolor,downcolor,opens,closes,use_prev_close=False): + # ----------------------------------------------------- + # Note that `nan` values result in `opn < cls` == False + # In other words, nans don't get plotted by collections + # but this function will choose DOWN COLOR for nans. + # ----------------------------------------------------- + if upcolor == downcolor: + return [upcolor]*len(opens) + cmap = {True : upcolor, False : downcolor} + if not use_prev_close: + return [ cmap[opn < cls] for opn,cls in zip(opens,closes) ] else: - cmap = {True: 'up', False: 'down'} - default = {'up': upcolor, 'down': downcolor} - custom = [] - if not use_prev_close: - for i in range(len(opens)): - opn = opens[i] - cls = closes[i] - if colors[i]: - custom.append(colors[i][cmap[opn < cls]]) - else: - custom.append(default[cmap[opn < cls]]) - else: - if color[0]: - custom.append(colors[0][cmap[opens[0] < closes[0]]]) - else: - custom.append(default[cmap[opens[0] < closes[0]]]) - - for i in range(len(closes) - 1): - pre = closes[1:][i] - cls = closes[i] - if colors[i]: - custom.append(colors[i][cmap[pre < cls]]) - else: - custom.append(default[cmap[pre < cls]]) - - return custom - - - + first = cmap[opens[0] < closes[0]] + _list = [ cmap[pre < cls] for cls,pre in zip(closes[1:], closes) ] + return [first] + _list + +def _make_updown_color_list(key,marketcolors,opens,closes,overrides=None): + length = len(opens) + ups = [marketcolors[key][ 'up' ]]*length + downs = [marketcolors[key]['down']]*length + if overrides is not None: + for ix,mco in enumerate(overrides): + if mco is None: continue + if mcolors.is_color_like(mco): + ups[ix] = mco + downs[ix] = mco + else: # assume it is correctly a marketcolors object (dict) + ups[ix] = mco[key][ 'up' ] + downs[ix] = mco[key]['down'] + return [ups[ix] if opens[ix] < closes[ix] else downs[ix] for ix in range(length)] + + def _updownhollow_colors(upcolor,downcolor,hollowcolor,opens,closes): if upcolor == downcolor: return upcolor @@ -232,7 +219,7 @@ def _updownhollow_colors(upcolor,downcolor,hollowcolor,opens,closes): def _date_to_iloc(dtseries,date): - '''Convert a `date` to a location, given a date series w/a datetime index. + '''Convert a `date` to a location, given a date series w/a datetime index. If `date` does not exactly match a date in the series then interpolate between two dates. If `date` is outside the range of dates in the series, then raise an exception . @@ -269,7 +256,7 @@ def _date_to_iloc_linear(dtseries,date,trace=False): i1 = 0.0 i2 = len(dtseries) - 1.0 if trace: print('i1,i2=',i1,i2) - + slope = (i2 - i1) / (d2 - d1) yitrcpt1 = i1 - (slope*d1) if trace: print('slope,yitrcpt=',slope,yitrcpt1) @@ -279,7 +266,7 @@ def _date_to_iloc_linear(dtseries,date,trace=False): print('WARNING: yintercepts NOT equal!!!(',yitrcpt1,yitrcpt2,')') yitrcpt = (yitrcpt1 + yitrcpt2) / 2.0 else: - yitrcpt = yitrcpt1 + yitrcpt = yitrcpt1 return (slope * _date_to_mdate(date)) + yitrcpt def _date_to_iloc_5_7ths(dtseries,date,direction,trace=False): @@ -299,14 +286,14 @@ def _date_to_iloc_5_7ths(dtseries,date,direction,trace=False): return loc_5_7ths def _date_to_iloc_extrapolate(dtseries,date): - '''Convert a `date` to a location, given a date series w/a datetime index. + '''Convert a `date` to a location, given a date series w/a datetime index. If `date` does not exactly match a date in the series then interpolate between two dates. If `date` is outside the range of dates in the series, then extrapolate: Extrapolation results in increased error as the distance of the extrapolation increases. We have two methods to extrapolate: (1) Determine a linear equation based on the data provided in `dtseries`, and use that equation to calculate the location for the date. - (2) Multiply by 5/7 the number of days between the edge date of dtseries and the + (2) Multiply by 5/7 the number of days between the edge date of dtseries and the date for which we are requesting a location. THIS ASSUMES DAILY data AND a 5 DAY TRADING WEEK. Empirical observation (scratch_pad/date_to_iloc_extrapolation.ipynb) shows that @@ -359,7 +346,7 @@ def _date_to_mdate(date): def _convert_segment_dates(segments,dtindex): ''' - Convert line segment dates to matplotlib dates + Convert line segment dates to matplotlib dates Inputted segment dates may be: pandas-parseable date-time string, pandas timestamp, or a python datetime or date, or (if dtindex is not None) integer index A "segment" is a "sequence of lines", @@ -374,7 +361,7 @@ def _convert_segment_dates(segments,dtindex): new_line = [] for dt,value in line: if dtindex is not None: - date = _date_to_iloc(dtseries,dt) + date = _date_to_iloc(dtseries,dt) else: date = _date_to_mdate(dt) if date is None: @@ -385,13 +372,13 @@ def _convert_segment_dates(segments,dtindex): def _valid_renko_kwargs(): ''' - Construct and return the "valid renko kwargs table" for the mplfinance.plot(type='renko') - function. A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are - the valid key-words for the function. The value for each key is a dict containing 2 + Construct and return the "valid renko kwargs table" for the mplfinance.plot(type='renko') + function. A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are + the valid key-words for the function. The value for each key is a dict containing 2 specific keys: "Default", and "Validator" with the following values: "Default" - The default value for the kwarg if none is specified. "Validator" - A function that takes the caller specified value for the kwarg, - and validates that it is the correct type, and (for kwargs with + and validates that it is the correct type, and (for kwargs with a limited set of allowed values) may also validate that the kwarg value is one of the allowed values. ''' @@ -399,7 +386,7 @@ def _valid_renko_kwargs(): 'brick_size' : { 'Default' : 'atr', 'Validator' : lambda value: isinstance(value,(float,int)) or value == 'atr' }, 'atr_length' : { 'Default' : 14, - 'Validator' : lambda value: isinstance(value,int) or value == 'total' }, + 'Validator' : lambda value: isinstance(value,int) or value == 'total' }, } _validate_vkwargs_dict(vkwargs) @@ -408,13 +395,13 @@ def _valid_renko_kwargs(): def _valid_pnf_kwargs(): ''' - Construct and return the "valid pnf kwargs table" for the mplfinance.plot(type='pnf') - function. A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are - the valid key-words for the function. The value for each key is a dict containing 2 + Construct and return the "valid pnf kwargs table" for the mplfinance.plot(type='pnf') + function. A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are + the valid key-words for the function. The value for each key is a dict containing 2 specific keys: "Default", and "Validator" with the following values: "Default" - The default value for the kwarg if none is specified. "Validator" - A function that takes the caller specified value for the kwarg, - and validates that it is the correct type, and (for kwargs with + and validates that it is the correct type, and (for kwargs with a limited set of allowed values) may also validate that the kwarg value is one of the allowed values. ''' @@ -424,7 +411,7 @@ def _valid_pnf_kwargs(): 'atr_length' : { 'Default' : 14, 'Validator' : lambda value: isinstance(value,int) or value == 'total' }, 'reversal' : { 'Default' : 1, - 'Validator' : lambda value: isinstance(value,int) } + 'Validator' : lambda value: isinstance(value,int) } } _validate_vkwargs_dict(vkwargs) @@ -433,14 +420,14 @@ def _valid_pnf_kwargs(): def _valid_lines_kwargs(): ''' - Construct and return the "valid lines (hlines,vlines,alines,tlines) kwargs table" + Construct and return the "valid lines (hlines,vlines,alines,tlines) kwargs table" for the mplfinance.plot() `[h|v|a|t]lines=` kwarg functions. - A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are - the valid key-words for the function. The value for each key is a dict containing 2 + A valid kwargs table is a `dict` of `dict`s. The keys of the outer dict are + the valid key-words for the function. The value for each key is a dict containing 2 specific keys: "Default", and "Validator" with the following values: "Default" - The default value for the kwarg if none is specified. "Validator" - A function that takes the caller specified value for the kwarg, - and validates that it is the correct type, and (for kwargs with + and validates that it is the correct type, and (for kwargs with a limited set of allowed values) may also validate that the kwarg value is one of the allowed values. ''' @@ -463,12 +450,12 @@ def _valid_lines_kwargs(): 'Validator' : lambda value: value is None or value in valid_linestyles }, 'linewidths': { 'Default' : None, 'Validator' : lambda value: value is None or - isinstance(value,(float,int)) or + isinstance(value,(float,int)) or all([isinstance(v,(float,int)) for v in value]) }, 'alpha' : { 'Default' : 1.0, 'Validator' : lambda value: isinstance(value,(float,int)) }, - 'tline_use' : { 'Default' : 'close', + 'tline_use' : { 'Default' : 'close', 'Validator' : lambda value: isinstance(value,str) or (isinstance(value,(list,tuple)) and all([isinstance(v,str) for v in value]) ) }, 'tline_method': { 'Default' : 'point-to-point', @@ -480,7 +467,7 @@ def _valid_lines_kwargs(): return vkwargs -def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None, colors=None): +def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None): """Represent the time, open, high, low, close as a vertical line ranging from low to high. The left tick is the open and the right tick is the close. @@ -502,11 +489,11 @@ def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors= Returns ------- - ret : list + ret : list a list or tuple of matplotlib collections to be added to the axes """ - _check_input(opens, highs, lows, closes, colors) + _check_input(opens, highs, lows, closes) if marketcolors is None: mktcolors = _get_mpfstyle('classic')['marketcolors']['ohlc'] @@ -530,25 +517,11 @@ def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors= # we'll translate these to the date, close location closeSegments = [((dt, close), (dt+ticksize, close)) for dt, close in zip(dates, closes)] - bar_c = None - if colors: - bar_c = [] - for color in colors: - if color: - bar_up = color['ohlc']['up'] - bar_down = color['ohlc']['down'] - if bar_up == 'k': - bar_up = mktcolors['up'] - if bar_down == 'k': - bar_down = mktcolors['down'] - - bar_c.append({'up': mcolors.to_rgba(bar_up, 1), 'down': mcolors.to_rgba(bar_down, 1)}) - else: - bar_c.append(None) - - uc = mcolors.to_rgba(mktcolors['up']) - dc = mcolors.to_rgba(mktcolors['down']) - colors = _updown_colors(uc, dc, opens, closes, colors=bar_c) + if mktcolors['up'] == mktcolors['down'] and config['marketcolor_overrides'] is None: + colors = mktcolors['up'] + else: + overrides = config['marketcolor_overrides'] + colors = _make_updown_color_list('ohlc',marketcolors,opens,closes,overrides) lw = config['_width_config']['ohlc_linewidth'] @@ -570,7 +543,7 @@ def _construct_ohlc_collections(dates, opens, highs, lows, closes, marketcolors= return [rangeCollection, openCollection, closeCollection] -def _construct_candlestick_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None, colors=None): +def _construct_candlestick_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None): """Represent the open, close as a bar line and high low range as a vertical line. @@ -597,8 +570,8 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market ret : list (lineCollection, barCollection) """ - - _check_input(opens, highs, lows, closes, colors) + + _check_input(opens, highs, lows, closes) if marketcolors is None: marketcolors = _get_mpfstyle('classic')['marketcolors'] @@ -618,62 +591,22 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market rangeSegLow = [((date, low), (date, min(open,close))) for date, low, open, close in zip(dates, lows, opens, closes)] - + rangeSegHigh = [((date, high), (date, max(open,close))) for date, high, open, close in zip(dates, highs, opens, closes)] - + rangeSegments = rangeSegLow + rangeSegHigh alpha = marketcolors['alpha'] - candle_c = None - wick_c = None - edge_c = None - if colors: - candle_c = [] - wick_c = [] - edge_c = [] - for color in colors: - if color: - candle_up = color['candle']['up'] - candle_down = color['candle']['down'] - edge_up = color['edge']['up'] - edge_down = color['edge']['down'] - wick_up = color['wick']['up'] - wick_down = color['wick']['down'] - if candle_up == 'w': - candle_up = marketcolors['candle']['up'] - if candle_down == 'k': - candle_down = marketcolors['candle']['down'] - if edge_up == 'k': - edge_up = candle_up - if edge_down == 'k': - edge_down = candle_down - if wick_up == 'k': - wick_up = candle_up - if wick_down == 'k': - wick_down = candle_down - - candle_c.append({'up': mcolors.to_rgba(candle_up, alpha), 'down': mcolors.to_rgba(candle_down, alpha)}) - edge_c.append({'up': mcolors.to_rgba(edge_up, 1), 'down': mcolors.to_rgba(edge_down, 1)}) - wick_c.append({'up': mcolors.to_rgba(wick_up, 1), 'down': mcolors.to_rgba(wick_down, 1)}) - - else: - candle_c.append(None) - wick_c.append(None) - edge_c.append(None) - - uc = mcolors.to_rgba(marketcolors['candle'][ 'up' ], alpha) - dc = mcolors.to_rgba(marketcolors['candle']['down'], alpha) - colors = _updown_colors(uc, dc, opens, closes, colors=candle_c) - - uc = mcolors.to_rgba(marketcolors['edge'][ 'up' ], 1.0) - dc = mcolors.to_rgba(marketcolors['edge']['down'], 1.0) - edgecolor = _updown_colors(uc, dc, opens, closes, colors=edge_c) + overrides = config['marketcolor_overrides'] + faceonly = config['mco_faceonly'] - uc = mcolors.to_rgba(marketcolors['wick'][ 'up' ], 1.0) - dc = mcolors.to_rgba(marketcolors['wick']['down'], 1.0) - wickcolor = _updown_colors(uc, dc, opens, closes, colors=wick_c) + colors = _make_updown_color_list('candle',marketcolors,opens,closes,overrides) + colors = [mcolors.to_rgba(c,alpha) for c in colors] # include alpha + if faceonly: overrides = None + edgecolor = _make_updown_color_list('edge',marketcolors,opens,closes,overrides) + wickcolor = _make_updown_color_list('wick',marketcolors,opens,closes,overrides) lw = config['_width_config']['candle_linewidth'] @@ -691,10 +624,10 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market return [rangeCollection, barCollection] -def _construct_hollow_candlestick_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None, colors=None): +def _construct_hollow_candlestick_collections(dates, opens, highs, lows, closes, marketcolors=None, config=None): """Represent today's open to close as a "bar" line (candle body) and high low range as a vertical line (candle wick) - + If config['type']=='hollow_and_filled' (hollow and filled candles) then candle edge and wick color depend on PREVIOUS close to today's close (up or down), and the center of the candle body (hollow or filled) depends on the today's open to close (up or down). @@ -721,7 +654,7 @@ def _construct_hollow_candlestick_collections(dates, opens, highs, lows, closes, ret : list (lineCollection, barCollection) """ - + _check_input(opens, highs, lows, closes) if marketcolors is None: @@ -742,23 +675,23 @@ def _construct_hollow_candlestick_collections(dates, opens, highs, lows, closes, rangeSegLow = [((date, low), (date, min(open,close))) for date, low, open, close in zip(dates, lows, opens, closes)] - + rangeSegHigh = [((date, high), (date, max(open,close))) for date, high, open, close in zip(dates, highs, opens, closes)] - + rangeSegments = rangeSegLow + rangeSegHigh alpha = marketcolors['alpha'] uc = mcolors.to_rgba(marketcolors['candle'][ 'up' ], alpha) dc = mcolors.to_rgba(marketcolors['candle']['down'], alpha) - + hc = mcolors.to_rgba(marketcolors['hollow']) if 'hollow' in marketcolors else (0,0,0,0) - + colors = _updownhollow_colors(uc, dc, hc, opens, closes) # for candle body. edgecolor = _updown_colors(uc, dc, opens, closes, use_prev_close=True) - + wickcolor = _updown_colors(uc, dc, opens, closes, use_prev_close=True) # For hollow candles, we scale the candle linewidth up a little: @@ -788,19 +721,19 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param --------------------- In the first part of the algorithm, we populate the cdiff array along with adjusting the dates and volumes arrays into the new_dates and - new_volumes arrays. A single date includes a range from no bricks to many - bricks, if a date has no bricks it shall not be included in new_dates, - and if it has n bricks then it will be included n times. Volumes use a + new_volumes arrays. A single date includes a range from no bricks to many + bricks, if a date has no bricks it shall not be included in new_dates, + and if it has n bricks then it will be included n times. Volumes use a volume cache to save volume amounts for dates that do not have any bricks before adding the cache to the next date that has at least one brick. - We populate the cdiff array with each close values difference from the + We populate the cdiff array with each close values difference from the previously created brick divided by the brick size. In the second part of the algorithm, we iterate through the values in cdiff - and add 1s or -1s to the bricks array depending on whether the value is + and add 1s or -1s to the bricks array depending on whether the value is positive or negative. Every time there is a trend change (ex. previous brick is an upbrick, current brick is a down brick) we draw one less brick to account - for the price having to move the previous bricks amount before creating a + for the price having to move the previous bricks amount before creating a brick in the opposite direction. In the final part of the algorithm, we enumerate through the bricks array and @@ -811,7 +744,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param Useful sources: https://avilpage.com/2018/01/how-to-plot-renko-charts-with-python.html https://school.stockcharts.com/doku.php?id=chart_analysis:renko - + Parameters ---------- dates : sequence @@ -836,10 +769,10 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param if marketcolors is None: marketcolors = _get_mpfstyle('classic')['marketcolors'] #print('default market colors:',marketcolors) - + brick_size = renko_params['brick_size'] atr_length = renko_params['atr_length'] - + if brick_size == 'atr': if atr_length == 'total': @@ -860,7 +793,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param dc = mcolors.to_rgba(marketcolors['candle']['down'], alpha) euc = mcolors.to_rgba(marketcolors['edge'][ 'up' ], 1.0) edc = mcolors.to_rgba(marketcolors['edge']['down'], 1.0) - + cdiff = [] # holds the differences between each close and the previously created brick / the brick size prev_close_brick = closes[0] volume_cache = 0 # holds the volumes for the dates that were skipped @@ -887,7 +820,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param last_diff_sign = 0 # direction the bricks were last going in -1 -> down, 1 -> up dates_volumes_index = 0 # keeps track of the index of the current date/volume for diff in cdiff: - + curr_diff_sign = diff/abs(diff) if last_diff_sign != 0 and curr_diff_sign != last_diff_sign: last_diff_sign = curr_diff_sign @@ -900,7 +833,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param new_volumes.pop(dates_volumes_index) continue last_diff_sign = curr_diff_sign - + if diff > 0: bricks.extend([1]*abs(diff)) else: @@ -922,7 +855,7 @@ def _construct_renko_collections(dates, highs, lows, volumes, config_renko_param curr_price += (brick_size * number) brick_values.append(curr_price) - + x, y = index, curr_price verts.append(( @@ -954,41 +887,41 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf --------------------- In the first part of the algorithm, we populate the boxes array along with adjusting the dates and volumes arrays into the new_dates and - new_volumes arrays. A single date includes a range from no boxes to many - boxes, if a date has no boxes it shall not be included in new_dates, - and if it has n boxes then it will be included n times. Volumes use a + new_volumes arrays. A single date includes a range from no boxes to many + boxes, if a date has no boxes it shall not be included in new_dates, + and if it has n boxes then it will be included n times. Volumes use a volume cache to save volume amounts for dates that do not have any boxes before adding the cache to the next date that has at least one box. - We populate the boxes array with each close values difference from the + We populate the boxes array with each close values difference from the previously created brick divided by the box size. The second part of the algorithm has a series of step. First we combine the adjacent like signed values in the boxes array (ex. [-1, -2, 3, -4] -> [-3, 3, -4]). - Next we subtract 1 from the absolute value of each element in boxes except the + Next we subtract 1 from the absolute value of each element in boxes except the first to ensure every time there is a trend change (ex. previous box is - an X, current brick is a O) we draw one less box to account for the price - having to move the previous box's amount before creating a box in the - opposite direction. During this same step we also combine like signed elements - and associated volume/date data ignoring any zero values that are created by - subtracting 1 from the box value. Next we recreate the box array utilizing a - rolling_change and volume_cache to store and sum the changes that don't break + an X, current brick is a O) we draw one less box to account for the price + having to move the previous box's amount before creating a box in the + opposite direction. During this same step we also combine like signed elements + and associated volume/date data ignoring any zero values that are created by + subtracting 1 from the box value. Next we recreate the box array utilizing a + rolling_change and volume_cache to store and sum the changes that don't break the reversal threshold. Lastly, we enumerate through the boxes to populate the line_seg and circle_patches - arrays. line_seg holds the / and \ line segments that make up an X and + arrays. line_seg holds the / and \ line segments that make up an X and circle_patches holds matplotlib.patches Ellipse objects for each O. We start - by filling an x and y array each iteration which contain the x and y + by filling an x and y array each iteration which contain the x and y coordinates for each box in the column. Then for each coordinate pair in - x, y we add to either the line_seg array or the circle_patches array - depending on the value of sign for the current column (1 indicates - line_seg, -1 indicates circle_patches). The height of the boxes take - into account padding which separates each box by a small margin in + x, y we add to either the line_seg array or the circle_patches array + depending on the value of sign for the current column (1 indicates + line_seg, -1 indicates circle_patches). The height of the boxes take + into account padding which separates each box by a small margin in order to increase readability. Useful sources: https://stackoverflow.com/questions/8750648/point-and-figure-chart-with-matplotlib https://www.investopedia.com/articles/technical/03/081303.asp - + Parameters ---------- dates : sequence @@ -1013,7 +946,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf if marketcolors is None: marketcolors = _get_mpfstyle('classic')['marketcolors'] #print('default market colors:',marketcolors) - + box_size = pointnfig_params['box_size'] atr_length = pointnfig_params['atr_length'] reversal = pointnfig_params['reversal'] @@ -1033,7 +966,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf if reversal < 1 or reversal > 9: raise ValueError("Specified reversal must be an integer in the range [1,9]") - + alpha = marketcolors['alpha'] uc = mcolors.to_rgba(marketcolors['ohlc'][ 'up' ], alpha) @@ -1044,7 +977,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf prev_close_box = closes[0] # represents the value of the last box in the previous column volume_cache = 0 # holds the volumes for the dates that were skipped temp_volumes, temp_dates = [], [] # holds the temp adjusted volumes and dates respectively - + for i in range(len(closes)-1): box_diff = int((closes[i+1] - prev_close_box) / box_size) if box_diff == 0: @@ -1062,7 +995,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf # combine adjacent similarly signed differences boxes, indexes = combine_adjacent(boxes) new_volumes, new_dates = coalesce_volume_dates(temp_volumes, temp_dates, indexes) - + adjusted_boxes = [boxes[0]] temp_volumes, temp_dates = [new_volumes[0]], [new_dates[0]] volume_cache = 0 @@ -1098,7 +1031,7 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf boxes = [adjusted_boxes[0]] new_volumes = [temp_volumes[0]] new_dates = [temp_dates[0]] - + rolling_change = 0 volume_cache = 0 biggest_difference = 0 # only used for the last column @@ -1106,11 +1039,11 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf #Clean data to account for reversal size (added to allow overriding the default reversal of 1) for i in range(1, len(adjusted_boxes)): - # Add to rolling_change and volume_cache which stores the box and volume values + # Add to rolling_change and volume_cache which stores the box and volume values rolling_change += adjusted_boxes[i] volume_cache += temp_volumes[i] - # if rolling_change is the same sign as the previous box and the abs value is bigger than the + # if rolling_change is the same sign as the previous box and the abs value is bigger than the # abs value of biggest_difference then we should replace biggest_difference with rolling_change if rolling_change*boxes[-1] > 0 and abs(rolling_change) > abs(biggest_difference): biggest_difference = rolling_change @@ -1128,14 +1061,14 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf boxes.append(rolling_change) new_volumes.append(volume_cache) new_dates.append(temp_dates[i]) - + # reset rolling_change and volume_cache once we've used them rolling_change = 0 volume_cache = 0 - + # reset biggest_difference as we start from the beginning every time there is a reversal biggest_difference = 0 - + # Adjust the last box column if the left over rolling_change is the same sign as the column boxes[-1] += biggest_difference new_volumes[-1] += volume_cache @@ -1150,33 +1083,33 @@ def _construct_pointnfig_collections(dates, highs, lows, volumes, config_pointnf sign = (difference / abs(difference)) # -1 or 1 start_iteration = 0 if sign > 0 else 1 - + x = [index] * (diff) y = [curr_price + (i * box_size * sign) for i in range(start_iteration, diff+start_iteration)] curr_price += (box_size * sign * (diff)) box_values.append( y ) - + for i in range(len(x)): # x and y have the same length height = box_size * 0.85 width = 0.6 if height < 0.5: width = height - + padding = (box_size * 0.075) if sign == 1: # X line_seg.append([(x[i]-width/2, y[i] + padding), (x[i]+width/2, y[i]+height + padding)]) # create / part of the X line_seg.append([(x[i]-width/2, y[i]+height+padding), (x[i]+width/2, y[i]+padding)]) # create \ part of the X else: # O circle_patches.append(Ellipse((x[i], y[i]-(height/2) - padding), width, height)) - + useAA = 0, # use tuple here - lw = 0.5 + lw = 0.5 cirCollection = PatchCollection(circle_patches) cirCollection.set_facecolor([tfc] * len(circle_patches)) cirCollection.set_edgecolor([dc] * len(circle_patches)) - + xCollection = LineCollection(line_seg, colors=[uc] * len(line_seg), linewidths=lw, @@ -1194,7 +1127,7 @@ def _construct_aline_collections(alines, dtix=None): ---------- alines : sequence sequences of segments, which are sequences of lines, - which are sequences of two or more points ( date[time], price ) or (x,y) + which are sequences of two or more points ( date[time], price ) or (x,y) date[time] may be (a) pandas.to_datetime parseable string, (b) pandas Timestamp, or @@ -1284,7 +1217,7 @@ def _construct_hline_collections(hlines,minx,maxx): #print('hconfig=',hconfig) #print('hlines=',hlines) - + lines = [] if not isinstance(hlines,(list,tuple)): hlines = [hlines,] # may be a single price value @@ -1347,7 +1280,7 @@ def _construct_vline_collections(vlines,dtix,miny,maxy): #print('vconfig=',vconfig) #print('vlines=',vlines) - + if not isinstance(vlines,(list,tuple)): vlines = [vlines,] @@ -1430,7 +1363,7 @@ def _tline_lsq(dfslice,tline_use): https://mmas.github.io/least-squares-fitting-numpy-scipy ''' si = dfslice[tline_use].mean(axis=1) - s = si.dropna() + s = si.dropna() if len(s) < 2: err = 'NOT enough data for Least Squares' if (len(si) > 2): @@ -1467,7 +1400,7 @@ def _tline_lsq(dfslice,tline_use): alines.append((p1,p2)) del tconfig['alines'] - alines = dict(alines=alines,**tconfig) + alines = dict(alines=alines,**tconfig) alines['tlines'] = None return _construct_aline_collections(alines, dtix) @@ -1485,7 +1418,7 @@ class IntegerIndexDateTimeFormatter(Formatter): you would otherwise plot on that axis. Construct this formatter by providing the arrange of datetimes (as matplotlib floats). When the formatter receives an integer in the range, it will look up the - datetime and format it. + datetime and format it. """ def __init__(self, dates, fmt='%b %d, %H:%M'): @@ -1499,7 +1432,7 @@ def __call__(self, x, pos=0): # not sure what 'pos' is for: see # https://matplotlib.org/gallery/ticks_and_spines/date_index_formatter.html ix = int(np.round(x)) - + if ix >= self.len or ix < 0: date = None dateformat = '' diff --git a/src/mplfinance/plotting.py b/src/mplfinance/plotting.py index 0478e70f..14ef37dd 100644 --- a/src/mplfinance/plotting.py +++ b/src/mplfinance/plotting.py @@ -39,8 +39,7 @@ from mplfinance._arg_validators import _alines_validator, _tlines_validator from mplfinance._arg_validators import _scale_padding_validator, _yscale_validator from mplfinance._arg_validators import _valid_panel_id, _check_for_external_axes -from mplfinance._arg_validators import _xlim_validator -from mplfinance._arg_validators import _colors_validator +from mplfinance._arg_validators import _xlim_validator, _mco_validator from mplfinance._panels import _build_panels from mplfinance._panels import _set_ticks_on_bottom_panel_only @@ -50,8 +49,6 @@ from mplfinance._helpers import _num_or_seq_of_num from mplfinance._helpers import _adjust_color_brightness -from mplfinance._styles import make_marketcolors - VALID_PMOVE_TYPES = ['renko', 'pnf'] DEFAULT_FIGRATIO = (8.00,5.75) @@ -95,7 +92,7 @@ def _valid_plot_kwargs(): 2 specific keys: "Default", and "Validator" with the following values: "Default" - The default value for the kwarg if none is specified. "Validator" - A function that takes the caller specified value for the kwarg, - and validates that it is the correct type, and (for kwargs with + and validates that it is the correct type, and (for kwargs with a limited set of allowed values) may also validate that the kwarg value is one of the allowed values. ''' @@ -107,46 +104,46 @@ def _valid_plot_kwargs(): and all(isinstance(c, str) for c in value) }, 'type' : { 'Default' : 'ohlc', 'Validator' : lambda value: value in _get_valid_plot_types() }, - + 'style' : { 'Default' : None, 'Validator' : _styles._valid_mpf_style }, - + 'volume' : { 'Default' : False, 'Validator' : lambda value: isinstance(value,bool) or isinstance(value,mpl_axes.Axes) }, - + 'mav' : { 'Default' : None, 'Validator' : _mav_validator }, - + 'renko_params' : { 'Default' : dict(), 'Validator' : lambda value: isinstance(value,dict) }, 'pnf_params' : { 'Default' : dict(), 'Validator' : lambda value: isinstance(value,dict) }, - + 'study' : { 'Default' : None, - 'Validator' : lambda value: _kwarg_not_implemented(value) }, - - 'marketcolors' : { 'Default' : None, # use 'style' for default, instead. - 'Validator' : lambda value: isinstance(value,dict) }, - - 'override_marketcolors' : { 'Default' : None, # use default style instead. - 'Validator' : lambda value: _colors_validator(value) }, - + 'Validator' : lambda value: _kwarg_not_implemented(value) }, + + 'marketcolor_overrides' : { 'Default' : None, + 'Validator' : _mco_validator }, + + 'mco_faceonly' : { 'Default' : False, # If True: Override only the face of the candle + 'Validator' : lambda value: isinstance(value,bool) }, + 'no_xgaps' : { 'Default' : True, # None means follow default logic below: 'Validator' : lambda value: _warn_no_xgaps_deprecated(value) }, - - 'show_nontrading' : { 'Default' : False, + + 'show_nontrading' : { 'Default' : False, 'Validator' : lambda value: isinstance(value,bool) }, - + 'figscale' : { 'Default' : None, # scale base figure size up or down. 'Validator' : lambda value: isinstance(value,float) or isinstance(value,int) }, - + 'figratio' : { 'Default' : None, # aspect ratio; scaled to 8.0 height 'Validator' : lambda value: isinstance(value,(tuple,list)) and len(value) == 2 and isinstance(value[0],(float,int)) and isinstance(value[1],(float,int)) }, - + 'figsize' : { 'Default' : None, # figure size; overrides figratio and figscale 'Validator' : lambda value: isinstance(value,(tuple,list)) and len(value) == 2 @@ -155,32 +152,32 @@ def _valid_plot_kwargs(): 'fontscale' : { 'Default' : None, # scale all fonts up or down 'Validator' : lambda value: isinstance(value,float) or isinstance(value,int) }, - + 'linecolor' : { 'Default' : None, # line color in line plot 'Validator' : lambda value: mcolors.is_color_like(value) }, 'title' : { 'Default' : None, # Figure Title 'Validator' : lambda value: isinstance(value,(str,dict)) }, - + 'axtitle' : { 'Default' : None, # Axes Title (subplot title) 'Validator' : lambda value: isinstance(value,(str,dict)) }, - + 'ylabel' : { 'Default' : 'Price', # y-axis label 'Validator' : lambda value: isinstance(value,str) }, - + 'ylabel_lower' : { 'Default' : None, # y-axis label default logic below 'Validator' : lambda value: isinstance(value,str) }, - - 'addplot' : { 'Default' : None, + + 'addplot' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,dict) or (isinstance(value,list) and all([isinstance(d,dict) for d in value])) }, - - 'savefig' : { 'Default' : None, + + 'savefig' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,dict) or isinstance(value,str) or isinstance(value, io.BytesIO) or isinstance(value, os.PathLike) }, - - 'block' : { 'Default' : None, + + 'block' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,bool) }, - - 'returnfig' : { 'Default' : False, + + 'returnfig' : { 'Default' : False, 'Validator' : lambda value: isinstance(value,bool) }, 'return_calculated_values' : {'Default' : None, @@ -188,29 +185,29 @@ def _valid_plot_kwargs(): 'set_ylim' : {'Default' : None, 'Validator' : lambda value: _warn_set_ylim_deprecated(value) }, - + 'ylim' : {'Default' : None, - 'Validator' : lambda value: isinstance(value, (list,tuple)) and len(value) == 2 + 'Validator' : lambda value: isinstance(value, (list,tuple)) and len(value) == 2 and all([isinstance(v,(int,float)) for v in value])}, - + 'xlim' : {'Default' : None, 'Validator' : lambda value: _xlim_validator(value) }, - + 'set_ylim_panelB' : {'Default' : None, 'Validator' : lambda value: _warn_set_ylim_deprecated(value) }, - - 'hlines' : { 'Default' : None, + + 'hlines' : { 'Default' : None, 'Validator' : lambda value: _hlines_validator(value) }, - - 'vlines' : { 'Default' : None, + + 'vlines' : { 'Default' : None, 'Validator' : lambda value: _vlines_validator(value) }, - 'alines' : { 'Default' : None, + 'alines' : { 'Default' : None, 'Validator' : lambda value: _alines_validator(value) }, - - 'tlines' : { 'Default' : None, + + 'tlines' : { 'Default' : None, 'Validator' : lambda value: _tlines_validator(value) }, - + 'panel_ratios' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,(tuple,list)) and len(value) <= 10 and all([isinstance(v,(int,float)) for v in value]) }, @@ -237,7 +234,7 @@ def _valid_plot_kwargs(): 'Validator' : lambda value: isinstance(value,bool) }, 'fill_between' : { 'Default' : None, - 'Validator' : lambda value: _num_or_seq_of_num(value) or + 'Validator' : lambda value: _num_or_seq_of_num(value) or (isinstance(value,dict) and 'y1' in value and _num_or_seq_of_num(value['y1'])) }, @@ -258,8 +255,8 @@ def _valid_plot_kwargs(): 'saxbelow' : { 'Default' : True, # Issue#115 Comment#639446764 'Validator' : lambda value: isinstance(value,bool) }, - - 'scale_padding' : { 'Default' : 1.0, # Issue#193 + + 'scale_padding' : { 'Default' : 1.0, # Issue#193 'Validator' : lambda value: _scale_padding_validator(value) }, 'ax' : { 'Default' : None, @@ -300,7 +297,7 @@ def plot( data, **kwargs ): # translate alias types: config['type'] = _get_valid_plot_types(config['type']) - + dates,opens,highs,lows,closes,volumes = _check_and_prepare_data(data, config) config['xlim'] = _check_and_convert_xlim_configuration(data, config) @@ -375,7 +372,7 @@ def plot( data, **kwargs ): fmtstring = _determine_format_string(dates, config['datetime_format']) - ptype = config['type'] + ptype = config['type'] if config['show_nontrading']: formatter = mdates.DateFormatter(fmtstring) @@ -397,21 +394,14 @@ def plot( data, **kwargs ): rwc = config['return_width_config'] if isinstance(rwc,dict) and len(rwc)==0: config['return_width_config'].update(config['_width_config']) - - if config['override_marketcolors']: - override_marketcolors = config['override_marketcolors'] - for c in range(len(override_marketcolors)): - if isinstance(override_marketcolors[c], str): - config['override_marketcolors'][c] = make_marketcolors(up=override_marketcolors[c], down=override_marketcolors[c], edge=override_marketcolors[c], wick=override_marketcolors[c], ohlc=override_marketcolors[c], volume=override_marketcolors[c]) - else: - config['override_marketcolors'] = None + collections = None if ptype == 'line': lw = config['_width_config']['line_width'] axA1.plot(xdates, closes, color=config['linecolor'], linewidth=lw) else: - collections =_construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style,config['override_marketcolors']) + collections =_construct_mpf_collections(ptype,dates,xdates,opens,highs,lows,closes,volumes,config,style) if ptype in VALID_PMOVE_TYPES: collections, calculated_values = collections @@ -498,7 +488,7 @@ def plot( data, **kwargs ): if len(mav) != len(mavprices): warnings.warn('len(mav)='+str(len(mav))+' BUT len(mavprices)='+str(len(mavprices))) else: - for jj in range(0,len(mav)): + for jj in range(0,len(mav)): retdict['mav' + str(mav[jj])] = mavprices[jj] retdict['minx'] = minx retdict['maxx'] = maxx @@ -525,7 +515,7 @@ def plot( data, **kwargs ): tlines = [tlines,] for tline_item in tlines: line_collections.append(_construct_tline_collections(tline_item, dtix, dates, opens, highs, lows, closes)) - + for collection in line_collections: if collection is not None: axA1.add_collection(collection) @@ -561,7 +551,7 @@ def plot( data, **kwargs ): axA1.set_yscale(yscale,**ysd) elif isinstance(ysd,str): axA1.set_yscale(ysd) - + addplot = config['addplot'] if addplot is not None and ptype not in VALID_PMOVE_TYPES: @@ -595,7 +585,7 @@ def plot( data, **kwargs ): for apdict in addplot: - panid = apdict['panel'] + panid = apdict['panel'] if not external_axes_mode: if panid == 'main' : panid = 0 # for backwards compatibility elif panid == 'lower': panid = 1 # for backwards compatibility @@ -606,11 +596,11 @@ def plot( data, **kwargs ): if aptype == 'ohlc' or aptype == 'candle': ax = _addplot_collections(panid,panels,apdict,xdates,config) _addplot_apply_supplements(ax,apdict) - else: + else: apdata = apdict['data'] if isinstance(apdata,list) and not isinstance(apdata[0],(float,int)): raise TypeError('apdata is list but NOT of float or int') - if isinstance(apdata,pd.DataFrame): + if isinstance(apdata,pd.DataFrame): havedf = True else: havedf = False # must be a single series or array @@ -636,7 +626,7 @@ def plot( data, **kwargs ): fb['x'] = xdates ax = panels.at[panid,'axes'][0] ax.fill_between(**fb) - + # put the primary axis on one side, # and the twinx() on the "other" side: if not external_axes_mode: @@ -653,14 +643,14 @@ def plot( data, **kwargs ): # TODO: =========== # TODO: It appears to me that there may be some or significant overlap # TODO: between what the following functions actually do: - # TODO: At the very least, all four of them appear to communicate + # TODO: At the very least, all four of them appear to communicate # TODO: to matplotlib that the xaxis should be treated as dates: # TODO: -> 'ax.autoscale_view()' # TODO: -> 'ax.xaxis_dates()' # TODO: -> 'plt.autofmt_xdates()' # TODO: -> 'fig.autofmt_xdate()' # TODO: ================================================================ - + #if config['autofmt_xdate']: #print('CALLING fig.autofmt_xdate()') @@ -671,7 +661,7 @@ def plot( data, **kwargs ): # for `addplot`, that this IS necessary when the only thing done to the # the axes is .add_collection(). (However, if ax.plot() .scatter() or # .bar() was called, then possibly this is not necessary; not entirely - # sure, but it definitely was necessary to get 'ohlc' and 'candle' + # sure, but it definitely was necessary to get 'ohlc' and 'candle' # working in `addplot`). axA1.set_ylabel(config['ylabel']) @@ -727,7 +717,7 @@ def plot( data, **kwargs ): offset = '\n'+offset vol_label = config['ylabel_lower'] + offset volumeAxes.set_ylabel(vol_label) - + if config['title'] is not None: if config['tight_layout']: # IMPORTANT: `y=0.89` is based on the top of the top panel @@ -747,8 +737,8 @@ def plot( data, **kwargs ): else: title = config['title'] # config['title'] is a string fig.suptitle(title,**title_kwargs) - - + + if config['axtitle'] is not None: axA1.set_title(config['axtitle']) @@ -784,10 +774,10 @@ def plot( data, **kwargs ): if config['closefig']: # True or 'auto' plt.close(fig) elif not config['returnfig']: - plt.show(block=config['block']) # https://stackoverflow.com/a/13361748/1639359 + plt.show(block=config['block']) # https://stackoverflow.com/a/13361748/1639359 if config['closefig'] == True or (config['block'] and config['closefig']): plt.close(fig) - + if config['returnfig']: if config['closefig'] == True: plt.close(fig) return (fig, axlist) @@ -852,7 +842,7 @@ def _addplot_collections(panid,panels,apdict,xdates,config): apdata = apdict['data'] aptype = apdict['type'] external_axes_mode = apdict['ax'] is not None - + #--------------------------------------------------------------# # Note: _auto_secondary_y() sets the 'magnitude' column in the # `panels` dataframe, which is needed for automatically @@ -871,18 +861,18 @@ def _addplot_collections(panid,panels,apdict,xdates,config): if not isinstance(apdata,pd.DataFrame): raise TypeError('addplot type "'+aptype+'" MUST be accompanied by addplot data of type `pd.DataFrame`') d,o,h,l,c,v = _check_and_prepare_data(apdata,config) - collections = _construct_mpf_collections(aptype,d,xdates,o,h,l,c,v,config,config['style'],config['override_marketcolors']) + collections = _construct_mpf_collections(aptype,d,xdates,o,h,l,c,v,config,config['style']) if not external_axes_mode: lo = math.log(max(math.fabs(np.nanmin(l)),1e-7),10) - 0.5 hi = math.log(max(math.fabs(np.nanmax(h)),1e-7),10) + 0.5 secondary_y = _auto_secondary_y( panels, panid, lo, hi ) if 'auto' != apdict['secondary_y']: - secondary_y = apdict['secondary_y'] + secondary_y = apdict['secondary_y'] if secondary_y: - ax = panels.at[panid,'axes'][1] + ax = panels.at[panid,'axes'][1] panels.at[panid,'used2nd'] = True - else: + else: ax = panels.at[panid,'axes'][0] else: ax = apdict['ax'] @@ -908,9 +898,9 @@ def _addplot_columns(panid,panels,ydata,apdict,xdates,config): #print("apdict['secondary_y'] says secondary_y is",secondary_y) if secondary_y: - ax = panels.at[panid,'axes'][1] + ax = panels.at[panid,'axes'][1] panels.at[panid,'used2nd'] = True - else: + else: ax = panels.at[panid,'axes'][0] else: ax = apdict['ax'] @@ -999,7 +989,7 @@ def _plot_mav(ax,config,xdates,prices,apmav=None,apwidth=None): mavgs = mavgs, # convert to tuple if len(mavgs) > 7: mavgs = mavgs[0:7] # take at most 7 - + if style['mavcolors'] is not None: mavc = cycle(style['mavcolors']) else: @@ -1049,8 +1039,8 @@ def _valid_addplot_kwargs(): 'mav' : { 'Default' : None, 'Validator' : _mav_validator }, - - 'panel' : { 'Default' : 0, + + 'panel' : { 'Default' : 0, 'Validator' : lambda value: _valid_panel_id(value) }, 'marker' : { 'Default' : 'o', @@ -1066,7 +1056,7 @@ def _valid_addplot_kwargs(): 'linestyle' : { 'Default' : None, 'Validator' : lambda value: value in valid_linestyles }, - 'width' : { 'Default' : None, # width of `bar` or `line` + 'width' : { 'Default' : None, # width of `bar` or `line` 'Validator' : lambda value: isinstance(value,(int,float)) or all([isinstance(v,(int,float)) for v in value]) }, @@ -1082,12 +1072,12 @@ def _valid_addplot_kwargs(): 'y_on_right' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,bool) }, - + 'ylabel' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,str) }, 'ylim' : {'Default' : None, - 'Validator' : lambda value: isinstance(value, (list,tuple)) and len(value) == 2 + 'Validator' : lambda value: isinstance(value, (list,tuple)) and len(value) == 2 and all([isinstance(v,(int,float)) for v in value])}, 'title' : { 'Default' : None, @@ -1100,7 +1090,7 @@ def _valid_addplot_kwargs(): 'Validator' : lambda value: _yscale_validator(value) }, 'stepwhere' : { 'Default' : 'pre', - 'Validator' : lambda value : value in valid_stepwheres }, + 'Validator' : lambda value : value in valid_stepwheres }, } _validate_vkwargs_dict(vkwargs) @@ -1112,7 +1102,7 @@ def make_addplot(data, **kwargs): ''' Take data (pd.Series, pd.DataFrame, np.ndarray of floats, list of floats), and kwargs (see valid_addplot_kwargs_table) and construct a correctly structured dict - to be passed into plot() using kwarg `addplot`. + to be passed into plot() using kwarg `addplot`. NOTE WELL: len(data) here must match the len(data) passed into plot() ''' if not isinstance(data, (pd.Series, pd.DataFrame, np.ndarray, list)): From def4e86e5452ed27908d2c68449319ba9be68caf Mon Sep 17 00:00:00 2001 From: Daniel Goldfarb Date: Thu, 9 Dec 2021 13:05:19 -0500 Subject: [PATCH 08/11] clean up test code --- examples/scratch_pad/pr451_test.py | 29 ++++ examples/scratch_pad/pr451_testing.ipynb | 180 +++++++++++++++++++++++ examples/scratch_pad/pr451data.csv | 124 ++++++++++++++++ src/Figure_1.png | Bin 59649 -> 0 bytes src/mplfinance/_version.py | 2 +- src/trial.py | 45 ------ 6 files changed, 334 insertions(+), 46 deletions(-) create mode 100644 examples/scratch_pad/pr451_test.py create mode 100644 examples/scratch_pad/pr451_testing.ipynb create mode 100644 examples/scratch_pad/pr451data.csv delete mode 100644 src/Figure_1.png delete mode 100644 src/trial.py diff --git a/examples/scratch_pad/pr451_test.py b/examples/scratch_pad/pr451_test.py new file mode 100644 index 00000000..40b60e6c --- /dev/null +++ b/examples/scratch_pad/pr451_test.py @@ -0,0 +1,29 @@ +import pandas as pd +import mplfinance as mpf +import ast + +df = pd.read_csv('pr451data.csv',index_col=0,parse_dates=True) + +print(df.head(3)) + +custom_colors = [] +for i in range(len(df)): + if i % 3 == 0: + #custom_colors.append(mpf.make_marketcolors(up='#29c9ff', down='#f3b5ff', edge='#29c9ff', wick='#29c9ff', ohlc='#32a852', volume='#a89132')) + custom_colors.append(mpf.make_marketcolors(up='#29c9ff',down='#f3b5ff',edge='#29c9ff',wick='#29c9ff', + ohlc={'up':'lime','down':'blue'}, volume='#a89132')) + elif i%5 == 0: + custom_colors.append("#000000") + else: + custom_colors.append(None) + +STYLE = 'binance' +STYLE = 'yahoo' + +#mpf.plot(df, type='candle',style=STYLE,volume=True,block=False,figscale=1.25,savefig='pr451t2no.jpg') +mpf.plot(df, type='ohlc',style=STYLE,volume=True,block=False,figscale=1.25) +#mpf.plot(df, type='hollow',style=STYLE,volume=True,block=False,figscale=1.25) + +#mpf.plot(df, type='candle',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25,savefig='pr451t2ye.jpg') +mpf.plot(df, type='ohlc',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25) +#mpf.plot(df, type='hollow',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25) diff --git a/examples/scratch_pad/pr451_testing.ipynb b/examples/scratch_pad/pr451_testing.ipynb new file mode 100644 index 00000000..6e517a9d --- /dev/null +++ b/examples/scratch_pad/pr451_testing.ipynb @@ -0,0 +1,180 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "\n", + "## PR451 Testing\n", + "\n", + "---" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# This allows multiple outputs from a single jupyter notebook cell:\n", + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "%matplotlib inline\n", + "import pandas as pd\n", + "import mplfinance as mpf\n", + "#import datetime as datetime\n", + "#import numpy as np\n", + "#import matplotlib.dates as mdates\n", + "#import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " Open Close High Low Date.1 Volume\n", + "Date \n", + "2019-09-01 29 20 29 20 2019-09-01 10787\n", + "2019-09-02 29 31 33 23 2019-09-02 17215\n", + "2019-09-03 29 20 29 20 2019-09-03 16697\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAp0AAAHcCAYAAACUORFqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAA9hAAAPYQGoP6dpAABWfUlEQVR4nO3de3wTdf7v8XeS0guXXii2gNACUgtYBNYtLKiARXRVRBZYXRTQVcTLHtdVuQmiIivKT3S9IIoo608RUS7rBVbAgwjeVpEVBQRsD1BEoeXWlgKlbTLnj9pIek2amSZpX8/Hg0fp5DvTbz6ZmbwzmZmvzTAMQwAAAICF7IHuAAAAABo+QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAy4V508jlcrn/b7PZLOsMAABAsDhz/By7neN0/vIqdErS8ePHrewHAABAUGrRokWgu9AgeB06JSkyMjLoj3Q6nU5lZmYqJSVFDocj0N0JedTTfNTUXNTTfNTUfNTUXPVVT8MwVFRUZNnyGxuvQmd50LTZbEEfOm02mwzDCIm+hgLqaT5qai7qaT5qaj5qaq76rievmTk4QQEAAACWI3QCAADAcoROAAAAWI7QCQAAAMsROgEAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAEJAXl6e3nvvPeXl5QW6K0CdEDoBAAgB+fn5WrlypfLz8wPdFaBOCJ0AAACwHKETAAAAliN0AgAAwHKETgAAAFiO0AkAAADLEToBAABgOUInAAAALEfoBAAAgOUInQAAALAcoRMAAACWI3QCAADAcoROAAAAWI7QCQAAAMsROgEAAGA5QicAAAAsR+gEAAAwwSuvvKILL7xQSUlJSkpK0mWXXaYPP/zQ/fiQIUMUFxfn8e+ee+4JYI/rV1igOwAAANAQtG3bVg899JDOOeccGYahN998UzfccIM2bNigrl27SpJuvPFG3X///e55oqKiAtXdekfoBAAAMMEVV1zh8fv06dO1cOFCff311+7QGRUVpcTExEB0L+D4eh0AAMBkTqdTy5cv18mTJ5Wenu6evnTpUp1zzjnq27evZsyYoZMnTwawl/XLpyOdTqdTNpvNqr6Ywul0evyEf6in+aipuain+aip+cyoqcvlcv9s7K9Nfa2jhmFIkgoKCjzyT0REhCIiIqqcZ/v27br88stVVFSkZs2a6fXXX1eXLl0kSSNHjlT79u3VunVrbd++XTNmzFBWVpZef/11S59HsLAZ5RWtgWEYKigoUHZ2trxoDgAATJabm6vFixfr+uuvV0JCQqC70yjYbDYlJycrLS1NhYWF7umTJ0/WlClTqpynuLhY+/fvV0FBgd599129/vrrWrlypTt4nmnjxo265ppr9N///lcdO3a07HkEC5+OdKakpITEkc6srCx17txZDocj0N0JedTTfNTUXNTTfNTUfGbUtPyCk+TkZCUlJZnZvZBTX+uoYRgqLi7Wtm3bKh3prE54eLg6deokSerZs6e++eYbvfjii3r66acrtb3gggskSbt37yZ0VuRwOII+dJZzOBzsLE1EPc1HTc1FPc1HTc3nT03tdrv7J69LGavX0fJvd6Ojo+ucf1wul4qLi6t8bOvWrZLUaC4s4up1AAAAE8yYMUOXXnqp2rdvr+PHj2vZsmX69NNPtXz5cu3Zs0fLli3T4MGD1bJlS23btk3Tpk1Tv379lJaWFuiu1wtCJwAAgAkOHz6sO+64Qzk5OYqOjtZ5552n5cuX65JLLtH+/fv18ccf64UXXtDJkyd19tln6+qrr9aECRMC3e16Q+gEAAAwwXPPPVftY+3atdOqVavqsTfBh/t0AgAAwHKETgAAAFiO0AkAAADLEToBAABgOUInAACNRF5ent577z3l5eUFuitohAidAAA0Evn5+Vq5cqXy8/MD3RU0QoROAAAAWI7QCQAAAMsROgEAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByYYHuAAAAqGDfPunkSc9pOTllP/fulU6d+nV606ZSUlK9dQ2oK0JnBXl5edq4caP69++v2NjYQHcHANDY7NunsJHXVpocHxamoa3iFX//NIWVlno8VrrsbYIngh5fr1fAEGEAgICqeITzF7GlpRp2MEexFQJnTfMAwYTQCQAAAMsROgEAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6AQCA1/Ly8vTee+8pLy8vIPMjdBE6AQCA1/wdLprhphsvQicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6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K8LPq/dQhnqaj5qai3qaj5qaj5qai3qGJq8uJAIAAAD80eCOdAIAACD4EDoBAABgOUInAAAALEfoBAAAgOUInTAV16Uh2J05whoQrNiXoiFq1KGTjdpcn376qdasWaOSkpJAd6VBYT01z7p16/TGG2/o9OnTge5Kg8I6ai72pWioGmXo3L59u3Jzc2Wz2dhZmuT111/X6NGjlZubq2PHjknijchfX3/9tfbt28d6apLXX39dN998s06fPq0jR464p1PbumNfaj72pWjIGl3oXLp0qa666io9++yzysnJYWdpgnXr1mn69Ol64oknNHbsWCUkJEiSnE6nJL7OrIvly5fryiuv1NSpU7V3717WUz998sknmjFjhp544gmNGzdOrVu3liSVlpYytnIdsS81H/tSNHSN6ubwn332mf72t78pPj5epaWluvjii3X77bcrMTFRhmHw5uOj8prNnDlThw8f1jPPPKOsrCy9+OKLOnDggMLDw/Xggw+qY8eOge5qSPniiy903333KSkpSadOnVJ8fLwefPBBdejQgfXUR+X1evbZZ/Xtt9/qlVde0Q8//KAnnnhCOTk5On36tB544AH17dtXYWFhge5uyGBfai72pWgsGs2RTsMw9P/+3/9T9+7d9c9//lOXX365PvroI7344ot8SvfTnj17dM455+jEiRMaMmSITp8+rfj4eB09elQDBgzQ119/LYlP6d46cOCAOnTooMcff1zXXXedcnJy9Mgjj7iPeFJH75WHn5ycHCUmJqqwsFDXXHONmjdvrr59+6p9+/YaOXKk3n33XUmso95gX2od9qVo6BrNR3ubzaahQ4fq/PPPV5s2bTRx4kQ5nU598MEHkqTbbrvN/ZUbn9S9U16jxMREvf/++zIMQ5deeqmee+45SVJxcbH+8pe/aNy4cfrkk0/UokWLQHY3ZAwfPlwpKSnq0KGDOnToIKfTqSVLluiRRx7R9OnT3Uc7ytdTl8slu73RfH6sk7i4OL322mtKTU1VRkaG/vGPf7gfmz59uqZMmaIBAwaoVatWAexlaGBfaj72pWgsGtU7VUxMjHr27On+FD5lyhRdeeWV+uijjzR//nwdOnRIJ06c0JQpU5Sfnx/g3oaOa665RlFRUXrjjTfUrFkzSWXnIIWHh+uWW26R0+nU/v37A9zL4FW+Pp559KJ79+7u/48ZM0Z/+tOfdPDgQc2cOVP79u1TUVGRbrnlFh07dozAWUF5PQ3DcP9/9OjRSk5O1uOPP66CggJJZW/kknTrrbcqPDxcu3btCkyHQ1BsbKx69uzp/p19qTmGDh2qpk2bsi9Fg9Wgj3R+9tln+v7779WkSROdf/75+s1vfiOp7FNlaWmpwsLCNHnyZEnS6tWrVVRUpK+++kpHjx7VrFmzAtn1oFVVTXv27Knzzz9fX3zxhZo1a6aSkhI1adJEktSiRQvFxsbK4XAEuOfB6+DBg2rTpo3sdnulI0PlRzHHjBkjm82mJUuWaNq0afrpp5+UnZ3NEY8qlNfzzK95W7VqpSuvvFLPP/+8tm/frhMnTrjf1A3DUFxcnKKiogLZ7aD23Xffaffu3XI4HOratas6d+7sfqx8HWVf6puqatqjRw9169ZNX3zxhb766iv2pWh4jAbqtddeM5KSkoxLL73U6NOnj5GQkGDMmTPHyMvLc7cpKSlx///BBx804uLijIEDBxrFxcWGYRhGaWlpvfc7mFVV0yeeeMJwOp3GyZMnjcmTJxsdO3Y0/vCHPxg7duww/vvf/xrXX3+9MXz4cMPpdAa6+0Hp7bffNjp37mwsWbLEPc3lcnm0ObN28+bNM+Li4oxBgwaxnlahqnqWb+enTp0ynn32WaNz585G7969jfXr1xv/9//+X+P66683rrrqKtbRarz++utGWlqaceGFFxrnn3++cfnllxvffvutR5sz10H2pbWrqqb//e9/DcMwjMLCQmPSpElGp06d2JeiwWmQofOHH34wunXrZixdutQwDMM4dOiQsXDhQiM+Pt647777jCNHjrjbulwuIy8vz7jiiiuMQYMGud+gzgykqLmmd999t1FcXGycOnXKeOmll4yMjAzjrLPOMvr162f8/ve/d7/xsLP0tH79eqNLly7GgAEDjL59+xpvvfWW+7GKwbN8Pb3yyiuN/v37s55WoaZ6ltfp9OnTxtq1a40RI0YYycnJxoUXXmgMGzaMdbQa77//vpGcnGwsW7bMKCgoMD755BNj+PDhxnPPPWcYhud6yr7UO7XV1DAM4+TJk+xL0SA1yNC5Y8cOo1evXsbOnTs9pv/73/824uPjjRkzZhiG8esO89VXXzXOOecc9wbNTrKy2mr64IMPGobx6xGN//73v8aePXvcO0dq6qmwsNC46667jLvvvtv45JNPjHvuucfo3bu3R1Cq+MayfPlyo2/fvqynVfCmnhXrlZmZaeTm5rKOViM3N9e4/vrrjccee8xj+j333GP8/ve/r3Ie9qU186am5etj+fsT+1I0JA3ynE6Xy6Xs7GwdOHBAqampcjqdstlsuuKKK/TCCy/otttuU9++fTV48GBJ0o033qgxY8bIbre7z/WEJ29q2q9fP11++eWSpF69ennMS009NWvWTLfccosOHTqkiy66SK1atZJhGHryySclSddee22lczyHDx+uP/zhDx7nJKOMN/UMCwuTy+WSzWaTzWZTp06d3BdhsY5WZrfb1aVLF/Xt21fSr+du9u7dW9u3b5dU+ep09qU186am5fUs/9mjRw/WUzQYDfKy127dumnUqFGaPn26duzY4T7x2ul06o9//KOuvvpqvffee3I6ne6xbcvf4Nmgq+ZNTVeuXCmn01npHnJcXV21Hj166NJLL5UkdenSRePHj1e/fv00Z84cvf3225Kkw4cPa82aNe55yi+OYT2tzJt6HjlyRGvXrpXkuV6yjlYWHx+vG2+8UQMGDJD0awhq2bKlJM/RnHbs2OGej31p9epSU9ZTNCQNdq9w3XXX6aefftLMmTP10EMPKTU11X0la3R0tAoKCuRwODyuBOR+cjXztqbwTfnRoq5du+rWW2+VzWbTU089pePHj2vp0qU6cuSILrvsskpHQFA1X+uJ6iUlJUnyPKKZl5engoICd6gcMWKEioqKtGrVKvd81LZ6da0p0BA02I9NF198sUaNGqXCwkLdd999+uabb2Sz2XTy5En9+OOPatOmTaC7GHKoqTXOfIPu1q2bbrvtNl1wwQWaOHGiTp8+rc8//5xRXnxAPc1XMURGRERIKjtt4ccff9Q777wTgF6FNmqKxqhBHuks/wR57bXXqkWLFnrrrbc0aNAg9ezZU6dOnZLNZtPSpUs92qJm1LT+nH322frmm2/Uq1cvrVmzRmFhYZwf5wfqaa6EhASFh4frqquu0oEDB/Tll1+qSZMm1NQP1BSNRciuzeXB5syAU35S9plDA15xxRW66KKLdN111yk7O1vNmjXTqFGjeOOpAjU1X001rUpJSYkefvhhGYah1atXU9MKqKf5fK3psWPH9PXXX+v8888nHFWDmgJVsxkh+B3TmRvvoUOHFBUVpWbNmlU6ulbTETen08n5h2egpubztqYV7dixQ+eee64cDgdvPGegnuarS023bt2qt956Sw8//DAhvgrUFKheSIbOco899pjee+892e12tWrVSo899pi6du3KV7t+oKbmq2tNCfFVo57mq2tNCUfVo6ZAZSF1IdGZt+JZvHix5s+fr9tvv1033XST7Ha7hgwZ4r4dSghn6XpFTc1nVk0JSGWop/nqWtOK9SUc/YqaArULySOdq1ev1n//+1917NhRo0aNck+/4447tHbtWn322Wdq3bp1AHsYeqip+aipuain+aip+agpUL2QOtIpSd98842mT5+uuXPnur+mKC4uliS98MILOvvss/Xcc88Fsoshh5qaj5qai3qaj5qaj5oCNQv60FnxQGynTp10yy23KC4uzj3KSHh4uEpLS+V0OtW2bVsVFRUFoqshg5qaj5qai3qaj5qaj5oCvgnq0Fk+TnK5EydOKCYmRjfddJPuu+8+7d27V+PHj5dUdh6Mw+HQoUOH3DfZRWXU1HzU1FzU03zU1HzUFPBd0J7TeeZtJ+bOnastW7bou+++05gxYzR48GClpKRo4cKFevrppxUbG6tzzz1XdrtdW7Zs0ZdffsnJ2FWgpuajpuainuajpuajpkAdGUHu4YcfNs4991zj+eefN/75z38aycnJxpgxY4zjx48bx48fNxYsWGD89re/NX73u98Z69evd89XUlISuE4HOWpqPmpqLuppPmpqPmoK+CaoP2598803WrlypRYtWqT09HR98803Kiws1JVXXqnmzZtLkm644Qa5XC69/fbbWrFihQYOHCip8ri2KENNzUdNzUU9zUdNzUdNgToIdOo9U1FRkcfvmzdvNjIyMgzDMIwVK1YY7dq1M15++WXDMAzj+PHjxkcffWQYhmEUFBQY8+fPNwYOHGj8+c9/rt9OBzlqaj5qai7qaT5qaj5qCvgvaC4k+uijjzR//nxt3rzZPa24uFgHDx7Ua6+9pr/97W966KGHdMstt0iSNm/erIULF+qHH35QixYtdP3112vYsGE6ePCgDh48GKinEVSoqfmoqbmop/moqfmoKWCSQKdewzCMRYsWGd26dTPuvfdeY/PmzR6P3XLLLUZcXJwxe/Zs97SioiLjuuuuM8aOHWs4nU739OPHjxvHjh2rr24HNWpqPmpqLuppPmpqPmoKmCfg53QuX75ckyZN0ty5czVo0CBFR0d7PD5+/Hjl5uZq8eLFSkpKUl5enj788EP9/PPP2rhxo+x2u/vWFeXn0TR21NR81NRc1NN81NR81BQwV0BvmXT48GH9+c9/1tChQ3Xrrbe6pxcWFmrnzp0KCwtTz549lZWVpaeffloff/yxOnXqpA4dOuipp55SWFiYSktLuf3EGaip+aipuain+aip+agpYL6Abw2HDx9W27Zt3b+/8sor+uSTT/Tee+8pISFBqampevfddzV37lwdOXJE8fHx7rZs0FWjpuajpuainuajpuajpoC5An4hUUFBgdauXauNGzfqxhtv1MKFCxUfH6/ly5dr9uzZys7O1hNPPCFJiomJcc9nGAYbdDWoqfmoqbmop/moqfmoKWCugG4VrVq10rx58zR27Fht3LhRzZs312OPPaa0tDS1bNlSeXl5io6OltPpLOvsGRsx9zmrGjU1HzU1F/U0HzU1HzUFzBfwj2IDBgzQ5s2bdeLECSUnJ1d6vHnz5mrdunUAeha6qKn5qKm5qKf5qKn5qClgrqAde/3w4cP6y1/+oqNHj2r16tVyOByB7lLIo6bmo6bmop7mo6bmo6ZA3QT8SGdFR44c0Wuvvab//Oc/Onz4sHuDdjqdbNh1RE3NR03NRT3NR03NR00B/wT8QqKKfv75Z3355Zfq1KmT1qxZoyZNmqi0tJQN2g/U1HzU1FzU03zU1HzUFPBPUH69np+fr+joaNlsNj5BmoSamo+amot6mo+amo+aAnUXlKGznGEYXAVoMmpqPmpqLuppPmpqPmoK+C6oQycAAAAahqA7pxMAAAAND6ETAAAAliN0AgAAwHKETgAAAFiO0AkAAADLEToBAABgOUInAAAALEfoBAAAgOUInQAAALAcoRMAAACW+/8YGgsZjss0lQAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAp0AAAHcCAYAAACUORFqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAA9hAAAPYQGoP6dpAABY00lEQVR4nO3de3wU9f3v8ffu5g7kQiABhCwgMVyCQG2g4AUE0aqIFKgWBbSKeOmxVuWOqEhF+YnUC6KIpf4qIsqlXqAKHkTw0ipSUUDA5ABBLCRcE0IISXbn/IFZ2Vx3szPZTfJ6Ph48lsx+Z/Ldz87MvjM7M1+bYRiGAAAAAAvZg90BAAAANHyETgAAAFiO0AkAAADLEToBAABgOUInAAAALEfoBAAAgOUInQAAALAcoRMAAACWC/Olkdvt9vzfZrNZ1hkAAIBQce74OXY7x+kC5VPolKSTJ09a2Q8AAICQ1KxZs2B3oUHwOXRKUlRUVMgf6XS5XMrMzFRqaqocDkewu1PvUU/zUVNzUU/zUVPzUVNz1VU9DcNQUVGRZctvbHwKnWVB02azhXzotNlsMgyjXvS1PqCe5qOm5qKe5qOm5qOm5qrrevKemYMTFAAAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6AQAAYDlCJwAAACxH6AQAoB44ceKE3n33XZ04cSLYXQFqhdAJAEA9kJeXp9WrVysvLy/YXQFqhdAJAAAAyxE6AQAAYDlCJwAAACxH6AQAAIDlCJ0AAACwHKETAAAAliN0AgAAwHKETgAAAFiO0AkAAADLEToBAABgOUInAAAALEfoBAAAgOUInQAAALAcoRMAAACWI3QCAADAcoROAAAAE/z1r3/VxRdfrJSUFKWkpOjKK6/Uhx9+6Hl+yJAhSkhI8Pp3//33B7HHdSss2B0AAABoCNq0aaNHHnlE559/vgzD0BtvvKGbb75ZGzduVJcuXSRJt9xyi6ZOneqZJzo6OljdrXOETgAAABNcffXVXj/PmDFDixcv1ldffeUJndHR0UpOTg5G94KOr9cBAABM5nK5tHLlShUWFiojI8Mzffny5Tr//PPVt29fzZw5U4WFhUHsZd3y60iny+WSzWazqi+mcLlcXo8IDPU0HzU1F/U0HzU1nxk1dbvdnsfG/t7U1TpqGIYkKT8/3yv/REZGKjIystJ5duzYoauuukpFRUVq0qSJXnvtNXXu3FmSNHLkSLVr106tWrXSjh07NHPmTGVlZem1116z9HWECptRVtFqGIah/Px8ZWdny4fmAADAZLm5uVq6dKluuukmJSUlBbs7jYLNZpPT6VR6eroKCgo80ydPnqwpU6ZUOk9xcbEOHDig/Px8vfPOO3rttde0evVqT/A816ZNm3T99dfrP//5jzp06GDZ6wgVfh3pTE1NrRdHOrOystSpUyc5HI5gd6feo57mo6bmop7mo6bmM6OmZRecOJ1OpaSkmNm9eqeu1lHDMFRcXKzt27dXONJZlYiICHXs2FGS1LNnT3399dd66aWX9Mwzz1Roe9FFF0mS9uzZQ+gsz+FwhHzoLONwONhZmoh6mo+amot6mo+ami+Qmtrtds8j78tZVq+jZd/uxsbG1jr/uN1uFRcXV/rctm3bJKnRXFjE1esAAAAmmDlzpq644gq1a9dOJ0+e1IoVK/Tpp59q5cqV2rt3r1asWKHBgwerefPm2r59u6ZPn65+/fopPT092F2vE4ROAAAAExw5ckR33323cnJyFBsbq27dumnlypW6/PLLdeDAAX388cd68cUXVVhYqPPOO0/XXXedJkyYEOxu1xlCJwAAgAmef/75Kp9r27at1qxZU4e9CT3cpxMAAACWI3QCAADAcoROAAAAWI7QCQAAAMsROgEAaCQOl0gvHrTrcEmwe4LGiNAJAEAjcaREeumQQ0cInQgCQicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6AQAAYLmwYHcAAACUs3+/VFjoPS0n5+zjvn3S6dM/T4+JkVJS6qxrQG0ROss5ceKENm3apMsuu0zx8fHB7g4AoLHZv19hI2+oMDkxLExDWyQqcep0hZWWej1XuuItgidCHl+vl5OXl6fVq1crLy8v2F0BADRG5Y9w/iS+tFTDDuUovlzgrG4eIJQQOgEAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6AQAAYDlCJwAA8NmJEyf07rvv6sSJE0GZH/UXoRMAAPgs0OGiGW668SJ0AgAAwHKETgAAAFiO0AkAAADLEToBAABgOUInAAAALEfoBAAAgOUInQAAALAcoRMAAACWCwt2B4It81SOCkqLPD8fLjgoSdpdcFDHyt23tmlYlFKbJNdl9wAACJ79+6XCQu9pOTlnH/ftk06f/nl6TIyUklJhEXzOokyjDp2Zp3LUbeMMr2nRRVJamvTm7sU6nV1xnh39Z7FBAAD8cvDgQb344ouaPHmy2rZtG+zu+Gb/foWNvKHC5MSwMA1tkajEqdMVVlrq9Vzpire8giefszhXo/56/dy/vMqcjpK2djn76Os8AABU59ChQ1q4cKEOHToU7K74rvwRzp/El5Zq2KEcxZcLnJXNw+csztWoQycAAADqBqETAAAAliN0AgAAwHKETgAAAFiO0AkAAADLEToBAABM8Ne//lUXX3yxUlJSlJKSoiuvvFIffvih5/mioiJNmDBBHTt2VNu2bTV27Fjl5uYGscd1i9AJAABggjZt2uiRRx7Rhg0b9NFHH+nSSy/VzTffrJ07d0qSpk2bpg8++ECvvvqqVq9erUOHDmnMmDFB7nXdadQ3hwcAADDL1Vdf7fXzjBkztHjxYn311Vdq06aNlixZokWLFumyyy6TJM2fP199+vTR5s2blZGREYwu1ym/QqfL5ZLNZrOqL6ZwuVxej9W2dbv9X77b7dOyGwp/6omKsrKydPLkSa9pbrdbP/zwgwoKCmS3//xlQ7NmzdSpU6e67mK9s/+MTafOWR3dbkM/uKNVWmDIbvfepps4pJRIo8IybD/8UOWNryuIiZHRrl0gXa532O4DU9l2X3akq+yxTGXbva0Wn01ut1uGL597LttPj265XBW3DbP7YdXnbF2to4Zxtkb5+fle+ScyMlKRkZHVzutyufT222+rsLBQGRkZ+uabb1RSUqIBAwZ42lxwwQVq27YtobMymZmZnjcg1GVlZdXYJvuM/+dRZO/LVkzk6ZobNjC+1BPesrOzdf311/s1zzvvvCOn02lRj+q/g+4IPVDSpZJnLpD2VD7PvPCdam0v9vwccShHnadM9ev37nryCRW3anzD8rHd+6+m7f7222+vMK38dh+9L1up/v7efdny5ZMp2x0t6QJlZ2fLbq9+DjP6cbjkeMXlFklpe6XdHSoflejw/v9qd7hvn7NWr6M2m01Op1Pp6ekqKCjwTJ88ebKmTJlS6Tw7duzQVVddpaKiIjVp0kSvvfaaOnfurG3btikiIkJxcXFe7ZOSkpRTNp59A+dX6ExNTa0XRzqzsrLUqVMnORyOatsW5kdLB/1bvrO9U2mxKTU3bCD8qSe8Ffp6JO0cLVu2VFpamgW9aRjchTYpS3rspNS+khH4zrUvTHq4mZTs7Ki0mJ//WK7NHqxjq2QZjeh9YbuvPTO2+9qso872Tp/W0bJtyOl0em0XlTGjH2mStnXoqJOun4e2PPLjIa364G967Krfq8V5rbzmb+aIUqcmSTX+nrpaRw3DUHFxsbZv317hSGdVUlNTtWnTJuXn5+udd97RPffco9WrV1vWx/rEr9DpcDhCPnSWcTgcNa6IDrv/11E57PZGuRP2pZ7wVpt6UefqlZWmfanU2cdv1RwOu7xKWovt3m63S43wfWF99J8p272F62hZkwrbReULNaUfabGtvX7Ozj+73C7N2siZENg3O1avo2Xf7sbGxvqcfyIiItSxY0dJUs+ePfX111/rpZde0vDhw1VcXKy8vDyvo525ublKTm4c36Rw9ToAAIBF3G63iouL1aNHD4WHh2vjxo2e5zIzM3XgwIFGcT6nxNXrAAAAppg5c6auuOIKtWvXTidPntSKFSv06aefauXKlYqLi9Po0aM1ffp0JSQkqFmzZpo0aZIyMjIInQAAAPDdkSNHdPfddysnJ0exsbHq1q2bVq5cqcsvv1ySNHv2bNntdo0dO1bFxcUaOHCg5s6dG+Re1x1CJwAAgAmef/75ap+PiorS3LlzG1XQPBfndAIAAMByhE4AAABYjtAJAAAAy9Xrczqzi6TCciNsuVw2Zbuj5S60ed0qLMYuOSsZ+cAU+/f7NaSeUhrPzeWBc2WeylFBaVHNDSU1DYtSapPGce86AGgM6m3ozC6Shu4Mr+LZC6RKRsZ6t0uJV/BsGlYxhdY0PFeFefbvV9jIG3zvuKTSFW8RPNHoZJ7KUbeNM/yaZ0f/WfUmeJ44cUKbNm3SZZddpvj4+GB3ByY6XCKtOGLXyBZutazqYwdAjept6Cw7wunPcHjlj4qmNknWjv6zvI68HD5wUCs+WKw///o2tWzrPYpCpUdeajHkWa3mAeo5X49wBjpPsOTl5Wn16tXq0aMHobOBOVIivXTIoQFxhE4gEPU2dJbxZzi8ypQPkdknzj6mNW0tZ1xgw3MBAADgLC4kAgAAgOUInQAAALAcoRMAAACWI3QCAADAcoROAAAAWI7QCQAAAMsROgEAAGC5en+fTgB1gyEs0RhUNrzy3iLvxzKWDq8MNECETgA1auhDWAJSTcMrS1OzKz5XfnhlU8TEVDr5RFiYPm6RqAFHjiq+tNSneYBQQugEUKOGPoQlIFU8wmnVPDVKSVHpircqDJl8NCdH777+uro/+ICaJp/zB11MjJSSYkFHAHMROgEACDWVhcjo6LOP7dtLToZpRv3DhUQAAACwHKETAAAAliN0AgAAwHKETgAAAFiO0AkAAADLEToBAABgOUInAAAALMd9OgGgFsoPC3q44KAkaXfBQR3L827LsKAAQOgE4IOmYZWP8xddJKXtlXZ3kE5H+TZP0FUyXGC1wwtWMk9lw4JGF0lpadKbuxfrdHbFRTAsKAIVFxenIUOGKC4urm5+IcNxwmSETgA1Sm2SrB39Z1UY2vLwgYNa8cFi/fnXt6ll29ae6SF9ZK+SIQarHF5QqnSIwcqG+DwdJW3tUvWvZVhQBCo+Pl5Dhw6tu1/IcJwwGaETgE8qC5HZJ84+pjVtLWdcPRqWr/wHI8MLApVjOE6YiAuJAAAAYDlCJwAAACxH6AQAAIDlCJ0AAACwHKETAAAAliN0AgAA1DPFxcXKzMxUaWX3Fg5RhE4AAIB6orCwUPfee6/atGmjvn376sCBA5KkSZMm6S9/+UuQe1c9QicAAA1QdpG0s9D7396fxijYW+65bMYuqDcee+wxbd++Xe+9956ion4e+W3AgAH6xz/+EcSe1YybwwP10IkTJ7Rp0yZddtllio+Pr9UyDpdIK47YNbKFWy3Dze1fZWozLGZdDaVZ58MLwidmrOdmLMMfTZs2rZN5apJdJA3dWfWGPTW74nPvdimRM0RHr8XP1qxZo8WLFysjI0M2m80zvXPnztq3b1/wOuYDQidQD+Xl5Wn16tXq0aNHrT9Ij5RILx1yaEBc3YTOqobSrEpdDqVZ58MLwidmrOdmLMMfqamp2rFjhwoKCrymu1wuZWdny+l0yuFweKY3bdpUqamppvej0H328bGTUvsaTvnbFyY93OzneRDajh49qpYtW1aYfurUqSD0xj+ETgB1JmTHYwdMVFmIdLlciomJUVpamlfotFr7Uqmzq85+HepAz549tW7dOo0fP16SPEc7X3vtNfXu3TuYXasRoRMAAKCemDFjhm644Qbt2rVLpaWleumll7R79259+eWXWr16dbC7Vy0uJAIAAKgn+vbtq02bNsnlcqlr167asGGDWrRoobVr16pnz57B7l61ONIJAABQj3To0EHPPvtssLvhN450AgAAmGDevHkaOHCg2rVrp9TUVN18883KzMz0ajNkyBAlJCR4/bv//vt9/h3r1q3T+vXrK0xfv369Pvzww4Bfg5UInQAAACb4/PPPNW7cOK1bt06rVq1SSUmJhg8fXuHK8ltuuUW7du3y/Js5c6bPv2PmzJlyuSpeHWYYhl/LCQa+XgcAADDBihUrvH5esGCBUlNTtXXrVl188cWe6dHR0UpOrt3dPPbs2aPOnTtXmH7BBRdo7969tVpmXeFIJwAAgAXy8/MlSQkJCV7Tly9frvPPP199+/bVzJkzVVhY6PMyY2NjK70J/J49exQTExNQf63m15FOl8vldff7YHK5/O+Hy+WWy2VU28btdnseKzt8XZ7N7f/ddN1utwwflh0KymrgSy0amv1nbDrl48tu4pBSIr3XrdrUzOVyVZgv61SuTrq8b6h+5OQhSdLOk//V4eM/r4PNHFHq1CTJx99l++mx5u2iKv5uL4Gyarv3e5m12O5ddVQjM9Rmuw90e6mMv+tXoNuKletXXe9Ly17LPh8+5cva+PpaAt3uzdhv1FU9DeNsPfLz873yT2RkpCIjI6ud1+12a+rUqerTp4+6du3qmT5y5Ei1a9dOrVq10o4dOzRz5kxlZWXptdde86lPV199taZOnaolS5aoQ4cOks4GzoceekhXX321vy+xTvkVOjMzMz1vQLBlu6MlXeDfPNnZsttPV9smNzfX0/b06erbSlL0vmz5O5ZE9r5s1bzkwJ06dUrffvutLrzwQjVp0iSgZWVlZZnUq/rhoDtCD5R08WueeeE71dpe7Pk5Ozvb79+bnZ3t9ZdqdslxXf/j/1ZoF10kpaVJb37/N53e7/3cO+fdImd4QoV5Kvyun7YhX7aLqvi7vQTKqu3e736cyfV/nn3Ziomsiy3fPL5u92ZsL5XxZ/0yY1upi/WrrvalOe4ISV30cDM/5sneI3sN74kU+HZv5n7D6nrabDY5nU6lp6d7jTI1efJkTZkypdp5J0yYoJ07d+r999/3mn7rrbd6/t+tWze1atVK119/vfbu3esJkdWZOXOmfvvb36p3795q06aNJOm///2v+vbtq1mzZvnx6uqeX6EzNTU1ZI50ugttkp/rmtPpVFpM9aE5Ojra0zYlJaXGZdamGs72ThlpabWY0z/79+/XF198oYEDB/r0WirjcrmUlZWlTp061ekoGsFWm/Ur2dnRa/3y5+uSMk6nU2nnrBuF+fulHyu2Ox0lba3iM75lShulxdb8fpe9Rl+2i6r4u70Eyqrt3l+F+dHSQT/70d7p0/sSCvzd7s3YXirjz/plxrZi5fpV1/vSNElvnznj59HnmgOPFPh2b8Z+o67qaRiGiouLtX379gpHOqszceJErV27Vv/85z913nnnVdv2oosuknT2aKUvoTMuLk5r167Vhg0btH37dkVFRalbt25e54yGKr9Cp8PhCJnQWZt1zOGw1zif3W73PPq0Itv9Py3WbrfX7gXU5vfIj9dSDYfD0ahCpxnrV23qVb7OjlqsXw4f3++yJr5sF1Uxcx3zhVXbvd/LtPB9CSW+bvehsD824z2pi/WrLvelHSw6vS/Q7b4+fTaVfbsbGxvrU/4xDEOTJk3SmjVr9N5778npdNY4z7Zt2yTJrwuLbDabBg4cqIEDB/o8Tyjg6nUAAAATTJgwQStWrNDSpUvVtGlT5eTkSDobWqOjo7V3716tWLFCgwcPVvPmzbV9+3ZNnz5d/fr1U3p6epXLXbhwoW655RZFRUVp4cKF1fbhzjvvNPU1mYnQCQAAYILFixdLOnsD+HO98MILuummmxQeHq6PP/5YL774ogoLC3Xeeefpuuuu04QJE6pd7oIFC/Tb3/5WUVFRWrBgQZXtbDYboRMAAKChO378eLXPt23bVmvWrPF7ud98802l/69vuE8nAABAPVBSUqJevXpp9+7dwe5KrRA6AQAA6oHw8HCdOXMm2N2oNUInAABAPXH77bfr2WefVWlpabC74jfO6QwR2UVSoY+DnMTYJWeUNf3IzMz0ugGuy+VSdna2CgsLK9yWomnTpkpN9ffW+ABCDds9UH98/fXX2rRpkzZs2KCuXbtWGPrS15GNgoHQGQKyi6ShO8P9mufdLiWmB8/MzEx169bNr3l27NjBB1AVmjZtGvA8TcMqf5Oji6S0vdLuDmdvfu3LPGgcTpw4oU2bNumyyy5TfHx8je3Z7uGvuLg4DRkyRHFxccHuSqMUFxen6667LtjdqBVCZwgoO8L52EmpfQ1Hy/eFSQ838/2oqD/OPdJh5TyNRWpqqnbs2FGhRt99951+//vf629/+5vXeLyVHUFKbZKsHf1nqaDUezzpwwcOasUHi/XnX9+mlm1b/7yMsCilNvH9BsNoePLy8rR69Wr16NHDp9DJdg9/xcfHa+jQocHuRqPjdrv13HPPKSsrSyUlJbr00ks1ZcoUzwhP9QGhM4S0L5U6+zhkGeqHyo4GuVxn3+S0tDT16tWr5mVUEiKzT5x9TGvaWs64mke8AADUb08//bSefPJJDRgwQFFRUXr55Zd19OhRzZ8/P9hd8xkXEgEAAIS4ZcuWae7cuVq5cqVef/11vfHGG1q+fLncbgu++rQIoRMAACDEHThwQIMHD/b8PGDAANlsNh08eDCIvfIPoRMAACDElZaWKirK+0LR8PDwenXrJM7pBAAACHGGYeiee+5RZGSkZ1pRUZEeeOABr9smccskAAAA1NqoUaMqTLvhhhuC0JPaI3QCAACEuBdeeCHYXQgY53QCAADAchzpbEj275cKC3/+OSfn7OO+fdLp095tY2KklJQ66xpgpn0+7Ll8aRNsoTL8bUgov/+Sqt6Hsf8C6qV6sFuuW/V2eK/9+xU20vvcjsSwMA1tkajEqdMVVsnVbaUr3mLHHQStWrXSnXfeqVatWgW7K/VOzE/fzTzczP95Qk2oDH9rxnCtAatk/yVVvw+zYv9Vm3UlVNevUFZvP2cRMEJnOfV2eK/yRwgkxZeWatihHL/mgfVat26tu+++W61bt665Mbw4o84Gr3OPDmadMvTQgQj9uW2xOjWxebUP5aODtRnK1orhbysbrrWqoVqlyodrDVgV+6Jq92EW7L8qW7+qE8rrVyirt5+zCBihE0C9Uv5D3uUyJEkdogx1ibFVMgdqUj5E+jtUa0NCiASswxcDAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6AQAAYDlCJwAAACzHfTqBRuBwiXSkxHva3iLvxzItwqWW/g2UAwBAjQid8LBqOLzDJdKKI3aNbOEmzATJiiN2vXTIUelzU7O935S7Wrl0d2sLhr5pQJqG+X8H8drMAwANCaETHlYNh3ekRHrpkEMD4gidwTKyhVsD4ryD5N6is4HzCWeJOpyTh1rwHtUotUmydvSfpYLSopob62zgTG2SbHGvACC0ETrhheHwGqaW1Xxl3iFK6hJTt/1pCAiRAOAfLiQCAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6AQAAYDnu0wkA9dn+/VJh4c8/5+Scfdy3Tzp92rttTIyUklJnXQOAcxE6gUaqRfjZIS8DGYEoLi5OQ4YMUVxcnHkd81OLcEMjHIfUIjw+aH0Imv37FTbyBq9JiWFhGtoiUYlTpyustLTCLKUr3iJ4AggKQifQSLUMV8BjrMfHx2vo0KEm9ah2WoZLI8Ny1LIxhs5zj3D+JL60VMMO5fg1DwDUBc7pBAAAgOUInQAAALAcoRMAAACWI3QCAADAcoROAAAAWI7QCQAAYIJ58+Zp4MCBateunVJTU3XzzTcrMzPTq01RUZEmTJigjh07qm3btho7dqxyc3OD1OO6RegEAAAwweeff65x48Zp3bp1WrVqlUpKSjR8+HCdOnXK02batGn64IMP9Oqrr2r16tU6dOiQxowZE8Re1x3u0wkAAGCCFStWeP28YMECpaamauvWrbr44ouVl5enJUuWaNGiRbrsssskSfPnz1efPn20efNmZWRkBKPbdcav0OlyuWSz2azqi19crrP92OfDKyhr43K55XIZpvbD5vb/5tput1uGy+X5uey1+KP8azGjH1W1KXt01dC2KmWvz4r6V8X2ww++3wQ7JkZGu3Zek8x4T6pu5/J6rA0z3peGwox6BkND2u4DfS2m7EdrsQxXHW4/9XU9DVV1VU/DOLuO5ufne+WfyMhIRUZG1jh/fn6+JCkhIUGS9M0336ikpEQDBgzwtLngggvUtm1bQmd5mZmZnjcg2HLcEZK66OFmfsyTvUd2e7Gp/Yg4lKPOfs6z51COzu1Ftjta0gV+LSM7O1t2+8/jKlfWjxNhYfq4RaIGHDmq+EqGwyvfj8qcPn1ad955p06fPq3du3f71UdPX396feX7bJWIQznqPGWqX/PsevIJFbdK9vxsxntSk6ysLL+Wf66y83+ys7N1uvz42o1UIPUMBjPWseh92Ur19/fuy1ZNa8wPP/zgeWzatGnNywzwtVS1H61uH1ZhP3rG/3PisvdlKyaybref+raehjqr62mz2eR0OpWenq6CggLP9MmTJ2vKlCnVzut2uzV16lT16dNHXbt2lSTl5OQoIiKiwtDBSUlJysmpZiSxBsKv0JmamhoyRzrTJL195oxOlfsjx+1264cfflC7du1kt/98ymoTh5QS2cGCjqSp+K1lfh1V61DuqJq70Cb5ud04nU6lxZzzB0Al/TiSm6t3ly5V+gP3KyYpqcZ+VKZTp05q2bKlOnXqJIfD4V8nf1L2+ir02SK1WUM7tkqWkZbm+dmU96QKLpdLWVlZAdU0Ojra8ztTGvk42mbUMxjMWMdqs6472zu91vXKlH24tmvXTmk1tJVMeC1V7Eer3IdVsv8qzI+WDvrZh/ZOpcXWzfZTX9fTUFVX9TQMQ8XFxdq+fXuFI501mTBhgnbu3Kn333/fsv7VN36FTofDETKhU5I6xFSc5nIZCrOfVlpTmxyOOrpOqn37gGavzfbicNgrzleuH7YmTc4+duggu9NZu855fp+j1ht22WyV9tkKdv/fd7vd7vVGmPaeVNu+9jUt+4PKbrfzAfaTQOoZDKasYyas61W2ke/rlymvpZL9qD/7MEctauEIwvZT39bTUGd1Pcu+3Y2NjfUr/0ycOFFr167VP//5T5133nme6cnJySouLlZeXp7X0c7c3FwlJydXtqgGhavXAQAATGAYhiZOnKg1a9bo3XfflbPcH0s9evRQeHi4Nm7c6JmWmZmpAwcONPjzOSWuXgcAADDFhAkTtGLFCi1dulRNmzb1nKcZGxur6OhoxcXFafTo0Zo+fboSEhLUrFkzTZo0SRkZGYROAAAA+Gbx4sWSpCFDhnhNf+GFF3TTTTdJkmbPni273a6xY8equLhYAwcO1Ny5c+u8r8FA6AQAADDB8ePHa2wTFRWluXPnNpqgeS7O6QQAAIDlCJ0AAACwHKETAAAAluOcTpguu0gqPGdEur1F3o/nirFLzqi66RcAAAgeQidMlV0kDd0ZXulzU7Mrn/5ulxKCp5/i4uI0ZMiQCkOpof6IqcX3TLWZpzZatWqlO++8U61ataqbXwigUSB0wlRlRzgfOym1rzjcu5d9YdLDzbyPisI38fHxGjp0aLC7gQA4o87+wVX+W4Gp2eF6wlmiDuX+EKvLbwVat26tu+++W61bt66bXwigUSB0whLtS6XOrmD3AghtVYXIDlFSl0qG+QWA+owLiQAAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6ASBEtAiX7mrlUovKR4xtdPwZ7rVpWOV32o8uknruPPvo6zwArMGIRAAQIlqGS3e3ZlzYMv4M95raJFk7+s9SQal3ujx84KBWfLBYf/71bWrZ9udhPZuGRSm1SbKp/QVQPUInAKBBqCxEZp84+5jWtLWccc667RAAL3y9DgAAAMsROgEAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJVCKmFltGbeYBYC1/htIEYC1GJAIq4YyS3u1SosJyIxLuLZKmZofrCWeJOpwzbHOM/ew8AEKLP0NpArAWoROoQnUhskOU1CWm7voCAEB9xxeCAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6AQAAYDlCJwAAACzHfTpDyD4f3g1f2gAAAIQaIkwIKBs+8eFm/s+DSsRUftf2E2Fh+rhFogYcOar40lKf5imvRbh0VyuXWoQH2kkAABoXQmcIqGzIxaqGW5QYcrFGKSkqXfGWVFjoNfloTo7eff11dX/wATVNTv75iZgYKSXFp0W3DJfubu2uuSEAAPBC6AwRVYVIhluspcpCZHT02cf27SWns067AwBAY8eXtAAAALAcoRMAAACWI3QCAADAcoROAAAAE3z22Wf63e9+py5duighIUFr1qzxev6ee+5RQkKC17+RI0cGqbd1jwuJAAAATFBYWKj09HSNHj1aY8aMqbTNoEGD9MILL3h+joyMrKvuBR2hEwAAwASDBw/W4MGDq20TGRmp5HNv29eI+BU6XS6XbDabVX0xhcvl8nqsr1wu20+PbrlcRq2W4Xa7PY+1rYe/9Szrtz+jKwXyGv1hRj3M0FDW0VDRmOtpc/t/z1i32y2jhlrVdrv3R11t96GiMa+nVqirehrG2XU0Pz/fK/9ERkbW+gjlp59+qtTUVMXHx+vSSy/VQw89pObNm5vS31DnV+jMzMz0vAGhLisrK9hdCEieEaYRjkTl7T+q3bbSmmeoxKlTp9SnTx8dOXJEp0+fDqg/vtYzxx0hqYtfoyvlZO+R3V5cbZtTp07p22+/1YUXXqgmTZr4vvBz5ObmSpKys7MDrocZ6vs6GmoaYz2j92Ur1c95svdly9e139/t3h++bPcNUWNcT61kdT1tNpucTqfS09NVUFDgmT558mRNmTLF7+UNGjRIQ4YMkdPp1L59+zRr1iz99re/1bp16+RwOMzsekjyK3SmpqbWiyOdWVlZ6tSpU71/A38lSYoPaBm/+MUvAprf33qmSXr7zBmdOuePz71FNj10IEJ/blusDlHef7Q0cUgpkR1qXO7+/fv1xRdfaODAgUrxcfSg8qJ/ujm80+ms9TLM0JDW0VDQmOtZm72xs71TRlpatW3M2O6r4+t235A05vXUCnVVT8MwVFxcrO3bt1c40lkbI0aM8Py/W7du6tatm3r16qVPP/1U/fv3D7i/oc6v0OlwOEI+dJZxOBxs2Cbyp54dyo2gVDZbpyY2dYmp3fpjt9s9j7V9X81YhplYR83VKOtp9/8GJHa7/eeNsgaBbPeoXKNcTy1kdT3Lvt2NjY21JP+0b99eiYmJ2rNnT6MIndwyCQAAIAh+/PFHHTt2rNFcWMTV6wAAACYoKCjQ3r17PT9nZ2dr27Ztio+PV0JCgubMmaOhQ4cqOTlZe/fu1SOPPKKOHTtq0KBBQex13SF0AgAAmGDr1q267rrrPD9Pnz5dkjRq1Cg9/fTT+u6777Rs2TLl5eWpVatWGjhwoKZNm9Zo7tVJ6AQAADDBJZdcouPHj1f5/MqVK+uwN6GHczoBAABgOUInAAAALEfoBAAAgOUInQAAALAcoROWaxEu3dXKpRbhwe1HXFychgwZori4uOB2BDBLTC3uyF6beQDABFy9Dsu1DJfubu0OdjcUHx+voUOHBrsbgHlSUlS64i2psNC39jExUhCHgAXQuBE6AaA+I0QCqCf4eh0AAACWI3QCAADAcoROAAAAWI7QCQAAAMsROgEAAGA5QicAAAAsR+gEAACA5bhPJ0LTkSNn/5XJyTn7uG+fdPq0d9sWLc7+AwAAIYvQiZBkX/UP2V/5q+fnxLAwDW2RqMSp0xVWWurV1j3udrnH31HXXQQAAH4gdCIkuYf/Ru7LLvX83FTSkJ/+X1q+MUc5AQAIeYROhCa+MgcAoEHhQiIAAABYjtAJAAAAyxE6AQAAYDlCJwAAACxH6AQAAIDlCJ0AAACwHKETAAAAliN0AgAAwHKETgAAAFjOpxGJXC6X59FuD+2c6na7Zbfb5Xa7ZbPZgt2deo96mo+amot6mo+amo+amquu6ul2uyWdzT9hYQziGCibYRhGTY1KS0t16tSpuugPAABASGnSpAmh0wR+VTAqKirk/0JzuVzKzMxUamqqHA5HsLtT71FP81FTc1FP81FT81FTc9VVPQ3DUFFRkWXLb2x8Cp1lb6jNZgv50Gmz2WQYRr3oa31APc1HTc1FPc1HTc1HTc1V1/XkDwVzhPYJmgAAAGgQCJ0AAACwHKETAAAAliN0AgAAwHKETgAAABPMmzdPAwcOVLt27ZSamqqbb75ZmZmZXm2Kioo0YcIEdezYUW3bttXYsWOVm5vr1eaHH37QDTfcoDZt2ig1NVUzZsxQaWmpV5tPP/1U/fv3V3Jysn7xi19o6dKlFfqzaNEiXXjhhWrVqpWuuOIKbdmyxfwX7QdCJwAAgAk+//xzjRs3TuvWrdOqVatUUlKi4cOHe93rfNq0afrggw/06quvavXq1Tp06JDGjBnjed7lcunGG29USUmJ1q5dqwULFuiNN97Q7NmzPW2ys7N144036tJLL9WmTZt011136Y9//KPWr1/vabNq1So99NBDmjx5sj7++GOlp6drxIgROnz4cN0UoxKETgAAABOsWLFCN910k7p06aLu3btrwYIFOnDggLZu3SpJysvL05IlS/T444/rsssuU8+ePTV//nx9+eWX2rx5syTpo48+0u7du7Vw4UJ1795dgwcP1rRp0/TKK6+ouLhYkrR48WKlpKToz3/+s9LS0jR+/HgNHTpUL774oqcvCxYs0NixY3XzzTerc+fOmjdvnmJiYrRkyZI6r0sZv24O73K5Qv7+YucO2YnAUU/zUVNzUU/zUVPzUVNz1VU9ywZtzM/P98o/kZGRioyMrHH+/Px8SVJCQoIk6ZtvvlFJSYkGDBjgaXPBBReobdu22rx5szIyMrR582Z17dpVSUlJnjaDBg3Sgw8+qF27dunCCy/U5s2bvZZR1mbq1KmSpOLiYm3dulX333+/53m73a7+/ft7wm0w+BU6MzMz5cOomSEhKysr2F1oUKin+aipuain+aip+aipuayup81mk9PpVHp6ugoKCjzTJ0+erClTplQ7r9vt1tSpU9WnTx917dpVkpSTk6OIiAjFxcV5tU1KSlJOTo4kKTc31ytwSlLLli0985e1KZt2bpuTJ0/q9OnTOnHihFwuV6Vtyp9jWpf8Cp2pqan14khnVlaWOnXqxAgCJqCe5qOm5qpv9Qz/w73SsWOBLaR5c5W88Lw5HapEfatpfUBNzVVX9TQMQ8XFxdq+fXuFI501mTBhgnbu3Kn333/fsv7VN36FTofDEfKhs4zD4WDDNhH1NB81NVe9qeexY7Kd1yagRRg//rdOXmu9qWk9Qk3NZXU9y77djY2N9Sv/TJw4UWvXrtU///lPnXfeeZ7pycnJKi4uVl5entfRztzcXCUnJ0s6e9Sz/FXmZRf/nNum/AVBhw8fVrNmzRQdHe2pS2Vtyh9FrUt+hU4AQMMw5quXdbT4VBXPGnK7Ddm/+EBS5R+0iRFN9Novx1vWP6A+MgxDkyZN0po1a/Tee+/J6XR6Pd+jRw+Fh4dr48aNGjp0qKSzpy4eOHBAGRkZkqSMjAw9/fTTOnz4sOfr8Q0bNqhZs2ZKS0vztPnwww+9lr1hwwb17t1bkhQREaGePXtq48aNuvbaayWd/bp/06ZNGjdunHUFqAGhEwAaoaPFpxTtw1eEVc5/pqrAWj9VH8JrRgiHdPYr9RUrVmjp0qVq2rSp5xzM2NhYRUdHKy4uTqNHj9b06dOVkJCgZs2aadKkScrIyPCEzoEDByotLU133XWXHn30UeXm5urxxx/XuHHjPF/r33bbbXrllVf08MMPa/To0dq0aZPefvttvfnmm56+3HPPPbrnnnvUq1cv/eIXv9CLL76oU6dO6eabb677wvyE0AkAaPQI4TDD4sWLJUlDhgzxmv7CCy/opptukiTNnj1bdrtdY8eOVXFxsQYOHKi5c+d62jocDi1btkwPPvigrrrqKsXExGjUqFGaNm2ap43T6dSbb76padOmaeHChWrTpo2ee+45DRo0yNNm+PDhOnLkiGbPnq3c3Fx1795dK1as4Ot1AACA+u748eM1tomKitLcuXO9gmZ5KSkpWr58ebXLueSSS7Rp06Zq24wfP17jx4fOEXhCJwAAISDQr/glvuZHaCN0AgAQAgL9il/ia36ENkInUA4XFAAAYD5CJ1AOFxQA8NdfX/5S9md+V+XzdkldDbfsNnvVC7m7pxTgkU4glBE6AQAIUGJBsWztnNW2qfEW5vVkmGmgtqr5kwsAAAAwB0c60aCYcT4mQo/9rnuqHK/cp68tJal5c7lfWmB+5wAAPiF0okHhfMwGqobxyn0Zedn48b/m9QchhT82gfqB0AkAqNf4YxOoHzinEwAAAJZrlEc6GfUBAALHPW0B+KNRhk5GfUBjUN3FNz7j4htUg6+1AfijUYZOoFGo4eIbX3DxDQDALITOWqpp9AmfcBQJAGAiPpsQygidteTL6BM14SgSAMBMfDYhlBE6ATQKo8d01ZHP/xLQMrjwBQBqj9AJoFE40iScCwgBIIi4TycAAAC8fP755xo/fryuvPJK/fe/Z0+5WLZsmf71r3/VepmETgAAAHi8++67GjlypKKjo/Xtt9+quLhYkpSfn6958+bVermETgAAABN89tln+t3vfqcuXbooISFBa9as8Xr+nnvuUUJCgte/kSNHerU5fvy47rjjDqWkpMjpdOree+9VQUGBV5vt27fr6quvVqtWrdStWzc9++yzFfry9ttvq3fv3mrVqpX69eundevW+fw65s6dq3nz5unZZ59VeHi4Z/qvfvUrffvttz4vpzxCJwAAgAkKCwuVnp6up556qso2gwYN0q5duzz/XnnlFa/n77jjDu3atUurVq3SsmXL9Pnnn+tPf/qT5/n8/HyNGDFC7dq104YNG/TYY49pzpw5evXVVz1tvvjiC40bN06jR4/Wxo0bde2112r06NH67rvvfHodWVlZ6tevX4XpsbGxysvL82kZleFCIgAAABMMHjxYgwcPrrZNZGSkkpOTK31u9+7dWr9+vT766CP16tVLkjRnzhzdcMMNmjVrllq3bq3ly5eruLhY8+fPV0REhLp06aJt27ZpwYIFuvXWWyVJCxcu1KBBg/THP/5RkjR9+nR9/PHHWrRokf7yl5rv4pGUlKQ9e/YoJSXFa/q///1vtW/fvsb5q8KRTgAAgDry6aefKjU1VRkZGXrggQd07Jzhijdv3qy4uDhP4JSkAQMGyG63a8uWLZ42/fr1U0REhKfNoEGDlJmZqRMnTkiSvvzySw0YMMDr9w4cOFCbN2/2qY9jx47V1KlT9dVXX8lms+ngwYN66623NGPGDN122221fOV+Hul0uVyy2Wy1/mV1weVyeT1Wzqibzvig+n4Gn2/1DCWBvrdmrBtGtfWqq5qa9RdlKLz3ofPXcfXvrS9C530J/W3Fn+UEd/6GJxS2++rU1X7UMM6uG/n5+V75JzIyUpG1uAXboEGDNGTIEDmdTu3bt0+zZs3Sb3/7W61bt04Oh0M5OTlq2bKl1zxhYWFKSEhQTk6OJCk3N7fCEciyeXJychQfH6/c3NwKy2nZsqVyc3N96uf9998vt9utYcOGqbCwUNdee60iIyP1f/7P/9H48bW/V7FfoTMzM9PzBoS6rKysKp9zu0PjNbgNt3bv3h3sbvikunqGkkDfWzPWDbfb8Ol9tbqmXQ23HAEuI1TWUTNeixl8fW+rEyrvS33aVqzuS6h8JoSKUNnufWH1ftRms8npdCo9Pd3rYp7JkydrypQpfi9vxIgRnv9369ZN3bp1U69evfTpp5+qf//+pvTZDDabTRMmTNAf//hH7dmzR6dOnVJaWpqaNm0a0HL9Cp2pqan14khnVlaWOnXqJIej8l27/YsP6rhXlbPb7EpLSwt2N6rlSz1DSaDvrd0e+Pptt9uqfV/rqqZ2W+DH1EJlHTXjtZihpvfWp2WY8b4Ulyj90cdqv4DmzWUf2ymwPtTBtuLzckJgu29IQmW7r05d7UcNw1BxcbG2b99e4UinGdq3b6/ExETt2bNH/fv3V3Jysg4fPuzVprS0VMePH/ecB5qUlFShTdnPNbVJSkryq38RERHq3LmzX/NUx6/Q6XA4Qj50lnE4HNWsiKHzGupDkJNqqmcoCfS9NWPdsPlUq/pS0/rQx7rj23tbF2zntan1vGfH1q4/24ovywnu/A1PqKznNbF6P1r27W5sbKwl+efHH3/UsWPHPGExIyNDeXl52rp1q3r27ClJ2rRpk9xuty666CJPmz//+c8qKSnx3M5ow4YNSk1NVXx8vCSpd+/e2rhxo+6++27P79qwYYMyMjJ86ldRUZFefvllffLJJzpy5IjcbrfX8xs3bqzV6+XqdQAAABMUFBRo7969np+zs7O1bds2xcfHKyEhQXPmzNHQoUOVnJysvXv36pFHHlHHjh01aNAgSVJaWpoGDRqk++67T/PmzVNJSYkmTZqk4cOHq3Xr1pKkkSNH6n/+539077336r777tPOnTu1cOFCPf74457fe+edd2rIkCGaP3++rrzySq1atUpbt27VM88849PruPfee7VhwwYNHTpUF110kWmBm9AJAABggq1bt+q6667z/Dx9+nRJ0qhRo/T000/ru+++07Jly5SXl6dWrVpp4MCBmjZtmtfX9YsWLdLEiRM1bNgw2Ww2DR06VE8++aTn+bi4OK1cuVITJ07U5ZdfrsTERE2cONFzuyRJ6tOnjxYtWqTHH39cs2bNUseOHbVkyRJ17drVp9exdu1avfXWW/rVr34VYEW8EToBAABMcMkll+j48eNVPr9y5coal5GQkFDhhvHlpaen6/3336+2zbBhwzRs2LAaf19l2rRpE/BFQ5UJjbPzAQAAEBJmzZqlRx99VPv37zd1uRzpBAAAgEevXr105swZ9erVSzExMQoL846L55636g9CJzTmq5d1tPhUFc8acruNn25JUvmJxIkRTfT6K1ulc0ZV8Fvz5nK/tKD28wMAAFOMGzdOBw8e1IwZM5SUlMSFRDDP0eJTig7gnmNHz5ySjh0L+BYu9rvuCTi4amxq7ecHAAD68ssvtXbtWnXv3t3U5RI6ETpMCK4AACAwqampKioqMn25hE4AVRo9pquOfP6XgJaRGNFEr/2y9mP1AgDq1iOPPKKHHnpIM2bMUNeuXSuc0xkbG1ur5RI6AVTpSJPwgE69kH46/QIAUG+MHDlSknT99dd7TTcMQzabTUePHq3VcgmdAAAA8HjvvfcsWS6hEwAAeJhxWk2Ju1Th9sAiBqfmBM/FF19syXIJnQAAwMOM02qKCosVy6k59dZnn31W7fO1DaWETgAAAHicO358mXPv1ck5nfXRmTOy3/C7gBYx+tbuOhIfE1g3XCWKVmB/kQIAgIah/IhDpaWl+vbbbzV79mw99NBDtV4uoTPIArkvpSQdibKb8jUIgJr99eUvZX8msD8UdeaMOZ0BAIvExcVVmHb55ZcrIiJC06dP18cff1yr5RI6AcBHiQXFsrVzBrQMY0/txiwGgGBr2bKlsrKyaj0/oRMAAAAe27dv9/rZMAzl5OTomWeeUXp6eq2XS+gEAACAx2WXXSabzSbDMLym//KXv9T8+fNrvVxCJwAAADy2bt3q9bPdbleLFi0UFRUV0HIJnQAAAPBISUmxZLmETgAAgEZu4cKFPre98847a/U76l3otN91j3TsWNXPS+pquGW32ateyN09pQBvMwTAN2dcJbomwCH13nGXKrAvdRCqatqn16h5c2lsqnkdAhqpBQsW+NTOZrM1ntCpY8dqvLelo6ZllDsxFoB1DBkB30vWENtsg+XDPr06xo//NbEzQGA+++wzPf/88/rmm2906NAhLVmyRNdee63necMw9MQTT+jvf/+78vLy1KdPHz399NM6//zzPW2OHz+uSZMmae3atbLZbBo6dKieeOIJNW3a1NNm+/btmjhxor7++mslJiZq/Pjxuu+++7z68vbbb2v27Nnav3+/OnbsqEcffVRXXnlllX3/5ptvTKxE5ao5HAgAAABfFRYWKj09XU899VSlzz/77LNauHCh5s2bpw8//FAxMTEaMWKEioqKPG3uuOMO7dq1S6tWrdKyZcv0+eef609/+pPn+fz8fI0YMULt2rXThg0b9Nhjj2nOnDl69dVXPW2++OILjRs3TqNHj9bGjRt17bXXavTo0fruu+/8fk2GYVS4ir22CJ0AAAAmGDx4sB566CENGTKkwnOGYeill17ShAkTdM011yg9PV0vvviiDh06pDVr1kiSdu/erfXr1+u5557TL3/5S/Xt21dz5szRqlWrdPDgQUnS8uXLVVxcrPnz56tLly4aMWKExo8f7/X1+MKFCzVo0CD98Y9/VFpamqZPn64ePXpo0aJFPr+WZcuWqV+/fmrdurVat26tiy++WMuWLQuoPn59ve5yubwGfA8GUnIoCqWvPgPtixmvxaj2PDWfzjtu3lwlLzwfUC/YVlC90NhWzBEKrwXmM+RyuSp9pmx6Vc+b1oOfjvDl5+d75Z/IyEhF+nnaUHZ2tnJycjRgwADPtLi4OF100UXavHmzRowYoc2bNysuLk69evXytBkwYIDsdru2bNmiIUOGaPPmzerXr58iIiI8bQYNGqRnn31WJ06cUHx8vL788kv94Q9/8Pr9AwcO9ITbmrzwwguaPXu2xo0bpz59+kiS/v3vf+vBBx/UsWPHdM899/j12sv4FTozMzNNO8RaW10Nd83nbNYbDWNH53Ybcgf4vrgNtyQfzsetYRlud2A1DXT+smW4jx6Ro23bKtvU9DpvGhivw/96JqB+vOsuUXRAS4A1gh/WQmpbMWHfEQqvBeZzuw3t3r272jaBDMnoC5vNJqfTqfT0dBUUFHimT548WVOmTPFrWTk5OZLODiV5rqSkJOXm5nralH8+LCxMCQkJnvlzc3Mr3NKobJ6cnBzFx8crNze3wnJatmzp+T01efnll/X000/rd7/7nWfaNddcoy5duujJJ5+sm9CZmpoa/COd1R0dqneCW0uz2O22gN8XM95Xu80uuz2wmgY6f9kyAn09R5uEq0k0kbFhMmO7D3A9b0DbSqi8FpjPbrcpLS2t0udcLpeysrLUqVMnORzWHYoyDEPFxcXavn17hSOdDVlOTo569+5dYXrv3r094bc2/AqdDocj6KEToSiU1olA+xL8QADUjYa0rYTCa4H5bDUGSofDYXnolKTY2NiA809ycrIk6fDhw2rVqpVnem5urrp37+5pc/jwYa/5SktLdfz4cc/8SUlJFdqU/VxTm6SkJJ/62qFDB/3jH//Qgw8+6DX9H//4hzp27OjTMirTkA4bAgAAhCSn06nk5GRt3LjRMy0/P19btmxRRkaGJCkjI0N5eXlew1Bu2rRJbrdbF110kafN559/rpKSEk+bDRs2KDU1VfHx8ZLOHpE89/eUtSn7PVUpu7p92rRpeuKJJzRy5Eg99dRTeuqppzRy5EjNmTNH06ZNq3UNCJ0AAAAmKCgo0LZt27Rt2zZJZy8e2rZtm3744QfZbDbdddddmjt3rv75z39qx44duvvuu9WqVSvPvTzT0tI0aNAg3XfffdqyZYv+/e9/a9KkSRo+fLhat24tSRo5cqQiIiJ07733aufOnVq1apUWLlzodZ7lnXfeqfXr12v+/Pn6/vvv9eSTT2rr1q264447qu3/JZdcoiuuuEJHjx7VO++8o+bNm2vNmjVas2aNmjdvrvXr11d6Zb6v6t/N4QEAAELQ1q1bdd1113l+nj59uiRp1KhRWrBgge677z4VFhbq/vvvV15enn71q19pxYoVior6ecy1RYsWaeLEiRo2bJjn5vBPPvmk5/m4uDitXLlSEydO1OWXX67ExERNnDhRt956q6dNnz59tGjRIj3++OOaNWuWOnbsqCVLlqhr167V9n/16tVaunSpHn74Ybndbl133XV6/PHHdfHFF5tSH0InAACACS655BIdP368yudtNpumTZtW7VfUCQkJeuWVV6r9Penp6Xr//ferbTNs2DANGzas2jbl9evXT/369dOcOXP09ttva+nSpRo6dKg6dOig0aNHa9SoUZ7zRmuDr9cBAADg0aRJE918881as2aNNm/erOuvv16vvPKKunfvrlGjRtV6uYROAAAAVKpjx4564IEHNGHCBDVt2lTr1q2r9bL4eh0AAAAVfPbZZ3r99df13nvvyWaz6Te/+Y1Gjx5d6+UROgEAACBJOnjwoJYuXao33nhDe/bsUe/evfXkk09q2LBhatKkSUDLJnQCAABAI0eO1MaNG5WYmKgbb7xRo0ePVmpqqmnLJ3QCAABA4eHh+t///V9dddVVloz0ROgEAACA3njjDUuXz9XrAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6AQAAYDlCJwAAACxH6AQAAIDlCJ0AAACwHKETAAAAliN0AgAAwHKETgAAAFiO0AkAAADLEToBAABM8OSTTyohIcHrX+/evT3P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29/+Vtddd53effdduVwuz9i2ZR/wbNCV86Wmq1evlsvlqnAPOa6urlyPHj10xRVXSJI6d+6s8ePHq1+/fpo7d67eeustSdKRI0e0du1azzxlF8ewnlbkSz2PHj2qdevWSfJeL1lHK0pMTNQtt9yi/v37S/o5BDVv3lyS92hOO3fu9MzHvrRqtakp6ykakga7V7jxxhv1448/atasWXrkkUeUlpbmuZI1NjZW+fn5cjgcXlcCcj+56vlaU/in7GhRly5ddMcdd8hms2nevHk6efKkli9frqNHj+rKK6+scAQElfO3nqhaSkqKJO8jmidOnFB+fr4nVI4YMUJFRUVas2aNZz5qW7Xa1hRoCBrsn02XXnqpRo0apYKCAj344IP6+uuvZbPZVFhYqB9++EGtW7cOdhfrHWpqjXM/oLt27ao777xTF110kSZOnKgzZ87o888/Z5QXP1BP85UPkZGRkZLOnrbwww8/6O233w5Cr+o3aorGqEEe6Sz7C/KGG25Qs2bN9Oabb2rQoEHq2bOnTp8+LZvNpuXLl3u1RfWoad0577zz9PXXX6tXr15au3atwsLCOD8uANTTXElJSYqIiNC1116rgwcP6osvvlB4eDg1DQA1RWNRb9fmsmBzbsApOyn73KEBr776al1yySW68cYblZ2drSZNmmjUqFF88FSCmpqvuppWpqSkRI8++qgMw9AHH3xATcuhnubzt6bHjx/XV199pQsvvJBwVAVqClTOZtTD75jO3XgPHz6s6OhoNWnSpMLRteqOuLlcLs4/PAc1NZ+vNS1v586duuCCC+RwOPjgOQf1NF9tarpt2za9+eabevTRRwnxlaCmQNXqZegs88QTT+jdd9+V3W5XixYt9MQTT6hLly58tRsAamq+2taUEF856mm+2taUcFQ1agpUVK8uJDr3VjxLly7VwoULddddd+nWW2+V3W7XkCFDPLdDqcdZuk5RU/OZVVMC0lnU03y1rWn5+hKOfkZNgZrVyyOdH3zwgf7zn/+oQ4cOGjVqlGf63XffrXXr1umzzz5Tq1atgtjD+oeamo+amot6mo+amo+aAlWrV0c6Jenrr7/WjBkzNH/+fM/XFMXFxZKkF198Ueedd56ef/75YHax3qGm5qOm5qKe5qOm5qOmQPVCPnSWPxDbsWNH3X777UpISPCMMhIREaHS0lK5XC61adNGRUVFwehqvUFNzUdNzUU9zUdNzUdNAf+EdOgsGye5zKlTpxQXF6dbb71VDz74oPbt26fx48dLOnsejMPh0OHDhz032UVF1NR81NRc1NN81NR81BTwX8ie03nubSfmz5+vrVu36ttvv9WYMWM0ePBgpaamavHixXrmmWcUHx+vCy64QHa7XVu3btUXX3zBydiVoKbmo6bmop7mo6bmo6ZALRkh7tFHHzUuuOAC44UXXjD+9re/GU6n0xgzZoxx8uRJ4+TJk8aiRYuMX/7yl8avfvUrY8OGDZ75SkpKgtfpEEdNzUdNzUU9zUdNzUdNAf+E9J9bX3/9tVavXq0lS5YoIyNDX3/9tQoKCnTNNdeoadOmkqSbb75Zbrdbb731llatWqUBAwZIqjiuLc6ipuajpuainuajpuajpkAtBDv1nquoqMjr5y1bthgDBw40DMMwVq1aZbRt29Z45ZVXDMMwjJMnTxofffSRYRiGkZ+fbyxcuNAYMGCA8fvf/75uOx3iqKn5qKm5qKf5qKn5qCkQuJC5kOijjz7SwoULtWXLFs+04uJiHTp0SH//+9/1pz/9SY888ohuv/12SdKWLVu0ePFiff/992rWrJluuukmDRs2TIcOHdKhQ4eC9TJCCjU1HzU1F/U0HzU1HzUFTBLs1GsYhrFkyRKja9euxgMPPGBs2bLF67nbb7/dSEhIMObMmeOZVlRUZNx4443G2LFjDZfL5Zl+8uRJ4/jx43XV7ZBGTc1HTc1FPc1HTc1HTQHzBP2czpUrV2rSpEmaP3++Bg0apNjYWK/nx48fr9zcXC1dulQpKSk6ceKEPvzwQ/33v//Vpk2bZLfbPbeuKDuPprGjpuajpuainuajpuajpoC5gnrLpCNHjuj3v/+9hg4dqjvuuMMzvaCgQLt27VJYWJh69uyprKwsPfPMM/r444/VsWNHtW/fXvPmzVNYWJhKS0u5/cQ5qKn5qKm5qKf5qKn5qClgvqBvDUeOHFGbNm08P//1r3/VJ598onfffVdJSUlKS0vTO++8o/nz5+vo0aNKTEz0tGWDrhw1NR81NRf1NB81NR81BcwV9AuJ8vPztW7dOm3atEm33HKLFi9erMTERK1cuVJz5sxRdna2nnrqKUlSXFycZz7DMNigq0BNzUdNzUU9zUdNzUdNAXMFdato0aKFFixYoLFjx2rTpk1q2rSpnnjiCaWnp6t58+Y6ceKEYmNj5XK5znb2nI2Y+5xVjpqaj5qai3qaj5qaj5oC5gv6n2L9+/fXli1bdOrUKTmdzgrPN23aVK1atQpCz+ovamo+amou6mk+amo+agqYK2THXj9y5Ij+8Ic/6NixY/rggw/kcDiC3aV6j5qaj5qai3qaj5qaj5oCtRP0I53lHT16VH//+9/173//W0eOHPFs0C6Xiw27lqip+aipuain+aip+agpEJigX0hU3n//+1998cUX6tixo9auXavw8HCVlpayQQeAmpqPmpqLepqPmpqPmgKBCcmv1/Py8hQbGyubzcZfkCahpuajpuainuajpuajpkDthWToLGMYBlcBmoyamo+amot6mo+amo+aAv4L6dAJAACAhiHkzukEAABAw0PoBAAAgOUInQAAALAcoRMAAACWI3QCAADAcoROAAAAWI7QCQAAAMsROgEAAGA5QicAAAAsR+gEAACA5f4/CV7x8FnYepIAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAp0AAAHcCAYAAACUORFqAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjQuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8rg+JYAAAACXBIWXMAAA9hAAAPYQGoP6dpAABYX0lEQVR4nO3de3wTdf7v8XeS0guXXii0gNACUgtYBNYtLKiAILoqIguoiwK6injZ47oqN0FUZEX4ia4XRBFl/a2IKJf1AivgQQRvq8iKggK2Byii0HJrS4HSNpnzR2kkvSbNTJO0r+fjwaN08p3pN5/MTN6ZzMzXZhiGIQAAAMBC9kB3AAAAAPUfoRMAAACWI3QCAADAcoROAAAAWI7QCQAAAMsROgEAAGA5QicAAAAsR+gEAACA5cK8aeRyudz/t9lslnUGAAAgWJw9fo7dznE6f3kVOiXp+PHjVvYDAAAgKDVr1izQXagXvA6dkhQZGRn0RzqdTqcyMjKUkpIih8MR6O6EPOppPmpqLuppPmpqPmpqrrqqp2EYKiwstGz5DY1XobMsaNpstqAPnTabTYZhhERfQwH1NB81NRf1NB81NR81NVdd15PXzBycoAAAAADLEToBAABgOUInAAAALEfoBAAAgOUInQAAALAcoRMAAACWI3QCAADAcoROAAAAWI7QCQAAAMsROgEAAGA5QicAACEgNzdX7733nnJzcwPdFaBWCJ0AAISAvLw8rVq1Snl5eYHuClArhE4AAABYjtAJAAAAyxE6AQAAYDlCJwAAACxH6AQAAIDlCJ0AAACwHKETAAAAliN0AgAAwHKETgAAAFiO0AkAAADLEToBAABgOUInAAAALEfoBAAAgOUInQAAALAcoRMAAACWI3QCAACY4NVXX9VFF12kpKQkJSUl6fLLL9eHH37ofnzIkCGKi4vz+HffffcFsMd1KyzQHQAAAKgP2rRpo0ceeUTnnnuuDMPQm2++qZtuukkbN25Uly5dJEk333yzHnzwQfc8UVFRgepunSN0AgAAmODKK6/0+H369OlatGiRvv76a3fojIqKUmJiYiC6F3B8vQ4AAGAyp9OpFStW6OTJk0pPT3dPX7Zsmc4991z16dNHM2bM0MmTJwPYy7rl05FOp9Mpm81mVV9M4XQ6PX7CP9TTfNTUXNTTfNTUfGbU1OVyuX829NemrtZRwzAkSfn5+R75JyIiQhEREZXO8/333+uKK65QYWGhmjRpotdff12dO3eWJI0cOVLt2rVTq1at9P3332vGjBnKzMzU66+/bunzCBY2o6yi1TAMQ/n5+crKypIXzQEAgMlycnK0ZMkS3XjjjUpISAh0dxoEm82m5ORkpaWlqaCgwD198uTJmjJlSqXzFBUVaf/+/crPz9e7776r119/XatWrXIHz7Nt2rRJ1157rf773/+qQ4cOlj2PYOHTkc6UlJSQONKZmZmpTp06yeFwBLo7IY96mo+amot6mo+ams+MmpZdcJKcnKykpCQzuxdy6modNQxDRUVF2r59e4UjnVUJDw9Xx44dJUk9evTQN998o5deeknPPPNMhbYXXnihJGn37t2EzvIcDkfQh84yDoeDnaWJqKf5qKm5qKf5qKn5/Kmp3W53/+R1KWX1Olr27W50dHSt84/L5VJRUVGlj23btk2SGsyFRVy9DgAAYIIZM2bosssuU7t27XT8+HEtX75cn376qVasWKE9e/Zo+fLlGjx4sJo3b67t27dr2rRp6tu3r9LS0gLd9TpB6AQAADDB4cOHdddddyk7O1vR0dE6//zztWLFCl166aXav3+/Pv74Y7344os6efKkzjnnHF1zzTWaMGFCoLtdZwidAAAAJnj++eerfKxt27ZavXp1HfYm+HCfTgAAAFiO0AkAAADLEToBAABgOUInAAAALEfoBACggcjNzdV7772n3NzcQHcFDRChEwCABiIvL0+rVq1SXl5eoLuCBojQCQAAAMsROgEAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYLizQHQAAAOXs2yedPOk5LTu79OfevdKpU79Ob9xYSkqqs64BtUXoLCc3N1ebNm1Sv379FBsbG+juAAAamn37FDby+gqT48PCNLRFvOIfnKawkhKPx0qWv03wRNDj6/VyGCIMABBQ5Y9wnhFbUqJhB7MVWy5wVjcPEEwInQAAALAcoRMAAACWI3QCAADAcoROAAAAWI7QCQAAAMsROgEAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAeC03N1fvvfeecnNzAzI/QhehEwAAeM3f4aIZbrrhInQCAADAcoROAAAAWI7QCQAAAMsROgEAAGA5QicAAAAsR+gEAACA5QidAAAAsByh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UlI0ffp0lZSUeLT59NNP1b9/fyUmJuo3v/mNlixZUqE/Cxcu1AUXXKBWrVrpsssu05YtW8x/0j4gdAIAAJjg888/17hx47Ru3TqtXLlSxcXFGj58uMe9zqdOnao1a9botdde06pVq3Tw4EGNGTPG/bjT6dQNN9yg4uJirV27VvPnz9ebb76pWbNmudtkZWXphhtu0CWXXKJNmzbpzjvv1F/+8hetX7/e3WblypV66KGHNHnyZH388cdKS0vTiBEjdOjQobopRiUInQAAACZYvny5brzxRnXp0kXdunXT/PnztX//fm3dulWSlJeXp8WLF+vxxx9Xv3791KNHD82bN09fffWVNm/eLEn66KOPtGvXLi1YsEDdunXT4MGDNXXqVL3yyisqKiqSJC1atEhJSUn629/+ptTUVI0fP15Dhw7Viy++6O7L/PnzNXbsWN10003q3Lmznn76aTVu3FiLFy+u87qU8enm8E6nM+jvL3b2kJ3wH/U0HzU1F/U0HzU1HzU1V13Vs2zQxvz8fI/8ExERoYiIiBrnz8/PlyTFxcVJkr799lsVFxdrwIAB7jbnnXee2rZtq82bNys9PV2bN29W165dlZCQ4G4zaNAgPfDAA9q5c6cuuOACbd682WMZZW0efPBBSVJRUZG2bt2q++67z/243W5X//793eE2EHwKnRkZGfJi1MygkJmZGegu1CvU03zU1FzU03zU1HzU1FxW19Nmsyk5OVlpaWkqKChwT588ebKmTJlS7bwul0sPPvigevfura5du0qSsrOzFR4erpiYGI+2CQkJys7OliTl5OR4BE5JatmypXv+sjZl085uc/z4cZ06dUq5ublyOp2Vtil/jmld8il0pqSkhMSRzszMTHXq1IkRBExAPc1HTc0VavVs9Od7pKNH/VtI8+YqfuF5czpUiVCraSigpuaqq3oahqGioiJt3769wpHOmkyYMEE7duzQBx98YFn/Qo1PodPhcAR96CzjcDjYsE1EPc1HTc0VMvU8elS2c9r4tQjj51/q5LmGTE1DCDU1l9X1LPt2Nzo62qf8M3HiRK1du1b//ve/dc4557inJyYmqqioSHl5eR5HO3NycpSYmCip9Khn+avMyy7+ObtN+QuCDh06pGbNmikqKspdl8ralD+KWpd8Cp0AgPphzNcv60jRiSoeNeRyGbJ/uUZS5W+08eFN9Ppvx1vWPyAUGYahSZMmafXq1Xr//feVnJzs8Xj37t3VqFEjbdy4UUOHDpVUeuri/v37lZ6eLklKT0/XU089pUOHDrm/Ht+wYYOaNWum1NRUd5sPP/zQY9kbNmxQr169JEnh4eHq0aOHNm7cqKuvvlpS6df9mzZt0rhx46wrQA0InQDQAB0pOqEoL74irHL+01UF1tBUfQivGSEcUulX6suXL9eSJUvUtGlT9zmY0dHRioqKUkxMjEaPHq1p06YpLi5OzZo106RJk5Senu4OnQMHDlRqaqruvPNOPfroo8rJydHjjz+ucePGub/Wv/XWW/XKK6/o4Ycf1ujRo7Vp0ya98847euutt9x9ufvuu3X33XerZ8+e+s1vfqMXX3xRJ06c0E033VT3hTmD0AkAaPAI4TDDokWLJElDhgzxmP7CCy/oxhtvlCTNmjVLdrtdY8eOVVFRkQYOHKi5c+e62zocDi1dulQPPPCArrjiCjVu3FijRo3S1KlT3W2Sk5P11ltvaerUqVqwYIHatGmj5557ToMGDXK3GT58uA4fPqxZs2YpJydH3bp10/Lly/l6HQAAINQdO3asxjaRkZGaO3euR9AsLykpScuWLat2ORdffLE2bdpUbZvx48dr/PjgOQJP6AQAIAj4+xW/xNf8CG6ETgAAgoC/X/FLfM2P4EboBMrhggIAAMxH6ATK4YICAL569eWvZH/mj1U+bpfU1XDJbrNXvZC7ekh+HukEghmhEwAAP8UXFMnWLrnaNjXewjxEhpkGaquaj1wAAACAOTjSiXrFjPMxEXzsd95d5XjlXn1tKUnNm8v10nzzOwcA8AqhE/UK52PWUzWMV+7NyMvGz7+Y1x8EFT5sAqGB0AkACGl82ARCA+d0AgAAwHIN8kgnoz4AgP+4py0AXzTI0MmoD2gIqrv4xmtcfINq8LU2AF80yNAJNAg1XHzjDS6+AQCYhdBZSzWNPuEVjiIBAEzEexOCGaGzlrwZfaImHEUCAJiJ9yYEM0IngAZh9JiuOvz53/1aBhe+AEDtEToBNAiHmzTiAkIACCDu0wkAAAAPn3/+ucaPH6/LL79cv/xSesrF0qVL9cUXX9R6mYROAAAAuL333nsaOXKkoqKi9N1336moqEiSlJ+fr6effrrWyyV0AgAAmOCzzz7TH//4R3Xp0kVxcXFavXq1x+N333234uLiPP6NHDnSo82xY8d0++23KykpScnJybrnnntUUFDg0Wb79u268sor1apVK51//vl69tlnK/TlnXfeUa9evdSqVSv17dtX69at8/p5zJ07V08//bSeffZZNWrUyD39d7/7nb777juvl1MeoRMAAMAEJ0+eVFpamp588skq2wwaNEg7d+50/3vllVc8Hr/99tu1c+dOrVy5UkuXLtXnn3+uv/71r+7H8/PzNWLECLVr104bNmzQY489pjlz5ui1115zt/nyyy81btw4jR49Whs3btTVV1+t0aNH64cffvDqeWRmZqpv374VpkdHRysvL8+rZVSGC4kAAABMMHjwYA0ePLjaNhEREUpMTKz0sV27dmn9+vX66KOP1LNnT0nSnDlzdP3112vmzJlq3bq1li1bpqKiIs2bN0/h4eHq0qWLtm3bpvnz5+uWW26RJC1YsECDBg3SX/7yF0nStGnT9PHHH2vhwoX6+99rvotHQkKCdu/eraSkJI/p//nPf9S+ffsa568KRzoBAADqyKeffqqUlBSlp6fr/vvv19GzhivevHmzYmJi3IFTkgYMGCC73a4tW7a42/Tt21fh4eHuNoMGDVJGRoZyc3MlSV999ZUGDBjg8XcHDhyozZs3e9XHsWPH6sEHH9TXX38tm82mAwcO6O2339b06dN166231vKZ+3ik0+l0ymaz1fqP1QWn0+nxs3JG3XTGC9X3M/C8q2cw8fe1NWPdMKqtV13V1KxPlMHw2gfPp+PqX1tvBM/rEvzbii/LCez89U8wbPfVqav9qGGUrhv5+fke+SciIkIRtbgF26BBgzRkyBAlJydr7969mjlzpq677jqtW7dODodD2dnZatmypcc8YWFhiouLU3Z2tiQpJyenwhHIsnmys7MVGxurnJycCstp2bKlcnJyvOrnfffdJ5fLpWHDhunkyZO6+uqrFRERof/zf/6Pxo+v/b2KfQqdGRkZ7hcg2GVmZlb5mMsVHM/BZbi0a9euQHfDK9XVM5j4+9qasW64XIZXr6vVNe1quOTwcxnBso6a8VzM4O1rW51geV1CaVuxui/B8p4QLIJlu/eG1ftRm82m5ORkpaWleVzMM3nyZE2ZMsXn5Y0YMcL9//PPP1/nn3++evbsqU8//VT9+/c3pc9msNlsmjBhgv7yl79o9+7dOnHihFJTU9W0aVO/lutT6ExJSQmJ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TtUTTzyhkSNH6sknn9STTz6pkSNHas6cOZo6dWqta0DoBAAAMEFBQYG2bdumbdu2SSq9eGjbtm366aefZLPZdOedd2ru3Ln697//re+//1533XWXWrVq5b6XZ2pqqgYNGqR7771XW7Zs0X/+8x9NmjRJw4cPV+vWrSVJI0eOVHh4uO655x7t2LFDK1eu1IIFCzzOs7zjjju0fv16zZs3Tz/++KNmz56trVu36vbbb6+2/xdffLEuu+wyHTlyRO+++66aN2+u1atXa/Xq1WrevLnWr19f6ZX53gq9m8MDAAAEoa1bt+qaa65x/z5t2jRJ0qhRozR//nzde++9OnnypO677z7l5eXpd7/7nZYvX67IyF/HXFu4cKEmTpyoYcOGuW8OP3v2bPfjMTExWrFihSZOnKhLL71U8fHxmjhxom655RZ3m969e2vhwoV6/PHHNXPmTHXs2FGLFy9W165dq+3/qlWrtGTJEj388MNyuVy65ppr9Pjjj+uiiy4ypT6ETgAAABNcfPHFOnbsWJWP22w2TZ06tdqvqOPi4vTKK69U+3fS0tL0wQcfVNtm2LBhGjZsWLVtyuvbt6/69u2rOXPm6J133tGSJUs0dOhQdejQQaNHj9aoUaPc543WBl+vAwAAwK1Jkya66aabtHr1am3evFnXXnutXnnlFXXr1k2jRo2q9XIJnQAAAKhUx44ddf/992vChAlq2rSp1q1bV+tl8fU6AAAAKvjss8/0xhtv6P3335fNZtMf/vAHjR49utbLI3QCAABAknTgwAEtWbJEb775pnbv3q1evXpp9uzZGjZsmJo0aeLXsgmdAAAA0MiRI7Vx40bFx8frhhtu0OjRo5WSkmLa8gmdAAAAUKNGjfS///u/uuKKKywZ6YnQCQAAAL355puWLp+r1wEAAGA5QicAAAAsR+gEAACA5QidAAAAsByhEwAAAJYjdAIAAMByhE4AAABYjtAJAAAAyxE6AQAAYDlCJwAAACxH6AQAAIDlCJ0AAACwHKETAAAAliN0AgAAmGD27NmKi4vz+NerVy/344WFhZowYYI6duyotm3bauzYscrJyfFYxk8//aTrr79ebdq0UUpKiqZPn66SkhKPNp9++qn69++vxMRE/eY3v9GSJUvq5Pn5i9AJAABgks6dO2vnzp3ufx988IH7salTp2rNmjV67bXXtGrVKh08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f39Jv4ag5s2bS/IczWnHjh3u+diXVq02NWU9RX1Sb/cKN9xwg37++WfNnDlTjzzyiFJTU91XskZHRys/P18Oh8PjSkDuJ1c9b2sK35QdLerSpYtuv/122Ww2Pf300zp+/LiWLVumI0eO6PLLL69wBASV87WeqFpSUpIkzyOaubm5ys/Pd4fKESNGqLCwUKtXr3bPR22rVtuaAvVBvf3YdMkll2jUqFEqKCjQAw88oG+++UY2m00nT57UTz/9pNatWwe6iyGHmlrj7Dforl276o477tCFF16oiRMn6vTp0/r8888Z5cUH1NN85UNkRESEpNLTFn766Se98847AehVaKOmaIjq5ZHOsk+Q119/vZo1a6a33npLgwYNUo8ePXTq1CnZbDYtW7bMoy2qR03rzjnnnKNvvvlGPXv21Nq1axUWFsb5cX6gnuZKSEhQeHi4rr76ah04cEBffvmlGjVqRE39QE3RUITs2lwWbM4OOGUnZZ89NOCVV16piy++WDfccIOysrLUpEkTjRo1ijeeSlBT81VX08oUFxfr0UcflWEYWrNmDTUth3qaz9eaHjt2TF9//bUuuOACwlEVqClQOZsRgt8xnb3xHjp0SFFRUWrSpEmFo2vVHXFzOp2cf3gWamo+b2ta3o4dO3TeeefJ4XDwxnMW6mm+2tR027Zteuutt/Too48S4itBTYGqhWToLPPEE0/ovffek91uV4sWLfTEE0+oS5cufLXrB2pqvtrWlBBfOeppvtrWlHBUNWoKVBRSFxKdfSueJUuWaMGCBbrzzjt1yy23yG63a8iQIe7boYRwlq5T1NR8ZtWUgFSKepqvtjUtX1/C0a+oKVCzkDzSuWbNGv33v/9Vhw4dNGrUKPf0u+66S+vWrdNnn32mVq1aBbCHoYeamo+amot6mo+amo+aAlULqSOdkvTNN99o+vTpmjdvnvtriqKiIknSiy++qHPOOUfPP/98ILsYcqip+aipuain+aip+agpUL2gD53lD8R27NhRt912m+Li4tyjjISHh6ukpEROp1Nt2rRRYWFhILoaMqip+aipuain+aip+agp4JugDp1l4ySXOXHihGJiYnTLLbfogQce0N69ezV+/HhJpefBOBwOHTp0yH2TXVRETc1HTc1FPc1HTc1HTQHfBe05nWffdmLevHnaunWrvvvuO40ZM0aDBw9WSkqKFi1apGeeeUaxsbE677zzZLfbtXXrVn355ZecjF0Jamo+amou6mk+amo+agrUkhHkHn30UeO8884zXnjhBeMf//iHkZycbIwZM8Y4fvy4cfz4cWPhwoXGb3/7W+N3v/udsWHDBvd8xcXFget0kKOm5qOm5qKe5qOm5qOmgG+C+uPWN998o1WrVmnx4sVKT0/XN998o4KCAl111VVq2rSpJOmmm26Sy+XS22+/rZUrV2rAgAGSKo5ri1LU1HzU1FzU03zU1HzUFKiFQKfesxUWFnr8vmXLFmPgwIGGYRjGypUrjbZt2xqvvPKKYRiGcfz4ceOjjz4yDMMw8vPzjQULFhgDBgww/vSnP9Vtp4McNTUfNTUX9TQfNTUfNQX8FzQXEn300UdasGCBtmzZ4p5WVFSkgwcP6p///Kf++te/6pFHHtFtt90mSdqyZYsWLVqkH3/8Uc2aNdONN96oYcOG6eDBgzp48GCgnkZQoabmo6bmop7mo6bmo6aASQKdeg3DMBYvXmx07drVuP/++40tW7Z4PHbbbbcZcXFxxpw5c9zTCgsLjRtuuMEYO3as4XQ63dOPHz9uHDt2rK66HdSoqfmoqbmop/moqfmoKWCegJ/TuWLFCk2aNEnz5s3ToEGDFB0d7fH4+PHjlZOToyVLligpKUm5ubn68MMP9csvv2jTpk2y2+3uW1eUnUfT0FFT81FTc1FP81FT81FTwFwBvWXS4cOH9ac//UlDhw7V7bff7p5eUFCgnTt3KiwsTD169FBmZqaeeeYZffzxx+rYsaPat2+vp59+WmFhYSopKeH2E2ehpuajpuainuajpuajpoD5Ar41HD58WG3atHH//uqrr+qTTz7Re++9p4SEBKWmpurdd9/VvHnzdOTIEcXHx7vbskFXjpqaj5qai3qaj5qaj5oC5gr4hUT5+flat26dNm3apJtvvlmLFi1SfHy8VqxYoTlz5igrK0tPPvmkJCkmJsY9n2EYbNBVoKbmo6bmop7mo6bmo6aAuQK6VbRo0ULz58/X2LFjtWnTJjVt2lRPPPGE0tLS1Lx5c+Xm5io6OlpOp7O0s2dtxNznrHLU1HzU1FzU03zU1HzUFDBfwD+K9e/fX1u2bNGJEyeUnJxc4fGmTZuqVatWAehZ6KKm5qOm5qKe5qOm5qOmgLmCduz1w4cP689//rOOHj2qNWvWyOFwBLpLIY+amo+amot6mo+amo+aArUT8COd5R05ckT//Oc/9Z///EeHDx92b9BOp5MNu5aoqfmoqbmop/moqfmoKeCfgF9IVN4vv/yiL7/8Uh07dtTatWvVqFEjlZSUsEH7gZqaj5qai3qaj5qaj5oC/gnKr9fz8vIUHR0tm83GJ0iTUFPzUVNzUU/zUVPzUVOg9oIydJYxDIOrAE1GTc1HTc1FPc1HTc1HTQHfBXXoBAAAQP0QdOd0AgAAoP4hdAIAAMByhE4AAABYjtAJAAAAyxE6AQAAYDlCJwAAACxH6AQAAIDlCJ0AAACwHKETAAAAliN0AgAAwHL/H6ldrA20YGGEAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "# %load pr451_test.py\n", + "import pandas as pd\n", + "import mplfinance as mpf\n", + "import ast \n", + "\n", + "df = pd.read_csv('pr451data.csv',index_col=0,parse_dates=True)\n", + "\n", + "df = df.iloc[0:30]\n", + "print(df.head(3))\n", + "\n", + "\n", + "custom_colors = []\n", + "for i in range(len(df)):\n", + " if i % 3 == 0:\n", + " custom_colors.append(mpf.make_marketcolors(up='#29c9ff', down='#f3b5ff', edge='#29c9ff',\n", + " wick='#29c9ff', ohlc='#32a852', volume='#a89132'))\n", + " elif i%5 == 0:\n", + " custom_colors.append(\"#000000\")\n", + " else:\n", + " custom_colors.append(None)\n", + "\n", + "#STYLE = 'binance'\n", + "STYLE = 'yahoo'\n", + "\n", + "#mpf.plot(df, type='candle',style=STYLE,volume=True,block=False,figscale=3.0,savefig='pr451t2no.jpg')\n", + "mpf.plot(df, type='candle',style=STYLE,volume=True,block=False)\n", + "\n", + "mpf.plot(df, type='candle',style=STYLE,volume=True,block=False,marketcolor_overrides=custom_colors)\n", + "\n", + "mpf.plot(df, type='candle',style=STYLE,volume=True,block=False,marketcolor_overrides=custom_colors,mco_faceonly=True)\n", + "\n", + "#nans = [float('nan')]*len(df.columns)\n", + "#for row in [8,9,10,11]:\n", + "# df.loc[df.index[row]] = nans\n", + "#mpf.plot(df, type='candle',style=STYLE,volume=True,block=False,figscale=1.5)\n", + "#mpf.plot(df, type='candle',style=STYLE,override_marketcolors=custom_colors,volume=True,figscale=3.0,savefig='pr451t2ye.jpg')\n", + "#mpf.plot(df, type='candle',style=STYLE,override_marketcolors=custom_colors,volume=True,figscale=1.5)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/scratch_pad/pr451data.csv b/examples/scratch_pad/pr451data.csv new file mode 100644 index 00000000..fe22c178 --- /dev/null +++ b/examples/scratch_pad/pr451data.csv @@ -0,0 +1,124 @@ +Date,Open,Close,High,Low,Date,Volume +2019-09-01,29,20,29,20,2019-09-01,10787 +2019-09-02,29,31,33,23,2019-09-02,17215 +2019-09-03,29,20,29,20,2019-09-03,16697 +2019-09-04,24,16,24,15,2019-09-04,12104 +2019-09-05,23,20,25,15,2019-09-05,12159 +2019-09-06,22,24,24,20,2019-09-06,13618 +2019-09-07,19,15,22,14,2019-09-07,13645 +2019-09-08,13,13,15,13,2019-09-08,13472 +2019-09-09,20,16,20,14,2019-09-09,17861 +2019-09-10,17,25,25,16,2019-09-10,18565 +2019-09-11,30,24,30,23,2019-09-11,10283 +2019-09-12,24,25,26,19,2019-09-12,10102 +2019-09-13,22,22,26,21,2019-09-13,17100 +2019-09-14,27,28,28,21,2019-09-14,13079 +2019-09-15,26,29,29,26,2019-09-15,10800 +2019-09-16,30,23,30,21,2019-09-16,17927 +2019-09-17,30,27,30,26,2019-09-17,16355 +2019-09-18,22,27,29,22,2019-09-18,12066 +2019-09-19,19,23,23,18,2019-09-19,19733 +2019-09-20,21,14,24,14,2019-09-20,14761 +2019-09-21,24,23,24,19,2019-09-21,19410 +2019-09-22,15,25,25,15,2019-09-22,17238 +2019-09-23,23,20,26,18,2019-09-23,10840 +2019-09-24,18,25,26,17,2019-09-24,17668 +2019-09-25,23,28,29,23,2019-09-25,19267 +2019-09-26,30,26,31,26,2019-09-26,18340 +2019-09-27,33,28,37,27,2019-09-27,18905 +2019-09-28,26,25,34,25,2019-09-28,16682 +2019-09-29,31,27,32,24,2019-09-29,12605 +2019-09-30,30,31,32,23,2019-09-30,12702 +2019-10-01,37,31,38,29,2019-10-01,17485 +2019-10-02,41,39,42,39,2019-10-02,12198 +2019-10-03,39,45,46,37,2019-10-03,14923 +2019-10-04,41,48,50,41,2019-10-04,10326 +2019-10-05,41,44,47,40,2019-10-05,17738 +2019-10-06,47,49,52,46,2019-10-06,13330 +2019-10-07,47,45,48,38,2019-10-07,19102 +2019-10-08,43,44,45,39,2019-10-08,16682 +2019-10-09,40,32,41,32,2019-10-09,12813 +2019-10-10,46,38,46,36,2019-10-10,12306 +2019-10-11,44,42,45,38,2019-10-11,17205 +2019-10-12,44,44,44,35,2019-10-12,14736 +2019-10-13,39,41,42,34,2019-10-13,19296 +2019-10-14,34,31,34,31,2019-10-14,12587 +2019-10-15,32,31,33,31,2019-10-15,14709 +2019-10-16,42,36,43,36,2019-10-16,18555 +2019-10-17,43,40,43,40,2019-10-17,18850 +2019-10-18,37,41,41,37,2019-10-18,14650 +2019-10-19,31,37,38,31,2019-10-19,10405 +2019-10-20,26,34,35,26,2019-10-20,12074 +2019-10-21,34,30,34,26,2019-10-21,17407 +2019-10-22,23,32,32,22,2019-10-22,18649 +2019-10-23,20,23,27,18,2019-10-23,16161 +2019-10-24,20,18,20,18,2019-10-24,14008 +2019-10-25,20,21,25,19,2019-10-25,16251 +2019-10-26,19,17,24,17,2019-10-26,14594 +2019-10-27,29,20,29,19,2019-10-27,10994 +2019-10-28,28,26,30,23,2019-10-28,16978 +2019-10-29,30,22,30,22,2019-10-29,11373 +2019-10-30,18,26,28,18,2019-10-30,11589 +2019-10-31,26,21,31,21,2019-10-31,14787 +2019-11-01,19,25,26,18,2019-11-01,15088 +2019-11-02,25,26,27,22,2019-11-02,10827 +2019-11-03,24,28,28,22,2019-11-03,12281 +2019-11-04,24,15,24,15,2019-11-04,19768 +2019-11-05,22,17,23,15,2019-11-05,11398 +2019-11-06,20,23,25,18,2019-11-06,15819 +2019-11-07,20,26,26,17,2019-11-07,14057 +2019-11-08,15,14,24,14,2019-11-08,15366 +2019-11-09,11,12,18,11,2019-11-09,10403 +2019-11-10,16,13,20,13,2019-11-10,15611 +2019-11-11,18,15,18,10,2019-11-11,14544 +2019-11-12,18,11,19,11,2019-11-12,12009 +2019-11-13,16,16,22,14,2019-11-13,18481 +2019-11-14,14,11,20,11,2019-11-14,11876 +2019-11-15,21,16,23,15,2019-11-15,16481 +2019-11-16,23,23,23,15,2019-11-16,18562 +2019-11-17,26,18,26,17,2019-11-17,16095 +2019-11-18,24,24,26,21,2019-11-18,14052 +2019-11-19,30,23,31,22,2019-11-19,12698 +2019-11-20,27,25,32,22,2019-11-20,10097 +2019-11-21,24,28,30,22,2019-11-21,12405 +2019-11-22,18,22,23,18,2019-11-22,11883 +2019-11-23,18,21,22,17,2019-11-23,15834 +2019-11-24,21,18,24,18,2019-11-24,17172 +2019-11-25,24,15,25,15,2019-11-25,11327 +2019-11-26,27,25,27,17,2019-11-26,11876 +2019-11-27,30,24,32,23,2019-11-27,17715 +2019-11-28,28,22,28,19,2019-11-28,14520 +2019-11-29,14,16,19,13,2019-11-29,18113 +2019-11-30,22,19,23,19,2019-11-30,16670 +2019-12-01,31,26,32,25,2019-12-01,15978 +2019-12-02,29,26,30,26,2019-12-02,15367 +2019-12-03,28,28,28,28,2019-12-03,18364 +2019-12-04,27,27,28,27,2019-12-04,17550 +2019-12-05,37,41,42,34,2019-12-05,16636 +2019-12-06,31,28,36,28,2019-12-06,15326 +2019-12-07,33,28,36,28,2019-12-07,15007 +2019-12-08,37,38,38,35,2019-12-08,16018 +2019-12-09,44,43,44,43,2019-12-09,17392 +2019-12-10,36,40,40,33,2019-12-10,17550 +2019-12-11,27,35,36,26,2019-12-11,13408 +2019-12-12,32,24,32,23,2019-12-12,19170 +2019-12-13,29,34,34,29,2019-12-13,12548 +2019-12-14,34,31,36,28,2019-12-14,19605 +2019-12-15,33,31,37,31,2019-12-15,14594 +2019-12-16,43,43,43,39,2019-12-16,16895 +2019-12-17,50,40,50,40,2019-12-17,18880 +2019-12-18,42,48,48,39,2019-12-18,18207 +2019-12-19,44,39,49,39,2019-12-19,17279 +2019-12-20,53,46,53,45,2019-12-20,11028 +2019-12-21,51,44,51,43,2019-12-21,19840 +2019-12-22,44,49,49,41,2019-12-22,10863 +2019-12-23,43,40,45,38,2019-12-23,13153 +2019-12-24,50,42,50,40,2019-12-24,16929 +2019-12-25,51,42,52,42,2019-12-25,17419 +2019-12-26,49,56,56,49,2019-12-26,13232 +2019-12-27,47,48,50,45,2019-12-27,19252 +2019-12-28,54,53,54,53,2019-12-28,11631 +2019-12-29,46,53,53,46,2019-12-29,14527 +2019-12-30,46,46,55,46,2019-12-30,10600 +2019-12-31,54,58,59,53,2019-12-31,17911 +2020-01-01,55,48,56,47,2020-01-01,17827 diff --git a/src/Figure_1.png b/src/Figure_1.png deleted file mode 100644 index 062eb929699fec7bc2f16bf363069783a7f67305..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59649 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�jZ4}H!Dd|&QQ4+F^Xy#MV3uCJ6I z0tU@3ghEFKT!>wwyP{C}*Q{CdhlI`yKA@d^m${BX{@ zUZje2|C0v}X1xSh{mE`WehlPHd!BzG5Kl@%-8!>56GSh)s?7O4#diZV_b{6??bUuQ zZCWeF9(&NBq*OYN^r0rINV3Z?=i}5P2}HqJ>0Yvo0qGscfg!ziIrVE=YbkajEu6XJ za#)^CRVc~DCR7c~$_U&H4u8$3UvfEl>X=#X!EtMc3#%w}T?b*Y0-OjxDnd@36Ur2IQ^a|hwqB4nez$V6I(oII&5nTTQ<1=xfBe3<9>_wv29 zb)}T3!V0F?tJgLl+$#tfE66h3G)bljzv-*ZXFA@`Lk>x5V^`+ToV<89>|b#`J;Yy& z{kGrkfp}Vfk}5#(k^nnF2#1JcIi>L%^LDKd{1;|#ci2VbQ%+t|#;TXLxLh;jsvczl zVeI(f!%+zZvN@2kLVtk}?Sg0{7%4&Facv3zDW@hGcWDY^q0;JJ^d(G=!e7}i#=4*vgSA2YOQfU>nmp$;~qYFy^dRSOOsR7kOsN0ILLvBE&I;;qz6 zs5>#2?v8@Jm;8YKQ(~l#f1cEp%AN9Cf7M%iw*J5;<>Pku8@G*&sNaMeha_4`1!_EY?9lA`D_4w#B@s?_ z4BS{4vBQHkNVvOGrgb%9z^MxxzA+c%_3l}4Q|UiV=UiO0nM7U1`Z0$@>=wVKIN{6j zAN2JWZYP0O?>1|%T4C0c=7Y)Z?gI(ru|IQ^ z%_;<*5ZsAS8v$hr7|VL?GX7fjd)IEYv0KImG*=PE7d^YA2NAagn4G|8i6S2SKK;18 zYAcGri0n{!yKx84F$pZbW4LnophN|mSL-DT119Lg6CEuHDLpS1k3l6_ZbWI05-CL?}=I!DV^MylNM|(ZL;#c&tFmsqQ-0Y~KZt2P3=qbf*%6-$?%tg$?hp3SRa0sA_U(J2eIhPgxF9lCT-Pzqc7dBG z))Nk$uK0SmU0ZWDJe;5+n8t#V5<9nd&?rDCbyoF0(Aka4>mF+Ojbk2mECq)xpP$T| zF8=a|li1Y`hm8kuNZB4@jKLFIQMlQVLSyBIQeY^fp;4VUKcaW2 zeK5-L9@r*3#HMhKx%*Ruxf(0$AadtOAW&8U&k4z9~Og1yvUZtQ~LgaSz^dW zIss78#&~VZn`j3wsN$mLXjB)kUm6!0k9SocSsRwcET>NJ6{14Nj1nQlU+()Rps10$ zNr-s}5V>f0Lb04+tS;L&Ju@d~A_cUSThP1z`iW%8s0B;3-mI4QI)I&-2R_4q^v7M8 z%hvg`-%U(r`zRZxWdCmO>kw~hpptk%P)+sD=g4WKekxS>iND$$TX zA}1%8PjG6W-{u%ar_d(0{nc+fYt8&bxd+)y&=kBwnjg-#w*S;{IEGhA#b9A40snXd z)uaG?`#DrHqE03*d4a0Y(*2|)I}4=^K15t~xn8<^;38}|Fz5}rqo-mN-i4Y|p01x$ zZ0tAH{NhE3tqC>hIR6l*xBJ(>oQHy_PE8%n!XEnV66Di?v8yx#mfQ1C_rPGxgmuzj zWfW~&vUS_GVzNUr)M(jB$H8?ku3bjfcHoL{B{Zg1TwQ%yNF;R$5j%E7qotMLRTXlF z(~S+Q-7YP~K!4a|wJp(6OYCv>+Yalz6~D=|dwDjxcwTr5r*l(_SZIiI|Y$28<-aBO;Hicvnhr#PJxapUe?9r$TYm;1G8Jd z>?kNK+%fG$G}mEES{8vR@uAO!*7NUq5l&}j8K}Y{<7*JA2qzj%1z%x zUtC}BY@symKUUBXHfl73OtPH-*p1E2y%eK}jS-lgADmmTK=tX6ykyrAeok{R=!)Y2 zb3dGzc4RME+y+a8kcXw~8=IP90B^MR%6-jh~!6)9+g)$ zEU0aGLJ-cbtQwh6Q1pptpxLd@D1B=>V?1lf@GIeeQ`#$xraohW%7cIB&4KbJ9SSXr)D_8CXbM(3X z4=ll}w{JB`w1Jh?Wir7LdQq|w^|Iw!ms>2pVH1v`{J4$2FvY@)jAFR*jWr6}z<^#; zudM%i{LQ_i3z)C6D6N%sp`@%lc)`YRu`xO`r(If6Ib2;GrPmPLG}JLM^m*3CXG()k zBaQ5#K%6fGJL=|@ElrE*B96Sc;LNr4^V1(QKxqgj^K@2%ET)FOW0qU9YLX{~NEhG4`IEr>Y2wz@n6Qa; z{w5)g9YIUcTRO|x3X9TYmm?5wHaz5*u*tF7j+1R;vxc$0ROdiT~MAd!7Dy=E5GP2Ko@6Tz^4QwsHsA)rTW3*k&DHs2LL zVdJn^otbgOd0WDDa!^}~ThNa)=bw#GGW+y{LSyBZH#RjH#3NhaiWk@a@ta{eKamWT zlFkG4ItPzvyU^2f$f!{+G>nblfjeDV>gKm}ln5Q_#30-C}PJ%!hY%NFl zD<0Uv;#EBUS+>0X*ow+5J?=OfIY$786vB|2(Y`H!5y75~TJdr&>bjn~tiwJ%*E9Ro z82soqf;A+3wLj}l9DPH1f8AucCIp|~+O_*wAvh0_Y{k<@ZUGZnv8sd!+*>iKp}`lV z5D9WH$3(ZZC~f2s%Knf|VWFY7;U;bt7Ftb1krhaUJHO2^A`6Xbi@SVT4CZcazwjk! z;-+iC?eX^tzAtO}`O^kYuv<{Qy6pJN%a<=Vq@a$7h*+O3b^1QVt$;x5<3oa;pi$~j z!0d(6DK`7vI#^xy*H&^pBwqGP`;y{MBZu&+U%h`n4C=af)SDva_lBa5IKkn0ZLWQA z^Fgg{ROst_yx?R?6zTk|qo(T-iq())tx04mX_*}l*P``gVoiMcki9B(_#VrC4@Rr+Tl2uj%qK-5&Q@$ z_G=#gmB62dL9LBe_+~uV42aJMC#kyq{9gaz!w&Z1V2T$UFb1Zkrd4m>N=tsAqYHwE zzHx=xXO~Av@+*H~HE7_=uPL*%Spg|VlX~)ULg51Pku+n6&B$XYV>QJPHMYP`#_$jn z?!wS#JZ@ay>-&DqDi`B=lYq?KqwnGt6r>3JjKPMcMMF|M zD+N8K#w%dOPtOWmFK2Zy(;ISth-yyaFFoNf0Nz*oot4nZj+xNd=6%paGb1KGy}4jR zOikU|lM!prv`mtRNb5a(?nFdSmf3xN3L~S?qPPqd6Mt>nINj8k*clE!cN5HxJ>enK zELx^L!Qk+`~qv9{M-})kI&AWY3rt^FzMBZ!CCpg@@{Sd(R-T`V`gF zcJiP+UB4GP|L}65P7FPEh@7_!(NV2mKR*r=Q#1CJpuyHs`sS(~Z+t(tqtgbA0vdwCAf6K|8Y+kn;R%u1XF`R}g=h#gRMSK~Xs54bl4m=D)=;!NeWwJXH? z-8Xz*9@swiyJLrqd9h7@$+Su7;m<(spUgkq&)&32P{WXfR$g8j(X*BBEKY*AL0Qg) zTJyuNi$ZDc7Upz(z|@ACeG6U@jl$@T742v|1W%q7LFFc7q1a5OL9Hqh;k3JRaI_pP zBKVtnz3foJxUW3ec5h#U6e6FH)WCsZAdV_14(szf4ZVxqLC-Y0{tgJAbpwT85xNfb z5zyZcLIZywp(<@rsk*QiX5OB%&A#6u9_$v%I`NyRB_`6adLF#-@!4es!~~wgWU`T7 zj|>x)zDK?_RGR}8Eyms|EG!(XsVU7UJOzM^%vsk%AIA;apjH2M+x)~kUR*;NL)3l} za#M%_(heU?8PG@UEaIDEy(0!_f8+M;(E4L!rh2Wm8DO9I`?Bll8FBQ@TOTm=j>+8Q zxo{y+-iks)6MTDV;)4SVWHueJXiVj-$Q(&ZQM;lh_E!7$%fd zRfnpp3!D{id}N*3L|NxGe?TeYLGD!Fps8u7%gH@+udSKd()>w>hw{dJM_JC{6Lv?b zFV=rzp9-WaXctiotZy-R_P+01wL?t~rjG(zno?QqjR}7*PCoaTjLag9VsqHQA;id- zizyAT5+zy*&fBW;leF!g5(GH@Vh3&(b#x8VSs}njSnm8kJnANzdf6F~@V$MnJN#~l zo1uw~CJOmMsZLtBvrQn2yIF=7p1ybQH!&RmlCj@5iIf z!gmSTY=!%gd)NW9vXGVV1G|Ax#PbRZW%#Vn8#iujO>zzUAGc>mWdF3wm&2x=2(e6Z zv|KFT-&6$_!yF<+N+Lv|f9K!W4sTYC3vFv;WTfHsxIM=`onJkh5c)mn_^`$O>b}dt zrmp+)Mi!ze4BwACsa04UC$#^dV=hw(y~Eq-w|qm@&>i_^JQ zJ1$UEHrNZC^gQ_=LC#Fu_r;9zCWgdUL_B^23lm4ZupM&f%)D!^M2a`me1=FjA^kfw zYwmA0S~jZg`u4-84Kp8X$fK27huypvg7V1~za-&vBNfLiUTQ7B!Awkcw zkD#ggG->|Jc{VUV1(nwhl$q?c*6`>WONpzq`c7qg-xaHtCO)`vxAqJxcss^n{FzVG z4V)j*dy#$^dC^u}JW{U3%foM|DHe$O2Uck%&hv zldiWpSYS9QAf)j4PQPEx%YM>sm4ePD%*oKa&hrC)G$e?~f{}NbZ>hefrlr7%&&wvo zI2upentm83L855aUiDTU@DqYUu#mhWScfmkMUWv0fOX9h2PJrw%@aN}gawE^!BNVs>^@03X!E;<^GoTG{Fc!{gPkwVJwNYhRTJdhW_r5iSM0Y{?N7<|kRFmf zDJPP)@7`TV+l3=6Iy^;pKvOOmY>;|GQ`4yZg>#ZhY0K)00~-Tv1&)^bpQFre9rj&H zPtU`qI-Sil#3t!MV?|6BjRX2CUYZI!2_%n<1PQ#82w%8$F;ZMyM(+nsOF)vjbrp58EE$Ukc3t)JeA+|A9Gj3@#ed~d5hwO^BH&p8kY08qp z#(tESqSV-Ly55kk7WskIr`98Z>8Wjed(-IP`3mK@3D`HP-@iZA`l-5FN+Mmf4AmN$ zR!aC2E)`ka8MUj-+RW6*Temqlx{q(Y^#I+M%5gzT4t3>J0^%JAd4qVmH*_^=U8s>8 z)V>MRGe{Xc?dB_IsKw(cj8D6~s=akRw!$j1nz;LwZ*C{Zmp)oFN~98j&QS6Ir-Oh$ zfXN&|Bqi^&f2|$abko!MmWP6Is_gDpO_N@Y_oypjsr+vLHG(+R1>3^M7uS08%q^q! z+kVrTB10z)tq}`Z-87n98!~24xkul-vp&*P2JpNo47A54N{M9y#K;jH{!}085W>7A zNpOeGT}9a|@FB&`bc$oa)~n9TksE%?FUFD~-a|dpWDY+FxAJQl*chMIG(=sj*DrYY z*}JcJB||km04t)Cj6z<})lfAr%MR_SON;zlzB%;9A+Ev$mGK7^vRHk_#>VcvY0;XG zA|&n!gJpOZ$w2mq@%k?s?8|VT#+NO2!;EbQZyYkgsGF)`Ct_Sa8%RpR{D8Bip5^R? z^-FC#2jtkCUH2wIp;x`Eof+tnHzI`k=PzCeTfD?NF0?K{^~{+w_nC4E^>=ipuXB#k z!K@19=FeD>J(ewtq}CtE!;l1%lLZnKE-{u;>A3}F70;f*cvmCMhPs}I7-KQo?}p}hBjRFLN^Vo5139edkzz&X2IQ6PZr2!Sz_Q?8J4*J9STG^U zWVtGs(+|t)O+(nE~5j{erixs{O6)cGRmzK>5 z3CKfxCH>#Ox_XHu2i|m@)1mOJUAVV*QJ)LzrRbYtjfepyqZXHSA{!UWhBAnSN-YgU zEc_GLkVPlhu$liZt(#ipQeiprB^lrE!y`Se{Wa>;tP6j4gA0vdJLaJP2iNs~a%S#j zY)Y0WxBS7{AV1J!kp~r}=q2RhI;>ljdm4}|I=}F`ttd*HF*w7q59^4Zx`pN7%YE<#fI52P}i4eFa$B(fUV!aq3yqt`FW1uL8|=;4^nYNgM-QRDfb6 ze}-IOT@WrN6qai09omaFhgWe$Q?MrMs%4r0&U&$Ngoi=c`>teWdcbC5hu&(~!Q3Lo zv5&9}5gn+~mgw7tD6!@YMCAhht;SP8fmFQm$TS&6#|=5(ewC8}JvekkbeJILa`ehVlf}V$6jZfEwM#FT#KMf!LxlQ_X2Wq>$xC)Bd zmEGbT7#RNk(ODgQ2hpNJFL``+jux^bukhdN@2nq&EF0AZYM#d4(qe7LP@$IA`KzlV zKg4EpK8prkooJS33A{}TFy9FYxzr~kPJX;I?S?yqYYvd1g*7z_PR@pfSOc_BR~O|B zcri}!fv~AU+7r@aDt3%#$*Mr?Vc2J|=QrOb91Y>7Kp7fBZNa*E8yUpHBIZ&HlO7gV zq$P}6S}{F!!J`X<`X4H*=6H18hH_SOHpo5jL zG~Q3xEj1{9_2Z{yc=VlWMkmFgz%NBwq6uXv1cDHvg_1*?S8v7q=<|5q@W?wCpfDi9 ztD}Ibf6+|1y&dTGRwax3LoAp)*GAx#Jn z>$}f%?U%J|xTnKD>0qK&5_m~O3yR53lH&4|-#=a}q-;zNiYBCPq!~suje&h8VWtuJ zTM()|=&?XJVY`9<9QLc2&HNgMRTw}p0WPbqjoA6xO*yrzNQNz8OW7&|seSSJ6)yq6 z-eT_=xaUYDvNmW9roo}n)ike3s>}!PbO$h8U-0uq&tWcIC?oTkFexp;Vc&6&uR~(c zU$$-KNei+94}5HEeQ{!VV|j{{wzvy8X+gpY_qc>FJThBmbo#Qx`2L3sU5U7C=U9^+ z+qZYv)19YJpLVdePMd#yU4m}?<8uRe*t)%v z4*LEN4tjlF=I{gydg5KGi4LN{azpdS)H}aqBp5*^V<0qGSkT4W4V;Zaq1dlqH@f<1 zGKv{LI^y>4~jJ5T@4ye=31C1c9f|S;~@${Kc2<6)_utOc*L& zJDoU?!~%i{J0+c=;%U8H;3?jlzR|t+FmK^RjfD(gV&qdwneyM>-Zz2X$Ie}&+!Z|< zwY)_h_z8`S>s1R62F2Xs>(di0WYKPVpgm7QZ);?oh;as3pbGF@Rlj|^jXHUf1+ydm zbL?X&k{uy05~g|(3IX6DpE{^CW68`EndiU^EWhG+r&roP@3@?CkSTa+-scYPnYyJt zUcap&lVwL?Foe55dU5R7v8vaPet)I{D`8IMAu6J(yAjKT)E)4?$z~QopJgu}@{Lpa zN}K*UrDeY<`wO&vDfX?9_%uvg`|@kbtbZSRDdbyY;T|T@3ieBwHbi~EGuQec_0KPj z(H={NJk);|pT_dYXJRJX_YxgTq8E!-RE4I{dCzoVBNUAu=p2&kHb~)lF&=i;7alU? z4)WvEzMtbV1nU6U$V)DfS4)X%U$@kD!AGeRXSM~nI2|dF(Qhm7E+sk>LN# zxmay_bqqU{hP{P+|DbeOQ-MWkv4YgCE($qNVOiNNAWt`mYF!Lo0A7B$CqCMMk2d@B z(N=m+LqzQc_>YN~uA1s(M2iKJzq`{6;65*_^QF?uh4K0&r9ugLbo2mN`gKD^(`T@> zTelH~dxin%gr)wv*2jLe19qXrhal$u;pM>Nesn9joSdGUSDLE)toGS!)6;P`qn}9M%kK7g@GBb4)jdzLwp|4qH%|*WrDNgrTa0r z9^R-ZFDi8apXcGAlG@E`ak3d$K_MV#sE+$?z0`xOCr$Y}A(=>m@sB0oJn6OTZGMhX z%km0kOP^fFKB|<}O_bFw_x(oLohqaVaX^#m-lIqI^VimOAIm~&?tM1~e3TtLx>`GOXRfDn3svaGlcN#`?3)OZiD=_I6=6y8 zZT{${*)67SNY>FP?F*O~s%~~@slv0auKw`8mYls0U(z-Zvv`t+@oB)Yx)Y^F@J_;<4V Gmj4H7in_o6 diff --git a/src/mplfinance/_version.py b/src/mplfinance/_version.py index ac383efb..8a17c325 100644 --- a/src/mplfinance/_version.py +++ b/src/mplfinance/_version.py @@ -1,5 +1,5 @@ -version_info = (0, 12, 7, 'alpha', 18) +version_info = (0, 12, 8, 'beta', 4) _specifier_ = {'alpha': 'a','beta': 'b','candidate': 'rc','final': ''} diff --git a/src/trial.py b/src/trial.py deleted file mode 100644 index d75885ec..00000000 --- a/src/trial.py +++ /dev/null @@ -1,45 +0,0 @@ -import pandas as pd -import random -from datetime import date, timedelta -from mplfinance.plotting import plot -from mplfinance._styles import make_marketcolors - -dict_data = [] -start_date = date(2019, 1, 1) -end_date = date(2020, 1, 1) -delta = timedelta(days=1) -start = 20 -end = 30 -while start_date <= end_date: - openval = random.randint(start, end) - closeval = random.randint(start, end) - high = random.randint(max(openval, closeval), end) - low = random.randint(start, min(openval, closeval)) - change = random.randint(-5, 5) - volume = random.randint(10000, 20000) - dict_data.append({ - "Open": openval, - "Close": closeval, - "High": high, - "Low": low, - "Date": start_date, - "Volume": volume - }) - start += change - end += change - start_date += delta - -df = pd.DataFrame(dict_data) -df.index = pd.to_datetime(df['Date']) - -custom_colors = [] -for i in range(len(df)): - if i % 3 == 0: - custom_colors.append(make_marketcolors(up='#29c9ff', down='#f3b5ff', edge='#29c9ff', wick='#29c9ff', ohlc='#32a852', volume='#a89132')) - elif i%5 == 0: - custom_colors.append("#000000") - else: - custom_colors.append(None) - -plot(df, type='candle', style='yahoo', override_marketcolors=custom_colors, volume=True) -# plot(df, type='candle', style='yahoo', volume=True) From fb9e6ff56690720602c1307c440a35c0f080e22f Mon Sep 17 00:00:00 2001 From: Daniel Goldfarb Date: Thu, 9 Dec 2021 18:24:40 -0500 Subject: [PATCH 09/11] add marketcolor_overrides tutorial --- examples/marketcolor_overrides.ipynb | 795 +++++++++++++++++++++++++++ examples/scratch_pad/pr451_test.py | 8 +- 2 files changed, 800 insertions(+), 3 deletions(-) create mode 100644 examples/marketcolor_overrides.ipynb diff --git a/examples/marketcolor_overrides.ipynb b/examples/marketcolor_overrides.ipynb new file mode 100644 index 00000000..6e436e51 --- /dev/null +++ b/examples/marketcolor_overrides.ipynb @@ -0,0 +1,795 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "# This allows multiple outputs from a single jupyter notebook cell:\n", + "from IPython.core.interactiveshell import InteractiveShell\n", + "InteractiveShell.ast_node_interactivity = \"all\"" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "# Coloring Individual Candlesticks\n", + "\n", + "- Users can **color one or more specific candlesticks (or ohlc bars) differently than others**.\n", + " - Users may choose to do this in order to highlight a specific pattern or technical signal.\n", + "\n", + "\n", + "- The **`marketcolor_overrides` kwarg** is used to specify individual candle colors.\n", + "\n", + "\n", + "- **`marketcolor_overrides`** must be set it to an interable (`list`,`tuple`,`ndarray`) **that is the *same length as the dataframe*** being plotted.\n", + " - The simplest way to do this is to create a \"marketcolor overrides\" column in the dataframe.\n", + "\n", + "\n", + "- **Rows where the user wants to override the candle color must contain a \"color-like\" object:**\n", + " - Examples of color-like objects include:\n", + " - a **string** such as `'yellow'` or `'#ffff00'`\n", + " - an **rgb or rgba tuple** such as `(255, 255, 0)` or `(255, 255, 0, 0.75)`\n", + " - an **mplfinance marketcolor object**, created with `mpf.make_marketcolors()`\n", + "\n", + "\n", + "- **Rows where the user does *NOT* want to override** the candle color ***MUST*** contain **`None`** values.\n", + "\n", + "---\n", + "---\n", + "\n", + "### To illustrate, we will first give simple examples using just a few candles.\n", + "### This is followed by examples using more realistic, larger, data sets:\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "pandas version= 1.1.2\n", + "mplfinance version= 0.12.8b4\n" + ] + } + ], + "source": [ + "%matplotlib inline\n", + "import pandas as pd\n", + "print('pandas version=',pd.__version__)\n", + "\n", + "import mplfinance as mpf\n", + "print('mplfinance version=',mpf.__version__)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "#### Start with a simple, 5-row DataFrame:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OpenHighLowCloseVolume
2021-10-11131.4133.2131.3132.119591
2021-10-12131.9132.7131.3131.421467
2021-10-13132.0133.2131.5131.820406
2021-10-14130.9132.7130.6132.122611
2021-10-15131.6131.8130.7131.022001
\n", + "
" + ], + "text/plain": [ + " Open High Low Close Volume\n", + "2021-10-11 131.4 133.2 131.3 132.1 19591\n", + "2021-10-12 131.9 132.7 131.3 131.4 21467\n", + "2021-10-13 132.0 133.2 131.5 131.8 20406\n", + "2021-10-14 130.9 132.7 130.6 132.1 22611\n", + "2021-10-15 131.6 131.8 130.7 131.0 22001" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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KD8/v9bzJXQCAADAo02bNtqzZ0+F4X//+98VERFR6/kSOgEAAOAxevRoPfLII9qxY4ccDoeysrL09ttv67HHHtMdd9xR6/ly9ToAAAA8JkyYILfbreTkZBUVFenGG2+Uv7+/7rvvvlpfDS8ROgEAAHAah8OhiRMn6v7779eePXt07Ngxde7cWS1atDiv+RI6AQAAUEHjxo3VpUsXr82P0AkAAACPEydO6NVXX9Xf/vY3HTlyRG63u9z4zZs312q+hE4AAAB4jB8/Xps2bdKgQYPUo0cPORwOr8yX0AkAAACPjz76SG+//bZ+9atfeXW+3DIJAAAAHu3atTvvi4YqQ+gEAACAx4wZM/Tkk09q//79Xp0vh9cBAADgERsbq5MnTyo2NlbNmjWTn1/5uLh3795azZfQCQAAAI9x48YpKytLjz32mNq0acOFRAAAAPC+r7/+Wh999JEuv/xyr86XczoBAADgERUVpRMnTnh9voROAAAAeDzxxBN69NFH9cUXX+jo0aMqKCgo96+2OLwOAAAAj2HDhkmSBg8eXG64YRhyOBzKzc2t1XwJnQAAAPBYu3atKfPl8DoAAIAXbN26VSNGjFB0dLSCgoK0fv36cuPvvfdeBQUFlftXtlexTF5enu68806FhYUpPDxc48ePV2FhYblp0tPTdf311ys0NFTdunXT/PnzK/TlvffeU3x8vEJDQ9W7d299/PHH1V6Oq666qsp/tcWeTgAAAC8oKipSTEyMRo0apdtuu63SaRISErRgwQLPe39//3Lj77zzTmVnZ2v16tUqLi7WfffdpwcffFBLly6VJBUUFGjo0KHq16+f5s2bp2+//Vbjx49XYGCgbr/9dknStm3bNG7cOD3++OP69a9/rVWrVmnUqFH6/PPP1bVr13Mux9atW6scX9vgSegEAADwgsTERCUmJlY5jb+/v0JCQiodt3v3bn366af67LPPFBsbK0maPXu2brrpJs2YMUNt27bVO++8I6fTqVdeeUWNGzdWdHS00tLStHDhQk/oXLx4sRISEnT//fdLkqZPn67PP/9cS5Ys0YsvvnjO5UhKSqow7PR7dVpyTqfL5apwg1CXy1XutW4y7O5AA2PI5XJxbofFSn9HWdetZVB3y7F9sUtdzQFV5RjDKP3dLSgoKJd//P39K+yhrK4vvvhCUVFRatmypfr27atHH31U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UV5entauXcsVkLVwes0bNWpUruYOh0OGYcjhcKh58+YKCAiQw+HQzJkzPYd+y/aEomaqWtddLpcCAwPVo0cPSaXh3zAMNW3aVJGRkXK73XI4HATPGjq95mV7LstqHhsbq7CwMA0bNkzffvut1q5dq3bt2mnRokXauHGjsrOzFRISYvMS1E1nrutlpzS0adNGY8aMUbNmzSSVhnqXy6WioiKFh4dzGgkuaHzz1XGZmZn6zW9+o4suukjHjh3TiBEjKnwxnP5+9OjRWrFihX7++Wdt2LDBc1gS1Vedmpdp0qSJWrVqpdmzZ+sPf/iDPvvsM11++eU29bxuO1fdz7xNj9vt1uzZs7Vp0ya9//777HGrhXPVPDAwUEeOHNH+/fv17rvv6rLLLpMk3XXXXRo3bhy3rKqlyup+evAMDAwsN72Pj48WLFig//znP+rdu7dNvQbOjavX67AjR47o7rvvlsPhUGBgoH788UeNGTNGt9xyiyRVCEElJSWaOHGili1bpr/97W8Ezlqoac0XLFigxx57TM2aNdO6det05ZVX2tTzuq2mdf/888+1bt06vffee1q9ejV7f2rhXDUvLi5Wo0aNVFRUpOzsbHXs2FGSPHv5UTs1Xdc//fRTrV27Vn/961/1/vvv80ctLmjs6azDTp48qRYtWuj2229X27Zt9dJLL+nNN9+UJN1yyy0V9r75+fmpV69eGjNmDIGzlqpT89O/dFu1aqXw8HCtXLmSuwach5rW/ciRI/L19dX69eupey2dq+aNGjVSSUmJmjVr5gmckgic56mm63rZOeMffvihunTpYmfXgXNiT2cdl5WVpbZt20qSvv32W82fP18//PCDRo8erVtvvVVS6R5OziH0nurUvGwvkCTOa/OS6tS97FZVUun9asvOe0PtsH2xR03X9WPHjql58+a29ReoLk5yquPKNkwul0tdu3bVhAkTFBERoWXLlmn58uWSpIcfflivv/66nd2sV6pT84kTJ2rJkiWSROD0kurUfdKkSfrTn/4kSQROL2D7Yo+arusETtQV7Omsh77//nu9+OKLOnDggBwOh7766itt3LhRv/jFL+zuWr1Fze1B3a1Hze1B3VEfEDrrqHOdrJ+Wlqabb75ZRUVFWrdunWJiYizsXf1Eze1B3a1Hze1B3VHfcXi9jii7OXBubq6kqk/WdzqdntsiffDBB2yYaoma24O6W4+a24O6o6EhdF7gMjMztW7dOvn6+uq9997TPffco8OHD1f5Mz///LO2b9+u999/X127drWop/UHNbcHdbceNbcHdUeDZeCC5XK5jOeee84ICgoyHn30USMoKMhYsWJFlT/jdrsNwzCMkydPWtHFeoea24O6W4+a24O6oyHjnM46YPjw4frss890xx136IUXXqj0yTdnMrhB83mh5vag7taj5vag7miIOLx+gSr7W6C4uFjBwcHq3bu3XnvtNb377ruemwOf+ffC6e/ZMNUcNbcHdbceNbcHdUeDZ9EeVdRA2aGUf/zjH8Ynn3xi/Pzzz4ZhGMYTTzxhBAcHG++880656fbt22dPR+sRam4P6m49am4P6g4YBns6LzDGqcMn77//voYPH66dO3fq4MGDkkpvwjx+/Hjdc889WrVqlRwOh+bOnavJkyfr2LFjNve87qLm9qDu1qPm9qDuwCm2Rl5U6quvvjLCwsKM119/3Th+/Hi5cQUFBcYzzzxjBAUFGdddd53Rtm1bIzU11aae1h/U3B7U3XrU3B7UHeBCoguKceqv4ZkzZ2rXrl3685//7Bnncrnk6+vref/JJ59oz549uu6669SxY0c7ulsvUHN7UHfrUXN7UHfgf/zs7gD+t1EqO0n80KFDnpsGl13RWLZh+uabb9S5c2clJiZyJeN5oOb2oO7Wo+b2oO5ARZzTaaPjx4/r5MmT+vHHH3Xy5EnP8Hbt2mnbtm3Kzc31XNEold4cePXq1dq2bZskrmSsDWpuD+puPWpuD+oOVMHKY/n4n++//9647bbbjF69ehkXX3yx0bdvX+Oxxx4zDMMwCgsLjauvvtro1auXkZ2dbbjdbqO4uNh46qmnjG7duhkHDhywufd1EzW3B3W3HjW3B3UHqsY5nTbYtWuXbrjhBt1000264oorFBQUpBUrVmjjxo265ppr9MYbbygjI0MTJkxQZmamunTpokaNGum7777T6tWrdcUVV9i9CHUONbcHdbceNbcHdQfOjdBpsSNHjmjo0KEaMGCAnnjiiXLD16xZoyeeeEJJSUlavHixDMPQkiVLdOTIEbVo0UJJSUmcXF4L1Nwe1N161Nwe1B2oJtv2sTZQ33zzjdGrVy9j165dRklJiWEYpc/iNQzD+Omnn4wXXnjBaNu2rbF27Vo7u1mvUHN7UHfrUXN7UHegeriQyGLp6enau3evunbtKl9fXxmG4XnebmBgoIYPH65GjRpp79695X7OYId0rVFze1B361Fze1B3oHoInRYrO4zy/vvvS6p4pWJ4eLgiIiKUlZVVbjhXNNYeNbcHdbceNbcHdQeqh9BpsbCwMF100UVauXKl9u/f7xnudrslST/99JOaNGmi7t2729XFeoea24O6W4+a24O6A9VD6LRY+/btNXfuXH366aeaOXOmvvvuO0nyHIpZsGCBDh06pF69etnZzXqFmtuDuluPmtuDugPVw9XrNnC5XFq2bJkmT56sjh07qmfPngoJCdG+ffu0ceNG/fWvf+X2GV5Gze1B3a1Hze1B3YFzI3TaaMeOHXr55ZeVkZGhwMBAxcTE6K677tJll11md9fqLWpuD+puPWpuD+oOnB2h02Yul0s+Pj5yOBye5/HCXNTcHtTdetTcHtQdqBy/CTYr2zBJXMloFWpuD+puPWpuD+oOVI49nQAAADAdezoBAABgOkInAAAATEfoBAAAgOkInQAAADAdoRMAAACmI3QCAADAdIROAAAAmI7QCQAAANMROgEAAGA6QicAAABM9/+DbfwmU5c69wAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "ix = pd.DatetimeIndex(['2021-10-11','2021-10-12','2021-10-13','2021-10-14','2021-10-15'])\n", + "\n", + "df = pd.DataFrame(dict( Open=[131.4, 131.9, 132.0, 130.9, 131.6],\n", + " High=[133.2, 132.7, 133.2, 132.7, 131.8],\n", + " Low=[131.3, 131.3, 131.5, 130.6, 130.7],\n", + " Close=[132.1, 131.4, 131.8, 132.1, 131.0],\n", + " Volume=[19591, 21467, 20406, 22611, 22001]),\n", + " index=ix)\n", + "df\n", + "mpf.plot(df,volume=True,style='yahoo',type='candle')" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "--- \n", + "\n", + "#### Suppose we want to color the third candle yellow, and the fourth candle blue.\n", + "#### Then we create a list of overrides as follows: `mco = [None,None,'yellow','blue',None]`" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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51b756qK0AkAAOAHPXr08IXDiqSkpFT687fccotuueWWSqeJiooq10bDhg01a9asGgXNUh9//LFcLpf69u1bZvinn34qr9db6f1Hq4rD6wAAAPXcU089dcZ7lT711FN+aYPQCQAAUM/t3r1bl112Wbnhl156qfbs2eOXNji8jtpp716psNDWJo0DB0peMzMlJ24O37ixFFW/7o0KALBHSEiIvv/+e0Wd9j2ze/duNW7c2C9tEDpR++zdq8ChN9ne7IWBgRp4YXNdOOUxBRYX296+JBUvf5vgCQDwu+uvv16PPvqo3nzzTbVr105SSeB87LHHdP311/ulDUInap+TezjNpk2lQPtW4VCZurHgqAKbNpFp603KJRUXyygosH3vLgCgfnjqqac0bNgwJSUl6aKLLpJUcnumbt26VfoYzuogdKL2Cgy0NXRK5s/t2h06AQCwUGhoqD766COtX79e27ZtU8OGDdWpUyddddVVfmuD0AkAAAAZhqE+ffqoT58+lsyf0AkAAFAPLVy4UKNHj1bDhg21cOHCSqe9++67z7k9QicAAEA9NH/+fA0bNkwNGzbU/PnzzzidYRiETgAAANTMt99+W+H/rcLN4QEAAOqxoqIiJSQkaNeuXZa2Q+gEAACox4KCgnTChoeeEDoBVFOxpKJ68M+ZBwAAgBP+53/+R3PnzlWxhQ8/4ZxOAFXUVJJkGD/a3nJQkO1NnqKpk42jHsnLy9NXX32lyMhIhYeHO90d1DP/+te/tHHjRq1fv14dO3Ys9+jLlJSUc26D0AmgimJVVLRdUoGtrZrmDjVoMEZu92syjI62tl0SOGNtbhP1VV5enr7++mv16dOH0AnbhYaGasCAAZa2QegEUA32BzDT9Jx8jZNhJNjePgDUZV6vV3/84x+VkZGhoqIi9ezZU5MnT1ajRo383hbndAIAANRTs2fP1rRp09S0aVO1atVKr7zyiiZMmGBJW4ROAACAemrZsmWaNWuW3n33Xf3lL3/R0qVL9c4778jr9fq9LUInAABAPfXDDz+oX79+vve9e/eWYRjKysrye1uETgAAgHqquLhYDRs2LDMsKCjIklsncSERAABAPWWapu69914FBwf7hh0/flwPP/xwmdsmccskAAAA1NiIESPKDbvpppssaYvQCQAAUE/NmzfPtrY4pxMAAACWI3QCAADAcoROAAAA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ffaZdu3apffee08tW7bU5ZdfrilTpujJJ5/U5MmT1aBBA7366quKiorSM888I0mKi4vTP/7xDy1YsEB9+/b1tT1q1Cjdeuutkkr2wn788cd688039dBDD9lYlZ9VK3R6PB4ZhlFu2KmvsEddqDu72e3l8XiU6y5Qo+CGTnel3sg9UXDyd9R0uiv1iCmPx8P2xQG19fuosu9T0yz53c3Pzy+Tf4KDgxUcHHzWeefn50uSwsLCJEnffvutioqK1Lt3b980l156qS6++GJf6Ny8ebM6duyoli1b+qbp27evHnnkEX333Xe64oortHnz5jLzKJ3m0UcflSS53W6lpqaWCZcBAQHq1auXNm/efNZ+W6VaoTM9Pd33AZwuIyPDLx1C9dTmunc0vbX2vpe1jdf0ateuXfJ6CT928npN6m6z0pqzfbFX6TamNqvo+9QwDEVHRys+Pl4FBQW+4ZMmTdLkyZMrnZ/X69Wjjz6qrl27qmPHjpKk7OxsNWjQQKGhoWWmbdmypbKzsyVJOTk5ZQKnJLVo0cL386XTlA47dZqffvpJx44d048//iiPx1PhNKefY2qnaoXO2NjYCvd0ZmRkqH379nK5+BW3S12oe618sk8tFWAEKC4u7uQhatglIMCg7jbz1Zzti61KtzG1UWXfp6Zpyu12a9u2beX2dJ7N+PHjtXPnTn344Yd+73NtVa3Q6XK5yoXOU8fV1vBTm1F3VFXJelK7zoms/QzqbjuDbaJDanvdK/o+LT26GxIScsb8U5EJEyboo48+0gcffKDWrVv7hkdERMjtdisvL6/M3s6cnBxFRERIKtnrefpV5qUX/5w6zekXBB08eFAXXHCBGjVq5FuWiqY5fS+qnbiQSFxcYTcurgAA1EWmaWrixIlas2aNVq1apejo6DLjO3furKCgIG3YsEEDBw6UVHLq4g8//KDExERJUmJiombPnq2DBw/6Do+vX79eF1xwgW9vcmJioj755JMy816/fr2SkpIkSQ0aNNCVV16pDRs26MYbb5RUcrh/48aNGjt2rHUFOAtCp6Rc91E1qsKucvhH7onaFvABADi78ePHa/ny5XrrrbfUtGlT3zmYISEhatSokUJDQzVy5EhNnTpVYWFhuuCCCzRx4kQlJib6QmefPn0UFxene+65R08++aRycnL07LPPauzYsb7D+nfccYcWL16sP/zh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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "mco = [None,None,'yellow','blue',None]\n", + "mpf.plot(df,volume=True,style='yahoo',type='candle',marketcolor_overrides=mco)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "#### We can change only the \"face\" (body) of the candle, with the `mco_faceonly` kwarg:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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vXv3+t7v27dPaWlpat68uUJDQzV37lxde+21CgsL09GjR7V06VJlZmZq8ODBvp85cOCAfvzxR/3www/yer1KS0uTJLVv317NmjWTJCUkJOjRRx/VgAED5HA4dNddd2nOnDmKjo5WZGSkZs6cqfDwcF1//fXWFuAsCJ0AAAB+kJqaqoEDB/reT58+XZI0cuRIzZs3T+np6Vq5cqVycnIUGhqqbt266b333lNsbKzvZ5555hmtWLHC9/7KK6+UJK1du1a9e/eWVHI3ofz8fN809913nwoLCzVhwgTl5eXpV7/6lVatWqVGjRqZurzVRegEAADwg969eys3N/eM46ty7ubChQu1cOHCSqc5vQ2Hw6Fp06Zp2rRpVeuoTTinEwAAAKYjdAIAAMB0HF4HgPNccfhBy9s0jJKnA3mdAZbep9OOZQVgDUInAJynmgWUXATw421LLG+78Qmp415pd3vpuA3XIpQuO4C6g9AJAOepmKZh2tV3hgqKT1jedtaBg1q94VU9+euxCmvXxtK2mwU0UkzTMEvbBGA+QicAnMfsCl97j3olSR2bhqt9cKQtfQBQt3AhEQAAAExH6AQAAIDpCJ0AAAAwHaETAAAApiN0AgAAwHSETgAAAJiO0AkAAADTEToBAABgOkInAAAATEfoBAAAgOkInQAAADAdoRMAAACmI3QCAADAdIROAAAAmI7QCQAAANMROgEAAGA6QicAAABMR+gEAOA8EBwcrB49eig4ONjurgCmIHQCAHAeCA4OVs+ePQmdqLMInQAAADAdoRMAAACmI3QCAADAdIROAAAAmI7QCQAAANMROgEAAGA6QicAAABMR+gEAACA6QidAIByeDoOAH8jdAIAyuHpOAD8jdAJAAAA0xE6AQAAYDpCJwAAAExH6AQAAIDpCJ0AAAB+sHXrVo0YMUKxsbEKCQnR+vXry4yfNWuWEhIS1LZtW0VFRSk5OVnbt28vM01ubq5uv/12RUREKDIyUuPHj1dBQUGl7Q4YMEAhISFl/k2YMMHvy3euCJ0AAAB+UFhYqLi4OD333HMVjr/44ov17LPPauvWrXr//fcVERGhIUOG6MiRI75pbr/9dn333XdavXq1Vq5cqc8//1z333//WdseM2aMvvvuO9+/J554wl+L5TcBdncAAACgLkhKSlJSUtIZxw8fPrzM+6eeekopKSnatWuX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F+vpp5/2tXvnnXdqwIABeumll3TNNddo9erVSk1N1QsvvFCl5UhNTS3z3ul06sILL1SjRo3OqT6ETgAAAD9ITU0tc7uh6dOnS5JGjhypuXPn6ptvvtHKlSuVl5en8PBw9e/fX9OmTStzjuiSJUs0adIkJScny+FwaNCgQZo1a5ZvfHBwsN5++21NmjRJV111lVq0aKFJkyb5bpckST169NCSJUv09NNPa8aMGYqOjtYbb7xRpXt0Sip3oZK/EDoBAAD8oHfv3srNzT3j+Lfffvus8wgJCfHdCP5M4uLi9P7771c6TXJyspKTk8/aXqnFixdXedo777yzytOeitAJAABQzy1cuLBK0zkcDkInAAAAaubrr782vQ1uZAYAAIAKGYZxxgcDVRehEwAAAGWsXLlSvXr1UuvWrdW6dWtdccUVWrly5TnNk8PrAAAA8FmwYIFmzpypcePGqUePHpKkv//973rwwQd19OhR3X333TWaL6ETAAAAPi+//LLmzp2rESNG+IZdd911io2N1axZs2ocOjm8DgAAAJ+srCwlJCSUG56QkKCsrKwaz5fQCQAAAJ/27dtrzZo15YavWbNG0dHRNZ4vh9cBAACgb775Rp07d9a0adM0duxYffHFF75zOr/88ktt3rxZr776ao3nz55OAAAAqHfv3rr66quVk5Ojv/71rwoNDdX69eu1fv16hYaG6uOPP9aAAQNqPH/2dAIAAEDr1q3T8uXL9eijj8rr9WrgwIF6+umndcUVV/hl/uzpBAAAgHr16qWXXnpJ3377rWbPnq39+/dr0KBB+uUvf6kXXnjhnC4ikgidAAAAOEXTpk118803a/369dq2bZsGDx6spUuX6tJLL9XIkSNrPF9CJwAAACoUHR2tBx54QBMnTlSzZs304Ycf1nhenNMJAACAcrZu3ao///nPWrt2rRwOh377299q1KhRNZ4foRMAAACSpMzMTC1fvlwrVqzQnj17lJCQoFmzZik5OVlNmzY9p3kTOgEAAKBhw4Zp8+bNatGihW688UaNGjVKMTExfps/oRMAAABq0KCBXn/9df3617+Wy+Xy+/wJnQAAANCKFStMnT9XrwMAAPjB1q1bNWLECMXGxiokJETr168vM94wDM2cOVOdOnVS69atlZycrP/85z9lpsnNzdXtt9+uiIgIRUZGavz48SooKCgzzc6d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7dKdd96p4uJiFRQUKDExUY8//rhCQkLs7lqddeLECQ0dOlQHDx7U4cOH9cwzz/iCp8vlsrt7dVZaWpoGDhyokSNHcjNz1Drs6ayj9u7dq+uvv17Lli3T0qVLtXv3bru7VOft3r1bgwYN0qWXXqonn3xS11xzjZYtW6Zvv/3W7q7Vad99950GDRqkxMRELV++XPfcc482bdrE3k6TNWzYUG3bttXNN9+sr776SpMnT5ZUsseTQ7/mSEtL07XXXqvbbrtNzz33nCSpuLhYbrdbPOcFtQFPJKqDCgsL9eCDD8rtduvSSy/VmjVr1K1bN/3ud79Tx44d7e5enZSXl6dx48apXbt2vsONkvSb3/xG7du316JFi2zsXd2Vm5urm266SV27dtWsWbN8w3/729/qzjvvVEhIiFq3bq2IiAgbe1l33X///YqJiZHL5dKrr76qq6++Wk8//bS2bNmiyy+/XEFBQXZ3sc7IyclR165dddVVVyklJUVFRUV66KGHtHfvXmVmZioxMVGjR49WTEyM3V0FzojD63VQo0aNdOWVV8rhcGjEiBG68MILtWTJEi1atIjgaZKsrCxdcMEF+u1vfytJcrvdatiwofr06aO9e/fa3Lu668SJExo+fLh69OjhGzZnzhxt3rxZhw4dUkBAgHJzc7V8+XJddtllNva0bik9hB4YGKjjx4/rgQcekCT9+c9/VteuXWUYhr744gt5vV45nRxQ8wePx6Prr79eGzdu1NatW/XCCy+osLBQV111lbKzs7Vjxw7985//1IIFCxQZGWl3d4EKsTWog5xOp4YOHaobb7xRkjRq1Cj93//9n1JTU7Vo0SLfofaioiIdOnTIzq7WGZdccomGDRumPn36SJICAkr+nrvwwgt14sSJMtP+9NNPlvevrmrdurUGDx6sLl26SJJWrFih2bNn67XXXtP69ev18ssvq1OnTlq4cKFOnjzJIUg/KQ2S/fv317fffiun06m77rpLAQEBys7OVvfu3dW0aVM5nU4OtftJq1at9Mwzz+iaa67RwIEDZRiGUlJSNHHiRD377LO65557lJOToy+++MLurgJnROisY0qvHm3YsKEcDofv/ejRozV27Fhf8Ny5c6ceffRRDR8+nCsgz1HpHQKuu+46SZJhGL4v5dIr2UvDzvPPP68ZM2aouLjYns7WIaXrdosWLXzDrrvuOm3YsEGDBg1SaGioYmNjFRQUpLy8PAUGBsrhcNjV3TqhNECW1jEwMFDffPONJOnee+/VwYMHNXbsWO3Zs0f33HOPJLGn0w9K1/XQ0FA98cQTevzxx3XbbbcpNDTU95lcd911crvd+vrrr+3sKlApDq/XAfv379fXX3+tgQMH+k7iL93Qn/p+zJgxcjgceu2113TTTTcpNzdXa9eu5QrIGji15g0aNChTc4fDIcMw5HA41LRpUwUFBcnhcGjmzJm+Q7+le0JRPZWt6x6PR8HBwerevbukkvBvGIYaN26s6Ohoeb1eORwOgmc1nVrz0j2XpTXv1q2bIiIiNGzYMH3zzTdau3at2rRpo0WLFmnjxo3KyspSWFiYzUtQO52+rpee0tCqVSuNGTNGTZo0kVQS6j0ejwoLCxUZGclpJDiv8c1Xy2VkZOg3v/mNLrjgAh07dkwjRowo98Vw6vvRo0drxYoV+umnn7RhwwbfYUlUXVVqXqpRo0Zq0aKFZs+erT/84Q/65JNPdOmll9rU89rtbHU//TY9Xq9Xs2fP1qZNm/Tuu++yx60Gzlbz4OBgHTlyRPv379fbb7+tSy65RJJ0xx13aNy4cdyyqoYqqvupwTM4OLjM9E6nUwsWLNB//vMf9erVy6ZeA2fH1eu12JEjR3TnnXfK4XAoODhYP/zwg8aMGaObbrpJksqFoOLiYk2cOFHLli3T3/72NwJnDVS35gsWLNAjjzyiJk2aaN26dbr88stt6nntVt26f/rpp1q3bp3eeecdrV69mr0/NXC2mhcVFalBgwYqLCxUVlaW2rdvL0m+vfyomequ6x9//LHWrl2rv/71r3r33Xf5oxbnNfZ01mInT55Us2bNdOutt6p169Z64YUX9Prrr0uSbrrppnJ73wICAtSzZ0+NGTOGwFlDVan5qV+6LVq0UGRkpFauXMldA85Bdet+5MgRuVwurV+/nrrX0Nlq3qBBAxUXF6tJkya+wCmJwHmOqruul54z/v7776tTp052dh04K/Z01nKZmZlq3bq1JOmbb77R/Pnz9f3332v06NG6+eabJZXs4eQcQv+pSs1L9wJJ4rw2P6lK3UtvVSWV3K+29Lw31AzbF3tUd10/duyYmjZtalt/gariJKdarnTD5PF41LlzZ02YMEFRUVFatmyZli9fLkl68MEH9eqrr9rZzTqlKjWfOHGilixZIkkETj+pSt0nTZqkP/3pT5JE4PQDti/2qO66TuBEbcGezjrou+++0/PPP68DBw7I4XDoiy++0MaNG/WLX/zC7q7VWdTcHtTdetTcHtQddQGhs5Y628n6aWlpuvHGG1VYWKh169YpLi7Owt7VTdTcHtTdetTcHtQddR2H12uJ0psD5+TkSKr8ZH232+27LdJ7773HhqmGqLk9qLv1qLk9qDvqG0LneS4jI0Pr1q2Ty+XSO++8o7vuukuHDx+u9Gd++uknbdu2Te+++646d+5sUU/rDmpuD+puPWpuD+qOesvAecvj8RjPPPOMERISYjz88MNGSEiIsWLFikp/xuv1GoZhGCdPnrSii3UONbcHdbceNbcHdUd9xjmdtcDw4cP1ySef6LbbbtNzzz1X4ZNvTmdwg+ZzQs3tQd2tR83tQd1RH3F4/TxV+rdAUVGRQkND1atXL73yyit6++23fTcHPv3vhVPfs2GqPmpuD+puPWpuD+qOes+iPaqohtJDKf/4xz+Mjz76yPjpp58MwzCMxx57zAgNDTXeeuutMtPt27fPno7WIdTcHtTdetTcHtQdMAz2dJ5njJ8Pn7z77rsaPny4duzYoYMHD0oquQnz+PHjddddd2nVqlVyOByaO3euJk+erGPHjtnc89qLmtuDuluPmtuDugM/szXyokJffPGFERERYbz66qvG8ePHy4zLz883nnrqKSMkJMS45pprjNatWxupqak29bTuoOb2oO7Wo+b2oO4AFxKdV4yf/xqeOXOmdu3apT//+c++cR6PRy6Xy/f+o48+0p49e3TNNdeoffv2dnS3TqDm9qDu1qPm9qDuwP8E2N0B/G+jVHqS+KFDh3w3DS69orF0w/T111+rY8eOSkpK4krGc0DN7UHdrUfN7UHdgfI4p9NGx48f18mTJ/XDDz/o5MmTvuFt2rTRl19+qZycHN8VjVLJzYFXr16tL7/8UhJXMtYENbcHdbceNbcHdQcqYeWxfPzPd999Z9xyyy1Gz549jQsvvNDo06eP8cgjjxiGYRgFBQXGlVdeafTs2dPIysoyvF6vUVRUZDzxxBNGly5djAMHDtjc+9qJmtuDuluPmtuDugOV45xOG+zatUvXXXedbrjhBl122WUKCQnRihUrtHHjRl111VV67bXXlJ6ergkTJigjI0OdOnVSgwYN9O2332r16tW67LLL7F6EWoea24O6W4+a24O6A2dH6LTYkSNHNHToUPXv31+PPfZYmeFr1qzRY489poEDB2rx4sUyDENLlizRkSNH1KxZMw0cOJCTy2uAmtuDuluPmtuDugNVZNs+1nrq66+/Nnr27Gns2rXLKC4uNgyj5Fm8hmEYP/74o/Hcc88ZrVu3NtauXWtnN+sUam4P6m49am4P6g5UDRcSWWznzp3au3evOnfuLJfLJcMwfM/bDQ4O1vDhw9WgQQPt3bu3zM8Z7JCuMWpuD+puPWpuD+oOVA2h02Klh1HeffddSeWvVIyMjFRUVJQyMzPLDOeKxpqj5vag7taj5vag7kDVEDotFhERoQsuuEArV67U/v37fcO9Xq8k6ccff1SjRo3UtWtXu7pY51Bze1B361Fze1B3oGoInRZr27at5s6dq48//lgzZ87Ut99+K0m+QzELFizQoUOH1LNnTzu7WadQc3tQd+tRc3tQd6BquHrdBh6PR8uWLdPkyZPVvn179ejRQ2FhYdq3b582btyov/71r9w+w8+ouT2ou/WouT2oO3B2hE4bbd++XS+++KLS09MVHBysuLg43XHHHbrkkkvs7lqdRc3tQd2tR83tQd2BMyN02szj8cjpdMrhcPiexwtzUXN7UHfrUXN7UHegYvwm2Kx0wyRxJaNVqLk9qLv1qLk9qDtQMfZ0AgAAwHTs6QQAAIDpCJ0AAAAwHaETAAAApiN0AgAAwHSETgAAAJiO0AkAAADTEToBAABgOkInAAAATEfoBAAAgOkInQAAADDd/wNxOfmg59fUUgAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "mco = [None,None,'yellow','blue',None]\n", + "mpf.plot(df,volume=True,style='yahoo',type='candle',marketcolor_overrides=mco,mco_faceonly=True)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "#### marketcolor overrides work also with ohlc plots\n", + "- Presently only `type='candle'` and `type='ohlc'` are supported.\n", + "- If there is enough demand, we will consider also supporting types 'hollow_and_filled', 'renko', and 'point_and_figure'." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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B8reurWFg2mealrXK47uBgUFnTL/1NeAAQO0bds25efna+XKlbrlllu0efPmaqGxKeJCIgAAAC8JDAxUVFSU4uPj9cc//lEtWrRQampqg5cXFhYmSTp06FCV6Xl5eWrfvv0ZjdXTCJ0AAAAWcblccjgcDf75yMhIhYWFaevWre5phYWF2rVrl+Lj4z0xRI+p1+F1AAAA1KyoqEh79+51P9+3b5/S09PVpk0bhYaGat68ebr66qsVFhamI0eOaNmyZTp48KCGDRvm/pnvvvtOP/74o77//nu5XC6lp6dLkrp27arWP592kZCQoEcffVRDhgyRzWbTnXfeqblz5yoqKkqRkZGaNWuWwsPDde2113q3AKdB6AQAAPCAtLQ0JSf/csurGTNmSJLGjBmj+fPnKysrS6tXr1Z+fr5CQ0MVFxend955RzExMe6feeaZZ7Rq1Sr388suu0yStH79evXv31/SibsJFRYWutvce++9Kikp0f3336+jR4/qN7/5jdasWSN/f39TX2992YxT3QOpEsMwVFhYqICAgBqvXs/MzFT37t052dyLqLv3UXNrUHfvKy6WQkJO3Kfz8OFjXL3uDaWlajHwcknS8Y82cyGRF9W2jTEMQ6WlpR69kKg545xOAAAAmI7D6wBwFqp8r8zm1DeApovQCQBnoYrD2wDQVHB4HQAAAKZjTycAnIUKCsos67u4WOrcmT2tADyL0AkAZ6FA6z56GwBMweF1AAAAmI7QCQAAANMROgEAAGA6QicAAABMR+gEAACA6QidAAAAMB2hEwAAAKYjdAIAAMB0hE4AAACYjtAJAAAA0xE6AQAAYDpCJwAAAExH6AQAAIDpCJ0AAAAwHaETAAAApiN0AgAAwHSETgAAAJiuhdUDAACg2QsI0PHPtiszM1PdAwKsHg1gCvZ0AgAAwHSETgAAAJiO0AkAAADTEToBAABgOkInAAAATEfoBAAAgOkInQAAADAdoRMAAACmI3QCAADAdIROAEAVgYFSaekxpaXtVmCg1aMB0FQQOgEAAGA6QicAAABMR+gEAACA6QidAAAAMB2hEwAAAKYjdAIAAHjA9u3bNXr0aMXExCgkJEQbN26sMn/27NlKSEhQp06d1KVLF6WkpGjnzp1V2hQUFOi2225TRESEIiMjNXHiRBUVFdXa75AhQxQSElLl6/777/f46ztThE4A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nVL561//Wi+99FKDXy+hEwAAwAOKioqqXISzb98+paenq02bNgoJCdGcOXM0dOhQhYWFae/evXrssccUFRWlxMRESVL37t2VmJioe++9V/Pnz1dZWZmmTJmi4cOHq0OHDpJOfFrQs88+q4kTJ+ree+/VV199pSVLlujpp59293vHHXdoyJAheumll3TllVdq7dq1SktL0wsvvFCn15GWllbluY+Pj84991z5+/ufUX0InQAAAB6QlpZW5XZDM2bMkCSNGTNG8+bN05dffqnVq1fr6NGjCg8P1+DBgzV9+vQq54guXbpUkydPVkpKimw2m4YOHarZs2e75wcHB+vNN9/U5MmTdfnll6tt27aaPHmy+3ZJknTJJZdo6dKlevrppzVz5kxFRUXptddeq9M9OiVVu1DJUwidAAAAHtC/f38VFBSccv6bb7552mWEhIS4bwR/KrGxsXr33XdrbZOSkqKUlJTT9ldhyZIldW57xx131LltZYROAACAZm7RokV1amez2QidAAAAaJjdu3eb3gc3MgMAAECNDMM45QcD1RehEwAAAFWsXr1a/fr1U4cOHdShQwddeumlWr169Rktk8PrAAAAcFu4cKFmzZqlCRMm6JJLLpEk/fOf/9SDDz6oI0eO6K677mrQcgmdAAAAcHv55Zc1b948jR492j3tmmuuUUxMjGbPnt3g0MnhdQAAALjl5uYqISGh2vSEhATl5uY2eLmETgAAALh17dpV69atqzZ93bp1ioqKavByObwOAAAAffnll+rRo4emT5+uW265RZ999pn7nM7PP/9cW7du1auvvtrg5bOnEwAAAOrfv7+uuOIK5efn6+9//7tCQ0O1ceNGbdy4UaGhofrwww81ZMiQBi+fPZ0AAADQhg0b9Prrr+vRRx+Vy+VScnKynn76aV166aUeWT57OgEAAKB+/frppZde0ldffaU5c+Zo//79Gjp0qH7961/rhRdeOKOLiCRCJwAAACoJDAzUjTfeqI0bN2rHjh0aNmyYli1bpl69emnMmDENXi6hEwAAADWKiorSAw88oEmTJql169Z6//33G7wszukEAABANdu3b9df/vIXrV+/XjabTb/73e80duzYBi+P0AkAAABJ0sGDB/X6669r1apVysnJUUJCgmbPnq2UlBQFBgae0bIJnQAAANDIkSO1detWtW3bVtdff73G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NDtFRUXKy8vT0aNHeSP2ovz8fP373/9Wenq6jhw5YvVwmoXMzEzNnz9fkmS321nfveTf//63xo4dq+PHj1s9FKBe6vTZ62icsrOz9eqrr2rs2LGKiYmxejjNwldffaXJkycrPz9fDodD48eP17hx49SmTRurh9ak7dmzR3fccYfKy8tVVFSkxMREPf744woJCbF6aE3WsWPHNGLECB04cECHDh3SM8884w6edrvd6uE1Wenp6UpOTtaYMWO4mTkaHfZ0NlF79+7Vtddeq5UrV2rZsmXKzMy0ekhNXmZmpoYOHapevXrpySef1JVXXqmVK1fqq6++snpoTdrXX3+toUOHKjExUa+//rruvvtubdmyhb2dJmvZsqU6deqkG2+8UV988YWmTJki6cQeTw79miM9PV1XX321br31Vj333HOSpPLycjkcDvE5L2gM+ESiJqikpEQPPvigHA6HevXqpXXr1ikuLk6///3v1b17d6uH1yQdPXpUEyZM0Hnnnec+3ChJV111lbp27arFixdbOLqmq6CgQDfccIN69+6t2bNnu6f/7ne/0x133KGQkBB16NBBERERFo6y6brvvvsUHR0tu92uV199VVdccYWefvppbdu2TRdffLGCgoKsHmKTkZ+fr969e+vyyy9XamqqysrK9NBDD2nv3r06ePCgEhMTNW7cOEVHR1s9VOCUOLzeBPn7++uyyy6TzWbT6NGjde6552rp0qVavHgxwdMkubm5Ouecc/S73/1OkuRwONSyZUsNGDBAe/futXh0TdexY8c0atQoXXLJJe5pc+fO1datW/XDDz+oRYsWKigo0Ouvv66LLrrIwpE2LRWH0P38/FRaWqoHHnhAkvSXv/xFvXv3lmEY+uyzz+RyueTjwwE1T3A6nbr22mu1efNmbd++XS+88IJKSkp0+eWXKy8vT7t27dK///1vLVy4UJGRkVYPF6gRW4MmyMfHRyNGjND1118vSRo7dqz+7//+T2lpaVq8eLH7UHtZWZl++OEHK4faZFxwwQUaOXKkBgwYIElq0eLE/3Pnnnuujh07VqXtTz/95PXxNVUdOnTQsGHD1LNnT0nSqlWrNGfOHC1fvlwbN27Uyy+/rAsvvFCLFi3S8ePHOQTpIRVBcvDgwfrqq6/k4+OjO++8Uy1atFBeXp769OmjwMBA+fj4cKjdQ9q3b69nnnlGV155pZKTk2UYhlJTUzVp0iQ9++yzuvvuu5Wfn6/PPvvM6qECp0TobGIqrh5t2bKlbDab+/m4ceN0yy23uINnRkaGHn30UY0aNYorIM9QxR0CrrnmGkmSYRjuN+WKK9krws7zzz+vmTNnqry83JrBNiEV63bbtm3d06655hpt2rRJQ4cOVWhoqGJiYhQUFKSjR4/Kz89PNpvNquE2CRUBsqKOfn5++vLLLyVJ99xzjw4cOKBbbrlFOTk5uvvuuyWJPZ0eULGuh4aG6oknntDjjz+uW2+9VaGhoe7fyTXXXCOHw6Hdu3dbOVSgVhxebwL279+v3bt3Kzk52X0Sf8WGvvLz8ePHy2azafny5brhhhtUUFCg9evXcwVkA1Suua+vb5Wa22w2GYYhm82mwMBABQUFyWazadasWe5DvxV7QlE/ta3rTqdTwcHB6tOnj6QT4d8wDAUEBCgqKkoul0s2m43gWU+Va16x57Ki5nFxcYqIiNDIkSP15Zdfav369erYsaMWL16szZs3Kzc3V2FhYRa/gsbp5HW94pSG9u3ba/z48WrVqpWkE6He6XSqpKREkZGRnEaCsxrvfI1cdna2rrrqKp1zzjkqLi7W6NGjq70xVH4+btw4rVq1Sj/99JM2bdrkPiyJuqtLzSv4+/urbdu2mjNnjv74xz/qo48+Uq9evSwaeeN2urqffJsel8ulOXPmaMuWLXr77bfZ49YAp6t5cHCwDh8+rP379+vNN9/UBRdcIEm6/fbbNWHCBG5Z1UA11b1y8AwODq7S3sfHRwsXLtQ333yjfv36WTRq4PS4er0RO3z4sO644w7ZbDYFBwfr+++/1/jx43XDDTdIUrUQVF5erkmTJmnlypX6xz/+QeBsgPrWfOHChXrkkUfUqlUrbdiwQRdffLFFI2/c6lv3jz/+WBs2bNBbb72ltWvXsvenAU5X87KyMvn6+qqkpES5ubnq2rWrJLn38qNh6ruuf/jhh1q/fr3+/ve/6+233+afWpzV2NPZiB0/flytW7fWzTffrA4dOuiFF17QihUrJEk33HBDtb1vLVq0UN++fTV+/HgCZwPVpeaV33Tbtm2ryMhIrV69mrsGnIH61v3w4cOy2+3auHEjdW+g09Xc19dX5eXlatWqlTtwSiJwnqH6rusV54y/++67uvDCC60cOnBa7Ols5A4ePKgOHTpIkr788kstWLBA3377rcaNG6cbb7xR0ok9nJxD6Dl1qXnFXiBJnNfmIXWpe8WtqqQT96utOO8NDcP2xRr1XdeLi4sVGBho2XiBuuIkp0auYsPkdDrVo0cP3X///erSpYtWrlyp119/XZL04IMP6tVXX7VymE1KXWo+adIkLV26VJIInB5Sl7pPnjxZf/7znyWJwOkBbF+sUd91ncCJxoI9nU3Q119/reeff17fffedbDabPvvsM23evFm/+tWvrB5ak0XNrUHdvY+aW4O6oykgdDZSpztZPz09Xddff71KSkq0YcMGxcbGenF0TRM1twZ19z5qbg3qjqaOw+uNRMXNgfPz8yXVfrK+w+Fw3xbpnXfeYcPUQNTcGtTd+6i5Nag7mhtC51kuOztbGzZskN1u11tvvaU777xThw4dqvVnfvrpJ+3YsUNvv/22evTo4aWRNh3U3BrU3fuouTWoO5otA2ctp9NpPPPMM0ZISIjx8MMPGyEhIcaqVatq/RmXy2UYhmEcP37cG0Nscqi5Nai791Fza1B3NGec09kIjBo1Sh999JFuvfVWPffcczV+8s3JDG7QfEaouTWou/dRc2tQdzRHHF4/S1X8L1BWVqbQ0FD169dPr7zyit588033zYFP/n+h8nM2TPVHza1B3b2PmluDuqPZ89IeVdRDxaGUf/3rX8YHH3xg/PTTT4ZhGMZjjz1mhIaGGm+88UaVdvv27bNmoE0INbcGdfc+am4N6g4YBns6zzLGz4dP3n77bY0aNUq7du3SgQMHJJ24CfPEiRN15513as2aNbLZbJo3b56mTJmi4uJii0feeFFza1B376Pm1qDuwM8sjbyo0WeffWZEREQYr776qlFaWlplXmFhofHUU08ZISEhxpVXXml06NDBSEtLs2ikTQc1twZ19z5qbg3qDnAh0VnF+Pm/4VmzZmnPnj36y1/+4p7ndDplt9vdzz/44APl5OToyiuvVNeuXa0YbpNAza1B3b2PmluDugO/aGH1APDLRqniJPEffvjBfdPgiisaKzZMu3fvVvfu3ZWUlMSVjGeAmluDunsfNbcGdQeq45xOC5WWlur48eP6/vvvdfz4cff0jh076vPPP1d+fr77ikbpxM2B165dq88//1wSVzI2BDW3BnX3PmpuDeoO1MKbx/Lxi6+//tq46aabjL59+xrnnnuuMWDAAOORRx4xDMMwioqKjMsuu8zo27evkZuba7hcLqOsrMx44oknjJ49exrfffedxaNvnKi5Nai791Fza1B3oHac02mBPXv26JprrtF1112niy66SCEhIVq1apU2b96syy+/XMuXL1dWVpbuv/9+ZWdn68ILL5Svr6+++uorrV27VhdddJHVL6HRoebWoO7eR82tQd2B0yN0etnhw4c1YsQIDR48WI899liV6evWrdNjjz2m5ORkLVmyRIZhaOnSpTp8+LBat26t5ORkTi5vAGpuDerufdTcGtQdqCPL9rE2U7t37zb69u1r7NmzxygvLzcM48Rn8RqGYfz444/Gc889Z3To0MFYv369lcNsUqi5Nai791Fza1B3oG64kMjLMjIytHfvXvXo0UN2u12GYbg/bzc4OFijRo2Sr6+v9u7dW+XnDHZINxg1twZ19z5qbg3qDtQNodPLKg6jvP3225KqX6kYGRmpLl266ODBg1Wmc0Vjw1Fza1B376Pm1qDuQN0QOr0sIiJC55xzjlavXq39+/e7p7tcLknSjz/+KH9/f/Xu3duqITY51Nwa1N37qLk1qDtQN4ROL+vUqZPmzZunDz/8ULNmzdJXX30lSe5DMQsXLtQPP/ygvn37WjnMJoWaW4O6ex81twZ1B+qGq9ct4HQ6tXLlSk2ZMkVdu3bVJZdcorCwMO3bt0+bN2/W3//+d26f4WHU3BrU3fuouTWoO3B6hE4L7dy5Uy+++KKysrIUHBys2NhY3X777brgggusHlqTRc2tQd29j5pbg7oDp0botJjT6ZSPj49sNpv783hhLmpuDerufdTcGtQdqBl/CRar2DBJXMnoLdTcGtTd+6i5Nag7UDP2dAIAAMB07OkEAACA6QidAAAAMB2hEwAAAKYjdAIAAMB0hE4AAACYjtAJAAAA0xE6AQAAYDpCJwAAAExH6AQAAIDpCJ0AAAAw3f8DD4CNpgvAyDsAAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "mco = [None,None,'yellow','blue',None]\n", + "mpf.plot(df,volume=True,style='yahoo',type='ohlc',marketcolor_overrides=mco)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "#### We can also fully customize indivual candles using a marketcolors object.\n", + "#### Notice that with the approach, we do not have to know whether a candle is up or down;
a single marketcolors object can specify different colors for up candles and down candles:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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nnX+medunqljx4764IMPKm0TERFRro+GDRtq9uzZF2TQPB3ndAIAAMB0hE4AAACYjtAJAAAA0xE6AQAAYDpCJwAAAExH6AQAAIDpCJ0AAAAwHaETAAAApiN0AgAAwHSETgAAAJiO0AkAAADTEToBAABgOkInAAAATEfoBAAAgOkInQAAADAdoRMAAACmI3QCAADAdIROAAAAmI7QCQAAANMROgEAAGA6QicAAABMR+gEAACA6QidAAAAMB2hE6iivLw8ff3118rLy7N7KIDpivIy5f52oYryMu0eCoA6gtAJVFFeXp6++eYbQifqheL8wzK2LVJx/mG7hwKgjiB0AgAAwHSETgAAAJiO0AkAAADTEToBAABgOkInAAAATEfoBAAAgOkInQAAADAdoRMAAACmI3QCAADAdIROAAAAmI7QCQAAANMROgEAAGA6QicAAABMR+gEAACA6QidAAAAPrBlyxYNHz5ccXFxCgkJ0bp168rMnzlzphITE9WmTRtFRUUpKSlJ27Zt884/cOCAxo8fr06dOql169bq3Lmznn/+eblcrkr77d+/v0JCQsr8e+ihh0xZx/Phb/cAAAAA6oLCwkLFx8dr5MiRGjVqVLn5l156qV544QVFRUXpxIkTWrhwoQYPHqx//vOfuuiii/Sf//xHHo9HL730kqKjo7Vr1y49+OCDKiws1PTp0yvte8yYMXr00Ue9zxs1auTz9TtfhE4AAAAf6Nevn/r163fW+cOGDSvz/Nlnn1VycrJ27typXr166brrrtN1113nnR8VFaX09HS9/vrr5wydjRo1UlhY2PmtgMmqFTrdbrccDke5aac/whoej8f7SO2tQc3tQd3tQd2tx+epPSqru2EYkqT8/Pwy+ScwMFCBgYHn1a/L5dJbb72loKAgxcfHn7Vdfn6+QkJCzrm8d999V++8845atWql3/3ud5o4caIaN258XmP0tWqFzrS0NO8LcKb09HSfDAhVk52dLUk6ePCgTp06ZfNo6gdqbg/jyEFJJXV3nGxq82jqD+puHz5P7VFR3R0OhyIjIxUfH6+CggLv9MmTJ2vKlCk16mf9+vUaN26cCgsLFR4ertWrV6tFixYVtt27d69ee+21c+7lHDp0qNq2bavw8HDt3LlTTz/9tNLT05WcnFyjMZqlWqEzJiamwj2d6enpat++vZxOp08Hh7Mr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zj59+ig2Nlb33HOPnnrqKWVnZ+u5557TuHHjvIf177jjDi1ZskRPPPGERo4cqc2bN+v999/XX//6V+9Y7r33Xt17773q3LmzfvWrX2nhwoU6fvy492p2OxA6AQAAfOD111+XJPXv37/M9Pnz5+vWW2+VJM2YMUN+fn4aPXq0XC6X+vTpo9mzZ3vbOp1OrVixQo888oh++9vfqnHjxhoxYoSmTp3qbRMZGam//vWvmjp1qhYtWqSLL75Yr7zyivd2SZI0ePBgHT16VDNmzFB2drauuOIKrVy5ksPrAAAAtV1ubu452zRs2FCzZ88uEzTPFBERoXfffbfS5fTo0UObN2+utM1dd92lu+6q2elsX331ld58803t379fb775pi6++GKtWLFCkZGR6tatW42WyeV9AAAA8Prggw80dOhQNWrUSP/+97/lcrkkldx3dO7cuTVeLqETAAAAXrNnz9bcuXM1b948BQQEeKf/5je/0b///e8aL5fQCQAAAK/09HR179693PSgoCDl5eXVeLmETgAAAHi1atVKe/fuLTf9H//4h6Kiomq8XEInAAAAvEaPHq1HH31U27Ztk8PhUGZmpt555x09/vjjuuOOO2q8XK5eBwAAgNdDDz0kj8ejpKQkFRYW6qabblJgYKDuu+++Gl8NLxE6AQAAcBqHw6EJEybo/vvv1969e3X8+HHFxsaqadOm57VcQicAAADKadCggS6//HKfLY/QCQAAAK+TJ0/qtdde09///ncdPXpUHo+nzPxNmzbVaLmETgAAAHiNHz9eGzdu1MCBA9WlSxc5HA6fLJfQCQAAAK+PP/5Y77zzjn7zm9/4dLncMgkAAABeF1988XlfNFQRQicAAAC8pk+frqeeekoHDhzw6XI5vA4AAACvzp0769SpU+rcubMaN24sf/+ycXHfvn01Wi6hEwAAAF7jxo1TZmamHn/8cbVq1YoLiQAAAOB73377rT7++GNdccUVPl0u53QCAADAKyYmRidPnvT5cgmdAAAA8HryySf12GOP6csvv9SxY8eUn59f5l9NcXgdAAAAXkOHDpUkDRo0qMx0wzDkcDiUk5NTo+USOgEAAOC1Zs0aU5bL4XUAAAAf2LJli4YPH664uDiFhIRo3bp1Zebfe++9CgkJKfOvdK9iqdzcXN15552KiIhQZGSkxo8fr4KCgjJtduzYoRtuuEHh4eHq2LGj5s2bV24s77//vhITExUeHq7u3bvrk08+qfJ6XH311ZX+qyn2dAIAAPhAYWGh4uPjNXLkSI0aNarCNn379tX8+fO9zwMDA8vMv/POO5WVlaVVq1apqKhI9913nx588EEtWbJEkpSfn68hQ4aoV69emjt3rnbt2qXx48crODhYt99+uyTpm2++0bhx4/TEE0/ot7/9rVauXKmRI0fqiy++UIcOHc65Hlu2bKl0fk2DJ6ETAADAB/r166d+/fpV2iYwMFBhYWEVztuzZ48+++wzff755+rcubMkadasWbr55ps1ffp0tW7dWu+++65cLpdeffVVNWjQQHFxcUpNTdWCBQu8oXPRokXq27ev7r//fknStGnT9MUXX2jx4sV66aWXzrkeAwYMKDft9Ht1WnJOp9vtLneDULfbXeaxdjLsHkA9Y8jtdnNuh8VKfkd5r1vLoO6WY/til9qaAyrLMYZR8rubn59fJv8EBgaW20NZVV9++aViYmLUvHlz9ezZU4899phCQ0MlSVu3blVwcLA3cEpS79695efnp+3bt6t///7aunWrunfvrgYNGnjb9O3bV/PmzdOPP/6o5s2b69tvv9Uf//jHMv326dOn3OH+sznzG4eKi4v173//WzNmzNBjjz1Wo/WWqhk609LSvC/AmdLT02s8CLt5PHwgWMnjMbRnzx51MDxy2j2YesJjeLRnzx7e6xYrfa9Td+uwfbFH6TamNqsoxzgcDkVGRio+Pr7MeZWTJ0/WlClTqt1H37591b9/f0VGRmr//v2aPn26hg0bpk8++UROp1NZWVlq2bJlmZ/x9/dXSEiIsrKyJEnZ2dmKiIgo06b0Z7KystS8eXNlZ2eXW07Lli2VnZ1dpXEGBweXm3bttdeqQYMG3r2mNVGt0BkTE1Phns709HS1b99eTmft/BX3+2a93UOoV/z8HIqNjZWfg30RVvFz+JXUnPe6pbzvdepuGbYv9ijdxtRGleUYwzDkcrm0Y8eOcns6a2LIkCHe/+/YsaM6duyozp0768svv1SvXr1qtgIWatmy5XntZKxW6HQ6nWf9/k2n01lrQ6fkm+8URVU5avF7pfYqqTnvdWs5qLvl2L7YpbbXvaIcU3p0NygoyGffP366qKgotWjRQnv37lWvXr0UFhamI0eOlGlTXFys3Nxc73mgrVq1Ktem9Pm52rRq1apK49qxY0eZ54ZhKCsrSy+//LLi4+OrvoJn4EIiAAAAG/zf//2fjh075g2LCQkJysvLU0pKiq666ipJ0ubNm+XxeNSlSxdvm2effVZFRUUKCAiQJG3cuNF7nqgkJSYmatOmTfrDH/7g7Wvjxo1KSEio0riuueYaORyOcqdU/vrXv9arr75a4/UldAIAAPhAQUFBmYtwMjIylJqaqubNmyskJESzZs3SwIEDFRYWpn379unJJ59UdHS0+vbtK0mKjY1V37599cADD2ju3LkqKirSpEmTNHjwYLVu3VpSybcFvfDCCxo/frweeOAB7d69W4sWLdJzzz3n7ffuu+9W//799eqrr+r666/XqlWrlJKSopdffrlK65GSklLmuZ+fny666CI1bNjwvOpD6AQAAPCBlJSUMrcbmjZtmiRpxIgRmjNnjnbt2qUVK1YoLy9P4eHh6tOnj6ZOnVrmHNHFixdr4sSJSkpKksPh0MCBAzVz5kzv/ODgYL333nuaOHGirr32WrVo0UITJ0703i5Jkrp27arFixfrueee0/Tp0xUdHa233367SvfolFTuQiVfIXQCAAD4QI8ePZSbm3vW+e+99945lxESEuK9EfzZxMfH66OPPqq0TVJSkpKSks7ZX6lFixZVue3dd99d5banI3QCAADUcwsWLKhSO4fDQegEAABAzXz33Xem98GNzAAAAFAhwzDO+sVA1UXoBAAAQBkrVqxQ9+7d1bp1a7Vu3VpXX321VqxYcV7L5PA6AAAAvObPn68ZM2Zo3Lhx6tq1qyTpH//4hx555BEdO3ZM9957b42WS+gEAACA12uvvaY5c+Zo+PDh3mk33nij4uLiNHPmzBqHTg6vAwAAwCsrK0uJiYnlpicmJiorK6vGyyV0AgAAwKtdu3ZavXp1uemrV69WdHR0jZfL4XUAAABo165d6tChg6ZOnaqxY8fq66+/9p7T+c0332jTpk164403arx89nQCAABAPXr00HXXXaecnBz97W9/U2hoqNatW6d169YpNDRUn332mfr371/j5bOnEwAAAFq7dq2WLVumJ554Qh6PRwMGDNBzzz2nq6++2ifLZ08nAAAA1L17d7366qvavXu3Zs2apQMHDmjgwIH69a9/rZdffvm8LiKSCJ0AAAA4TZMmTXTbbbdp3bp12rp1qwYNGqQlS5boiiuu0IgR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MH333XeKjY1Vv379uJLxPFBze1B361Fze1B3oDzO6bTRiRMndOrUKf3www86deqUd/rFF1+sb775Rjk5Od4rGqWSmwOvWrVK33zzjSSuZKwJam4P6m49am4P6g5Uwspj+fjF999/b4waNcro1q2bcdFFFxk9e/Y0Hn/8ccMwDKOgoMC45pprjG7duhlZWVmGx+MxioqKjKefftro2LGjcfDgQZtHXztRc3tQd+tRc3tQd6BynNNpg507d+rGG2/UzTffrCuvvFIhISFavny5NmzYoGuvvVZvvvmm0tLS9NBDDyk9PV2XX365AgICtHv3bq1atUpXXnml3atQ61Bze1B361Fze1B34NwInRY7evSohgwZoj59+ujJJ58sM3316tV68sknNWDAAC1atEiGYWjx4sU6evSomjZtqgEDBnByeQ1Qc3tQd+tRc3tQd6CKbNvHWk999913Rrdu3YydO3caxcXFhmGUfBevYRjGjz/+aLz44otG69atjTVr1tg5zDqFmtuDuluPmtuDugNVw4VEFtuxY4f27dunDh06yOl0yjAM7/ftBgcHa9iwYQoICNC+ffvK/JzBDukao+b2oO7Wo+b2oO5A1RA6LVZ6GOWDDz6QVP5KxcjISEVFRSkzM7PMdK5orDlqbg/qbj1qbg/qDlQNodNiERERatasmVasWKEDBw54p3s8HknSjz/+qIYNG6pTp052DbHOoeb2oO7Wo+b2oO5A1RA6LdamTRvNmTNHn332mWbMmKHdu3dLkvdQzPz583X48GF169bNzmHWKdTcHtTdetTcHtQdqBquXreB2+3W0qVLNWnSJLVr105du3ZVWFiYMjIytGHDBv3tb3/j9hk+Rs3tQd2tR83tQd2BcyN02mjbtm165ZVXlJaWpuDgYMXHx+uuu+7SZZddZvfQ6ixqbg/qbj1qbg/qDpwdodNmbrdbfn5+cjgc3u/jhbmouT2ou/WouT2oO1AxfhNsVrphkriS0SrU3B7U3XrU3B7UHagYezoBAABgOvZ0AgAAwHSETgAAAJiO0AkAAADTEToBAABgOkInAAAATEfoBAAAgOkInQAAADAdoRMAAACmI3QCAADAdIROAAAAmO7/AQ51/yYjNyW4AAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "mc = mpf.make_marketcolors(base_mpf_style='yahoo',up=(0.7,1.0,0.7,0.4),down='fuchsia',\n", + " edge={'up':'blue','down':'#000000'},wick='#cc6600')\n", + "#mc = mpf.make_marketcolors(base_mpf_style='yahoo',up=(0.7,1.0,0.7,0.4),down=(1,0.25,1),\n", + "# edge={'up':'blue','down':'#000000'},wick='#cc6600')\n", + "\n", + "mco = [None,None,mc,mc,None]\n", + "mpf.plot(df,volume=True,style='yahoo',type='candle',marketcolor_overrides=mco)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "#### When dealing with larger data sets we recommend setting up your marketcolor overrides as a COLUMN in your DataFrame\n", + "#### This has two advantages:\n", + "1. It helps ensure that your marketcolor overrides are the same length as your dataframe, and\n", + "2. It allows you to use the dataframe's DatetimeIndex to set the override values.\n", + "#### Note that you will still have to pass the `marketcolor_overrides` as an separate iterable (apart from the dataframe)." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(50, 5)" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OpenHighLowCloseVolume
Date
2011-08-29119.559998121.430000118.059998121.360001190977200
2011-08-30120.830002122.430000119.260002121.680000241315700
2011-08-31122.459999123.510002121.300003122.220001301828400
\n", + "
" + ], + "text/plain": [ + " Open High Low Close Volume\n", + "Date \n", + "2011-08-29 119.559998 121.430000 118.059998 121.360001 190977200\n", + "2011-08-30 120.830002 122.430000 119.260002 121.680000 241315700\n", + "2011-08-31 122.459999 123.510002 121.300003 122.220001 301828400" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df = pd.read_csv('data/SPY_20110701_20120630_Bollinger.csv',index_col=0,parse_dates=True)\n", + "df = df[['Open','High','Low','Close','Volume']].iloc[40:90] # Arbitrarily choose a 50 row subset of the data\n", + "df.shape\n", + "df.head(3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "#### Create a new column for the overrides:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OpenHighLowCloseVolumeMCOverrides
Date
2011-08-29119.559998121.430000118.059998121.360001190977200None
2011-08-30120.830002122.430000119.260002121.680000241315700None
2011-08-31122.459999123.510002121.300003122.220001301828400None
\n", + "
" + ], + "text/plain": [ + " Open High Low Close Volume \\\n", + "Date \n", + "2011-08-29 119.559998 121.430000 118.059998 121.360001 190977200 \n", + "2011-08-30 120.830002 122.430000 119.260002 121.680000 241315700 \n", + "2011-08-31 122.459999 123.510002 121.300003 122.220001 301828400 \n", + "\n", + " MCOverrides \n", + "Date \n", + "2011-08-29 None \n", + "2011-08-30 None \n", + "2011-08-31 None " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "df['MCOverrides'] = [None]*len(df)\n", + "df.head(3)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "#### Use the DatetimeIndex to set the Overrides:\n", + "#### For demonstration purposes, let's override every Monday as black, and every Tuesday as \"blueskies\" marketcolors:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
OpenHighLowCloseVolumeMCOverrides
Date
2011-08-29119.559998121.430000118.059998121.360001190977200black
2011-08-30120.830002122.430000119.260002121.680000241315700{'candle': {'up': 'w', 'down': '#0095ff'}, 'ed...
2011-08-31122.459999123.510002121.300003122.220001301828400None
2011-09-01122.290001123.400002120.779999120.940002254585900None
2011-09-02118.419998120.870003117.430000117.849998255517200None
\n", + "
" + ], + "text/plain": [ + " Open High Low Close Volume \\\n", + "Date \n", + "2011-08-29 119.559998 121.430000 118.059998 121.360001 190977200 \n", + "2011-08-30 120.830002 122.430000 119.260002 121.680000 241315700 \n", + "2011-08-31 122.459999 123.510002 121.300003 122.220001 301828400 \n", + "2011-09-01 122.290001 123.400002 120.779999 120.940002 254585900 \n", + "2011-09-02 118.419998 120.870003 117.430000 117.849998 255517200 \n", + "\n", + " MCOverrides \n", + "Date \n", + "2011-08-29 black \n", + "2011-08-30 {'candle': {'up': 'w', 'down': '#0095ff'}, 'ed... \n", + "2011-08-31 None \n", + "2011-09-01 None \n", + "2011-09-02 None " + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "mc = mpf.make_marketcolors(base_mpf_style='blueskies')\n", + "for ts in df.index:\n", + " if 0 == ts.weekday():\n", + " df.loc[ts,'MCOverrides'] = 'black'\n", + " elif 1 == ts.weekday():\n", + " df.loc[ts,'MCOverrides'] = [mc]\n", + "#mc\n", + "df.head()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "scrolled": false + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "=== without marketcolor overrides: ===\n" + ] + }, + { + "data": { + "image/png": "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/fXXmjRpkj777DN16tRJKSkpev755/XnP/9ZBw4cCHRRARwHwa6W0tJS7d69W/v27fN0Pzh69KhGjBihWbNm6S9/+Yu+/PLLAJcSwSgqKkoTJkzQNddco+joaEnSNddco927d+v666/X5MmTFRcXp7Fjx6qwsJAWO3j06tVLr732mkaPHu0JcKeddpquuuoqPf7449q7dy/dodCg2NhYDRs2TCNHjtQtt9yiyZMna9OmTYQ7NMlpp52mu+66Sz169NDQoUPlcrn04osv6sEHH9Tf//53TZo0SR988IG2b98e6KICOA66YtbSq1cvVVRU6JlnntGgQYN04MABzZ07V88//7zOOussvf7668rNzQ10MREkqm4qr+pa2bFjR89jOTk5iouLU3Z2trp16yZJSk5O1o033qg9e/botNNOC1SxEWTi4uLUq1cvT32q+j5ixAitWLFCn332mbp06SKXyyWbzRbo4iLIRERE6JJLLvEMmjJx4kRVVFTo2Wef1ZNPPqkbbrhBvXv3VllZmfLy8pSWlhbgEiPQqt5Lqt5rTjvtNM2ePVt9+/bVsGHDlJSU5Fln8uTJevDBB/XRRx/pvPPOC3TRATQi7INdTk6OnE6nJKlr16664IIL9L///U8rV67U8uXLJUlLly7VhRdeKEmqqKjQ999/rxEjRgSszAgeOTk56tSpk6drZVUrnGmaSktL05IlS2Sz2TyP2Ww2devWTYmJiQEuOQLtyy+/1M6dO2Wz2ZSenq6TTz7Z0ypX9f28887TySefrCVLlujiiy8m1KGOqpPvql4CVb9fddVVMk1Tf/vb3/Tkk0/qd7/7nV566SV98MEHeu+99zz3/SL8bN++XX/961/1zTff6Oyzz9aIESN03nnn6cwzz1RKSornAqXNZpPL5VJ+fr569OihU089NcAlB3A8YR3sli9frmeffVa7du1S9+7dlZGRoTlz5mjatGkaM2aM5+TqxBNPlCTt3r1b8fHxOuWUUwJZbASJf/zjH5o3b57uvfdeXXHFFYqIiPBc/ayqO1VBLyIiQqWlpXrqqad04oknqnPnzoEsOgKsqptTQkKCDh8+rE6dOumhhx7S6aef7lmn6gR9+vTpuvnmm/Xvf/9bY8aMCWCpESz27NmjLVu2aPTo0TUuHEmq8fvVV18twzD03HPPacKECSooKNCqVasIdWHs66+/1ujRo3XBBReoU6dO+uSTT/S///1PPXr0UKdOnTznO1VsNpv++te/qqCggF4mgAWEbbB77bXXNHPmTD3wwANKSkrSF198offee08ZGRk6++yzdeKJJ3pOzp1Op/bu3at58+YpOjpaw4YNC3DpEWj/+c9/dPvtt6tz585avHixDMPQ5ZdfXqMbneRueSktLdXXX3+t++67Tzk5OVq/fn2N7psIL9nZ2frTn/6khQsX6vzzz9eWLVu0aNEibdiwQaeffrqn/lS1zvXt21cOh0Nbt24l2EE7duzQhRdeqHbt2snhcGjcuHF1egxU//2qq67SK6+8osOHD+utt96i1SWM5eTk6MYbb9TEiRN11113SXJ/lk2ePFl79uxRp06daqz/7rvv6t1339Wrr76q7OzsOqEPQPAJy7PKb7/9Vk888YTuv/9+TZw4URdddJGuvvpq/fTTT9q6daukmvO27NixQ/PmzdP+/fu1Zs0aT/cEhCeHw6EVK1boggsu0L333qvBgwdr4cKFeu211yTJE9qqbNy4Uc8995wMw9D69esVFRWl8vJyQl0YOnjwoF555RVNnTpVl1xyidq1a6ehQ4eqW7duWr16taSa7z2maSopKUmvvvqq5s6dG6hiI0jk5uZqzpw5GjBggM4880z97W9/08svvyxJdUbajYiIUHl5uW655RZt3LhR2dnZhLow9+WXX6pLly4aN26cZ5Cm4cOH65RTTtGuXbsk1Rx9d/v27fr555/15ptv0loHWERYttg5HA716dNHZ555piT3G9mJJ56oIUOGKC8vT5JqDFLQtWtXzZgxQ2eeeaZsNpvKy8sVGRmWTx0k2e12XXfddTp48KCGDh2qDh06yDRNLVy4UJJ0+eWX1+iWOXjwYCUlJSk9Pd1zskX9CU8RERHq06ePhgwZIkmeVpVBgwbpq6++kqQaLb5V65xxxhmSRN0Jc6WlpWrbtq2uueYaderUSY8++qj+/ve/S5ImTJhQp+UuMjJSQ4YM0dVXX02og1JTU3X++eerb9++ko6FuNLSUh08eFBSzQtLVa178fHxrV9YAF4JyzOErl27avLkyerXr1+N5aZp6vDhw5JUY5CCtm3bauDAgZLcgY8TK/Tv39/zc58+fTRlyhRJ0sMPPyzJHe5yc3P12Wef6de//rWnrlVUVFB/wlhycrKuvvpqde3aVdKxk6ikpCRJNYPbN998o759+9Y40aLuhLfOnTvrgQce8HSZ+/3vf6/Fixfr73//u0zT1JVXXlnn4tEVV1wRyCIjiAwYMEADBgyQVPMCUkJCQo1znqefftozmByhDrCWsDxLSElJUUpKiqSa3Q6cTqdKS0s9v1922WUaNmyYpk2b5lnGqHSorurDsW/fvpo8ebIMw9Ajjzyiw4cP6x//+Ify8vJ04YUX1hlMBeGrKtRVP7E6dOiQioqKPCfjl1xyiUpKSjzdM4EqVaHO5XIpPT1d06dP16JFi/T888/LMAxNmDBBM2bM0IABA3TttdcGuLQIVtUvGLVt29Yzqurdd9+tv/zlL1q3bl2gigbAB2F/lll9BMP27durTZs2ktwnVj/88IOmTp0ayOIhyFX/cExPT9f111+vs846S7NmzVJpaak++ugjz4AqQHW1JxyvGqnw8ssv148//qh//etfASgVrKLqImOfPn00ffp0nXTSSXrxxRc1atQovfDCCzV6FQCNfQYdOnRIFRUVWrRokZ588kmtWbNGffr0acXSAWgpYdli15CoqCiVlpZq0qRJ+uGHH/TJJ594BrqgCxSaonPnztq0aZPOOOMMvf3224qMjKT+4LhSU1MVHR2tUaNGad++fdq4cSPvPaih9r2X1fXp00c333yzrrjiCh09elQbNmyoc6sBwkvVOAF5eXlKTk5usO5I7ha7Bx54QE6nU2vWrPF01wRgPSHdYtfcVpLCwkI9+eST2r17N6EOnvpTvR5VH3WutrKyMt15550yTVNvvfUWoS6MNbfuFBQU6LPPPpPD4SDUQZI8Iy9XDejV2Im50+n0TGmwZs0aQl0Y27Fjh7Kzs2Wz2fSvf/1LU6dO9QyM0pDExERFRUXp7bff9gzUBMCaQjbYVb+6+fzzz2vt2rXH3ebss8/WBRdcoHXr1nFiFeYqKio89Sc3N1dHjhyRaZqN3iMXFRWl6667Th988AH1J4x5U3dOOeUU3XjjjXrvvfeoO2HOmxPzw4cP69NPP9XKlSuVnp7eSiVFsKmoqNDrr7+uq666Srfddpt++9vf6pJLLvGMKdCQcePG6Z133mHkVCAEGGYI3vxTfbjnLVu26LbbbtO+ffv0xBNPaNCgQQ1ut3//fqWkpDAkPTz+/Oc/a+XKlYqIiFCHDh305z//uc5IhfWpPl0GwpO3dYf3nvBVUVGhhx56SA899JBuuukmPfHEE1q6dKnGjRvX4DZVFzGdTqdnAAyEt8suu0zr1q3Tb3/7Wy1YsKDGORGA0BaS/+lVb2B//vOf9dBDD6mkpER79+7VH/7wB/3f//1fg9t17NjRM/8YJ1bhqXp3uZdfflnLli3T1KlTdc011ygiIkKZmZl65513JDXe1ZdQF368rTu16xHvPeErIiJCc+fOVUZGhpYuXarrrrtO48aNa7Qbb9WFgqioqNYqJoJQ1ftIWVmZkpKSdO655+rZZ5/VG2+84Tmvqf1eE4LX9YGwF5ItdpL07LPP6vbbb9err76q3r1765NPPtGLL76oH3/8UQ899JDOO++8QBcRQeytt97SF198oe7du2v8+PGe5TfccIPeeecdffjhh0pLSwtgCRGsqDvwRlXLW1lZmW6++Wb9/PPP+uijj/TUU0/pkksu8ZyEV2/xbWxAFYSPqnqwadMm5eXlafDgwWrbtq3uvPNOPf7441q2bJkuvfRSz3p79uzxTLsCILSEZIudJG3atEkXXXSRzjvvPHXo0EGZmZmaNm2a2rVrp5kzZ2rjxo2BLiKC1KZNm3TbbbdpyZIlnpMmp9MpSXryySfVuXNnPf7444EsIoIUdQfeqH5i/v7772vhwoVatWqVpk2bpilTpuj111+vEeD27NkjqfEBVRAequrOypUrddlll+nzzz/Xzz//LEmaMWOGpk2bpqlTp3rq0MKFCzV79mw5HI4AlxyAP4REsKuvm0piYqJ2796toqIiz7LzzjtPmZmZ+u677zRr1ix9+OGHrVlMBKnajdY9evTQddddp8TERL322muSpOjoaJWXl8vlcumEE05QSUlJIIqKIEPdga84MYcvDMPQJ598omnTpulPf/qT/vCHP6hXr16SpHbt2mnGjBmaPn26pkyZogsuuEALFy7UrbfeKrvdHuCSA/CHkAh2VffUvffee55l6enp2r9/v956660aH4Ddu3dXZmam+vbtq2eeeUaFhYWtXl4Ej+ojGEqSw+FQQkKCrrnmGs2YMUM//PCDpkyZIsl975PNZtPBgwc9k0kjfFF30BI4MYe3qi4srVu3TkOHDtU111yj2NhYScemy2jXrp3mz5+vV199VWPHjtWHH37I5PVACAuZe+y++eYbnXfeeZo0aZIWL14sSZo6dao2bNigmTNnerpk3nzzzTrzzDPVqVMnzZs3T+vWrdMpp5wS4NIjEKqPFLZkyRJt3rxZX375pSZNmqSRI0eqZ8+eevbZZ/Xoo4+qffv26tWrlyIiIrR582Zt3LiRQS7CGHUHLaGqte7+++/XV199pZdeesnzWO2Rdd99913t3LlT559/vrp37x6I4iJI1L638ve//70OHDig5cuX1xkBc8uWLerdu7diY2O5JxMIAyHRYidJJ510kpYuXap//vOfuuWWWyRJf/nLX3T++efr2Wef1ciRI3XhhRfq+++/16xZs3TOOecoNTW10dHGENqqPvzuuusuPf744zrzzDN14403auHChbr//vtVXFys8ePHa/r06XI6nfr22281adIkff75557JxxGeqDvwRe2BUHJycjwtLFWfSVWhbsuWLSopKdHIkSM1ZcoUQl0YKy4uVmlpqfbu3avS0lLP8hNOOEEbN25UXl6eZwRMyT2/4YoVKzxjChDqgNAXMpeN4+LidPHFFysiIkK33HKLTNPU4sWL9eijj2rTpk3at2+fDMPQ+eefL0l65plnFBcXd9yJOxHaNm3apOzsbL344osaOHCgNm3apCNHjuiiiy5S27ZtJUlXXnmlKioq9Nprr2nFihUaPny4JD4kwx11B81VXFysiIgIHThwQKmpqZ5uuSeccIJWrVqlvLw8JScne1pWqk7MR4wYoV/+8pfUmzD23Xff6b777tOOHTu0fft29e3bV8OHD9fdd9+tadOm6c0339To0aP1r3/9SykpKSovL9eiRYv0xhtvaPLkyYEuPoDWYlrY448/bt511101lhUXF5vLly83U1JSzDlz5tTZ5qOPPjJvuukms0ePHuaXX37ZWkVFkCgpKanx++eff26OGDHCNE3TXLFihdmlSxfzmWeeMU3TNA8fPmyuW7fONE3TLCoqMpctW2YOHz7cvPbaa1u30AgK1B344ttvvzUnTZpkDhkyxOzQoYP5i1/8wrzttttM0zTNI0eOmMOGDTOHDBli7t+/36yoqDDLysrMu+66yzz11FPNH3/8McClRyBt27bN7Nq1qzlz5kzz+eefN1etWmVOmDDBTE1NNa+44gqzuLjY/PLLL82MjAyzW7du5gUXXGBmZmaaJ598srlly5ZAFx9AK7Jsi11xcbGOHj2qZcuWyW63a8aMGZKk2NhYZWVl6f3339dTTz2lw4cP64knnvBsFxkZqby8PK1atUrp6emBKj4CYN26ddq2bZvOO+88nXXWWZLcQ9Hn5OTo+eef12233aY77rhD1113nSTp888/17PPPqvOnTurV69emjBhgoqLi/X2228rJyeHucjCCHUHvvjqq6900UUX6fLLL9fIkSOVmJioV155RcuWLdP//vc/Pffcc1qyZImmT5+uQYMGqU+fPoqKitI333yjFStWqEuXLoH+ExAgubm5uvHGG/Xb3/5Wd9xxh2f54MGD9c9//lN33HGH/vCHP2jZsmV699139fTTTys3N1dt27bVY489RtddINwEOlk2lcvlqvHdNE0zNzfXfPzxx82uXbuaCxYsqLH+ggULzMsuu8y85JJLamxjmu5WPYSXF1980UxPTzf/+Mc/mp9//nmNx6677jozMTHRfPDBBz3LSkpKzCuuuMK86qqratSfw4cPmwUFBa1VbAQB6g58cfDgQXPYsGHmnXfeWWf5U089ZXbq1MmcMmWKaZqmWVFRYS5btsy87777zMWLF5s7d+4MRJERRLZs2WIOGTLE/Oqrr8zy8nLTNI+dBx06dMhcsGCB2alTJ3PVqlWBLCaAIGGJFrs33nhD69ev1y233KJOnTp5hnlOTk7WuHHjVFFRoUceeUSSNHPmTB05ckRff/21xowZoyuvvFJSzVHsqoYDRnh44403NHv2bC1ZskQZGRmKj4+v8fiUKVN04MABvfzyy+ratasOHTqkd999Vz///LM2bNigiIgIz9D2VfdOITxQd+Crn3/+WWVlZbrssss8I11WVFSoQ4cOuvzyy1VYWKhHHnlEo0ePVmZmpmeKDECStm3bpl27dnl6GJmm6TmXSUhI0GWXXabHH39cu3btqrGdyQiYQFgK+ukOioqKNHz4cB0+fFipqak666yzNGTIEI0fP96zzoEDB7RixQrdfvvt6tatmwzDUFRUlN5//31FRkbyBhfGcnNzde211yorK6vGDeRHjhzRt99+q8jISA0YMEA7duzQo48+qv/85z/q0aOHTjrpJD3yyCOeEQwZnj78UHfQEl5++WXNmDFD+/btk1T3hHv37t0aNmyYZs6cqWnTpnmW87kFSfr44481duxYLVu2TFlZWfWu88tf/lLnnXee7r///lYuHYBgE/RnHHa7XRdffLFOPPFEnXnmmdqwYYNuvfVWrVu3Tn369NHvf/97paamaurUqTr33HO1evVqtW/fXpMnT1ZkZGSduYAQfnJzc3XCCSd4fv/rX/+q//u//9PKlSuVmpqq3r1769///reWLFniGZWuCifm4Y26A19V3eO0cuVKZWVl1Qlr3bp100knneQJflUIdZCkrl27ql27dlq+fLkGDBigrl27SjrWC+nQoUOKjY1l0nEAkiwwj53NZtOQIUN0xx13yGazadq0afr222/VvXt33XfffcrIyNDixYv15Zdf6vTTT9ett96qG264wXO1nFCHoqIivfPOO9qwYYOuvvpqPfvss0pOTtYbb7yhBx98ULt379aCBQskubu2VDFNkxPzMEfdga+qn5jv2bPHs7xqvjpOzNGYzp07a+HChVq7dq3uv/9+ffPNN5KOzaX5xBNPKCcnR0OGDAlkMQEEiaDvilll5syZkqSHH35YkjRkyBCdfPLJ6t69u77++mutX79ejz32mCZOnBjIYiIIvf/++7rqqquUlJSktm3b6r777lO/fv2UlJSkQ4cOKSsrSxdddJHmzp0b6KIiyFB30BJWrVql3/3ud/rNb36jP/zhD+rbt6/nsfvuu0+vvfaaVq1a5WmNAapzuVx6/vnnNXv2bHXv3l3nnHOOOnbsqN27d+u9997Tv//9b51++umBLiaAIGCZS8r9+/fXSy+9pEOHDmnMmDFKSEjQ0qVLFR8fr59//lmffPJJg/3PEd5++ctf6vPPP5fD4VC3bt3qPN62bVuGn0e9qDtoCRdddJEeeOABzZ49W1988UW9J+aEOjTEZrPp2muv1WmnnabHHntMn332mRISEtSvXz+9/fbb6tWrV6CLCCBIWKbFTpIyMjK0adMmnXvuuXrhhReUmJhYZx3ua0FT5ebm6qabblJ+fr7eeustuu2iyag78MZnn32mxx57TNu3b/ecmE+ZMoUTczSZy+VSRESEDMOoMdo3AEgWCXZVo4O9+uqrWrx4sZYuXaoBAwYwahi8kpeXp+eff16ffPKJcnNz9dZbbykqKoqBdnBc1B34ihNz+KL6eQ/nQABqs8QnStUb1y9+8QsVFBRo/fr1NZYDzfHzzz9r48aN6tGjh95++21FRUUx0A6ahLoDX1WFOonPMDRf9TpD/QFQmyVa7Kp76qmn9OCDD2r16tXq06dPoIsDiyosLFR8fLwMw6C1Bc1C3QEAAMHIcjejjRw5Ups2beKeBPikamh60zQ5MUezUHcAAEAwslyLnXSsXzlXywEAAADAosEOAAAAAHCMJQZPAQAAAAA0jGAHAAAAABZHsAMAAAAAiyPYAQAAAIDFEewAAAAAwOIIdgAAAABgcQQ7AAAAALA4gh0AAAAAWBzBDgAAAAAs7v8BMza1qa3iyI0AAAAASUVORK5CYII=\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "=== WITH MARKETCOLOR OVERRIDES: ===\n" + ] + }, + { + "data": { + "image/png": "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2WyN+lgEOwAAAABoQr169VKvXr2a9DEIdgAAAADQDAoKCrRs2TJ99tln2rNnjyQpLS1NAwYM0IQJE9S+ffugj02wAwAAQIsXc/0NksvV8B0dDvn+vKTxC4So8+WXX+riiy9Wq1atdO6556p79+6SpL1792rp0qV67LHH9Oabb+r0008P6vgEOwAAALR8LpeMzsc1eDfzp5+boDAIl0WLFunee+/V9ddfrz/96U+SpMOHD+uOO+7Q8uXL5fF4NGzYMD3yyCNKS0sL7Ldz507NmDFDH374oex2u8aNG6e77rpLsbH1j1OzZ8/WhRdeqEWLFskwjCrrTNPU9OnTNXv2bL377rtBPTemOwAAAADQ4n355Zd64YUXdMopp1RZfvvtt+udd97RCy+8oJycHOXl5Wny5MmB9V6vV5dffrlKS0u1evVqLVmyRK+++qoeeOCBBj3+li1bdMMNN1QLdZJkGIZuuOEGbd68ObgnJ4IdAAAAgBbuwIEDmjJlih5//HG1bds2sLyoqEjLli3T/fffryFDhqhfv35avHix/vvf/+qzzz6TJK1bt07ff/+9li5dqlNPPVUjRozQ7bffrueee04ej6feZUhLS9OXX35Z6/ovv/xSHTp0CPo5NqgrptfrrTFhWonX663yHWgI6k94hHIFKlJeK+qOnxn0ftH8t6P+IBTUn3It4bMkHCKt/phm+edIcXFxlVySkJCghISEWvebOXOmzjvvPA0dOlSPPPJIYPmmTZtUWlqqoUOHBpaddNJJ6tKliz777DP1799fn332mXr37l2la2ZWVpZmzJih7777Tqeddlq9yn7TTTfplltu0caNGzVkyJDA8fbs2aP169frxRdfDGluuwYFu61btwb+mFa3bdu2cBcBFkb9aV69TZ+CmenFZ/r0/fffN3p5QhHtdcfnC+4zxOczI+61DIdorz8ITbTXn5b0WRIOkVJ/DMNQZmam+vTpowMHDgSWz549W3PmzKlxnzfffFObNm3SunXrqq3bvXu34uPjlZKSUmV5Wlqadu/eLak8eFUOdZICLWv+berj2muvVbt27fT000/rL3/5SyAs22w29evXT0899ZR++9vf1vt4R2tQsOvRo0eLaLHbtm2bTjzxxEafFBAtH/UnPGKM4K6zxhgx6tmzZyOXJjjUnXIxn74T3H4xRsS8luFA/UEoqD/lWsJn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Q8CmTZv05JNP6oUXXtCYMWMkSYMGDVJhYaE++eQTSbT0onYHDx7Uww8/rMGDB2vGjBn6/PPP9fTTT+v7778Pd9FgAXv27FH//v21ceNGffPNN5o8ebI+//xzderUSR06dNCLL76oP/3pT9qzZ0+4iwrgGAh2RykpKZHT6dQvv/wS6H5w8OBBDRs2TDNnztSf//xnffXVV2EuJSJRXFycJkyYoKuuukrx8fGSpKuuukpOp1PXXXedrr32WiUlJWns2LEqKiqixQ4BJ510kl5//XWNHj06EOBOPfVUXXHFFXryySe1a9cuukOhVomJiRoyZIhGjBihW265Rddee602bNhAuEO9nHrqqbrnnnvUrVs3DR48WF6vV8uWLdNDDz2kv/3tb5o8ebI+/PBDbd26NdxFBXAMdMU8ykknnSSfz6fnnntOAwYM0J49ezRnzhy9+OKLOvPMM/XGG28oPz8/3MVEhPDfVO7vWtmxY8fAury8PCUlJSknJ0eZmZmSpHbt2umGG25Qbm6uTj311HAVGxEmKSlJJ510UqA++b8PGzZMy5cv1+eff64uXbrI6/XKZrOFu7iIMDExMbr44osDg6ZMmjRJPp9Pzz//vJ5++mlNnTpVPXv2VGlpqQoKCpSenh7mEiPc/O8l/veaU089VbNmzdLJJ5+sIUOGyOFwBLa59tpr9dBDD+njjz/W2WefHe6iA6hD1Ae7vLw8eTweSVJGRoays7P1v//9TytWrNBrr70mSVqyZIl+85vfSJJ8Pp9++OEHDRs2LGxlRuTIy8tTp06dAl0r/a1wpmkqPT1dixcvls1mC6yz2WzKzMxUampqmEuOcPvqq6+0fft22Ww29e7dW927dw+0yvm/n3322erevbsWL16siy66iFCHavwn3/5eAv7fr7jiCpmmqb/+9a96+umn9fvf/14vv/yyPvzwQ61ZsyZw3y+iz9atW/WXv/xF3377rX71q19p2LBhOvvss3XGGWeoQ4cOgQuUNptNXq9XLpdL3bp10ymnnBLmkgM4lqgOdq+99pqef/557dixQ127dlVWVpZmz56tadOm6cILLwycXB1//PGSJKfTqeTkZJ144onhLDYixD/+8Q/dfvvtmj9/vi6//HLFxMQErn76644/6MXExKikpETPPPOMjj/+eHXu3DmcRUeY+bs5paSkaP/+/erUqZMefvhhnXbaaYFt/Cfo06dP10033aR///vfuvDCC8NYakSK3Nxcbdq0SaNHj65y4UhSld+vvPJKGYahF154QRMmTFBhYaFWrlxJqIti33zzjUaPHq3s7Gx16tRJn3zyif73v/+pW7du6tSpU+B8x89ms+kvf/mLCgsL6WUCWEDUBrvXX39dt956qx588EE5HA59+eWXWrNmjbKysvSrX/1Kxx9/fODk3OPxaNeuXbr99tsVHx+vIUOGhLn0CLf//Oc/mjdvnjp37qzHH39chmHosssuq9KNTipveSkpKdE333yj+++/X3l5eXr//ferdN9EdMnJydEdd9yhhQsX6rzzztOmTZu0aNEirV+/Xqeddlqg/vhb504++WS53W5t3ryZYAdt27ZNv/nNb9SmTRu53W6NGzeuWo+Byr9fccUVevXVV7V//3698847tLpEsby8PN1www2aNGmS7rnnHknln2XXXnutcnNz1alTpyrbv/fee3rvvff097//XTk5OdVCH4DIE5Vnld99952eeuopPfDAA5o0aZLOP/98XXnllfrpp5+0efNmSVXnbdm2bZtuv/127d69W2+99VagewKik9vt1vLly5Wdna358+dr4MCBWrhwoV5//XVJCoQ2v08//VQvvPCCDMPQ+++/r7i4OJWVlRHqotDevXv16quv6vrrr9fFF1+sNm3aaPDgwcrMzNSqVaskVX3vMU1TDodDf//73zVnzpxwFRsRIj8/X7Nnz1a/fv10xhln6K9//ateeeUVSao20m5MTIzKysp0yy236NNPP1VOTg6hLsp99dVX6tKli8aNGxcYpGno0KE68cQTtWPHDklVR9/dunWrfv75Z7399tu01gEWEZUtdm63W7169dIZZ5whqfyN7Pjjj9egQYNUUFAgSVUGKcjIyNCMGTN0xhlnyGazqaysTLGxUfmngyS73a5rrrlGe/fu1eDBg9W+fXuZpqmFCxdKki677LIq3TIHDhwoh8Oh3r17B062qD/RKSYmRr169dKgQYMkKdCqMmDAAH399deSVKXF17/N6aefLknUnShXUlKi1q1b66qrrlKnTp302GOP6W9/+5skacKECdVa7mJjYzVo0CBdeeWVhDooLS1N5513nk4++WRJR0JcSUmJ9u7dK6nqhSV/615ycnLzFxZAUKLyDCEjI0PXXnut+vTpU2W5aZrav3+/JFUZpKB169bq37+/pPLAx4kV+vbtG/i5V69emjJliiTpkUcekVQe7vLz8/X5559r5MiRgbrm8/moP1GsXbt2uvLKK5WRkSHpyEmUw+GQVDW4ffvttzr55JOrnGhRd6Jb586d9eCDDwa6zN188816/PHH9be//U2maWrixInVLh5dfvnl4SwyIki/fv3Ur18/SVUvIKWkpFQ553n22WcDg8kR6gBricqzhA4dOqhDhw6SqnY78Hg8KikpCfx+6aWXasiQIZo2bVpgGaPSoTL/h+PJJ5+sa6+9VoZh6NFHH9X+/fv1j3/8QwUFBfrNb35TbTAVRC9/qKt8YrVv3z4VFxcHTsYvvvhiHT58ONA9E/Dzhzqv16vevXtr+vTpWrRokV588UUZhqEJEyZoxowZ6tevn66++uowlxaRqvIFo9atWwdGVb333nv15z//WevWrQtX0QCEIOrPMiuPYNi2bVu1atVKUvmJ1Y8//qjrr78+nMVDhKv84di7d29dd911OvPMMzVz5kyVlJTo448/DgyoAlR29ITj/pEKL7vsMu3cuVP/+te/wlAqWIX/ImOvXr00ffp0nXDCCVq2bJkuuOACvfTSS1V6FQB1fQbt27dPPp9PixYt0tNPP6233npLvXr1asbSAWgsUdliV5u4uDiVlJRo8uTJ+vHHH/XJJ58EBrqgCxTqo3PnztqwYYNOP/10rV69WrGxsdQfHFNaWpri4+N1wQUX6JdfftGnn37Kew+qOPrey8p69eqlm266SZdffrkOHjyo9evXV7vVANHFP05AQUGB2rVrV2vdkcpb7B588EF5PB699dZbge6aAKynRbfYNbSVpKioSE8//bScTiehDoH6U7keVR517milpaW6++67ZZqm3nnnHUJdFGto3SksLNTnn38ut9tNqIMkBUZe9g/oVdeJucfjCUxp8NZbbxHqoti2bduUk5Mjm82mf/3rX7r++usDA6PUJjU1VXFxcVq9enVgoCYA1tRig13lq5svvvii1q5de8x9fvWrXyk7O1vr1q3jxCrK+Xy+QP3Jz8/XgQMHZJpmnffIxcXF6ZprrtGHH35I/YliwdSdE088UTfccIPWrFlD3YlywZyY79+/X5999plWrFih3r17N1NJEWl8Pp/eeOMNXXHFFbrzzjv1u9/9ThdffHFgTIHajBs3Tu+++y4jpwItgGG2wJt/Kg/3vGnTJt1555365Zdf9NRTT2nAgAG17rd792516NCBIekR8Kc//UkrVqxQTEyM2rdvrz/96U/VRiqsSeXpMhCdgq07vPdEL5/Pp4cfflgPP/ywbrzxRj311FNasmSJxo0bV+s+/ouYHo8nMAAGotull16qdevW6Xe/+50WLFhQ5ZwIQMvWIv/T/W9gf/rTn/Twww/r8OHD2rVrl/7whz/o//2//1frfh07dgzMP8aJVXSq3F3ulVde0dKlS3X99dfrqquuUkxMjEaNGqV3331XUt1dfQl10SfYunN0PeK9J3rFxMRozpw5ysrK0pIlS3TNNddo3LhxdXbj9V8oiIuLa65iIgL530dKS0vlcDh01lln6fnnn9ebb74ZOK85+r2mBV7XB6Jei2yxk6Tnn39e8+bN09///nf17NlTn3zyiZYtW6adO3fq4Ycf1tlnnx3uIiKCvfPOO/ryyy/VtWtXjR8/PrB86tSpevfdd/XRRx8pPT09jCVEpKLuIBj+lrfS0lLddNNN+vnnn/Xxxx/rmWee0cUXXxw4Ca/c4lvXgCqIHv56sGHDBhUUFGjgwIFq3bq17r77bj355JNaunSpLrnkksB2ubm5gWlXALQsLbLFTpI2bNig888/X2effbbat2+vUaNGadq0aWrTpo1uvfVWffrpp+EuIiLUhg0bdOedd2rx4sWBkyaPxyNJevrpp9W5c2c9+eST4SwiIhR1B8GofGL+wQcfaOHChVq5cqWmTZumKVOm6I033qgS4HJzcyXVPaAKooO/7qxYsUKXXnqpvvjiC/3888+SpBkzZmjatGm6/vrrA3Vo4cKFmjVrltxud5hLDqAptIhgV1M3ldTUVDmdThUXFweWnX322Ro1apS+//57zZw5Ux999FFzFhMR6uhG627duumaa65RamqqXn/9dUlSfHy8ysrK5PV6ddxxx+nw4cPhKCoiDHUHoeLEHKEwDEOffPKJpk2bpjvuuEN/+MMfdNJJJ0mS2rRpoxkzZmj69OmaMmWKsrOztXDhQt12222y2+1hLjmAptAigp3/nro1a9YElvXu3Vu7d+/WO++8U+UDsGvXrho1apROPvlkPffccyoqKmr28iJyVB7BUJLcbrdSUlJ01VVXacaMGfrxxx81ZcoUSeX3PtlsNu3duzcwmTSiF3UHjYETcwTLf2Fp3bp1Gjx4sK666iolJiZKOjJdRps2bTR37lz9/e9/19ixY/XRRx8xeT3QgrWYe+y+/fZbnX322Zo8ebIef/xxSdL111+v9evX69Zbbw10ybzpppt0xhlnqFOnTrr99tu1bt06nXjiiWEuPcKh8khhixcv1saNG/XVV19p8uTJGjFihHr06KHnn39ejz32mNq2bauTTjpJMTEx2rhxoz799FMGuYhi1B00Bn9r3QMPPKCvv/5aL7/8cmDd0SPrvvfee9q+fbvOO+88de3aNRzFRYQ4+t7Km2++WXv27NFrr71WbQTMTZs2qWfPnkpMTOSeTCAKtIgWO0k64YQTtGTJEv3zn//ULbfcIkn685//rPPOO0/PP/+8RowYod/85jf64YcfNHPmTP36179WWlpanaONoWXzf/jdc889evLJJ3XGGWfohhtu0MKFC/XAAw/o0KFDGj9+vKZPny6Px6PvvvtOkydP1hdffBGYfBzRibqDUBw9EEpeXl6ghcX/meQPdZs2bdLhw4c1YsQITZkyhVAXxQ4dOqSSkhLt2rVLJSUlgeXHHXecPv30UxUUFARGwJTK5zdcvnx5YEwBQh3Q8rWYy8ZJSUm66KKLFBMTo1tuuUWmaerxxx/XY489pg0bNuiXX36RYRg677zzJEnPPfeckpKSjjlxJ1q2DRs2KCcnR8uWLVP//v21YcMGHThwQOeff75at24tSZo4caJ8Pp9ef/11LV++XEOHDpXEh2S0o+6goQ4dOqSYmBjt2bNHaWlpgW65xx13nFauXKmCggK1a9cu0LLiPzEfNmyYzj33XOpNFPv+++91//33a9u2bdq6datOPvlkDR06VPfee6+mTZumt99+W6NHj9a//vUvdejQQWVlZVq0aJHefPNNXXvtteEuPoDmYlrYk08+ad5zzz1Vlh06dMh87bXXzA4dOpizZ8+uts/HH39s3njjjWa3bt3Mr776qrmKighx+PDhKr9/8cUX5rBhw0zTNM3ly5ebXbp0MZ977jnTNE1z//795rp160zTNM3i4mJz6dKl5tChQ82rr766eQuNiEDdQSi+++47c/LkyeagQYPM9u3bm+ecc4555513mqZpmgcOHDCHDBliDho0yNy9e7fp8/nM0tJS85577jFPOeUUc+fOnWEuPcJpy5YtZkZGhnnrrbeaL774orly5UpzwoQJZlpamnn55Zebhw4dMr/66iszKyvLzMzMNLOzs81Ro0aZ3bt3Nzdt2hTu4gNoRpZtsTt06JAOHjyopUuXym63a8aMGZKkxMREjRkzRh988IGeeeYZ7d+/X0899VRgv9jYWBUUFGjlypXq3bt3uIqPMFi3bp22bNmis88+W2eeeaak8qHo8/Ly9OKLL+rOO+/UXXfdpWuuuUaS9MUXX+j5559X586dddJJJ2nChAk6dOiQVq9erby8POYiiyLUHYTi66+/1vnnn6/LLrtMI0aMUGpqql599VUtXbpU//vf//TCCy9o8eLFmj59ugYMGKBevXopLi5O3377rZYvX64uXbqE+ykgTPLz83XDDTfod7/7ne66667A8oEDB+qf//yn7rrrLv3hD3/Q0qVL9d577+nZZ59Vfn6+WrdurSeeeIKuu0C0CXeyrC+v11vlu2maZn5+vvnkk0+aGRkZ5oIFC6psv2DBAvPSSy81L7744ir7mGZ5qx6iy7Jly8zevXubf/zjH80vvviiyrprrrnGTE1NNR966KHAssOHD5uXX365ecUVV1SpP/v37zcLCwubq9iIANQdhGLv3r3mkCFDzLvvvrva8meeecbs1KmTOWXKFNM0TdPn85lLly4177//fvPxxx83t2/fHo4iI4Js2rTJHDRokPn111+bZWVlpmkeOQ/at2+fuWDBArNTp07mypUrw1lMABHCEi12b775pt5//33dcsst6tSpU2CY53bt2mncuHHy+Xx69NFHJUm33nqrDhw4oG+++UYXXnihJk6cKKnqKHb+4YARHd58803NmjVLixcvVlZWlpKTk6usnzJlivbs2aNXXnlFGRkZ2rdvn9577z39/PPPWr9+vWJiYgJD2/vvnUJ0oO4gVD///LNKS0t16aWXBka69Pl8at++vS677DIVFRXp0Ucf1ejRozVq1KjAFBmAJG3ZskU7duwI9DAyTTNwLpOSkqJLL71UTz75pHbs2FFlP5MRMIGoFPHTHRQXF2vo0KHav3+/0tLSdOaZZ2rQoEEaP358YJs9e/Zo+fLlmjdvnjIzM2UYhuLi4vTBBx8oNjaWN7golp+fr6uvvlpjxoypcgP5gQMH9N133yk2Nlb9+vXTtm3b9Nhjj+k///mPunXrphNOOEGPPvpoYARDhqePPtQdNIZXXnlFM2bM0C+//CKp+gm30+nUkCFDdOutt2ratGmB5XxuQZL+7//+T2PHjtXSpUs1ZsyYGrc599xzdfbZZ+uBBx5o5tIBiDQRf8Zht9t10UUX6fjjj9cZZ5yh9evX67bbbtO6devUq1cv3XzzzUpLS9P111+vs846S6tWrVLbtm117bXXKjY2ttpcQIg++fn5Ou644wK//+Uvf9H/+3//TytWrFBaWpp69uypf//731q8eHFgVDo/TsyjG3UHofLf47RixQqNGTOmWljLzMzUCSecEAh+foQ6SFJGRobatGmj1157Tf369VNGRoakI72Q9u3bp8TERCYdByDJAvPY2Ww2DRo0SHfddZdsNpumTZum7777Tl27dtX999+vrKwsPf744/rqq6902mmn6bbbbtPUqVMDV8sJdSguLta7776r9evX68orr9Tzzz+vdu3a6c0339RDDz0kp9OpBQsWSCrv2uJnmiYn5lGOuoNQVT4xz83NDSz3z1fHiTnq0rlzZy1cuFBr167VAw88oG+//VbSkbk0n3rqKeXl5WnQoEHhLCaACBHxXTH9br31VknSI488IkkaNGiQunfvrq5du+qbb77R+++/ryeeeEKTJk0KZzERgT744ANdccUVcjgcat26te6//3716dNHDodD+/bt05gxY3T++edrzpw54S4qIgx1B41h5cqV+v3vf6/f/va3+sMf/qCTTz45sO7+++/X66+/rpUrVwZaY4DKvF6vXnzxRc2aNUtdu3bVr3/9a3Xs2FFOp1Nr1qzRv//9b5122mnhLiaACGCZS8p9+/bVyy+/rH379unCCy9USkqKlixZouTkZP3888/65JNPau1/juh27rnn6osvvpDb7VZmZma19a1bt2b4edSIuoPGcP755+vBBx/UrFmz9OWXX9Z4Yk6oQ21sNpuuvvpqnXrqqXriiSf0+eefKyUlRX369NHq1at10kknhbuIACKEZVrsJCkrK0sbNmzQWWedpZdeekmpqanVtuG+FtRXfn6+brzxRrlcLr3zzjt020W9UXcQjM8//1xPPPGEtm7dGjgxnzJlCifmqDev16uYmBgZhlFltG8AkCwS7Pyjg/3973/X448/riVLlqhfv36MGoagFBQU6MUXX9Qnn3yi/Px8vfPOO4qLi2OgHRwTdQeh4sQcoah83sM5EICjWeITxf/Gdc4556iwsFDvv/9+leVAQ/z888/69NNP1a1bN61evVpxcXEMtIN6oe4gVP5QJ/EZhoarXGeoPwCOZokWu8qeeeYZPfTQQ1q1apV69eoV7uLAooqKipScnCzDMGhtQYNQdwAAQCSy3M1oI0aM0IYNG7gnASHxD01vmiYn5mgQ6g4AAIhElmuxk470K+dqOQAAAABYNNgBAAAAAI6wxOApAAAAAIDaEewAAAAAwOIIdgAAAABgcQQ7AAAAALA4gh0AAAAAWBzBDgAAAAAsjmAHAAAAABZHsAMAAAAAiyPYAQAAAIDF/X+95fssMgCURwAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "print('\\n=== without marketcolor overrides: ===')\n", + "mpf.plot(df,volume=True,type='candle',style='yahoo',figscale=1.4)\n", + "\n", + "print('\\n=== WITH MARKETCOLOR OVERRIDES: ===')\n", + "mco = df['MCOverrides'].values\n", + "mpf.plot(df,volume=True,type='candle',style='yahoo',marketcolor_overrides=mco,figscale=1.4)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### TO DO:\n", + "1. `marketcolor_overrides` should affect volume *when the override is a marketcolor object* that includes a 'volume' key.\n", + "2. support \"hollow and filled\" candles.\n", + "3. support renko and point-and-figure. This may be tricky (since one \"box\" may cover more and/or less than one date). Also, is support for marketcolor overrides even needed for renko and pnf? (find out from those who commonly use them)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.8.5" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/examples/scratch_pad/pr451_test.py b/examples/scratch_pad/pr451_test.py index 40b60e6c..da439c37 100644 --- a/examples/scratch_pad/pr451_test.py +++ b/examples/scratch_pad/pr451_test.py @@ -17,13 +17,15 @@ else: custom_colors.append(None) -STYLE = 'binance' +#STYLE = 'binance' STYLE = 'yahoo' #mpf.plot(df, type='candle',style=STYLE,volume=True,block=False,figscale=1.25,savefig='pr451t2no.jpg') -mpf.plot(df, type='ohlc',style=STYLE,volume=True,block=False,figscale=1.25) +#mpf.plot(df, type='ohlc',style=STYLE,volume=True,block=False,figscale=1.25) +mpf.plot(df, type='candle',style=STYLE,volume=True,block=False,figscale=1.25) #mpf.plot(df, type='hollow',style=STYLE,volume=True,block=False,figscale=1.25) #mpf.plot(df, type='candle',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25,savefig='pr451t2ye.jpg') -mpf.plot(df, type='ohlc',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25) +#mpf.plot(df, type='ohlc',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25) +mpf.plot(df, type='candle',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25) #mpf.plot(df, type='hollow',style=STYLE,marketcolor_overrides=custom_colors,volume=True,figscale=1.25) From 328cf512f0f7623d47cc273836dea2f63276ddd9 Mon Sep 17 00:00:00 2001 From: Daniel Goldfarb Date: Fri, 10 Dec 2021 15:03:49 -0500 Subject: [PATCH 10/11] check length of overrides; allow (0-255) format for rgb --- examples/marketcolor_overrides.ipynb | 47 ++++++++++++++++++++++++---- src/mplfinance/_arg_validators.py | 16 +++++----- src/mplfinance/_helpers.py | 39 ++++++++++++++++++++++- src/mplfinance/_styles.py | 22 ++++++------- src/mplfinance/_utils.py | 3 +- src/mplfinance/plotting.py | 4 +++ 6 files changed, 104 insertions(+), 27 deletions(-) diff --git a/examples/marketcolor_overrides.ipynb b/examples/marketcolor_overrides.ipynb index 6e436e51..b58596d8 100644 --- a/examples/marketcolor_overrides.ipynb +++ b/examples/marketcolor_overrides.ipynb @@ -33,7 +33,7 @@ "- **Rows where the user wants to override the candle color must contain a \"color-like\" object:**\n", " - Examples of color-like objects include:\n", " - a **string** such as `'yellow'` or `'#ffff00'`\n", - " - an **rgb or rgba tuple** such as `(255, 255, 0)` or `(255, 255, 0, 0.75)`\n", + " - an **rgb or rgba tuple** such as `(1.0, 1.0, 0)` or `(1.0, 1.0, 0, 0.75)`, or `(255, 255, 0)` or `(255, 255, 0, 0.75)`\n", " - an **mplfinance marketcolor object**, created with `mpf.make_marketcolors()`\n", "\n", "\n", @@ -309,13 +309,31 @@ }, "metadata": {}, "output_type": "display_data" + }, + { + "data": { + "image/png": "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16b09dnatGrVqkrj2rZtW5nXhmEoOztbL730khISEqq+gqfhRiIAAAAb/N///Z+OHDniC4uJiYnKy8tTamqqrrjiCknSxo0b5fV61aVLF1+bZ555RkVFRQoMDJQkrV+/3nedqCQlJSVpw4YN+sMf/uDra/369UpMTKzSuK666io5HI5yl1T++te/1iuvvFLj9SV0AgAA+EFBQUGZm3AyMzOVlpam5s2bKzQ0VDNnztTAgQMVHh6uPXv26IknnlBMTIz69u0rSYqLi1Pfvn11//33a86cOSoqKtLEiRM1ePBgtW7dWlLJpwU9//zzGjdunO6//37t3LlTCxcu1LPPPuvr96677lL//v31yiuv6Nprr9WKFSuUmpqql156qUrrkZqaWua10+nUBRdcoIYNG55TfQidAAAAfpCamlrmcUNTp06VJI0YMUKzZ8/Wjh07tGzZMuXl5SkiIkJ9+vTRlClTylwjumjRIk2YMEHJyclyOBwaOHCgZsyY4ZsfEhKi9957TxMmTNDVV1+tFi1aaMKECb7HJUlS165dtWjRIj377LOaNm2aYmJi9NZbb1XpGZ2Syt2o5C+ETgAAAD/o0aOHjh49esb577333lmXERoa6nsQ/JkkJCToo48+qrRNcnKykpOTz9pfqYULF1a57V133VXltqcidAIAANRz8+fPr1I7h8NB6AQAAEDNfPfdd6b3wYPMAAAAUCHDMM74wUDVRegEAABAGcuWLVP37t3VunVrtW7dWldeeaWWLVt2Tsvk9DoAAAB85s2bp+nTp2vs2LHq2rWrJOkf//iHHn74YR05ckT33HNPjZZL6AQAAIDPq6++qtmzZ2v48OG+addff73i4+M1Y8aMGodOTq8DAADAJzs7W0lJSeWmJyUlKTs7u8bLJXQCAADAp127dlq5cmW56StXrlRMTEyNl8vpdQAAAGjHjh3q0KGDpkyZojFjxujrr7/2XdP5zTffaMOGDXr99ddrvHyOdAIAAEA9evTQNddco9zcXP3tb39TWFiY1qxZozVr1igsLEyfffaZ+vfvX+Plc6QTAAAAWr16td5++209/vjj8nq9GjBggJ599lldeeWVflk+RzoBAACg7t2765VXXtHOnTs1c+ZM7du3TwMHDtSvf/1rvfTSS+d0E5FE6AQAAMApmjRpoltuuUVr1qzR5s2bNWjQIC1evFiXXXaZRowYUePlEjoBAABQoZiYGD300EMaP368mjZtqk8++aTGy+KaTgAAAJSzadMm/eUvf9GqVavkcDj0+9//XiNHjqzx8gidAAAAkCRlZWXp7bff1tKlS7V7924lJSVpxowZSk5OVpMmTc5p2YROAAAAaOjQodqwYYNatGihm266SSNHjlRsbKzflk/oBAAAgAIDA/Xmm2/qt7/9rVwul9+XT+gEAACAli5dauryuXsdAADADzZt2qThw4crPj5eoaGhWrNmTZn5hmFo+vTpuvTSS9W6dWslJyfrv//9b5k2R48e1R133KHIyEhFRUVp3LhxKigoKNNm27Ztuu666xQREaGOHTtq7ty55cby/vvvKykpSREREerevfs53XXuL4ROAAAAPygsLFRCQoJeeOGFCufPnTtXCxcu1Jw5c/Tpp5+qcePGGjJkiE6cOOFrc8cdd+j777/XihUrtGzZMn311Vd64IEHfPPz8/M1ZMgQtW3bVuvXr9fTTz+tmTNn6o033vC1+eabbzR27FiNHDlSGzZs0A033KCRI0dqx44dZq16lRA6AQAA/KBfv3569NFHK/x8csMw9Oc//1njx4/X9ddfr4SEBC1YsEAHDx70HRHdtWuXPvvsM7388sv69a9/rW7dumnmzJlasWKFsrKyJEnvvvuu3G63XnnlFcXHx2vIkCG68847NX/+fF9fCxcuVN++fXXfffcpLi5OU6dOVadOnbRo0SJrCnEG1bqm0+PxyOFwlJt26tfaybB7APWMIY/Hw188Fiv5HWVbt5ZB3S3H/sUutTUHVJZjDKPkdzc/P79M/gkKClJQUFC1+snMzFR2drZ69+7tmxYSEqIuXbpo8+bNGjJkiDZv3qyQkBB17tzZ16Z3795yOp3aunWr+vfvr82bN6t79+5q0KCBr03fvn01d+5c/fjjj2revLm+/fZb/fGPfyzTf58+fcqd7rdatUJnenq67wdwuoyMDL8MyA5eL28IVvJ6De3atUsdDK/8f28cKuI1vNq1axfbusVKt3Xqbh32L/Yo3cfUZhXlGIfDoaioKCUkJJS5rnLSpEmaPHlytZZf+rnlLVu2LDO9VatWysnJ8bU5fX5AQIBCQ0N935+Tk6PIyMgybUq/Jzs7W82bN1dOTk655bRs2dLXj12qFTpjY2MrPNKZkZGh9u3bm3J7vRWc36y1ewj1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iYYOHaqePXtKkgICSv6eu+CCC3TixIkybX/66SfLx1dXtW7dWoMGDVLHjh0lSUuXLtXMmTP1xhtvaM2aNXr11Vd16aWXav78+Tp58iSnIP2kNEj26dNHO3fulNPp1N13362AgADl5OSoS5cuatKkiZxOJ6fa/aRVq1Z67rnndO2112rAgAEyDEMpKSkaP368nn/+ed17773Kzc3V119/bfdQgTMidNYxpXePNmjQQA6Hw/d61KhRGjNmjC94btu2TY8//riGDRvGHZDnqPQJAddff70kyTAM35ty6Z3spWHnxRdf1LRp01RcXGzPYOuQ0m27RYsWvmnXX3+91q5dq4EDByosLEzx8fEKDg5WXl6egoKC5HA47BpunVAaIEvrGBQUpB07dkiS7rvvPh04cEBjxozR7t27de+990oSRzr9oHRbDwsL01NPPaUnn3xSt99+u8LCwnw/k+uvv15ut1vfffednUMFKsXp9Tpg3759+u677zRgwADfRfylO/pTX48ePVoOh0NvvPGGbr75Zh09elSrVq3iDsgaOLXmgYGBZWrucDhkGIYcDoeaNGmi4OBgORwOTZ8+3Xfqt/RIKKqnsm3d4/EoJCREXbp0kVQS/g3DUKNGjRQTEyOv1yuHw0HwrKZTa1565LK05p07d1ZkZKSGDh2qHTt2aNWqVbrwwgu1YMECrVu3TtnZ2QoPD7d5DWqn07f10ksaWrVqpdGjR6tx48aSSkK9x+NRYWGhoqKiuIwE5zXe+Wq5jIwM/e53v1OzZs107NgxDR8+vNwbw6mvR40apaVLl+qnn37S2rVrfaclUXVVqXmphg0bqkWLFpo5c6b+9Kc/6fPPP9dll11m08hrt7PV/fTH9Hi9Xs2cOVPr16/XBx98wBG3GjhbzUNCQnT48GHt27dP7733ni655BJJ0p133qmxY8fyyKoaqqjupwbPkJCQMu2dTqfmzZun//73v+revbtNowbOjrvXa7HDhw/rrrvuksPhUEhIiH744QeNHj1aN998sySVC0HFxcUaP368lixZor///e8Ezhqobs3nzZunxx57TI0bN9bq1at1xRVX2DTy2q26df/iiy+0evVqvf/++1qxYgVHf2rgbDUvKipSYGCgCgsLlZ2drXbt2kmS7yg/aqa62/pnn32mVatW6W9/+5s++OAD/qjFeY0jnbXYyZMn1bRpU912221q3bq1XnrpJb355puSpJtvvrnc0beAgAB169ZNo0ePJnDWUFVqfuqbbosWLRQVFaVly5bx1IBzUN26Hz58WC6XS2vWrKHuNXS2mgcGBqq4uFiNGzf2BU5JBM5zVN1tvfSa8Y8++kiXXnqpnUMHzoojnbVcVlaWWrduLUnasWOH5s6dq71792rUqFG65ZZbJJUc4eQaQv+pSs1LjwJJ4ro2P6lK3UsfVSWVPK+29Lo31Az7F3tUd1s/duyYmjRpYtt4gariIqdarnTH5PF41KFDBz344IOKjo7WkiVL9Pbbb0uSHn74Yb3++ut2DrNOqUrNx48fr0WLFkkSgdNPqlL3CRMm6H//938licDpB+xf7FHdbZ3AidqCI5110Pfff68XX3xR+/fvl8Ph0Ndff61169bpV7/6ld1Dq7OouT2ou/WouT2oO+oCQmctdbaL9dPS0nTTTTepsLBQq1evVkJCgoWjq5uouT2ou/WouT2oO+o6Tq/XEqUPB87NzZVU+cX6brfb91ikDz/8kB1TDVFze1B361Fze1B31DeEzvNcRkaGVq9eLZfLpffff1933323Dh06VOn3/PTTT9q8ebM++OADdejQwaKR1h3U3B7U3XrU3B7UHfWWgfOWx+MxnnvuOSM0NNR49NFHjdDQUGPp0qWVfo/X6zUMwzBOnjxpxRDrHGpuD+puPWpuD+qO+oxrOmuBYcOG6fPPP9ftt9+uF154ocJPvjmdwQOazwk1twd1tx41twd1R33E6fXzVOnfAkVFRQoLC1P37t312muv6b333vM9HPj0vxdOfc2OqfqouT2ou/WouT2oO+o9i46oohpKT6X885//ND799FPjp59+MgzDMJ544gkjLCzMePfdd8u0y8zMtGegdQg1twd1tx41twd1BwyDI53nGePn0ycffPCBhg0bpq1bt+rAgQOSSh7CPG7cON19991avny5HA6HZs+erYkTJ+rYsWM2j7z2oub2oO7Wo+b2oO7Az2yNvKjQ119/bURGRhqvv/66cfz48TLz8vPzjWeeecYIDQ01rr32WqN169ZGamqqTSOtO6i5Pai79ai5Pag7wI1E5xXj57+Gp0+fru3bt+svf/mLb57H45HL5fK9/vTTT7V7925de+21ateunR3DrROouT2ou/WouT2oO/CLALsHgF92SqUXiR88eND30ODSOxpLd0zfffed4uLi1K9fP+5kPAfU3B7U3XrU3B7UHSiPazptdPz4cZ08eVI//PCDTp486Zt+4YUX6ptvvlFubq7vjkap5OHAK1as0DfffCOJOxlrgprbg7pbj5rbg7oDlbDyXD5+8f333xu33nqr0a1bN+OCCy4wevbsaTz22GOGYRhGQUGBcdVVVxndunUzsrOzDa/XaxQVFRlPPfWU0bFjR2P//v02j752oub2oO7Wo+b2oO5A5bim0wbbt2/X9ddfrxtvvFGXX365QkNDtXTpUq1bt05XX3213njjDaWnp+vBBx9URkaGLr30UgUGBmrnzp1asWKFLr/8crtXodah5vag7taj5vag7sDZETotdvjwYQ0ZMkR9+vTRE088UWb6ypUr9cQTT2jAgAFauHChDMPQokWLdPjwYTVt2lQDBgzg4vIaoOb2oO7Wo+b2oO5AFdl2jLWe+u6774xu3boZ27dvN4qLiw3DKPksXsMwjB9//NF44YUXjNatWxurVq2yc5h1CjW3B3W3HjW3B3UHqoYbiSy2bds27dmzRx06dJDL5ZJhGL7P2w0JCdGwYcMUGBioPXv2lPk+gwPSNUbN7UHdrUfN7UHdgaohdFqs9DTKBx98IKn8nYpRUVGKjo5WVlZWmenc0Vhz1Nwe1N161Nwe1B2oGkKnxSIjI9WsWTMtW7ZM+/bt8033er2SpB9//FENGzZUp06d7BpinUPN7UHdrUfN7UHdgaohdFqsTZs2mj17tj777DNNnz5dO3fulCTfqZh58+bp4MGD6tatm53DrFOouT2ou/WouT2oO1A13L1uA4/HoyVLlmjixIlq166dunbtqvDwcGVmZmrdunX629/+xuMz/Iya24O6W4+a24O6A2dH6LTRli1b9PLLLys9PV0hISFKSEjQnXfeqUsuucTuodVZ1Nwe1N161Nwe1B04M0KnzTwej5xOpxwOh+/zeGEuam4P6m49am4P6g5UjN8Em5XumCTuZLQKNbcHdbceNbcHdQcqxpFOAAAAmI4jnQAAADAdoRMAAACmI3QCAADAdIROAAAAmI7QCQAAANMROgEAAGA6QicAAABMR+gEAACA6QidAAAAMB2hEwAAAKb7f/DA/yy0kRFQAAAAAElFTkSuQmCC\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ + "# ===============================================================================================\n", + "# Here we specify `up` as rgba using the matplotlib convention: rgb are floats from 0.0 and 1.0 :\n", "mc = mpf.make_marketcolors(base_mpf_style='yahoo',up=(0.7,1.0,0.7,0.4),down='fuchsia',\n", " edge={'up':'blue','down':'#000000'},wick='#cc6600')\n", - "#mc = mpf.make_marketcolors(base_mpf_style='yahoo',up=(0.7,1.0,0.7,0.4),down=(1,0.25,1),\n", - "# edge={'up':'blue','down':'#000000'},wick='#cc6600')\n", + "\n", + "mco = [None,None,mc,mc,None]\n", + "mpf.plot(df,volume=True,style='yahoo',type='candle',marketcolor_overrides=mco)\n", + "\n", + "# ====================================================================================\n", + "# Here we specify `up` as rgba using the convention that rgb are ints from 0 and 255 :\n", + "mc = mpf.make_marketcolors(base_mpf_style='yahoo',up=(178,255,178,0.4),down='fuchsia',\n", + " edge={'up':'blue','down':'#000000'},wick='#cc6600')\n", "\n", "mco = [None,None,mc,mc,None]\n", "mpf.plot(df,volume=True,style='yahoo',type='candle',marketcolor_overrides=mco)" @@ -337,10 +355,27 @@ "#### When dealing with larger data sets we recommend setting up your marketcolor overrides as a COLUMN in your DataFrame\n", "#### This has two advantages:\n", "1. It helps ensure that your marketcolor overrides are the same length as your dataframe, and\n", - "2. It allows you to use the dataframe's DatetimeIndex to set the override values.\n", + "2. It allows you to use the dataframe's `DatetimeIndex` in order to position the override values.\n", + "\n", "#### Note that you will still have to pass the `marketcolor_overrides` as an separate iterable (apart from the dataframe)." ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "#### Step 1: read in the data:" + ] + }, { "cell_type": "code", "execution_count": 8, @@ -447,7 +482,7 @@ "source": [ "---\n", "\n", - "#### Create a new column for the overrides:" + "#### Step 2: Create a new column for the overrides:" ] }, { @@ -555,7 +590,7 @@ "source": [ "---\n", "\n", - "#### Use the DatetimeIndex to set the Overrides:\n", + "#### Step 3: Use the DatetimeIndex to position the Overrides:\n", "#### For demonstration purposes, let's override every Monday as black, and every Tuesday as \"blueskies\" marketcolors:" ] }, diff --git a/src/mplfinance/_arg_validators.py b/src/mplfinance/_arg_validators.py index 945f117f..e38bbeac 100644 --- a/src/mplfinance/_arg_validators.py +++ b/src/mplfinance/_arg_validators.py @@ -1,9 +1,8 @@ import matplotlib.dates as mdates -import matplotlib.colors as mcolors import pandas as pd import numpy as np import datetime -from mplfinance._helpers import _list_of_dict +from mplfinance._helpers import _list_of_dict, _mpf_is_color_like import matplotlib as mpl import warnings @@ -364,19 +363,20 @@ def _is_marketcolor_object(obj): if not isinstance(obj,dict): return False market_colors_keys = ('candle','edge','wick','ohlc') return all([k in obj for k in market_colors_keys]) - -def _mco_validator(value): # marketcolor overrides validator - if isinstance(value,dict): # not yet supported, but maybe we will have other - if 'colors' not in value: # kwargs related to mktcolor overrides (ex: `mco_faceonly`) + +def _mco_validator(value): # marketcolor overrides validator + if isinstance(value,dict): # not yet supported, but maybe we will have other + if 'colors' not in value: # kwargs related to mktcolor overrides (ex: `mco_faceonly`) raise ValueError('`marketcolor_overrides` as dict must contain `colors` key.') colors = value['colors'] else: colors = value if not isinstance(colors,(list,tuple,np.ndarray)): return False - return all([(c is None or mcolors.is_color_like(c) or _is_marketcolor_object(c)) for c in colors]) - + return all([(c is None or + _mpf_is_color_like(c) or + _is_marketcolor_object(c) ) for c in colors]) def _check_for_external_axes(config): ''' diff --git a/src/mplfinance/_helpers.py b/src/mplfinance/_helpers.py index ece35913..e8a38359 100644 --- a/src/mplfinance/_helpers.py +++ b/src/mplfinance/_helpers.py @@ -1,9 +1,13 @@ """ Some helper functions for mplfinance. +NOTE: This is the lowest level in mplfinance: + This file should have NO dependencies on + any other mplfinance files. """ import datetime -import matplotlib.dates as mdates +import matplotlib.dates as mdates +import matplotlib.colors as mcolors import numpy as np def _adjust_color_brightness(color,amount=0.5): @@ -82,3 +86,36 @@ def roundTime(dt=None, roundTo=60): seconds = (dt.replace(tzinfo=None) - dt.min).seconds rounding = (seconds+roundTo/2) // roundTo * roundTo return dt + datetime.timedelta(0,rounding-seconds,-dt.microsecond) + + +def _is_uint8_rgb_or_rgba(tup): + """ Deterine if rgb or rgba is in (0-255) format: + Matplotlib expects rgb (and rgba) tuples to contain + three (or four) floats between 0.0 and 1.0 + + Some people express rgb as tuples of three integers + between 0 and 255. + (In rgba, alpha is still a float from 0.0 to 1.0) + """ + if isinstance(tup,str): return False + if not np.iterable(tup): return False + L = len(tup) + if L < 3 or L > 4: return False + if L == 4 and (tup[3] < 0 or tup[3] > 1): return False + return not any([not isinstance(v,(int,np.unsignedinteger)) or v<0 or v>255 for v in tup[0:3]]) + +def _mpf_is_color_like(c): + """Determine if an object is a color. + + Identical to `matplotlib.colors.is_color_like()` + BUT ALSO considers int (0-255) rgb and rgba colors. + """ + if mcolors.is_color_like(c): return True + return _is_uint8_rgb_or_rgba(c) + +def _mpf_to_rgba(c, alpha=None): + cnew = c + if _is_uint8_rgb_or_rgba(c) and any(e>1 for e in c[:3]): + cnew = tuple([e/255. for e in c[:3]]) + if len(c) == 4: cnew += c[3:] + return mcolors.to_rgba(cnew, alpha) diff --git a/src/mplfinance/_styles.py b/src/mplfinance/_styles.py index fde40ae8..a8cb08dc 100644 --- a/src/mplfinance/_styles.py +++ b/src/mplfinance/_styles.py @@ -1,11 +1,11 @@ import matplotlib.pyplot as plt -import matplotlib.colors as mcolors import copy import pprint import os.path as path from mplfinance._arg_validators import _process_kwargs, _validate_vkwargs_dict from mplfinance._styledata import _styles +from mplfinance._helpers import _mpf_is_color_like def _get_mpfstyle(style): @@ -70,7 +70,7 @@ def _valid_make_mpf_style_kwargs(): 'Validator' : lambda value: isinstance(value,dict) }, 'mavcolors' : { 'Default' : None, - 'Validator' : lambda value: isinstance(value,list) }, # TODO: all([mcolors.is_color_like(v) for v in value.values()]) + 'Validator' : lambda value: isinstance(value,list) }, # TODO: all([_mpf_is_color_like(v) for v in value.values()]) 'facecolor' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,str) }, @@ -153,10 +153,10 @@ def make_mpf_style( **kwargs ): def _valid_mpf_color_spec(value): 'value must be a color, "inherit"-like, or dict of colors' - return ( mcolors.is_color_like(value) or + return ( _mpf_is_color_like(value) or ( isinstance(value,str) and value == 'inherit'[0:len(value)]) or ( isinstance(value,dict) and - all([mcolors.is_color_like(v) for v in value.values()]) + all([_mpf_is_color_like(v) for v in value.values()]) ) ) @@ -190,13 +190,13 @@ def _valid_mpf_style(value): def _valid_make_marketcolors_kwargs(): vkwargs = { 'up' : { 'Default' : None, - 'Validator' : lambda value: mcolors.is_color_like(value) }, + 'Validator' : lambda value: _mpf_is_color_like(value) }, 'down' : { 'Default' : None, - 'Validator' : lambda value: mcolors.is_color_like(value) }, + 'Validator' : lambda value: _mpf_is_color_like(value) }, 'hollow' : { 'Default' : None, - 'Validator' : lambda value: mcolors.is_color_like(value) }, + 'Validator' : lambda value: _mpf_is_color_like(value) }, 'alpha' : { 'Default' : None, 'Validator' : lambda value: ( isinstance(value,float) and @@ -208,17 +208,17 @@ def _valid_make_marketcolors_kwargs(): 'wick' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,dict) or isinstance(value,str) - or mcolors.is_color_like(value) }, + or _mpf_is_color_like(value) }, 'ohlc' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,dict) or isinstance(value,str) - or mcolors.is_color_like(value) }, + or _mpf_is_color_like(value) }, 'volume' : { 'Default' : None, 'Validator' : lambda value: isinstance(value,dict) or isinstance(value,str) - or mcolors.is_color_like(value) }, + or _mpf_is_color_like(value) }, 'vcdopcod' : { 'Default' : False, 'Validator' : lambda value: isinstance(value,bool) }, @@ -282,7 +282,7 @@ def _check_and_set_mktcolor(candle,**kwarg): else: colors = dict(up=value, down=value) for updown in ['up','down']: - if not mcolors.is_color_like(colors[updown]): + if not _mpf_is_color_like(colors[updown]): err = f'NOT is_color_like() for {key}[\'{updown}\'] = {colors[updown]}' raise ValueError(err) return colors diff --git a/src/mplfinance/_utils.py b/src/mplfinance/_utils.py index 9f519010..6dd7d366 100644 --- a/src/mplfinance/_utils.py +++ b/src/mplfinance/_utils.py @@ -17,6 +17,7 @@ from mplfinance._arg_validators import _alines_validator, _bypass_kwarg_validation from mplfinance._arg_validators import _xlim_validator, _is_datelike from mplfinance._styles import _get_mpfstyle +from mplfinance._helpers import _mpf_to_rgba from six.moves import zip @@ -603,7 +604,7 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market faceonly = config['mco_faceonly'] colors = _make_updown_color_list('candle',marketcolors,opens,closes,overrides) - colors = [mcolors.to_rgba(c,alpha) for c in colors] # include alpha + colors = [ _mpf_to_rgba(c,alpha) for c in colors ] # include alpha if faceonly: overrides = None edgecolor = _make_updown_color_list('edge',marketcolors,opens,closes,overrides) wickcolor = _make_updown_color_list('wick',marketcolors,opens,closes,overrides) diff --git a/src/mplfinance/plotting.py b/src/mplfinance/plotting.py index 14ef37dd..0bd0b987 100644 --- a/src/mplfinance/plotting.py +++ b/src/mplfinance/plotting.py @@ -306,6 +306,10 @@ def plot( data, **kwargs ): err = "`addplot` is not supported for `type='" + config['type'] +"'`" raise ValueError(err) + if config['marketcolor_overrides'] is not None: + if len(config['marketcolor_overrides']) != len(dates): + raise ValueError('`marketcolor_overrides` must be same length as dataframe.') + external_axes_mode = _check_for_external_axes(config) if external_axes_mode: From 28b05ca247f5557298f0b07e850796dfcdc826b1 Mon Sep 17 00:00:00 2001 From: Daniel Goldfarb Date: Sat, 11 Dec 2021 18:33:10 -0500 Subject: [PATCH 11/11] fix grammer; and add **`make_addplot()`** to TODO list --- examples/marketcolor_overrides.ipynb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/examples/marketcolor_overrides.ipynb b/examples/marketcolor_overrides.ipynb index b58596d8..e4968366 100644 --- a/examples/marketcolor_overrides.ipynb +++ b/examples/marketcolor_overrides.ipynb @@ -357,7 +357,7 @@ "1. It helps ensure that your marketcolor overrides are the same length as your dataframe, and\n", "2. It allows you to use the dataframe's `DatetimeIndex` in order to position the override values.\n", "\n", - "#### Note that you will still have to pass the `marketcolor_overrides` as an separate iterable (apart from the dataframe)." + "#### Note that you will still have to pass the `marketcolor_overrides` as a separate iterable (apart from the dataframe)." ] }, { @@ -787,8 +787,9 @@ "source": [ "### TO DO:\n", "1. `marketcolor_overrides` should affect volume *when the override is a marketcolor object* that includes a 'volume' key.\n", - "2. support \"hollow and filled\" candles.\n", - "3. support renko and point-and-figure. This may be tricky (since one \"box\" may cover more and/or less than one date). Also, is support for marketcolor overrides even needed for renko and pnf? (find out from those who commonly use them)." + "2. support `marketcolor_overrides` in **`mpf.make_addplot()`**\n", + "3. support \"hollow and filled\" candles (both `mpf.plot()` and `mpf.make_addplot()`).\n", + "4. support renko and point-and-figure. This may be tricky (since one \"box\" may cover more and/or less than one date). Also, is support for marketcolor overrides even needed for renko and pnf? (find out from those who commonly use them)." ] }, {