def plot_macd(symbol, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): """Calculates the macd for the given symbol, saves this data in a .csv file, and plots this data The MACD is a lagging trend indicator. Parameters: symbol : str period : int or list of int, optional Must contain 3 values. First value is signal line, second is fast line, third is slow line.\ refresh : bool, optional start_date : date, optional end_date : date, optional Returns: figure, axes A figure and axes containing the macd for the given symbol """ if not utils.refresh(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=refresh): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if len(period) != 3: raise ValueError("MACD requires 3 periods") if len(df) < period[-1]: raise ta.InsufficientDataException("Not enough data to compute a period length of " + str(period)) fig, ax = plt.subplots(2, figsize=config.figsize) ax[0].plot(df.index, df["Close"], label="Price") utils.prettify_ax(ax[0], title=symbol + "Price", start_date=start_date, end_date=end_date) macd_column_name = "MACD" + str(period[1]) + "-" + str(period[2]) signal_column_name = "MACD" + str(period[0]) if macd_column_name not in df.columns or signal_column_name not in df.columns: df = df.join(macd(symbol, period, refresh=False, start_date=start_date, end_date=end_date)) # if len(df) > period[0] and len(df) > period[1] and len(df) > period[2]: # to prevent AttributeError when the column is all None ax[1].plot(df.index, df[macd_column_name], label="MACD") ax[1].plot(df.index, df[signal_column_name], label="Signal") ax[1].plot(df.index, (df[macd_column_name] - df[signal_column_name]), label="Histogram") # Can't overlay a histogram with line plots so the histogram has to also be a line plot # ax[1].bar(df.index, np.histogram(np.isfinite(df[signal_column_name] - df[macd_column_name])), normed=True, alpha=config.alpha) # ValueError: incompatible sizes: argument 'height' must be length 3876 or scalar utils.prettify_ax(ax[1], title=symbol + "MACD", center=True, start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig(utils.get_file_path(config.ta_graphs_path, get_signal_name(period) + graph_filename, symbol=symbol)) utils.debug(fig) return fig, ax
def plot_ema(symbol, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): """Calculates the exponential moving agerage for each period for the given symbol, saves this data in a .csv file, and plots this data The EMA is a lagging trend indicator. Parameters: symbol : str period : int or list of int, optional refresh : bool, optional start_date : date, optional end_date : date, optional Returns: figure, axes A figure and axes containing the exponential moving agerage for the given symbol """ if not utils.refresh(utils.get_file_path( config.ta_data_path, table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=refresh): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if isinstance(period, int): period = [period] period.sort() if len(df) < period[-1]: raise ta.InsufficientDataException( "Not enough data to compute a period length of " + str(period[-1])) fig, ax = plt.subplots(figsize=config.figsize) ax.plot(df.index, df["Close"], label="Price") for p in period: column_name = "EMA" + str(p) if column_name not in df.columns: df = df.join( ema(symbol, p, refresh=False, start_date=start_date, end_date=end_date)) # if len(df) > p: # to prevent AttributeError when the column is all None ax.plot(df.index, df[column_name], label=column_name) utils.prettify_ax(ax, title=symbol + "EMA" + "-".join(str(p) for p in period), start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig( utils.get_file_path(config.ta_graphs_path, "-".join(str(p) for p in period) + graph_filename, symbol=symbol)) utils.debug(fig) return fig, ax
def plot_bb(symbol, period=default_period, std=default_std, refresh=False, start_date=config.start_date, end_date=config.end_date): """Calculates the bollinger bands for each period for the given symbol, saves this data in a .csv file, and plots this data The BB is a lagging volatility indicator. Parameters: symbol : str period : int, optional std : int, optional refresh : bool, optional start_date : date, optional end_date : date, optional Returns: figure, axes A figure and axes containing the bollinger bands for the given symbol """ if not utils.refresh(utils.get_file_path( config.ta_data_path, table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=refresh): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if len(df) < period: raise ta.InsufficientDataException( "Not enough data to compute a period length of " + str(period)) fig, ax = plt.subplots(figsize=config.figsize) ax.plot(df.index, df["Close"], label="Price") if "Lower" not in df.columns or "Upper" not in df.columns: df = df.join( bb(symbol, period, std, refresh=False, start_date=start_date, end_date=end_date)) # if len(df) > p: # to prevent AttributeError when the column is all None ax.plot(df.index, df["Lower"], label="Lower", color="skyblue") ax.plot(df.index, df["Upper"], label="Upper", color="skyblue") ax.fill_between(df.index, df["Lower"], df["Upper"], color='lightskyblue') utils.prettify_ax(ax, title=symbol + "BB", start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig( utils.get_file_path(config.ta_graphs_path, get_signal_name(period, std) + graph_filename, symbol=symbol)) utils.debug(fig) return fig, ax
def plot_rsi(symbol, period=default_period, thresholds=default_thresholds, refresh=False, start_date=config.start_date, end_date=config.end_date): """Calculates the relative strength index for each period for the given symbol, saves this data in a .csv file, and plots this data The RSI is a leading momentum indicator. Parameters: symbol : str period : int, optional thresholds: dict Must contain keys "Low" and "High", both with a value between 0 and 100 refresh : bool, optional start_date : date, optional end_date : date, optional Returns: figure, axes A figure and axes containing the relative strength index for the given symbol """ if not utils.refresh(utils.get_file_path( config.ta_data_path, table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: if utils.refresh(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), refresh=refresh): prices.download_data_from_yahoo(symbol, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if len(df) < period: raise ta.InsufficientDataException( "Not enough data to compute a period length of " + str(period)) fig, ax = plt.subplots(2, figsize=config.figsize) ax[0].plot(df.index, df["Close"], label="Price") utils.prettify_ax(ax[0], title=symbol + "Price", start_date=start_date, end_date=end_date) if "RSI" + str(period) not in df.columns: df = df.join( rsi(symbol, period, refresh=False, start_date=start_date, end_date=end_date)) # if len(df) > period: # to prevent AttributeError when the column is all None ax[1].plot(df.index, df["RSI" + str(period)], label="RSI" + str(period)) ax[1].plot(df.index, [thresholds["Low"]] * len(df.index), label="Oversold", color="red") ax[1].plot(df.index, [50] * len(df.index), color="black") ax[1].plot(df.index, [thresholds["High"]] * len(df.index), label="Overbought", color="red") utils.prettify_ax(ax[1], title=symbol + "RSI" + str(period), start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig( utils.get_file_path(config.ta_graphs_path, get_signal_name(period) + graph_filename, symbol=symbol)) utils.debug(fig) return fig, ax