From 70bee16a6de5a5fdce360543674ae8bde1295f9a Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Sep 2016 09:56:57 +0100 Subject: [PATCH 1/4] remove finance from api --- doc/api/finance_api.rst | 12 ------------ doc/api/index.rst | 1 - 2 files changed, 13 deletions(-) delete mode 100644 doc/api/finance_api.rst diff --git a/doc/api/finance_api.rst b/doc/api/finance_api.rst deleted file mode 100644 index 9b2c5021c675..000000000000 --- a/doc/api/finance_api.rst +++ /dev/null @@ -1,12 +0,0 @@ -******* -finance -******* - - -:mod:`matplotlib.finance` -========================= - -.. automodule:: matplotlib.finance - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/api/index.rst b/doc/api/index.rst index 02ee4f9d1e6c..4275a9a9be0b 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -29,7 +29,6 @@ dates_api.rst dviread.rst figure_api.rst - finance_api.rst font_manager_api.rst gridspec_api.rst image_api.rst From 097a26bcec344eb061413b45d7f8f8f88825ce06 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Sep 2016 09:57:20 +0100 Subject: [PATCH 2/4] remove no longer existing finance example from backend driver --- examples/tests/backend_driver.py | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/tests/backend_driver.py b/examples/tests/backend_driver.py index 84fe6b1809fd..43750d98bcf6 100755 --- a/examples/tests/backend_driver.py +++ b/examples/tests/backend_driver.py @@ -164,7 +164,6 @@ 'figure_title.py', 'fill_between_demo.py', 'fill_spiral.py', - 'finance_demo.py', 'findobj_demo.py', 'fonts_demo.py', 'fonts_demo_kw.py', From 53dae35e7a1a729044c49a61381fe3a2081e8360 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Sep 2016 09:59:58 +0100 Subject: [PATCH 3/4] remove finance module from pylab --- lib/matplotlib/pylab.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/matplotlib/pylab.py b/lib/matplotlib/pylab.py index bd1b4936cdc4..5617bf8b6157 100644 --- a/lib/matplotlib/pylab.py +++ b/lib/matplotlib/pylab.py @@ -226,9 +226,6 @@ silent_list, iterable, dedent import matplotlib as mpl -# make mpl.finance module available for backwards compatability, in case folks -# using pylab interface depended on not having to import it -import matplotlib.finance from matplotlib.dates import date2num, num2date,\ datestr2num, strpdate2num, drange,\ From 005c365254674cb9d280b2ccd6afffe81dd7c0e7 Mon Sep 17 00:00:00 2001 From: Jens Hedegaard Nielsen Date: Fri, 9 Sep 2016 10:15:33 +0100 Subject: [PATCH 4/4] remove matplotlib finance and replace with shim --- lib/matplotlib/finance.py | 1398 +------------------------------------ 1 file changed, 12 insertions(+), 1386 deletions(-) diff --git a/lib/matplotlib/finance.py b/lib/matplotlib/finance.py index 6fdd1b6367ec..90f07c168d05 100644 --- a/lib/matplotlib/finance.py +++ b/lib/matplotlib/finance.py @@ -1,1390 +1,16 @@ """ -A collection of functions for collecting, analyzing and plotting -financial data. User contributions welcome! - -This module is deprecated in 1.4 and will be moved to `mpl_toolkits` -or it's own project in the future. - +Shim to provide backword compatibility for finance """ -from __future__ import (absolute_import, division, print_function, - unicode_literals) - -import six -from six.moves import xrange, zip - -import contextlib -import os import warnings -from six.moves.urllib.request import urlopen - -import datetime - -import numpy as np - -from matplotlib import colors as mcolors, verbose, get_cachedir -from matplotlib.dates import date2num -from matplotlib.cbook import iterable, mkdirs -from matplotlib.collections import LineCollection, PolyCollection -from matplotlib.lines import Line2D, TICKLEFT, TICKRIGHT -from matplotlib.patches import Rectangle -from matplotlib.transforms import Affine2D - - -if six.PY3: - import hashlib - - def md5(x): - return hashlib.md5(x.encode()) +from matplotlib.cbook import mplDeprecation +try: + from mpl_finance import * +except ImportError: + raise ImportError("Matplotlib.finance has been split into a separate " + "module. Please install 'mpl_finance' to use.") else: - from hashlib import md5 - -cachedir = get_cachedir() -# cachedir will be None if there is no writable directory. -if cachedir is not None: - cachedir = os.path.join(cachedir, 'finance.cache') -else: - # Should only happen in a restricted environment (such as Google App - # Engine). Deal with this gracefully by not caching finance data. - cachedir = None - - -stock_dt_ohlc = np.dtype([ - (str('date'), object), - (str('year'), np.int16), - (str('month'), np.int8), - (str('day'), np.int8), - (str('d'), np.float), # mpl datenum - (str('open'), np.float), - (str('high'), np.float), - (str('low'), np.float), - (str('close'), np.float), - (str('volume'), np.float), - (str('aclose'), np.float)]) - - -stock_dt_ochl = np.dtype( - [(str('date'), object), - (str('year'), np.int16), - (str('month'), np.int8), - (str('day'), np.int8), - (str('d'), np.float), # mpl datenum - (str('open'), np.float), - (str('close'), np.float), - (str('high'), np.float), - (str('low'), np.float), - (str('volume'), np.float), - (str('aclose'), np.float)]) - - -def parse_yahoo_historical_ochl(fh, adjusted=True, asobject=False): - """Parse the historical data in file handle fh from yahoo finance. - - Parameters - ---------- - - adjusted : bool - If True (default) replace open, close, high, low prices with - their adjusted values. The adjustment is by a scale factor, S = - adjusted_close/close. Adjusted prices are actual prices - multiplied by S. - - Volume is not adjusted as it is already backward split adjusted - by Yahoo. If you want to compute dollars traded, multiply volume - by the adjusted close, regardless of whether you choose adjusted - = True|False. - - - asobject : bool or None - If False (default for compatibility with earlier versions) - return a list of tuples containing - - d, open, close, high, low, volume - - If None (preferred alternative to False), return - a 2-D ndarray corresponding to the list of tuples. - - Otherwise return a numpy recarray with - - date, year, month, day, d, open, close, high, low, - volume, adjusted_close - - where d is a floating poing representation of date, - as returned by date2num, and date is a python standard - library datetime.date instance. - - The name of this kwarg is a historical artifact. Formerly, - True returned a cbook Bunch - holding 1-D ndarrays. The behavior of a numpy recarray is - very similar to the Bunch. - - """ - return _parse_yahoo_historical(fh, adjusted=adjusted, asobject=asobject, - ochl=True) - - -def parse_yahoo_historical_ohlc(fh, adjusted=True, asobject=False): - """Parse the historical data in file handle fh from yahoo finance. - - Parameters - ---------- - - adjusted : bool - If True (default) replace open, high, low, close prices with - their adjusted values. The adjustment is by a scale factor, S = - adjusted_close/close. Adjusted prices are actual prices - multiplied by S. - - Volume is not adjusted as it is already backward split adjusted - by Yahoo. If you want to compute dollars traded, multiply volume - by the adjusted close, regardless of whether you choose adjusted - = True|False. - - - asobject : bool or None - If False (default for compatibility with earlier versions) - return a list of tuples containing - - d, open, high, low, close, volume - - If None (preferred alternative to False), return - a 2-D ndarray corresponding to the list of tuples. - - Otherwise return a numpy recarray with - - date, year, month, day, d, open, high, low, close, - volume, adjusted_close - - where d is a floating poing representation of date, - as returned by date2num, and date is a python standard - library datetime.date instance. - - The name of this kwarg is a historical artifact. Formerly, - True returned a cbook Bunch - holding 1-D ndarrays. The behavior of a numpy recarray is - very similar to the Bunch. - """ - return _parse_yahoo_historical(fh, adjusted=adjusted, asobject=asobject, - ochl=False) - - -def _parse_yahoo_historical(fh, adjusted=True, asobject=False, - ochl=True): - """Parse the historical data in file handle fh from yahoo finance. - - - Parameters - ---------- - - adjusted : bool - If True (default) replace open, high, low, close prices with - their adjusted values. The adjustment is by a scale factor, S = - adjusted_close/close. Adjusted prices are actual prices - multiplied by S. - - Volume is not adjusted as it is already backward split adjusted - by Yahoo. If you want to compute dollars traded, multiply volume - by the adjusted close, regardless of whether you choose adjusted - = True|False. - - - asobject : bool or None - If False (default for compatibility with earlier versions) - return a list of tuples containing - - d, open, high, low, close, volume - - or - - d, open, close, high, low, volume - - depending on `ochl` - - If None (preferred alternative to False), return - a 2-D ndarray corresponding to the list of tuples. - - Otherwise return a numpy recarray with - - date, year, month, day, d, open, high, low, close, - volume, adjusted_close - - where d is a floating poing representation of date, - as returned by date2num, and date is a python standard - library datetime.date instance. - - The name of this kwarg is a historical artifact. Formerly, - True returned a cbook Bunch - holding 1-D ndarrays. The behavior of a numpy recarray is - very similar to the Bunch. - - ochl : bool - Selects between ochl and ohlc ordering. - Defaults to True to preserve original functionality. - - """ - if ochl: - stock_dt = stock_dt_ochl - else: - stock_dt = stock_dt_ohlc - - results = [] - - # datefmt = '%Y-%m-%d' - fh.readline() # discard heading - for line in fh: - - vals = line.split(',') - if len(vals) != 7: - continue # add warning? - datestr = vals[0] - #dt = datetime.date(*time.strptime(datestr, datefmt)[:3]) - # Using strptime doubles the runtime. With the present - # format, we don't need it. - dt = datetime.date(*[int(val) for val in datestr.split('-')]) - dnum = date2num(dt) - open, high, low, close = [float(val) for val in vals[1:5]] - volume = float(vals[5]) - aclose = float(vals[6]) - if ochl: - results.append((dt, dt.year, dt.month, dt.day, - dnum, open, close, high, low, volume, aclose)) - - else: - results.append((dt, dt.year, dt.month, dt.day, - dnum, open, high, low, close, volume, aclose)) - results.reverse() - d = np.array(results, dtype=stock_dt) - if adjusted: - scale = d['aclose'] / d['close'] - scale[np.isinf(scale)] = np.nan - d['open'] *= scale - d['high'] *= scale - d['low'] *= scale - d['close'] *= scale - - if not asobject: - # 2-D sequence; formerly list of tuples, now ndarray - ret = np.zeros((len(d), 6), dtype=float) - ret[:, 0] = d['d'] - if ochl: - ret[:, 1] = d['open'] - ret[:, 2] = d['close'] - ret[:, 3] = d['high'] - ret[:, 4] = d['low'] - else: - ret[:, 1] = d['open'] - ret[:, 2] = d['high'] - ret[:, 3] = d['low'] - ret[:, 4] = d['close'] - ret[:, 5] = d['volume'] - if asobject is None: - return ret - return [tuple(row) for row in ret] - - return d.view(np.recarray) # Close enough to former Bunch return - - -def fetch_historical_yahoo(ticker, date1, date2, cachename=None, - dividends=False): - """ - Fetch historical data for ticker between date1 and date2. date1 and - date2 are date or datetime instances, or (year, month, day) sequences. - - Parameters - ---------- - ticker : str - ticker - - date1 : sequence of form (year, month, day), `datetime`, or `date` - start date - date2 : sequence of form (year, month, day), `datetime`, or `date` - end date - - cachename : str - cachename is the name of the local file cache. If None, will - default to the md5 hash or the url (which incorporates the ticker - and date range) - - dividends : bool - set dividends=True to return dividends instead of price data. With - this option set, parse functions will not work - - Returns - ------- - file_handle : file handle - a file handle is returned - - - Examples - -------- - >>> fh = fetch_historical_yahoo('^GSPC', (2000, 1, 1), (2001, 12, 31)) - - """ - - ticker = ticker.upper() - - if iterable(date1): - d1 = (date1[1] - 1, date1[2], date1[0]) - else: - d1 = (date1.month - 1, date1.day, date1.year) - if iterable(date2): - d2 = (date2[1] - 1, date2[2], date2[0]) - else: - d2 = (date2.month - 1, date2.day, date2.year) - - if dividends: - g = 'v' - verbose.report('Retrieving dividends instead of prices') - else: - g = 'd' - - urlFmt = ('http://ichart.yahoo.com/table.csv?a=%d&b=%d&' + - 'c=%d&d=%d&e=%d&f=%d&s=%s&y=0&g=%s&ignore=.csv') - - url = urlFmt % (d1[0], d1[1], d1[2], - d2[0], d2[1], d2[2], ticker, g) - - # Cache the finance data if cachename is supplied, or there is a writable - # cache directory. - if cachename is None and cachedir is not None: - cachename = os.path.join(cachedir, md5(url).hexdigest()) - if cachename is not None: - if os.path.exists(cachename): - fh = open(cachename) - verbose.report('Using cachefile %s for ' - '%s' % (cachename, ticker)) - else: - mkdirs(os.path.abspath(os.path.dirname(cachename))) - with contextlib.closing(urlopen(url)) as urlfh: - with open(cachename, 'wb') as fh: - fh.write(urlfh.read()) - verbose.report('Saved %s data to cache file ' - '%s' % (ticker, cachename)) - fh = open(cachename, 'r') - - return fh - else: - return urlopen(url) - - -def quotes_historical_yahoo_ochl(ticker, date1, date2, asobject=False, - adjusted=True, cachename=None): - """ Get historical data for ticker between date1 and date2. - - - See :func:`parse_yahoo_historical` for explanation of output formats - and the *asobject* and *adjusted* kwargs. - - Parameters - ---------- - ticker : str - stock ticker - - date1 : sequence of form (year, month, day), `datetime`, or `date` - start date - - date2 : sequence of form (year, month, day), `datetime`, or `date` - end date - - cachename : str or `None` - is the name of the local file cache. If None, will - default to the md5 hash or the url (which incorporates the ticker - and date range) - - Examples - -------- - >>> sp = f.quotes_historical_yahoo_ochl('^GSPC', d1, d2, - asobject=True, adjusted=True) - >>> returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] - >>> [n,bins,patches] = hist(returns, 100) - >>> mu = mean(returns) - >>> sigma = std(returns) - >>> x = normpdf(bins, mu, sigma) - >>> plot(bins, x, color='red', lw=2) - - """ - - return _quotes_historical_yahoo(ticker, date1, date2, asobject=asobject, - adjusted=adjusted, cachename=cachename, - ochl=True) - - -def quotes_historical_yahoo_ohlc(ticker, date1, date2, asobject=False, - adjusted=True, cachename=None): - """ Get historical data for ticker between date1 and date2. - - - See :func:`parse_yahoo_historical` for explanation of output formats - and the *asobject* and *adjusted* kwargs. - - Parameters - ---------- - ticker : str - stock ticker - - date1 : sequence of form (year, month, day), `datetime`, or `date` - start date - - date2 : sequence of form (year, month, day), `datetime`, or `date` - end date - - cachename : str or `None` - is the name of the local file cache. If None, will - default to the md5 hash or the url (which incorporates the ticker - and date range) - - Examples - -------- - >>> sp = f.quotes_historical_yahoo_ohlc('^GSPC', d1, d2, - asobject=True, adjusted=True) - >>> returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] - >>> [n,bins,patches] = hist(returns, 100) - >>> mu = mean(returns) - >>> sigma = std(returns) - >>> x = normpdf(bins, mu, sigma) - >>> plot(bins, x, color='red', lw=2) - - """ - - return _quotes_historical_yahoo(ticker, date1, date2, asobject=asobject, - adjusted=adjusted, cachename=cachename, - ochl=False) - - -def _quotes_historical_yahoo(ticker, date1, date2, asobject=False, - adjusted=True, cachename=None, - ochl=True): - """ Get historical data for ticker between date1 and date2. - - See :func:`parse_yahoo_historical` for explanation of output formats - and the *asobject* and *adjusted* kwargs. - - Parameters - ---------- - ticker : str - stock ticker - - date1 : sequence of form (year, month, day), `datetime`, or `date` - start date - - date2 : sequence of form (year, month, day), `datetime`, or `date` - end date - - cachename : str or `None` - is the name of the local file cache. If None, will - default to the md5 hash or the url (which incorporates the ticker - and date range) - - ochl: bool - temporary argument to select between ochl and ohlc ordering - - - Examples - -------- - >>> sp = f.quotes_historical_yahoo('^GSPC', d1, d2, - asobject=True, adjusted=True) - >>> returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] - >>> [n,bins,patches] = hist(returns, 100) - >>> mu = mean(returns) - >>> sigma = std(returns) - >>> x = normpdf(bins, mu, sigma) - >>> plot(bins, x, color='red', lw=2) - - """ - # Maybe enable a warning later as part of a slow transition - # to using None instead of False. - #if asobject is False: - # warnings.warn("Recommend changing to asobject=None") - - fh = fetch_historical_yahoo(ticker, date1, date2, cachename) - - try: - ret = _parse_yahoo_historical(fh, asobject=asobject, - adjusted=adjusted, ochl=ochl) - if len(ret) == 0: - return None - except IOError as exc: - warnings.warn('fh failure\n%s' % (exc.strerror[1])) - return None - - return ret - - -def plot_day_summary_oclh(ax, quotes, ticksize=3, - colorup='k', colordown='r', - ): - """Plots day summary - - Represent the time, open, close, high, low as a vertical line - ranging from low to high. The left tick is the open and the right - tick is the close. - - - - Parameters - ---------- - ax : `Axes` - an `Axes` instance to plot to - quotes : sequence of (time, open, close, high, low, ...) sequences - data to plot. time must be in float date format - see date2num - ticksize : int - open/close tick marker in points - colorup : color - the color of the lines where close >= open - colordown : color - the color of the lines where close < open - - Returns - ------- - lines : list - list of tuples of the lines added (one tuple per quote) - """ - return _plot_day_summary(ax, quotes, ticksize=ticksize, - colorup=colorup, colordown=colordown, - ochl=True) - - -def plot_day_summary_ohlc(ax, quotes, ticksize=3, - colorup='k', colordown='r', - ): - """Plots day summary - - 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. - - - - Parameters - ---------- - ax : `Axes` - an `Axes` instance to plot to - quotes : sequence of (time, open, high, low, close, ...) sequences - data to plot. time must be in float date format - see date2num - ticksize : int - open/close tick marker in points - colorup : color - the color of the lines where close >= open - colordown : color - the color of the lines where close < open - - Returns - ------- - lines : list - list of tuples of the lines added (one tuple per quote) - """ - return _plot_day_summary(ax, quotes, ticksize=ticksize, - colorup=colorup, colordown=colordown, - ochl=False) - - -def _plot_day_summary(ax, quotes, ticksize=3, - colorup='k', colordown='r', - ochl=True - ): - """Plots day summary - - - 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. - - - - Parameters - ---------- - ax : `Axes` - an `Axes` instance to plot to - quotes : sequence of quote sequences - data to plot. time must be in float date format - see date2num - (time, open, high, low, close, ...) vs - (time, open, close, high, low, ...) - set by `ochl` - ticksize : int - open/close tick marker in points - colorup : color - the color of the lines where close >= open - colordown : color - the color of the lines where close < open - ochl: bool - argument to select between ochl and ohlc ordering of quotes - - Returns - ------- - lines : list - list of tuples of the lines added (one tuple per quote) - """ - # unfortunately this has a different return type than plot_day_summary2_* - lines = [] - for q in quotes: - if ochl: - t, open, close, high, low = q[:5] - else: - t, open, high, low, close = q[:5] - - if close >= open: - color = colorup - else: - color = colordown - - vline = Line2D(xdata=(t, t), ydata=(low, high), - color=color, - antialiased=False, # no need to antialias vert lines - ) - - oline = Line2D(xdata=(t, t), ydata=(open, open), - color=color, - antialiased=False, - marker=TICKLEFT, - markersize=ticksize, - ) - - cline = Line2D(xdata=(t, t), ydata=(close, close), - color=color, - antialiased=False, - markersize=ticksize, - marker=TICKRIGHT) - - lines.extend((vline, oline, cline)) - ax.add_line(vline) - ax.add_line(oline) - ax.add_line(cline) - - ax.autoscale_view() - - return lines - - -def candlestick_ochl(ax, quotes, width=0.2, colorup='k', colordown='r', - alpha=1.0): - - """ - Plot the time, open, close, high, low as a vertical line ranging - from low to high. Use a rectangular bar to represent the - open-close span. If close >= open, use colorup to color the bar, - otherwise use colordown - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - quotes : sequence of (time, open, close, high, low, ...) sequences - As long as the first 5 elements are these values, - the record can be as long as you want (e.g., it may store volume). - - time must be in float days format - see date2num - - width : float - fraction of a day for the rectangle width - colorup : color - the color of the rectangle where close >= open - colordown : color - the color of the rectangle where close < open - alpha : float - the rectangle alpha level - - Returns - ------- - ret : tuple - returns (lines, patches) where lines is a list of lines - added and patches is a list of the rectangle patches added - - """ - return _candlestick(ax, quotes, width=width, colorup=colorup, - colordown=colordown, - alpha=alpha, ochl=True) - - -def candlestick_ohlc(ax, quotes, width=0.2, colorup='k', colordown='r', - alpha=1.0): - - """ - Plot the time, open, high, low, close as a vertical line ranging - from low to high. Use a rectangular bar to represent the - open-close span. If close >= open, use colorup to color the bar, - otherwise use colordown - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - quotes : sequence of (time, open, high, low, close, ...) sequences - As long as the first 5 elements are these values, - the record can be as long as you want (e.g., it may store volume). - - time must be in float days format - see date2num - - width : float - fraction of a day for the rectangle width - colorup : color - the color of the rectangle where close >= open - colordown : color - the color of the rectangle where close < open - alpha : float - the rectangle alpha level - - Returns - ------- - ret : tuple - returns (lines, patches) where lines is a list of lines - added and patches is a list of the rectangle patches added - - """ - return _candlestick(ax, quotes, width=width, colorup=colorup, - colordown=colordown, - alpha=alpha, ochl=False) - - -def _candlestick(ax, quotes, width=0.2, colorup='k', colordown='r', - alpha=1.0, ochl=True): - - """ - Plot the time, open, high, low, close as a vertical line ranging - from low to high. Use a rectangular bar to represent the - open-close span. If close >= open, use colorup to color the bar, - otherwise use colordown - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - quotes : sequence of quote sequences - data to plot. time must be in float date format - see date2num - (time, open, high, low, close, ...) vs - (time, open, close, high, low, ...) - set by `ochl` - width : float - fraction of a day for the rectangle width - colorup : color - the color of the rectangle where close >= open - colordown : color - the color of the rectangle where close < open - alpha : float - the rectangle alpha level - ochl: bool - argument to select between ochl and ohlc ordering of quotes - - Returns - ------- - ret : tuple - returns (lines, patches) where lines is a list of lines - added and patches is a list of the rectangle patches added - - """ - - OFFSET = width / 2.0 - - lines = [] - patches = [] - for q in quotes: - if ochl: - t, open, close, high, low = q[:5] - else: - t, open, high, low, close = q[:5] - - if close >= open: - color = colorup - lower = open - height = close - open - else: - color = colordown - lower = close - height = open - close - - vline = Line2D( - xdata=(t, t), ydata=(low, high), - color=color, - linewidth=0.5, - antialiased=True, - ) - - rect = Rectangle( - xy=(t - OFFSET, lower), - width=width, - height=height, - facecolor=color, - edgecolor=color, - ) - rect.set_alpha(alpha) - - lines.append(vline) - patches.append(rect) - ax.add_line(vline) - ax.add_patch(rect) - ax.autoscale_view() - - return lines, patches - - -def _check_input(opens, closes, highs, lows, miss=-1): - """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 - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - opens : sequence - sequence of opening values - highs : sequence - sequence of high values - lows : sequence - sequence of low values - closes : sequence - sequence of closing values - miss : int - identifier of the missing data - - Raises - ------ - ValueError - if the input sequences don't have the same length - """ - - def _missing(sequence, miss=-1): - """Returns the index in *sequence* of the missing data, identified by - *miss* - - Parameters - ---------- - sequence : - sequence to evaluate - miss : - identifier of the missing data - - Returns - ------- - where_miss: numpy.ndarray - indices of the missing data - """ - return np.where(np.array(sequence) == miss)[0] - - same_length = len(opens) == len(highs) == len(lows) == len(closes) - _missopens = _missing(opens) - same_missing = ((_missopens == _missing(highs)).all() and - (_missopens == _missing(lows)).all() and - (_missopens == _missing(closes)).all()) - - if not (same_length and same_missing): - msg = ("*opens*, *highs*, *lows* and *closes* must have the same" - " length. NOTE: this code assumes if any value open, high," - " low, close is missing (*-1*) they all must be missing.") - raise ValueError(msg) - - -def plot_day_summary2_ochl(ax, opens, closes, highs, lows, ticksize=4, - colorup='k', colordown='r', - ): - - """Represent the time, open, close, high, low, as a vertical line - ranging from low to high. The left tick is the open and the right - tick is the close. - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - opens : sequence - sequence of opening values - closes : sequence - sequence of closing values - highs : sequence - sequence of high values - lows : sequence - sequence of low values - ticksize : int - size of open and close ticks in points - colorup : color - the color of the lines where close >= open - colordown : color - the color of the lines where close < open - - Returns - ------- - ret : list - a list of lines added to the axes - """ - - return plot_day_summary2_ohlc(ax, opens, highs, lows, closes, ticksize, - colorup, colordown) - - -def plot_day_summary2_ohlc(ax, opens, highs, lows, closes, ticksize=4, - colorup='k', colordown='r', - ): - - """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. - *opens*, *highs*, *lows* and *closes* must have the same length. - NOTE: this code assumes if any value open, high, low, close is - missing (*-1*) they all are missing - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - opens : sequence - sequence of opening values - highs : sequence - sequence of high values - lows : sequence - sequence of low values - closes : sequence - sequence of closing values - ticksize : int - size of open and close ticks in points - colorup : color - the color of the lines where close >= open - colordown : color - the color of the lines where close < open - - Returns - ------- - ret : list - a list of lines added to the axes - """ - - _check_input(opens, highs, lows, closes) - - rangeSegments = [((i, low), (i, high)) for i, low, high in - zip(xrange(len(lows)), lows, highs) if low != -1] - - # the ticks will be from ticksize to 0 in points at the origin and - # we'll translate these to the i, close location - openSegments = [((-ticksize, 0), (0, 0))] - - # the ticks will be from 0 to ticksize in points at the origin and - # we'll translate these to the i, close location - closeSegments = [((0, 0), (ticksize, 0))] - - offsetsOpen = [(i, open) for i, open in - zip(xrange(len(opens)), opens) if open != -1] - - offsetsClose = [(i, close) for i, close in - zip(xrange(len(closes)), closes) if close != -1] - - scale = ax.figure.dpi * (1.0 / 72.0) - - tickTransform = Affine2D().scale(scale, 0.0) - - colorup = mcolors.to_rgba(colorup) - colordown = mcolors.to_rgba(colordown) - colord = {True: colorup, False: colordown} - colors = [colord[open < close] for open, close in - zip(opens, closes) if open != -1 and close != -1] - - useAA = 0, # use tuple here - lw = 1, # and here - rangeCollection = LineCollection(rangeSegments, - colors=colors, - linewidths=lw, - antialiaseds=useAA, - ) - - openCollection = LineCollection(openSegments, - colors=colors, - antialiaseds=useAA, - linewidths=lw, - offsets=offsetsOpen, - transOffset=ax.transData, - ) - openCollection.set_transform(tickTransform) - - closeCollection = LineCollection(closeSegments, - colors=colors, - antialiaseds=useAA, - linewidths=lw, - offsets=offsetsClose, - transOffset=ax.transData, - ) - closeCollection.set_transform(tickTransform) - - minpy, maxx = (0, len(rangeSegments)) - miny = min([low for low in lows if low != -1]) - maxy = max([high for high in highs if high != -1]) - corners = (minpy, miny), (maxx, maxy) - ax.update_datalim(corners) - ax.autoscale_view() - - # add these last - ax.add_collection(rangeCollection) - ax.add_collection(openCollection) - ax.add_collection(closeCollection) - return rangeCollection, openCollection, closeCollection - - -def candlestick2_ochl(ax, opens, closes, highs, lows, width=4, - colorup='k', colordown='r', - alpha=0.75, - ): - """Represent the open, close as a bar line and high low range as a - vertical line. - - Preserves the original argument order. - - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - opens : sequence - sequence of opening values - closes : sequence - sequence of closing values - highs : sequence - sequence of high values - lows : sequence - sequence of low values - ticksize : int - size of open and close ticks in points - colorup : color - the color of the lines where close >= open - colordown : color - the color of the lines where close < open - alpha : float - bar transparency - - Returns - ------- - ret : tuple - (lineCollection, barCollection) - """ - - candlestick2_ohlc(ax, opens, highs, lows, closes, width=width, - colorup=colorup, colordown=colordown, - alpha=alpha) - - -def candlestick2_ohlc(ax, opens, highs, lows, closes, width=4, - colorup='k', colordown='r', - alpha=0.75, - ): - """Represent the open, close as a bar line and high low range as a - vertical line. - - NOTE: this code assumes if any value open, low, high, close is - missing they all are missing - - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - opens : sequence - sequence of opening values - highs : sequence - sequence of high values - lows : sequence - sequence of low values - closes : sequence - sequence of closing values - ticksize : int - size of open and close ticks in points - colorup : color - the color of the lines where close >= open - colordown : color - the color of the lines where close < open - alpha : float - bar transparency - - Returns - ------- - ret : tuple - (lineCollection, barCollection) - """ - - _check_input(opens, highs, lows, closes) - - delta = width / 2. - barVerts = [((i - delta, open), - (i - delta, close), - (i + delta, close), - (i + delta, open)) - for i, open, close in zip(xrange(len(opens)), opens, closes) - if open != -1 and close != -1] - - rangeSegments = [((i, low), (i, high)) - for i, low, high in zip(xrange(len(lows)), lows, highs) - if low != -1] - - colorup = mcolors.to_rgba(colorup, alpha) - colordown = mcolors.to_rgba(colordown, alpha) - colord = {True: colorup, False: colordown} - colors = [colord[open < close] - for open, close in zip(opens, closes) - if open != -1 and close != -1] - - useAA = 0, # use tuple here - lw = 0.5, # and here - rangeCollection = LineCollection(rangeSegments, - colors=((0, 0, 0, 1), ), - linewidths=lw, - antialiaseds=useAA, - ) - - barCollection = PolyCollection(barVerts, - facecolors=colors, - edgecolors=((0, 0, 0, 1), ), - antialiaseds=useAA, - linewidths=lw, - ) - - minx, maxx = 0, len(rangeSegments) - miny = min([low for low in lows if low != -1]) - maxy = max([high for high in highs if high != -1]) - - corners = (minx, miny), (maxx, maxy) - ax.update_datalim(corners) - ax.autoscale_view() - - # add these last - ax.add_collection(rangeCollection) - ax.add_collection(barCollection) - return rangeCollection, barCollection - - -def volume_overlay(ax, opens, closes, volumes, - colorup='k', colordown='r', - width=4, alpha=1.0): - """Add a volume overlay to the current axes. The opens and closes - are used to determine the color of the bar. -1 is missing. If a - value is missing on one it must be missing on all - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - opens : sequence - a sequence of opens - closes : sequence - a sequence of closes - volumes : sequence - a sequence of volumes - width : int - the bar width in points - colorup : color - the color of the lines where close >= open - colordown : color - the color of the lines where close < open - alpha : float - bar transparency - - Returns - ------- - ret : `barCollection` - The `barrCollection` added to the axes - - """ - - colorup = mcolors.to_rgba(colorup, alpha) - colordown = mcolors.to_rgba(colordown, alpha) - colord = {True: colorup, False: colordown} - colors = [colord[open < close] - for open, close in zip(opens, closes) - if open != -1 and close != -1] - - delta = width / 2. - bars = [((i - delta, 0), (i - delta, v), (i + delta, v), (i + delta, 0)) - for i, v in enumerate(volumes) - if v != -1] - - barCollection = PolyCollection(bars, - facecolors=colors, - edgecolors=((0, 0, 0, 1), ), - antialiaseds=(0,), - linewidths=(0.5,), - ) - - ax.add_collection(barCollection) - corners = (0, 0), (len(bars), max(volumes)) - ax.update_datalim(corners) - ax.autoscale_view() - - # add these last - return barCollection - - -def volume_overlay2(ax, closes, volumes, - colorup='k', colordown='r', - width=4, alpha=1.0): - """ - Add a volume overlay to the current axes. The closes are used to - determine the color of the bar. -1 is missing. If a value is - missing on one it must be missing on all - - nb: first point is not displayed - it is used only for choosing the - right color - - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - closes : sequence - a sequence of closes - volumes : sequence - a sequence of volumes - width : int - the bar width in points - colorup : color - the color of the lines where close >= open - colordown : color - the color of the lines where close < open - alpha : float - bar transparency - - Returns - ------- - ret : `barCollection` - The `barrCollection` added to the axes - - """ - - return volume_overlay(ax, closes[:-1], closes[1:], volumes[1:], - colorup, colordown, width, alpha) - - -def volume_overlay3(ax, quotes, - colorup='k', colordown='r', - width=4, alpha=1.0): - """Add a volume overlay to the current axes. quotes is a list of (d, - open, high, low, close, volume) and close-open is used to - determine the color of the bar - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - quotes : sequence of (time, open, high, low, close, ...) sequences - data to plot. time must be in float date format - see date2num - width : int - the bar width in points - colorup : color - the color of the lines where close1 >= close0 - colordown : color - the color of the lines where close1 < close0 - alpha : float - bar transparency - - Returns - ------- - ret : `barCollection` - The `barrCollection` added to the axes - - - """ - - colorup = mcolors.to_rgba(colorup, alpha) - colordown = mcolors.to_rgba(colordown, alpha) - colord = {True: colorup, False: colordown} - - dates, opens, highs, lows, closes, volumes = list(zip(*quotes)) - colors = [colord[close1 >= close0] - for close0, close1 in zip(closes[:-1], closes[1:]) - if close0 != -1 and close1 != -1] - colors.insert(0, colord[closes[0] >= opens[0]]) - - right = width / 2.0 - left = -width / 2.0 - - bars = [((left, 0), (left, volume), (right, volume), (right, 0)) - for d, open, high, low, close, volume in quotes] - - sx = ax.figure.dpi * (1.0 / 72.0) # scale for points - sy = ax.bbox.height / ax.viewLim.height - - barTransform = Affine2D().scale(sx, sy) - - dates = [d for d, open, high, low, close, volume in quotes] - offsetsBars = [(d, 0) for d in dates] - - useAA = 0, # use tuple here - lw = 0.5, # and here - barCollection = PolyCollection(bars, - facecolors=colors, - edgecolors=((0, 0, 0, 1),), - antialiaseds=useAA, - linewidths=lw, - offsets=offsetsBars, - transOffset=ax.transData, - ) - barCollection.set_transform(barTransform) - - minpy, maxx = (min(dates), max(dates)) - miny = 0 - maxy = max([volume for d, open, high, low, close, volume in quotes]) - corners = (minpy, miny), (maxx, maxy) - ax.update_datalim(corners) - #print 'datalim', ax.dataLim.bounds - #print 'viewlim', ax.viewLim.bounds - - ax.add_collection(barCollection) - ax.autoscale_view() - - return barCollection - - -def index_bar(ax, vals, - facecolor='b', edgecolor='l', - width=4, alpha=1.0, ): - """Add a bar collection graph with height vals (-1 is missing). - - Parameters - ---------- - ax : `Axes` - an Axes instance to plot to - vals : sequence - a sequence of values - facecolor : color - the color of the bar face - edgecolor : color - the color of the bar edges - width : int - the bar width in points - alpha : float - bar transparency - - Returns - ------- - ret : `barCollection` - The `barrCollection` added to the axes - - """ - - facecolors = (mcolors.to_rgba(facecolor, alpha),) - edgecolors = (mcolors.to_rgba(edgecolor, alpha),) - - right = width / 2.0 - left = -width / 2.0 - - bars = [((left, 0), (left, v), (right, v), (right, 0)) - for v in vals if v != -1] - - sx = ax.figure.dpi * (1.0 / 72.0) # scale for points - sy = ax.bbox.height / ax.viewLim.height - - barTransform = Affine2D().scale(sx, sy) - - offsetsBars = [(i, 0) for i, v in enumerate(vals) if v != -1] - - barCollection = PolyCollection(bars, - facecolors=facecolors, - edgecolors=edgecolors, - antialiaseds=(0,), - linewidths=(0.5,), - offsets=offsetsBars, - transOffset=ax.transData, - ) - barCollection.set_transform(barTransform) - - minpy, maxx = (0, len(offsetsBars)) - miny = 0 - maxy = max([v for v in vals if v != -1]) - corners = (minpy, miny), (maxx, maxy) - ax.update_datalim(corners) - ax.autoscale_view() - - # add these last - ax.add_collection(barCollection) - return barCollection + msg = ("Matplotlib.finance has been split into a separate " + "module. Please update your imports to " + "replace 'matplotlib.finance' with 'mpl_finance'. " + "This shim will be removed in a future release.") + warnings.warn(msg, mplDeprecation, stacklevel=1)