-
Notifications
You must be signed in to change notification settings - Fork 2
/
backtest.py
76 lines (64 loc) · 2.54 KB
/
backtest.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# -*- coding: utf-8 -*-
import time
import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from tests.test_config import TEST_YAHOO_STOCK_UNIVERSE_16, TEST_YAHOO_STOCK_UNIVERSE_8, TEST_YAHOO_STOCK_UNIVERSE_4
from src.abacus.utils.portfolio import Portfolio
from src.abacus.utils.universe import Universe
from src.abacus.simulator.simulator import Simulator
from src.abacus.optimizer.optimizer import MPCMaximumReturn
# Backtesting setup.
instrument_specification = {}
inital_weights = {}
wealth = [100]
wealth_n = [100]
number_of_start_assets = 5
for i, ticker in enumerate(sorted(TEST_YAHOO_STOCK_UNIVERSE_8)):
file = f"tests/data/{ticker}.csv"
time_series = pd.read_csv(file, index_col='Date')
instrument_specification[ticker] = time_series
if i < number_of_start_assets: inital_weights[ticker] = 1 / number_of_start_assets
universe = Universe(instrument_specifications=instrument_specification)
portfolio = Portfolio(weights=inital_weights)
# Date range for backtesting.
start_date = "2020-01-02"
end_date = "2020-10-02" # "2023-05-31"
date_range = pd.date_range(start=start_date, end=end_date, freq='B')
solutions = {"2020-01-01": inital_weights}
times = {}
for date in date_range:
universe.date_today = date
simulator = Simulator(universe)
t0 = time.time()
simulator.calibrate()
print("Calibration", time.time() - t0)
t1 = time.time()
simulator.run_simulation(time_steps=10, number_of_simulations=1000)
print("Simulation", time.time() - t1)
optimizer = MPCMaximumReturn(universe, portfolio, simulator.return_tensor, gamma=2, l1_penalty=0, l2_penalty=0.02,
covariance_matrix=simulator.covariance_matrix)
optimizer.solve()
solution = optimizer.solution
portfolio.weights = solution
solutions[date] = solution
universe_returns = universe.todays_returns
portfolio_weights = np.array(list(solution.values()))
equal_weights = (1/8) * np.ones(8)
portfolio_return = np.dot(universe_returns, portfolio_weights)
equal_return = np.dot(universe_returns, equal_weights)
wealth.append(wealth[-1] * (1 + portfolio_return))
wealth_n.append(wealth_n[-1] * (1 + equal_return))
dates = ["2024-01-01"]
for date in date_range:
dates.append(str(date)[0:10])
np.savetxt('data.csv', np.array(wealth), delimiter=',')
plt.plot(dates, wealth)
plt.plot(dates, wealth_n)
plt.show()
print('\n' * 10)
for date, solution in solutions.items():
print(f"Took {times.get(date, -1)} seconds.")
for a, w in solution.items():
print(a, w)
print()