Last active
July 1, 2019 04:32
-
-
Save sshariff01/3f3060498c53240d903b9354a9237949 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""MC4-P6: Manual Strategy - Theoretical Optimal Strategy | |
Copyright 2018, Georgia Institute of Technology (Georgia Tech) | |
Atlanta, Georgia 30332 | |
All Rights Reserved | |
Template code for CS 4646/7646 | |
Georgia Tech asserts copyright ownership of this template and all derivative | |
works, including solutions to the projects assigned in this course. Students | |
and other users of this template code are advised not to share it with others | |
or to make it available on publicly viewable websites including repositories | |
such as github and gitlab. This copyright statement should not be removed | |
or edited. | |
We do grant permission to share solutions privately with non-students such | |
as potential employers. However, sharing with other current or future | |
students of CS 7646 is prohibited and subject to being investigated as a | |
GT honor code violation. | |
-----do not edit anything above this line--- | |
Student Name: Fady Ibrahim | |
GT User ID: fibrahim30 | |
GT ID: 903358183 | |
""" | |
import datetime as dt | |
import pandas as pd | |
import marketsimcode as msc | |
from util import get_data | |
import matplotlib.pyplot as plt | |
def author(): | |
return 'fibrahim30' | |
def testPolicy(symbol="AAPL", sd=dt.datetime(2010, 1, 1), ed=dt.datetime(2011, 12, 31), sv=100000): | |
# Get start and end dates from sorted dates range | |
dates = pd.date_range(sd, ed) | |
# From 'CS 7646 Spring 2016: Q&A on Market Simulator Project' - https://www.youtube.com/watch?v=1ysZptg2Ypk | |
# Make prices dataframe using util.py get_data | |
prices_df = get_data(symbol, dates, addSPY=False).dropna() | |
orders_df = prices_df | |
orders_df['Future'] = prices_df.shift(-1) | |
orders_df['Order'] = 0 | |
orders_df['Shares'] = 0 | |
orders_df['Holdings'] = 0 | |
orders_df.loc[orders_df['JPM'] < orders_df['Future'], 'Order'] = 'BUY' | |
orders_df.loc[orders_df['JPM'] > orders_df['Future'], 'Order'] = 'SELL' | |
orders_df.loc[orders_df['JPM'] == orders_df['Future'], 'Order'] = 'NOTHING' | |
orders_df.loc[orders_df['Future'].isnull(), 'Order'] = 'NOTHING' | |
# Initial conditions | |
orders_df.loc[orders_df['Order'] == 'BUY', 'Shares'] = 1000 | |
orders_df.loc[orders_df['Order'] == 'SELL', 'Shares'] = -1000 | |
if orders_df.ix[0, 'Order'] == 'BUY' and orders_df.ix[0, 'Holdings'] == 0: | |
orders_df.ix[0, 'Shares'] = 1000 | |
orders_df.ix[0, 'Holdings'] = 1000 | |
elif orders_df.ix[0, 'Order'] == 'SELL' and orders_df.ix[0, 'Holdings'] == 0: | |
orders_df.ix[0, 'Shares'] = -1000 | |
orders_df.ix[0, 'Holdings'] = -1000 | |
# populate trades dataframe with the resulting trades from orders data | |
for row in range(1, orders_df.shape[0]): | |
order = orders_df.ix[row, 'Order'] | |
date = orders_df.index[row] | |
if order == 'SELL' and orders_df.ix[row-1, 'Holdings'] == 0: | |
orders_df.ix[date, 'Shares'] = -1000 | |
orders_df.ix[date, 'Holdings'] = -1000 | |
elif order == 'SELL' and orders_df.ix[row-1, 'Holdings'] == -1000: | |
orders_df.ix[date, 'Shares'] = 0 | |
orders_df.ix[date, 'Holdings'] = -1000 | |
orders_df.ix[date, 'Order'] = 'NOTHING' | |
elif order == 'SELL' and orders_df.ix[row-1, 'Holdings'] == 1000: | |
orders_df.ix[date, 'Shares'] = -2000 | |
orders_df.ix[date, 'Holdings'] = -1000 | |
elif order == 'BUY' and orders_df.ix[row-1, 'Holdings'] == 0: | |
orders_df.ix[date, 'Shares'] = 1000 | |
orders_df.ix[date, 'Holdings'] = 1000 | |
elif order == 'BUY' and orders_df.ix[row-1, 'Holdings'] == -1000: | |
orders_df.ix[date, 'Shares'] = 2000 | |
orders_df.ix[date, 'Holdings'] = 1000 | |
elif order == 'BUY' and orders_df.ix[row-1, 'Holdings'] == 1000: | |
orders_df.ix[date, 'Shares'] = 0 | |
orders_df.ix[date, 'Holdings'] = 1000 | |
orders_df.ix[date, 'Order'] = 'NOTHING' | |
elif order == 'NOTHING' and orders_df.ix[row-1, 'Holdings'] == -1000: | |
orders_df.ix[date, 'Shares'] = 0 | |
orders_df.ix[date, 'Holdings'] = -1000 | |
elif order == 'NOTHING' and orders_df.ix[row-1, 'Holdings'] == 1000: | |
orders_df.ix[date, 'Shares'] = 0 | |
orders_df.ix[date, 'Holdings'] = 1000 | |
orders_df = orders_df[orders_df.Order != 'NOTHING'] | |
orders_df = orders_df.drop(['JPM'], axis=1) | |
orders_df = orders_df.drop(['Future'], axis=1) | |
orders_df = orders_df.drop(['Order'], axis=1) | |
orders_df = orders_df.drop(['Holdings'], axis=1) | |
orders_df.rename(columns={'Shares': 'JPM'}, inplace=True) | |
return orders_df | |
def benchMark(): | |
dev_start_date = dt.datetime(2008, 1, 1) | |
dev_end_date = dt.datetime(2009, 12, 31) | |
test_start_date = dt.datetime(2010, 1, 1) | |
test_end_date = dt.datetime(2011, 12, 31) | |
dev_dates = pd.date_range(dev_start_date, dev_end_date) | |
test_dates = pd.date_range(test_start_date, test_end_date) | |
symbol = ['JPM'] | |
benchmark_orders = testPolicy(symbol=symbol, sd=test_start_date, ed=test_end_date) | |
benchmark_orders = benchmark_orders * 0 | |
benchmark_orders.ix[0, 'JPM'] = 1000 | |
prices_df = get_data(symbol, test_dates, addSPY=False).dropna() | |
benchmark_portvals = msc.compute_portvals(benchmark_orders, commission=0., impact=0.) | |
print "Benchmark Portfolio Stats: " | |
msc.portfolio_stats(benchmark_portvals) | |
return benchmark_portvals | |
# Edited from util.py plot_data in order to save plots. | |
def save_plot(df, title="Stock prices", xlabel="Date", ylabel="Price"): | |
"""Plot stock prices with a custom title and meaningful axis labels.""" | |
ax = df.plot(title=title, fontsize=12, color=['green', 'red']) | |
ax.set_xlabel(xlabel) | |
ax.set_ylabel(ylabel) | |
plt.savefig(title) | |
plt.close() | |
if __name__ == "__main__": | |
""""" BENCHMARK """ | |
benchmark_portvals = benchMark() | |
# From Project Wiki - Part 2: Theoretically Optimal Strategy | |
# http://quantsoftware.gatech.edu/Summer_2019_Project_6:_Manual_Strategy | |
# Benchmark normalized to 1.0 at the start | |
normalized_benchmark = benchmark_portvals / benchmark_portvals.ix[0, :] | |
normalized_benchmark = normalized_benchmark.to_frame("Bench") | |
"""" THEORETICALLY OPTIMAL """ | |
trades_df = testPolicy(symbol=['JPM']) | |
optimal_portvals = msc.compute_portvals(trades_df, commission=0., impact=0.) | |
# From Project Wiki - Part 2: Theoretically Optimal Strategy | |
# http://quantsoftware.gatech.edu/Summer_2019_Project_6:_Manual_Strategy | |
# Value of the theoretically optimal portfolio (normalized to 1.0 at the start) | |
normalized_optimal = optimal_portvals / optimal_portvals.ix[0, :] | |
normalized_optimal = normalized_optimal.to_frame("Optimal") | |
print " " | |
print "Theoretically Optimal Strategy Portfolio Stats: " | |
msc.portfolio_stats(optimal_portvals) | |
""" Plot - Benchmark (Green Line), Optimal (Red Line) """ | |
temp_df = normalized_benchmark.join(normalized_optimal) | |
save_plot(temp_df, title='TOS vs Benchmark', xlabel='Date', ylabel='Normalized Price') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment