def plot_signals(symbol=default_symbols, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): short_vol_symbol = symbol[0] long_vol_symbol = symbol[1] generate_signals(symbol=symbol, period=period, refresh=refresh, start_date=start_date, end_date=end_date) fig, ax = plot_volforecast(period=period, refresh=refresh, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), index_col="Date", parse_dates=["Date"])[start_date:end_date] short_vol = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=short_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] long_vol = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=long_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] signal_column_name = get_signal_name() buy_signals = short_vol.loc[short_vol[signal_column_name] == ta.buy_signal] ax[0].scatter(buy_signals.index, df.loc[df.index.isin(buy_signals.index)][signal_column_name], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[1].scatter(buy_signals.index, short_vol.loc[short_vol.index.isin(buy_signals.index)]["Close"], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) buy_signals = long_vol.loc[long_vol[signal_column_name] == ta.buy_signal] ax[0].scatter(buy_signals.index, df.loc[df.index.isin(buy_signals.index)][signal_column_name], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[2].scatter(buy_signals.index, long_vol.loc[long_vol.index.isin(buy_signals.index)]["Close"], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) sell_signals = short_vol.loc[short_vol[signal_column_name] == ta.sell_signal] ax[0].scatter(sell_signals.index, df.loc[df.index.isin(sell_signals.index)][signal_column_name], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[1].scatter(sell_signals.index, short_vol.loc[short_vol.index.isin(sell_signals.index)]["Close"], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) sell_signals = long_vol.loc[long_vol[signal_column_name] == ta.sell_signal] ax[0].scatter(sell_signals.index, df.loc[df.index.isin(sell_signals.index)][signal_column_name], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[2].scatter(sell_signals.index, long_vol.loc[long_vol.index.isin(sell_signals.index)]["Close"], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) utils.prettify_ax(ax[0], title=signal_column_name, center=True, start_date=start_date, end_date=end_date) utils.prettify_ax(ax[1], title=short_vol_symbol + "Price", start_date=start_date, end_date=end_date) utils.prettify_ax(ax[2], title=long_vol_symbol + "Price", start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig(utils.get_file_path(config.ta_graphs_path, signal_column_name + graph_filename, symbol="")) utils.debug(fig) return fig, ax
def plot_signals(symbol, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): """Plots the macd buy/sell signals for the given symbol, saves this data in a .csv file, and plots this data. Only uses the first and last periods 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 signals for the given symbol """ if len(period) != 3: raise ValueError("MACD requires 3 periods") generate_signals(symbol, period=period, refresh=refresh, start_date=start_date, end_date=end_date) fig, ax = plot_macd(symbol, period=period, refresh=refresh, start_date=start_date, end_date=end_date) 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] macd_column_name = "MACD" + str(period[1]) + "-" + str(period[2]) signal_column_name = "MACD" + str(period[0]) signal_column_name = get_signal_name(period=period) buy_signals = df.loc[df[signal_column_name] == ta.buy_signal] ax[0].scatter(buy_signals.index, df.loc[df.index.isin(buy_signals.index)]["Close"], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[1].scatter(buy_signals.index, df.loc[df.index.isin(buy_signals.index)][macd_column_name], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) sell_signals = df.loc[df[signal_column_name] == ta.sell_signal] ax[0].scatter(sell_signals.index, df.loc[df.index.isin(sell_signals.index)]["Close"], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[1].scatter(sell_signals.index, df.loc[df.index.isin(sell_signals.index)][macd_column_name], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) soft_buy_signals = df.loc[df[signal_column_name] == ta.soft_buy_signal] ax[0].scatter(soft_buy_signals.index, df.loc[df.index.isin(soft_buy_signals.index)]["Close"], label=ta.soft_buy_signal, color=ta.signal_colors[ta.soft_buy_signal], marker=ta.signal_markers[ta.soft_buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[1].scatter(soft_buy_signals.index, df.loc[df.index.isin(soft_buy_signals.index)][macd_column_name], label=ta.soft_buy_signal, color=ta.signal_colors[ta.soft_buy_signal], marker=ta.signal_markers[ta.soft_buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) soft_sell_signals = df.loc[df[signal_column_name] == ta.soft_sell_signal] ax[0].scatter(soft_sell_signals.index, df.loc[df.index.isin(soft_sell_signals.index)]["Close"], label=ta.soft_sell_signal, color=ta.signal_colors[ta.soft_sell_signal], marker=ta.signal_markers[ta.soft_sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[1].scatter(soft_sell_signals.index, df.loc[df.index.isin(soft_sell_signals.index)][macd_column_name], label=ta.soft_sell_signal, color=ta.signal_colors[ta.soft_sell_signal], marker=ta.signal_markers[ta.soft_sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) utils.prettify_ax(ax[0], title=symbol + "Price", start_date=start_date, end_date=end_date) utils.prettify_ax(ax[1], title=symbol + signal_column_name, 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_percentage_gains(symbol, refresh=False, start_date=config.start_date, end_date=config.end_date): """Plots a graph of the percentage gains for the given symbol Parameters: symbol : str refresh : bool, optional start_date : date, optional end_date : date, optional Returns: figure, axes A subplot containing the percentage gains for the given symbol """ if isinstance(symbol, str): symbol = [symbol] symbol.sort() fig, ax = plt.subplots(figsize=config.figsize) for s in symbol: if utils.refresh(utils.get_file_path(config.prices_data_path, price_table_filename, symbol=s), refresh=refresh): download_data_from_yahoo(s, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.prices_data_path, price_table_filename, symbol=s), index_col="Date", parse_dates=["Date"])[start_date:end_date] ax.plot(df.index, df["Close"] / df["Close"][0], label=s + "Price") utils.prettify_ax(ax, title="".join(str(s) for s in symbol) + "Price", start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig( utils.get_file_path(config.prices_graphs_path, price_graph_filename, symbol=",".join(str(s) for s in symbol))) utils.debug(fig) return fig, ax
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_volforecast(symbol=default_symbols, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): short_vol_symbol = symbol[0] long_vol_symbol = symbol[1] if not utils.refresh(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: volforecast(period=period, refresh=refresh, start_date=start_date, end_date=end_date) df = pd.read_csv(utils.get_file_path(config.ta_data_path, table_filename, symbol=""), index_col="Date", parse_dates=["Date"])[start_date:end_date] if not utils.refresh(utils.get_file_path(config.prices_data_path, table_filename, symbol=short_vol_symbol), refresh=refresh): short_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, table_filename, symbol=short_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: prices.download_data_from_yahoo(short_vol_symbol, start_date=start_date, end_date=end_date) short_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=short_vol_symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] if not utils.refresh(utils.get_file_path(config.prices_data_path, table_filename, symbol=long_vol_symbol), refresh=refresh): long_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, table_filename, symbol=long_vol_symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] else: prices.download_data_from_yahoo(long_vol_symbol, start_date=start_date, end_date=end_date) long_vol = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=long_vol_symbol), usecols=["Date", "Close"], index_col="Date", parse_dates=["Date"])[start_date:end_date] fig, ax = plt.subplots(3, figsize=config.figsize) ax[0].plot(df.index, df[get_signal_name()], label=get_signal_name()) ax[1].plot(df.index, short_vol["Close"], label=short_vol_symbol) ax[2].plot(df.index, long_vol["Close"], label=long_vol_symbol) utils.prettify_ax(ax[0], title=get_signal_name(), center=True, start_date=start_date, end_date=end_date) utils.prettify_ax(ax[1], title=short_vol_symbol, start_date=start_date, end_date=end_date) utils.prettify_ax(ax[2], title=long_vol_symbol, start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig(utils.get_file_path(config.ta_graphs_path, graph_filename, symbol=get_signal_name())) utils.debug(fig) return fig, ax
def after_during_hours_returns(symbol, period=0, refresh=False, start_date=config.start_date, end_date=config.end_date): """Plots a graph of the after hours and daily hours return for the given symbol, saves this data in a .csv file, and returns this data Parameters: symbol : str period : int The number of trading days to look back. There are ~260 trading days in a year refresh : bool, optional start_date : date, optional end_date : date, optional Returns: dataframe A dataframe containing the after hours and daily hours return by date for the given symbol """ if not utils.refresh(utils.get_file_path(config.prices_data_path, daily_return_table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.prices_data_path, daily_return_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, price_table_filename, symbol=symbol), refresh=refresh): 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, price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[start_date:end_date] if period != 0: period = -abs(period) start_date = df.index[period] df = df[start_date:end_date] after_hours_cum_sum = pd.Series(df["Open"] - df["Close"].shift(1)).cumsum() df[total_after_hours_name] = after_hours_cum_sum + df["Close"][0] during_hours_cum_sum = pd.Series(df["Close"] - df["Open"]).cumsum() df[total_during_hours_name] = during_hours_cum_sum + df["Close"][0] fig, ax = plt.subplots(2, figsize=config.figsize) ax[0].plot(df.index, df["Close"], label="Close") ax[0].plot(df.index, df[total_after_hours_name], label=total_after_hours_name) ax[0].plot(df.index, df[total_during_hours_name], label=total_during_hours_name) if config.debug: all_hours_cum_sum = pd.Series(df["Close"] - df["Close"].shift(1)).cumsum() df[total_return_name] = all_hours_cum_sum + df["Close"][0] ax[0].plot(df.index, df[total_return_name], label=total_return_name) df = df[[ "Open", "Close", total_after_hours_name, total_during_hours_name, total_return_name if total_return_name in df.columns else None ]] df.to_csv( utils.get_file_path(config.prices_data_path, during_and_after_hours_table_filename, symbol=symbol)) utils.prettify_ax(ax[0], title=symbol + during_and_after_hours_name, start_date=start_date, end_date=end_date) df[total_after_hours_normalized_name] = pd.Series( df[total_after_hours_name] - df["Close"]) df[total_during_hours_normalized_name] = pd.Series( df[total_during_hours_name] - df["Close"]) ax[1].plot(df.index, df[total_after_hours_normalized_name], label=total_after_hours_normalized_name) ax[1].plot(df.index, df[total_during_hours_normalized_name], label=total_during_hours_normalized_name) utils.prettify_ax(ax[1], title=symbol + during_and_after_hours_normalized_name, center=True, start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig( utils.get_file_path(config.prices_graphs_path, during_and_after_hours_graph_filename, symbol=symbol, dated=True, start_date=start_date, end_date=end_date)) utils.debug(fig) return df[[total_after_hours_name, total_after_hours_name]]
def get_daily_return(symbol, period=["daily", "after_hours", "during_hours"], refresh=False, start_date=config.start_date, end_date=config.end_date): """Plots a graph of the daily return for the given symbol, adds the data to the existing corresponding .csv file, and returns this data Parameters: symbol : str period : str Valid values are "daily", "after_hours", "during_hours" refresh : bool, optional start_date : date, optional end_date : date, optional Returns: dataframe A dataframe containing the daily return by date for the given symbol """ if not utils.refresh(utils.get_file_path(config.prices_data_path, daily_return_table_filename, symbol=symbol), refresh=refresh): df = pd.read_csv(utils.get_file_path(config.prices_data_path, daily_return_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, price_table_filename, symbol=symbol), refresh=refresh): 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, price_table_filename, symbol=symbol), iusecols=["Date", "Open", "Close"], ndex_col="Date", parse_dates=["Date"])[start_date:end_date] if isinstance(period, str): period = [period] used_columns = [] fig, ax = plt.subplots(len(period) + 1, figsize=config.figsize) # + 1 to plot against vix for i, f in enumerate(period): if f == "daily": column_name = daily_return_name return_name = daily_return_name elif f == "after_hours": column_name = after_hours_daily_return_name return_name = after_hours_daily_return_name elif f == "during_hours": column_name = during_hours_daily_return_name return_name = during_hours_daily_return_name else: raise ValueError( "Valid inputs are 'daily', 'after_hours', and 'during_hours'") used_columns.append(column_name) if column_name not in df.columns: if f == "daily": df[column_name] = (df["Close"] / df["Close"].shift(1)) - 1 if f == "after_hours": df[column_name] = (df["Open"] / df["Close"].shift(1)) - 1 if f == "during_hours": df[column_name] = (df["Close"] / df["Open"]) - 1 utils.debug(df[column_name]) df.to_csv( utils.get_file_path(config.prices_data_path, daily_return_table_filename, symbol=symbol)) ax[i].plot(df.index, df[column_name], label=symbol + return_name) utils.prettify_ax(ax[i], title=symbol + return_name, center=True, start_date=start_date, end_date=end_date) if utils.refresh(utils.get_file_path(config.prices_data_path, price_table_filename, symbol=config.vix), refresh=refresh): download_data_from_yahoo(config.vix, start_date=start_date, end_date=end_date) vix_df = pd.read_csv(utils.get_file_path(config.prices_data_path, price_table_filename, symbol=config.vix), index_col="Date", parse_dates=["Date"])[start_date:end_date] ax[-1].plot(vix_df.index, vix_df["Close"], label=config.vix + "Price") utils.prettify_ax(ax[-1], title=config.vix + "Price", start_date=start_date, end_date=end_date) utils.prettify_fig(fig) fig.savefig( utils.get_file_path(config.prices_graphs_path, ("-".join(str(c) for c in used_columns)), symbol=symbol)) utils.debug(fig) return df[used_columns]
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_signals(symbol, period=default_periods, refresh=False, start_date=config.start_date, end_date=config.end_date): """Plots the exponential moving agerage buy/sell signals for each period for the given symbol, saves this data in a .csv file, and plots this data. Only uses the first and last periods The EMA is a lagging trend indicator. Parameters: symbol : str period : int or list of int, optional What periods to calculate for. Only uses the first two periods refresh : bool, optional start_date : date, optional end_date : date, optional Returns: figure, axes A figure and axes containing the exponential moving agerage signals for the given symbol """ if len(period) < 2: raise ValueError("Requires at least two periods") if len(period) > 2: period = period[:2] period.sort() generate_signals(symbol, period=period, refresh=refresh, start_date=start_date, end_date=end_date) fig, ax = plot_ema(symbol, period=period, refresh=refresh, start_date=start_date, end_date=end_date) 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] fast_column_name = "EMA" + str(period[0]) slow_column_name = "EMA" + str( period[1]) # can use either column since I'm plotting crossovers signal_column_name = get_signal_name(period=period) buy_signals = df.loc[df[signal_column_name] == ta.buy_signal] ax.scatter(buy_signals.index, df.loc[df.index.isin(buy_signals.index)][fast_column_name], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax.plot((buy_signals.index, buy_signals.index), (df.loc[df.index.isin( buy_signals.index)][fast_column_name], buy_signals["Close"]), color=ta.signal_colors[ta.buy_signal]) sell_signals = df.loc[df[signal_column_name] == ta.sell_signal] ax.scatter(sell_signals.index, df.loc[df.index.isin(sell_signals.index)][fast_column_name], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax.plot((sell_signals.index, sell_signals.index), (df.loc[df.index.isin( sell_signals.index)][fast_column_name], sell_signals["Close"]), color=ta.signal_colors[ta.sell_signal]) soft_buy_signals = df.loc[df[signal_column_name] == ta.soft_buy_signal] ax.scatter(soft_buy_signals.index, df.loc[df.index.isin(soft_buy_signals.index)][fast_column_name], label=ta.soft_buy_signal, color=ta.signal_colors[ta.soft_buy_signal], marker=ta.signal_markers[ta.soft_buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax.plot((soft_buy_signals.index, soft_buy_signals.index), (df.loc[df.index.isin(soft_buy_signals.index)][fast_column_name], soft_buy_signals["Close"]), color=ta.signal_colors[ta.soft_buy_signal]) soft_sell_signals = df.loc[df[signal_column_name] == ta.soft_sell_signal] ax.scatter(soft_sell_signals.index, df.loc[df.index.isin( soft_sell_signals.index)][fast_column_name], label=ta.soft_sell_signal, color=ta.signal_colors[ta.soft_sell_signal], marker=ta.signal_markers[ta.soft_sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax.plot((soft_sell_signals.index, soft_sell_signals.index), (df.loc[df.index.isin(soft_sell_signals.index)][fast_column_name], soft_sell_signals["Close"]), color=ta.signal_colors[ta.soft_sell_signal]) utils.prettify_ax(ax, title=symbol + signal_column_name, 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_against_benchmark(self, log, benchmark=None): """Plots data comparing the simulation to the benchmarks and available symbols Parameters: log : dataframe benchmark : list of str """ if benchmark is None: benchmark = self.benchmark fig, ax = plt.subplots(2, 2, figsize=config.figsize) # Portfolio performance ax[0][0].plot(log.index, log[portfolio_value_column_name], label=portfolio_value_column_name) if len(self.symbols) > 1: ax[0][0].plot(log.index, log[cash_column_name], label=cash_column_name) ax[0][0].plot(log.index, log[total_commission_column_name], label=total_commission_column_name) ax[0][0].plot(log.index, log[total_dividend_column_name], label=total_dividend_column_name) utils.prettify_ax(ax[0][0], title=portfolio_value_column_name, start_date=self.start_date, end_date=self.end_date) # Benchmark performance for bench in benchmark: df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=bench), index_col="Date", parse_dates=["Date"])[self.start_date:self.end_date] ax[1][0].plot(df.index, df["Close"].add(df["Dividends"].cumsum()), label=bench + "Price") utils.prettify_ax(ax[1][0], title="Benchmarks", start_date=self.start_date, end_date=self.end_date) # Fix this for when not all symbols start at the same date. Fill_value=1 flattens before dates where the return can be calculated, and is inaccurate for dates after the return has already been calculated # Average return of available symbols if len(self.symbols) > 1: avg_return = pd.Series(0, index=self.dates) # count = pd.Series(0, index=self.dates) for symbol in self.symbols: df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[self.start_date:self.end_date] avg_return = avg_return.add((df["Close"].add(df["Dividends"].cumsum()) / df["Close"][0]), fill_value=1) # count = count.add(self.dates.isin(df.index).astype(int)) avg_return = avg_return / len(self.symbols) # Portfolio compared to benchmarks ax[0][1].plot(log.index, (log[portfolio_value_column_name] / log[portfolio_value_column_name][0]), label="Portfolio") for bench in benchmark: df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=bench), index_col="Date", parse_dates=["Date"])[self.start_date:self.end_date] ax[0][1].plot(df.index, (df["Close"].add(df["Dividends"].cumsum()) / df["Close"][0]), label=bench) # if len(benchmark) > 1: # ax[0][1].plot(df.index, (log[portfolio_value_column_name] / log[portfolio_value_column_name][0]) / (df["Close"] / df["Close"][0]), label="PortfolioVS" + bench) # add AverageReturnOfSymbols to the PortfolioVSBenchmarks graph if len(self.symbols) > 1: ax[0][1].plot(avg_return.index, avg_return, label="AverageReturnOfSymbols") utils.prettify_ax(ax[0][1], title="PortfolioVSBenchmarks", start_date=self.start_date, end_date=self.end_date) # Simulation compared to available symbols if len(self.symbols) < 6: ax[1][1].plot(log.index, (log[portfolio_value_column_name] / log[portfolio_value_column_name][0]), label="Portfolio") for symbol in self.symbols: df = pd.read_csv(utils.get_file_path(config.prices_data_path, prices.price_table_filename, symbol=symbol), index_col="Date", parse_dates=["Date"])[self.start_date:self.end_date] # ax[1][1].plot(df.index, (log[log.index in df.index][total_value_column_name] / log[log.index in df.index][cash_column_name][0]) / (df["Close"] / df["Close"][0]), label="PortfolioVS" + symbol) ax[1][1].plot(df.index, (df["Close"].add(df["Dividends"].cumsum()) / df["Close"][0]), label=symbol) # add AverageReturnOfSymbols to the PortfolioVSSymbols graph if len(self.symbols) > 1: ax[1][1].plot(avg_return.index, avg_return, label="AverageReturnOfSymbols") utils.prettify_ax(ax[1][1], title="PortfolioVSSymbols", start_date=self.start_date, end_date=self.end_date) utils.prettify_fig(fig, title=self.filename) fig.savefig(utils.get_file_path(config.simulation_graphs_path, self.filename + simulation_graph_filename)) utils.debug(fig)
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_signals(symbol, period=default_period, std=default_std, refresh=False, start_date=config.start_date, end_date=config.end_date): """Plots the bollinger bands buy/sell signals for each period for the given symbol, saves this data in a .csv file, and plots this data. Only uses the first and last periods 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 signals for the given symbol """ generate_signals(symbol, period=period, std=std, refresh=refresh, start_date=start_date, end_date=end_date) fig, ax = plot_bb(symbol, period=period, std=std, refresh=refresh, start_date=start_date, end_date=end_date) 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] lower_column_name = "Lower" upper_column_name = "Upper" signal_column_name = get_signal_name(period=period, std=std) buy_signals = df.loc[df[signal_column_name] == ta.buy_signal] ax.scatter(buy_signals.index, df.loc[df.index.isin(buy_signals.index)][lower_column_name], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax.plot((buy_signals.index, buy_signals.index), (df.loc[df.index.isin( buy_signals.index)][lower_column_name], buy_signals["Close"]), color=ta.signal_colors[ta.buy_signal]) sell_signals = df.loc[df[signal_column_name] == ta.sell_signal] ax.scatter(sell_signals.index, df.loc[df.index.isin(sell_signals.index)][upper_column_name], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax.plot((sell_signals.index, sell_signals.index), (df.loc[df.index.isin( sell_signals.index)][upper_column_name], sell_signals["Close"]), color=ta.signal_colors[ta.sell_signal]) soft_buy_signals = df.loc[df[signal_column_name] == ta.soft_buy_signal] ax.scatter(soft_buy_signals.index, df.loc[df.index.isin( soft_buy_signals.index)][lower_column_name], label=ta.soft_buy_signal, color=ta.signal_colors[ta.soft_buy_signal], marker=ta.signal_markers[ta.soft_buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax.plot((soft_buy_signals.index, soft_buy_signals.index), (df.loc[df.index.isin(soft_buy_signals.index)][lower_column_name], soft_buy_signals["Close"]), color=ta.signal_colors[ta.soft_buy_signal]) soft_sell_signals = df.loc[df[signal_column_name] == ta.soft_sell_signal] ax.scatter(soft_sell_signals.index, df.loc[df.index.isin( soft_sell_signals.index)][upper_column_name], label=ta.soft_sell_signal, color=ta.signal_colors[ta.soft_sell_signal], marker=ta.signal_markers[ta.soft_sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax.plot((soft_sell_signals.index, soft_sell_signals.index), (df.loc[df.index.isin(soft_sell_signals.index)][upper_column_name], soft_sell_signals["Close"]), color=ta.signal_colors[ta.soft_sell_signal]) utils.prettify_ax(ax, title=symbol + signal_column_name, 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
def plot_signals(symbol, period=default_period, thresholds=default_thresholds, refresh=False, start_date=config.start_date, end_date=config.end_date): """Plots the rsi buy/sell signals for the given symbol, saves this data in a .csv file, and plots this data. Only uses the first and last periods 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 rsi signals for the given symbol """ generate_signals(symbol, period=period, thresholds=thresholds, refresh=refresh, start_date=start_date, end_date=end_date) fig, ax = plot_rsi(symbol, period=period, refresh=refresh, start_date=start_date, end_date=end_date) 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] rsi_column_name = "RSI" + str(period) signal_column_name = get_signal_name(period=period) buy_signals = df.loc[df[signal_column_name] == ta.buy_signal] ax[0].scatter(buy_signals.index, df.loc[df.index.isin(buy_signals.index)]["Close"], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[1].scatter(buy_signals.index, df.loc[df.index.isin(buy_signals.index)][rsi_column_name], label=ta.buy_signal, color=ta.signal_colors[ta.buy_signal], marker=ta.signal_markers[ta.buy_signal], s=config.scatter_size, alpha=config.scatter_alpha) sell_signals = df.loc[df[signal_column_name] == ta.sell_signal] ax[0].scatter(sell_signals.index, df.loc[df.index.isin(sell_signals.index)]["Close"], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) ax[1].scatter(sell_signals.index, df.loc[df.index.isin(sell_signals.index)][rsi_column_name], label=ta.sell_signal, color=ta.signal_colors[ta.sell_signal], marker=ta.signal_markers[ta.sell_signal], s=config.scatter_size, alpha=config.scatter_alpha) utils.prettify_ax(ax[0], title=symbol + "Price", start_date=start_date, end_date=end_date) utils.prettify_ax(ax[1], title=symbol + signal_column_name, percentage=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