Implement marketsim without commission and impact
This commit is contained in:
@@ -29,9 +29,11 @@ import pandas as pd
|
||||
import numpy as np
|
||||
import datetime as dt
|
||||
import os
|
||||
import sys
|
||||
from util import get_data, plot_data
|
||||
from optimize_something.optimization import calculate_stats
|
||||
|
||||
|
||||
def read_orders(orders_file):
|
||||
"""
|
||||
Parser orders into the form:
|
||||
@@ -48,35 +50,78 @@ def read_orders(orders_file):
|
||||
2011-01-10,AAPL,SELL,1500
|
||||
"""
|
||||
orders = pd.read_csv(orders_file,
|
||||
index_col=['Date'],
|
||||
dtype='|str, str, str, i4',
|
||||
parse_dates=["Date"])
|
||||
parse_dates=['Date'])
|
||||
orders.sort_values(by="Date", inplace=True)
|
||||
return orders
|
||||
|
||||
|
||||
def get_order_book_info(orders):
|
||||
"""Return start_date, end_date, and symbols (as a list)."""
|
||||
start_date = orders.iloc[0].Date
|
||||
end_date = orders.iloc[0].Date
|
||||
start_date = orders.index[0]
|
||||
end_date = orders.index[-1]
|
||||
symbols = sorted(list((set(orders.Symbol.tolist()))))
|
||||
return start_date, end_date, symbols
|
||||
|
||||
|
||||
def get_portfolio_value(holding, prices):
|
||||
"""Calculate the current portofolio value."""
|
||||
value = 0
|
||||
for ticker, shares in holding.items():
|
||||
if ticker == 'cash':
|
||||
value += shares
|
||||
else:
|
||||
value += shares * prices[ticker]
|
||||
return value
|
||||
|
||||
|
||||
def handle_orders(orders, holding, adj_closing_prices):
|
||||
"""Process the orders."""
|
||||
for date, order in orders.iterrows():
|
||||
symbol, order, shares = order
|
||||
adj_closing_price = adj_closing_prices[symbol]
|
||||
cost = shares * adj_closing_price
|
||||
if order == "BUY":
|
||||
# print(f"Buy {shares:6} of {symbol:4} on {date}")
|
||||
holding['cash'] -= cost
|
||||
holding[symbol] += shares
|
||||
elif order == "SELL":
|
||||
# print(f"Sell {shares:6} of {symbol:4} on {date}")
|
||||
holding['cash'] += cost
|
||||
holding[symbol] -= shares
|
||||
else:
|
||||
raise Exception("Unexpected order type.")
|
||||
|
||||
|
||||
def compute_portvals(orders_file="./orders/orders-01.csv", start_val=1000000, commission=9.95, impact=0.005):
|
||||
orders = read_orders(orders_file)
|
||||
start_date, end_date, symbols = get_order_book_info(orders)
|
||||
|
||||
# In the template, instead of computing the value of the portfolio, we just
|
||||
# read in the value of IBM over 6 months
|
||||
start_date = dt.datetime(2008, 1, 1)
|
||||
end_date = dt.datetime(2008, 6, 1)
|
||||
portvals = get_data(['IBM'], pd.date_range(start_date, end_date))
|
||||
portvals = portvals[['IBM']] # remove SPY
|
||||
# Tickers in the orderbook over the date_range in the order book.
|
||||
prices = get_data(symbols, pd.date_range(start_date, end_date))
|
||||
prices['Portval'] = pd.Series(0.0, index=prices.index)
|
||||
|
||||
# A dictionary to keep track of the assets we are holding.
|
||||
holding = {s: 0 for s in symbols}
|
||||
holding['cash'] = start_val
|
||||
|
||||
orders_processed = 0
|
||||
for date, values in prices.iterrows():
|
||||
if date in orders.index:
|
||||
current_orders = orders.loc[date:date]
|
||||
orders_processed += current_orders.shape[0]
|
||||
handle_orders(current_orders, holding, values)
|
||||
|
||||
# Compute portfolio value at the end of day.
|
||||
values['Portval'] = get_portfolio_value(holding, values)
|
||||
|
||||
# Make sure we have processed all orders. If there was an order on a
|
||||
# non-trading day we would currently not handle it.
|
||||
assert(orders.shape[0] == orders_processed)
|
||||
|
||||
portvals = prices[['Portval']]
|
||||
return portvals
|
||||
# Don't know why this was in template. Keep for now.
|
||||
# rv = pd.DataFrame(index=portvals.index, data=portvals.values)
|
||||
# return rv
|
||||
|
||||
|
||||
def test_code():
|
||||
@@ -89,20 +134,14 @@ def test_code():
|
||||
else:
|
||||
raise Exception("warning, code did not return a DataFrame")
|
||||
|
||||
# One way of getting the portfolio dates
|
||||
# print(portvals.index[0])
|
||||
|
||||
# Get portfolio stats.
|
||||
start_date = dt.datetime(2008, 1, 1)
|
||||
end_date = dt.datetime(2008, 6, 1)
|
||||
|
||||
|
||||
start_date = portvals.index[0]
|
||||
end_date = portvals.index[-1]
|
||||
cum_ret, avg_daily_ret, \
|
||||
std_daily_ret, sharpe_ratio = calculate_stats(portvals.to_frame(), [1])
|
||||
std_daily_ret, sharpe_ratio = calculate_stats(portvals.to_frame(), [1])
|
||||
|
||||
spy = get_data(['SPY'], pd.date_range(start_date, end_date))
|
||||
cum_ret_SPY, avg_daily_ret_SPY, \
|
||||
std_daily_ret_SPY, sharpe_ratio_SPY = calculate_stats(spy, [1])
|
||||
std_daily_ret_SPY, sharpe_ratio_SPY = calculate_stats(spy, [1])
|
||||
|
||||
# Compare portfolio against $SPY
|
||||
print(f"Date Range: {start_date} to {end_date}")
|
||||
|
||||
Reference in New Issue
Block a user