diff --git a/marketsim/marketsim.py b/marketsim/marketsim.py index 98387a6..50d2c41 100644 --- a/marketsim/marketsim.py +++ b/marketsim/marketsim.py @@ -26,10 +26,6 @@ GT ID: 1337 (replace with your GT ID) """ 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 @@ -76,25 +72,26 @@ def get_portfolio_value(holding, prices): 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 handle_order(date, order, holding, prices, commission, impact): + """Process the order.""" + symbol, order, shares = order + adj_closing_price = prices[symbol] + cost = shares * adj_closing_price + # Charge commission and deduct impact penalty + holding['cash'] -= (commission + impact * adj_closing_price * shares) + 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): +def compute_portvals(orders_file, start_val=1000000, commission=9.95, impact=0.005): orders = read_orders(orders_file) start_date, end_date, symbols = get_order_book_info(orders) @@ -106,22 +103,17 @@ def compute_portvals(orders_file="./orders/orders-01.csv", start_val=1000000, co holding = {s: 0 for s in symbols} holding['cash'] = start_val - orders_processed = 0 + # Iterate over all trading days that are in the (inclusive) range of the + # order book dates. This implicitly ignores orders placed on non-trading + # days. 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) - + # Process orders for that day. + for date, order in orders.loc[date:date].iterrows(): + handle_order(date, order, holding, values, commission, impact) # 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 + return prices[['Portval']] def test_code(): @@ -129,6 +121,7 @@ def test_code(): sv = 1000000 portvals = compute_portvals(orders_file=of, start_val=sv) + if isinstance(portvals, pd.DataFrame): portvals = portvals[portvals.columns[0]] # just get the first column else: @@ -161,5 +154,9 @@ def test_code(): print(f"Final Portfolio Value: {portvals[-1]}") +def author(): + return 'felixm' + + if __name__ == "__main__": test_code() diff --git a/marketsim/orders/orders-short.csv b/marketsim/orders/orders-short.csv new file mode 100644 index 0000000..0785a65 --- /dev/null +++ b/marketsim/orders/orders-short.csv @@ -0,0 +1,3 @@ +Date,Symbol,Order,Shares +2011-01-05,AAPL,BUY,1500 +2011-01-20,AAPL,SELL,1500