import pandas as pd import datetime as dt import matplotlib.pyplot as plt import TheoreticallyOptimalStrategy as tos from util import plot_data, get_data from marketsim.marketsim import compute_portvals from optimize_something.optimization import calculate_stats def author(): return "felixm" def test_optimal_strategy(): symbol = "JPM" start_value = 100000 sd = dt.datetime(2008, 1, 1) ed = dt.datetime(2009, 12, 31) orders = tos.testPolicy(symbol=symbol, sd=sd, ed=ed, sv=start_value) portvals = compute_portvals(orders, start_value, 0, 0) start_date = portvals.index[0] end_date = portvals.index[-1] cum_ret, avg_daily_ret, \ std_daily_ret, sharpe_ratio = calculate_stats(portvals, [1]) d = {"Symbol": [symbol, symbol], "Order": ["BUY", "SELL"], "Shares": [1000, 1000]} orders = pd.DataFrame(data=d, index=[start_date, end_date]) bench = compute_portvals(orders, start_value, 0, 0) cum_ret_bench, avg_daily_ret_bench, \ std_daily_ret_bench, sharpe_ratio_bench = calculate_stats(bench, [1]) # Compare portfolio against benchmark print(f"Date Range: {start_date} to {end_date}") print() print(f"Sharpe Ratio of Optimal Strategy: {sharpe_ratio}") print(f"Sharpe Ratio of bench: {sharpe_ratio_bench}") print() print(f"Cumulative Return of Optimal Strategy: {cum_ret}") print(f"Cumulative Return of bench: {cum_ret_bench}") print() print(f"Standard Deviation of Optimal Strategy: {std_daily_ret}") print(f"Standard Deviation of bench: {std_daily_ret_bench}") print() print(f"Average Daily Return of Optimal Strategy: {avg_daily_ret}") print(f"Average Daily Return of bench: {avg_daily_ret_bench}") print() print(f"Final Portfolio Value Optimal: {portvals.iloc[-1][0]}") print(f"Final Portfolio Value Bench: {bench.iloc[-1][0]}") portvals["Optimal"] = portvals["Portval"] portvals["Bench"] = bench["Portval"] portvals.drop(columns=["Portval"], inplace=True) portvals.plot(title="Optimal strategy versus 1000 shares of JPM") plt.savefig('figure_5.png') def normalize(timeseries): return timeseries / timeseries.iloc[0] def bollinger_band(df, symbol, period=20, m=2): boll_sma = df[symbol].rolling(period).mean() std = df[symbol].rolling(period).std() boll_up = boll_sma + m * std boll_lo = boll_sma - m * std df[f"Boll({symbol}, {period})-sma"] = boll_sma df[f"Boll({symbol}, {period})-up"] = boll_up df[f"Boll({symbol}, {period})-lo"] = boll_lo def sma(df, symbol, period): """Adds a new column to the dataframe SMA(period)""" df[f"{symbol}-sma({period})"] = df[symbol].rolling(period).mean() def price_sma(df, symbol, period): """Calculates SMA and adds new column price divided by SMA to the df.""" sma = df[symbol].rolling(period).mean() df[f"{symbol}-price/sma({period})"] = df[symbol] / sma def main(): # test_optimal_strategy() symbol = "JPM" sd = dt.datetime(2008, 1, 1) ed = dt.datetime(2009, 12, 31) df = get_data([symbol], pd.date_range(sd, ed)) df.drop(columns=["SPY"], inplace=True) df = normalize(df) sma(df, symbol, 8) # price_sma(df, symbol, 8) # bollinger_band(df, symbol) # TODO # rsi(df, symbol) # macd(df, symbol) plot_data(df) if __name__ == "__main__": main()