Skip to content

Commit

Permalink
WIP: Solution property of a optimzation model.
Browse files Browse the repository at this point in the history
  • Loading branch information
Sinbad-The-Sailor committed Feb 23, 2024
1 parent ea87442 commit c7e4ec3
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 14 deletions.
23 changes: 15 additions & 8 deletions backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
inital_holdings = {}
inital_cash = 10_000

# TODO: Should be in a universe class maybe...
instrument_mapping = {}
for id, ticker in enumerate(sorted(TEST_YAHOO_STOCK_UNIVERSE_8)):
file = f"tests/data/{ticker}.csv"
time_series = pd.read_csv(file, index_col='Date')
Expand All @@ -34,12 +36,13 @@
instruments.append(ins)
initial_weights[ins] = 1 / len(TEST_YAHOO_STOCK_UNIVERSE_8)
inital_holdings[ins] = 10
instrument_mapping[ticker] = ins

ts = time_series_data["XOM"]
start_date = "2020-01-02"
end_date = "2023-05-31"
end_date = "2020-01-05"
pr = pd.period_range(start=start_date, end=end_date, freq='B')
end_date = "2020-01-03" # "2023-05-31"
us_bd = CustomBusinessDay(calendar=USFederalHolidayCalendar())
pr = pd.date_range(start=start_date, end=end_date, freq='B')

portfolio1 = Portfolio(weights=initial_weights)
portfolio2 = Portfolio(weights=initial_weights)
Expand All @@ -49,6 +52,7 @@
wealth = np.zeros(len(pr))
for i, date in enumerate(pr):


# Build universe.
for ins in instruments:
ins.price_history = time_series_data[ins.identifier].loc[:str(date)]
Expand All @@ -61,16 +65,19 @@
# Run optimizer on portfolio.
optimizer = MPCMaximumReturn(portfolio1, simulator.return_tensor, gamma=10, l1_penalty=0, l2_penalty=1, covariance_matrix=simulator.covariance_matrix)
optimizer.solve()
optimizer.solution()
exit()

solution = optimizer.solution
solution = {instrument_mapping[ticker]: weight for ticker, weight in solution.items()}
print(solution)
# optimizer = MPCMaximumUtility(portfolio2, simulator.return_tensor, gamma=1)
# optimizer.solve()

# optimizer = SPMaximumUtility(portfolio3, simulator.price_tensor, simulator._inital_prices, gamma=-3)
# optimizer.solve()

exit()


# Update portfolio weights.



# Record portfolio wealth.
wealth[i] = 0
2 changes: 1 addition & 1 deletion src/abacus/models/garch.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ def _sanity_check(self):

if not parameter_check or not solution_check:
# TODO: Make more stable or catch this error when running loop!
#raise ParameterError("Parameters could not be asceratined succesfully.")
# raise ParameterError("Parameters could not be asceratined succesfully.")
...

def _check_parameters(self) -> bool:
Expand Down
15 changes: 10 additions & 5 deletions src/abacus/optimizer/optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def __init__(self, portfolio: Portfolio, simulation_tensor: torch.Tensor, solver
self._ampl = None

def solve(self):
# TODO: Consider a verbose mode to display command line output.
self._initiate_ampl_engine()
self._set_ampl_data()
self._solve_optimzation_problem()
Expand Down Expand Up @@ -70,6 +71,7 @@ def solve(self):
print(self._ampl.eval("display OBJECTIVE;"))

def _set_ampl_data(self):
# TODO: Make consistent parameters.
assets = self._portfolio.instruments
asset_identifiers = [instrument.identifier for instrument in assets]
instrument_holdings = np.array(list(self._portfolio.holdings.values()))
Expand Down Expand Up @@ -144,19 +146,22 @@ def __init__(self, portfolio: Portfolio, simulation_tensor: torch.Tensor, gamma:
def _return_expectation_tensor(self):
return torch.mean(self._simulation_tensor, dim=2)

@property
def solution(self):
self._check_solved()
print(self._ampl.get_variable("weights").get_values())
print(type(self._ampl.get_variable("weights").get_values()))
# TODO: Should be general?
ampl_output = self._ampl.get_variable("weights").to_pandas().loc[1].to_dict()["weights.val"]
return ampl_output

def solve(self):
# TODO: Should weights be a configuration variable?
super().solve()
print(self._ampl.get_variable("weights").to_pandas().loc[1])
print(self._ampl.eval("display OBJECTIVE;"))
#print(self._ampl.eval("display OBJECTIVE;"))


def _set_ampl_data(self):
assets = self._portfolio.instruments
inital_weights = self._portfolio.weights
assets = self._portfolio.instruments
asset_identifiers = [instrument.identifier for instrument in assets]
inital_weights = dict(zip(asset_identifiers, inital_weights.values()))
expected_return_tensor = np.array(self._return_expectation_tensor)
Expand Down

0 comments on commit c7e4ec3

Please sign in to comment.