Compare commits
2 Commits
5a24622410
...
f53f6a4d40
Author | SHA1 | Date |
---|---|---|
Felix Martin | f53f6a4d40 | |
Felix Martin | 61bc03e230 |
|
@ -1,17 +1,64 @@
|
|||
import pandas as pd
|
||||
from util import get_data
|
||||
from marketsim.marketsim import compute_portvals
|
||||
from optimize_something.optimization import calculate_stats
|
||||
from collections import namedtuple
|
||||
|
||||
Position = namedtuple("Pos", ["cash", "shares", "transactions"])
|
||||
|
||||
|
||||
def author():
|
||||
return "felixm"
|
||||
|
||||
|
||||
def testPolicy(symbol, sd, ed, sv):
|
||||
print(f"{symbol=} {sd} - {ed} {sv=}")
|
||||
# trade = date, shares (-2000, -1000, 0, 1000, 2000)
|
||||
prices = get_data([symbol], pd.date_range(sd, ed))
|
||||
print(prices.index)
|
||||
return
|
||||
def new_positions(positions, price):
|
||||
"""Calculate all potential new positions and then keep the best three."""
|
||||
# Execute all possible transactions
|
||||
new_positions = []
|
||||
for p in positions:
|
||||
for t in [-2000, -1000, 0, 1000, 2000]:
|
||||
ts = p.transactions + [t]
|
||||
p_new = Position(p.cash - t * price, p.shares + t, ts)
|
||||
new_positions.append(p_new)
|
||||
|
||||
# Keep the positions with the highest cash value for each amount of shares.
|
||||
best = {}
|
||||
for p in new_positions:
|
||||
if p.shares not in [-1000, 0, 1000]:
|
||||
pass
|
||||
elif p.shares in best and p.cash > best[p.shares].cash:
|
||||
best[p.shares] = p
|
||||
elif not p.shares in best:
|
||||
best[p.shares] = p
|
||||
return list(best.values())
|
||||
|
||||
|
||||
def transactions_to_orders(transactions, prices, symbol):
|
||||
order = pd.Series("", index=prices.index)
|
||||
shares = pd.Series(0, index=prices.index)
|
||||
|
||||
for i, t in enumerate(transactions):
|
||||
if t > 0:
|
||||
order.iloc[i] = "BUY"
|
||||
shares.iloc[i] = t
|
||||
if t < 0:
|
||||
order.iloc[i] = "SELL"
|
||||
shares.iloc[i] = -t
|
||||
|
||||
prices["Symbol"] = pd.Series(symbol, index=prices.index)
|
||||
prices["Order"] = order
|
||||
prices["Shares"] = shares
|
||||
prices.drop(columns=[symbol], inplace=True)
|
||||
prices = prices[shares != 0]
|
||||
return prices
|
||||
|
||||
|
||||
def testPolicy(symbol, sd, ed, sv):
|
||||
prices = get_data([symbol], pd.date_range(sd, ed))
|
||||
prices.drop(columns=["SPY"], inplace=True)
|
||||
|
||||
positions = [Position(sv, 0, [])]
|
||||
for date, price in prices.iterrows():
|
||||
positions = new_positions(positions, price[0])
|
||||
|
||||
price = prices.iloc[-1][symbol]
|
||||
best_position = max(positions, key=lambda p: p.cash + p.shares * price)
|
||||
return transactions_to_orders(best_position.transactions, prices, symbol)
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
import pandas as pd
|
||||
import datetime as dt
|
||||
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():
|
||||
|
@ -7,10 +11,52 @@ def author():
|
|||
|
||||
|
||||
def test_policy():
|
||||
symbol = "JPM"
|
||||
start_value = 100000
|
||||
sd = dt.datetime(2008, 1, 1)
|
||||
# ed = dt.datetime(2008, 1, 30)
|
||||
ed = dt.datetime(2009, 12, 31)
|
||||
tos.testPolicy(symbol="JPM", sd=sd, ed=ed, sv=100000)
|
||||
|
||||
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)
|
||||
|
||||
#XXX: Save to file instead.
|
||||
plot_data(portvals)
|
||||
|
||||
def normalize(timeseries):
|
||||
return timeseries / timeseries.iloc[0]
|
||||
|
@ -22,6 +68,8 @@ def bollinger_band(prices):
|
|||
|
||||
def main():
|
||||
test_policy()
|
||||
|
||||
# plot_data(prices)
|
||||
# sd = dt.datetime(2008, 1, 1)
|
||||
# ed = dt.datetime(2009, 12, 31)
|
||||
# prices = get_data(['JPM'], pd.date_range(sd, ed))
|
||||
|
|
|
@ -92,7 +92,11 @@ def handle_order(date, order, holding, prices, commission, impact):
|
|||
|
||||
|
||||
def compute_portvals(orders_file, start_val=1000000, commission=9.95, impact=0.005):
|
||||
orders = read_orders(orders_file)
|
||||
if isinstance(orders_file, pd.DataFrame):
|
||||
orders = orders_file
|
||||
else:
|
||||
orders = read_orders(orders_file)
|
||||
|
||||
start_date, end_date, symbols = get_order_book_info(orders)
|
||||
|
||||
# Tickers in the orderbook over the date_range in the order book.
|
||||
|
|
Loading…
Reference in New Issue