def testPolicy(symbol="JPM", sd=dt.datetime(2008, 1, 1), ed=dt.datetime(2009, 12, 31), sv=100000): # Retrieve prices on the symbol to be traded policy_frame = id.get_prices([symbol], sd, ed) # Calculate daily returns policy_frame['Daily Rets'] = id.get_daily_returns(policy_frame) # Calculate positions based on the next day's daily returns policy_frame['Positions'] = policy_frame['Daily Rets'].shift(-1) policy_frame['Positions'] = np.where(policy_frame['Positions'] > 0, 1, policy_frame['Positions']) policy_frame['Positions'] = np.where(policy_frame['Positions'] < 0, -1, policy_frame['Positions']) # Calculate trades based on positions policy_frame['Trades'] = policy_frame['Positions'].shift(1) policy_frame['Trades'][0] = 0 policy_frame['Trades'] = (policy_frame['Positions'] - policy_frame['Trades']) * 1000 policy_frame['Trades'][-1] = 0 return policy_frame['Trades']
def get_indicators(self, prices, window = 10, band_size = 2): """ Computes indicators for a symbol, given prices. Parameters: prices: array of prices window: time-window in days band_size: band_size for the Bollinger(R) Bands Returns: Tuple of indicators for price/SMA, momentum, BB """ self.window = window sma, price_to_sma = ind.get_simple_moving_average(prices, window = window) momentum = ind.get_momentum(prices, window = window) upper, lower, bb_val = ind.get_bollinger_bands(prices, window = window, band_size = band_size) return price_to_sma, momentum, bb_val
def _build_tech_ind(dfs: dict) -> dict: """ Build technical indicators and append them to the DataFrames as columns. :param dfs: Dict containing DataFrames by symbol containing all stock data as provided by group_by_stockname() :return: dict: {stock_name:string -> stock_data:DataFrame} with additional feature columns """ result = {} for symbol, stock_df in dfs.items(): pmas = TechnicalIndicators.sma(stock_df, 5, 'PMA_S', col=ADJ_CLOSE_COL) pmal = TechnicalIndicators.sma(stock_df, 20, 'PMA_L', col=ADJ_CLOSE_COL) vmas = TechnicalIndicators.sma(stock_df, 5, 'VMA_S', col=ADJ_VOL_COL) vmal = TechnicalIndicators.sma(stock_df, 20, 'VMA_L', col=ADJ_VOL_COL) rsi = TechnicalIndicators.rsi(stock_df, 14, col=ADJ_CLOSE_COL) sto = TechnicalIndicators.sto(stock_df, 14, 3, col=ADJ_CLOSE_COL, col_low=ADJ_LOW_COL, col_high=ADJ_HIGH_COL) bb = TechnicalIndicators.bbands(stock_df, 8, 2, col=ADJ_CLOSE_COL) result[symbol] = pd.concat( [stock_df, pmas, pmal, vmas, vmal, rsi, sto, bb], axis=1) return result
def main_optimal(): # Set-up initial parameters for simulation symbol = "JPM" sd = dt.datetime(2008, 1, 2) ed = dt.datetime(2009, 12, 31) sv = 100000 commission = 0 impact = 0 # Calculate optimal portfolio values optimal_trades = testPolicy(symbol=symbol, sd=sd, ed=ed, sv=sv) optimal_trades = process_trades_df(optimal_trades, "JPM") optimal_port_vals = ms.compute_portvals(optimal_trades, start_val=sv, commission=commission, impact=impact) optimal_port_vals = optimal_port_vals / optimal_port_vals.iloc[0, :] # Calculate benchmark portfolio values benchmark_trades = pd.DataFrame(data=[["JPM", "BUY", 1000]], index=[sd, ed], columns=["Symbol", "Order", "Shares"]) benchmark_port_vals = ms.compute_portvals(benchmark_trades, start_val=sv, commission=commission, impact=impact) benchmark_port_vals = benchmark_port_vals / benchmark_port_vals.iloc[0, :] # Plot optimal strategy plt.plot(benchmark_port_vals, color='g', linewidth=0.7) plt.plot(optimal_port_vals, color='r', linewidth=0.7) plt.legend(["Benchmark", "Optimal"]) plt.title("Portfolio Values: Benchmark vs. Optimal", fontsize=10) plt.ylabel("Normalized Values", fontsize=8) plt.xlabel("Date Range", fontsize=8) plt.savefig('Optimal.png') ocr, oadr, osddr, osr = id.calculate_portfolio_metrics(optimal_port_vals) bcr, badr, bsddr, bsr = id.calculate_portfolio_metrics(benchmark_port_vals) print("Optimal: ", ocr, oadr, osddr, osr) print("Benchmark:", bcr, badr, bsddr, bsr)
def build_tech_ind(dfs: dict) -> dict: """ Build technical indicators and append them to the DataFrames as columns. :param dfs: Dict containing DataFrames by symbol containing all stock data as provided by group_by_stockname() :return: dict: {stock_name:string -> stock_data:DataFrame} with additional feature columns """ result = {} for symbol, stock_df in dfs.items(): close_col = 'adj_close' if 'adj_close' in stock_df else 'close' open_col = 'adj_open' if 'adj_open' in stock_df else 'open' low_col = 'adj_low' if 'adj_low' in stock_df else 'low' high_col = 'adj_high' if 'adj_high' in stock_df else 'high' pmas = TechnicalIndicators.sma(stock_df, 10, 'PMA_S', col=close_col) pmal = TechnicalIndicators.sma(stock_df, 21, 'PMA_L', col=close_col) vmas = TechnicalIndicators.sma(stock_df, 10, 'VMA_S', col=vol_col) vmal = TechnicalIndicators.sma(stock_df, 21, 'VMA_L', col=vol_col) rsi = TechnicalIndicators.rsi(stock_df, 14, col=close_col) sto = TechnicalIndicators.sto(stock_df, 14, 3, col=close_col, col_low=low_col, col_high=high_col) bb = TechnicalIndicators.bbands(stock_df, 8, 2, col=close_col) result[symbol] = pd.concat([stock_df, pmas, pmal, vmas, vmal, rsi, sto, bb], axis=1) return result
def testPolicy(symbol="JPM", sd=dt.datetime(2008, 1, 1), ed=dt.datetime(2009, 12, 31), sv=100000, bb_threshold=1, sma_threshold=0.06, momentum_threshold = 0.4): ''' Generates a dataframe of trades based on the manual strategy policy. The policy is described in the attached report. Parameters: symbol (string) - The symbol with which to trade. sd (datetime) - Trading period start date. ed (datetime) - Trading period end date. sv (int) - Starting cash value. bb_threshold (float) - Threshold at which to trigger indicator. sma_threshold (float) - Threshold at which to trigger indicator. momentum_threshold(float) - Threshold at which to trigger indicator. ''' window = 10; prices = id.get_prices([symbol], sd, ed) indicators = id.get_indicators(prices, [symbol], window = window) position = 0; holdings = 0; df_trades = pd.DataFrame(index = indicators.index); df_trades["Symbol"] = symbol df_trades["Order"] = "NONE" df_trades["Shares"] = 0 for day in indicators.iloc[window-1:].index: bb = indicators["Normal BB"][day] sma = indicators["Price/SMA"][day] momentum = indicators["Momentum"][day] # Short Positions: # Stock is above upper Bollinger Band # Price/SMA ratio is above 1. # Momentum is smaller than lower threshold if (bb > bb_threshold or sma > 1+sma_threshold) or momentum < -momentum_threshold: position = -1 # Long Positions: # Price is below lower Bollinger Band # Price/SMA ratio is below 1. # Momentum is larger than upper threshold elif (bb < -bb_threshold or sma < 1-sma_threshold) or momentum > momentum_threshold: position = 1 # Otherwise, maintain position. else: position = 0 # Calculate needed shares to trade based on position. if position == -1: shares_to_trade = -1000-holdings holdings = -1000 elif position == 1: shares_to_trade = 1000-holdings holdings = 1000 else: shares_to_trade = 0 if shares_to_trade<0: df_trades.loc[day, "Order"] = "SELL" df_trades.loc[day, "Shares"]= -shares_to_trade elif shares_to_trade>0: df_trades.loc[day, "Order"] = "BUY" df_trades.loc[day, "Shares"] = shares_to_trade df_trades = df_trades[df_trades.Order != "NONE"] return df_trades
port_vals.fillna(method = 'ffill', inplace=True) # Plot optimal strategy plt.gcf().subplots_adjust(bottom=0.2) plt.plot(port_vals["Benchmark"], color = 'g', linewidth = 0.7) plt.plot(port_vals["Manual"], color = 'r', linewidth = 0.7) if out_file == "Manual_In.png": print("In-sample") for day in manual_trades.index: if manual_trades.loc[day, "Order"] == "BUY": plt.axvline(day, color = 'b') else: plt.axvline(day, color = 'k') plt.legend(["Benchmark", "Manual Strategy"]) plt.title("Portfolio Values: Benchmark vs. Manual Strategy\n"+out_subtitle, fontsize = 10) plt.ylabel("Normalized Values", fontsize = 8) plt.xlabel("Date Range", fontsize = 8) plt.xticks(rotation = 45) plt.savefig(out_file) #plt.show() mcr, madr, msddr, msr = id.calculate_portfolio_metrics(manual_port_vals) bcr, badr, bsddr, bsr = id.calculate_portfolio_metrics(benchmark_port_vals) print("Manual Strategy: ", mcr, madr, msddr, msr) print("Benchmark:", bcr, badr, bsddr, bsr) if __name__ == "__main__": main_manual(out_file = "Manual_In.png", out_subtitle = "In Sample") plt.figure() main_manual(sd = dt.datetime(2010, 1, 4), ed = dt.datetime(2011, 12, 30), out_file = "Manual_Out.png", out_subtitle = "Out of Sample")
def test_ti(): data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] df = pd.DataFrame(data=data) #print("dataframe before: ") #print(df) #df_out = ti.calculate_cci(df, 3) #print("dataframe after: ") #print(df_out) df.plot() plt.show() plt.savefig(code_path + "plot.png") if __name__ == "__main__": test_ti() # build dataframe df_price, df_price_nonan = build_dataframe_price() df_dr = ti.calculate_daily_returns(df_price) df_sr = ti.calculate_sharpe_ratio(df_dr) print(df_sr) #print(df_price["btc"]) #df_price["btc"].plot() ##plt.show() #plt.savefig(code_path + "plot.png")
def experiment_2_helper(symbol, start_train, end_train, start_test, end_test, sv=100000, commission=0.0, impact=0.0): np.random.seed(1000) random.seed(1000) slearner = sl.StrategyLearner(impact=impact) slearner.addEvidence(symbol=symbol, sd=start_train, ed=end_train, sv=sv) # In-Sample Experiment 1 # Calculate manual strategy portfolio values manual_trades = man.testPolicy(symbol=symbol, sd=start_test, ed=end_test, sv=sv) manual_port_vals = ms.compute_portvals(manual_trades, start_val=sv, commission=commission, impact=impact) manual_port_vals = manual_port_vals / manual_port_vals.iloc[0, :] manual_port_vals.rename(columns={"Portfolio Value": "Manual"}, inplace=True) # Calculate benchmark portfolio values dates = pd.date_range(start_test, end_test) syms = [symbol] price_range = get_data(syms, dates) # automatically adds SPY benchmark_trades = pd.DataFrame( data=[[symbol, "BUY", 1000]], index=[price_range.index[0], price_range.index[-1]], columns=["Symbol", "Order", "Shares"]) bench_port_vals = ms.compute_portvals(benchmark_trades, start_val=sv, commission=commission, impact=impact) bench_port_vals = bench_port_vals / bench_port_vals.iloc[0, :] bench_port_vals.rename(columns={"Portfolio Value": "Benchmark"}, inplace=True) # Calculate strategy learner portfolio values temp_strategylearner_trades = slearner.testPolicy(symbol=symbol, sd=start_test, ed=end_test, sv=sv) strategylearner_trades = pd.DataFrame( columns=['Order', 'Symbol', 'Shares']) for row_idx in temp_strategylearner_trades.index: nshares = temp_strategylearner_trades.loc[row_idx][0] if nshares == 0: continue order = 'SELL' if nshares < 0 else 'BUY' new_row = pd.DataFrame([ [order, symbol, abs(nshares)], ], columns=['Order', 'Symbol', 'Shares'], index=[ row_idx, ]) strategylearner_trades = strategylearner_trades.append(new_row) strategylearner_port_vals = ms.compute_portvals(strategylearner_trades, start_val=sv, commission=commission, impact=impact) strategylearner_port_vals = strategylearner_port_vals / strategylearner_port_vals.iloc[ 0, :] strategylearner_port_vals.rename(columns={"Portfolio Value": "Strategy"}, inplace=True) port_vals = pd.DataFrame(bench_port_vals["Benchmark"], index=bench_port_vals.index) port_vals["Manual"] = manual_port_vals["Manual"] port_vals["Strategy"] = strategylearner_port_vals["Strategy"] port_vals.fillna(method='ffill', inplace=True) mcr, madr, msddr, msr = id.calculate_portfolio_metrics(manual_port_vals) bcr, badr, bsddr, bsr = id.calculate_portfolio_metrics(bench_port_vals) scr, sadr, ssddr, ssr = id.calculate_portfolio_metrics( strategylearner_port_vals) return mcr, madr, msddr, msr, bcr, badr, bsddr, bsr, scr, sadr, ssddr, ssr
def run_experiment_1(symbol, start_train, end_train, start_test, end_test, sv=100000, commission=0.0, impact=0.0, output="default.png"): np.random.seed(1000) random.seed(1000) slearner = sl.StrategyLearner(impact=impact) slearner.addEvidence(symbol=symbol, sd=start_train, ed=end_train, sv=sv) # In-Sample Experiment 1 # Calculate manual strategy portfolio values manual_trades = man.testPolicy(symbol=symbol, sd=start_test, ed=end_test, sv=sv) manual_port_vals = ms.compute_portvals(manual_trades, start_val=sv, commission=commission, impact=impact) manual_port_vals = manual_port_vals / manual_port_vals.iloc[0, :] manual_port_vals.rename(columns={"Portfolio Value": "Manual"}, inplace=True) # Calculate benchmark portfolio values dates = pd.date_range(start_test, end_test) syms = [symbol] price_range = get_data(syms, dates) # automatically adds SPY benchmark_trades = pd.DataFrame( data=[[symbol, "BUY", 1000]], index=[price_range.index[0], price_range.index[-1]], columns=["Symbol", "Order", "Shares"]) bench_port_vals = ms.compute_portvals(benchmark_trades, start_val=sv, commission=commission, impact=impact) bench_port_vals = bench_port_vals / bench_port_vals.iloc[0, :] bench_port_vals.rename(columns={"Portfolio Value": "Benchmark"}, inplace=True) # Calculate strategy learner portfolio values temp_strategylearner_trades = slearner.testPolicy(symbol=symbol, sd=start_test, ed=end_test, sv=sv) strategylearner_trades = pd.DataFrame( columns=['Order', 'Symbol', 'Shares']) for row_idx in temp_strategylearner_trades.index: nshares = temp_strategylearner_trades.loc[row_idx][0] if nshares == 0: continue order = 'SELL' if nshares < 0 else 'BUY' new_row = pd.DataFrame([ [order, symbol, abs(nshares)], ], columns=['Order', 'Symbol', 'Shares'], index=[ row_idx, ]) strategylearner_trades = strategylearner_trades.append(new_row) strategylearner_port_vals = ms.compute_portvals(strategylearner_trades, start_val=sv, commission=commission, impact=impact) strategylearner_port_vals = strategylearner_port_vals / strategylearner_port_vals.iloc[ 0, :] strategylearner_port_vals.rename(columns={"Portfolio Value": "Strategy"}, inplace=True) port_vals = pd.DataFrame(bench_port_vals["Benchmark"], index=bench_port_vals.index) port_vals["Manual"] = manual_port_vals["Manual"] port_vals["Strategy"] = strategylearner_port_vals["Strategy"] port_vals.fillna(method='ffill', inplace=True) # Plot in-sample strategy plt.figure() plt.gcf().subplots_adjust(bottom=0.2) plt.plot(port_vals["Benchmark"], color='g', linewidth=0.7) plt.plot(port_vals["Manual"], color='r', linewidth=0.7) plt.plot(port_vals["Strategy"], color='b', linewidth=0.7) plt.legend(["Benchmark", "Manual", "StrategyLearner"]) plt.title( "Portfolio Values: Benchmark vs. Manual Strategy vs. StrategyLearner\n", fontsize=10) plt.ylabel("Normalized Values", fontsize=8) plt.xlabel("Date Range", fontsize=8) plt.xticks(rotation=45) plt.savefig(output) mcr, madr, msddr, msr = id.calculate_portfolio_metrics(manual_port_vals) bcr, badr, bsddr, bsr = id.calculate_portfolio_metrics(bench_port_vals) scr, sadr, ssddr, ssr = id.calculate_portfolio_metrics( strategylearner_port_vals) print("--------------------Manual Strategy--------------------") print("Cumulative Return:", mcr) print("Average Daily Return:", madr) print("Stdev Daily Return:", msddr) print("Sharpe Ratio:", msr) print("--------------------Benchmark Strategy-----------------") print("Cumulative Return:", bcr) print("Average Daily Return:", badr) print("Stdev Daily Return:", bsddr) print("Sharpe Ratio:", bsr) print("--------------------StrategyLearner---------------------") print("Cumulative Return:", scr) print("Average Daily Return:", sadr) print("Stdev Daily Return:", ssddr) print("Sharpe Ratio:", ssr)