diff --git a/pyproject.toml b/pyproject.toml index 90aeef7..ad027ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,3 +6,6 @@ build-backend = "setuptools.build_meta" testpaths=[ "tests", ] +pythonpath = [ + "." +] diff --git a/run.py b/run.py index 893bb1f..a67fbd2 100644 --- a/run.py +++ b/run.py @@ -1,4 +1,5 @@ # -*- coding: utf-8 -*- +import torch import pandas as pd from matplotlib import pyplot @@ -22,28 +23,32 @@ # Simulation ... simulator = Simulator(instruments) simulator.calibrate() -simulator.run_simulation(time_steps=10, number_of_simulations=1000) +simulator.run_simulation(time_steps=10, number_of_simulations=1) # Portfolio creation... -holdings = 500, 200, 100, 125 +holdings = 1, 1, 1, 1 holdings = dict(zip(instruments[0:4], holdings)) -print(holdings) -cash = 100_000 +cash = 100 portfolio = Portfolio(holdings, cash) # Risk assessor creation... -assessor = RiskAssessor(portfolio=portfolio, return_tensor=simulator.return_tensor, time_step=5) -assessor.summary() +# assessor = RiskAssessor(portfolio=portfolio, return_tensor=simulator.return_tensor, time_step=5) +# assessor.summary() # Display reasonableness of simulations... -for i in range(25): - y = simulator.price_tensor[0,:,i] - x = [i for i in range(len(y))] - pyplot.plot(x, y) -pyplot.show() +# for i in range(25): +# y = simulator.price_tensor[0,:,i] +# x = [i for i in range(len(y))] +# pyplot.plot(x, y) +# pyplot.show() + + +# Mock prices... +# price_tensor = torch.tensor([ [[1000]], [[0]], [[0]], [[0]]]) +# inital_prices = torch.tensor([ [[10]], [[10]], [[10]], [[10]]]) # Create optimizer with different optimization models... -optimizer = SPMaximumUtility(portfolio, simulator.price_tensor) +optimizer = SPMaximumUtility(portfolio, simulator._price_tensor, simulator._inital_prices) optimizer.solve() diff --git a/src/abacus/optimizer/optimization_models/sp_maximize_utility.mod b/src/abacus/optimizer/optimization_models/sp_maximize_utility.mod index 4d9aaf8..8663154 100644 --- a/src/abacus/optimizer/optimization_models/sp_maximize_utility.mod +++ b/src/abacus/optimizer/optimization_models/sp_maximize_utility.mod @@ -3,28 +3,27 @@ problem spMaximizeUtility; set assets; param dt > 0; -param gamma <= 1; param risk_free_rate; param inital_cash > 0; -param number_of_scenarios >0 integer; +param number_of_scenarios > 0 integer; param number_of_assets > 0 integer; - param inital_holdings {assets}; +param inital_prices {assets}; param prices {1..number_of_scenarios, assets}; var x_buy {assets}; var x_sell {assets}; maximize Objective: - sum{i in 1..number_of_scenarios} (((inital_cash + (sum{j in assets} (x_sell[j] - x_buy[j]) * prices[i, j] )) * exp(risk_free_rate * dt)) + sum{j in assets} prices[i, j] * (inital_holdings[j] + x_buy[j] - x_sell[j])) ** gamma / gamma -; + sum{i in 1..number_of_scenarios} 1/number_of_scenarios * ((inital_cash + sum{j in assets} (inital_prices[j] * (x_sell[j] - x_buy[j]))) * exp(risk_free_rate * dt) + sum{j in assets} (prices[i, j] * (inital_holdings[j] + x_buy[j] - x_sell[j]))); + -subject to SHORTING_CONSTRAINT {i in 1..number_of_scenarios, j in assets}: +subject to SHORTING_CONSTRAINT {j in assets}: inital_holdings[j] + x_buy[j] - x_sell[j] >= 0 ; -subject to LEVERAGE_CONSTRAINT {i in 1..number_of_scenarios}: - inital_cash + (sum{j in assets} (x_sell[j] - x_buy[j] * prices[i, j])) * exp(risk_free_rate * dt) >= 0 +subject to LEVERAGE_CONSTRAINT: + inital_cash + sum{j in assets} ( (x_sell[j] - x_buy[j]) * inital_prices[j]) >= 0 ; subject to FEASIBLE_CONSTRAINT_BUY {j in assets}: diff --git a/src/abacus/optimizer/optimizer.py b/src/abacus/optimizer/optimizer.py index eede165..f0dfa55 100644 --- a/src/abacus/optimizer/optimizer.py +++ b/src/abacus/optimizer/optimizer.py @@ -62,33 +62,35 @@ class SPMaximumUtility(OptimizationModel): _model_specification = OptimizationSpecifications.SP_MAXIMIZE_UTILITY - def __init__(self, portfolio: Portfolio, price_tensor: torch.Tensor): + def __init__(self, portfolio: Portfolio, price_tensor: torch.Tensor, inital_prices: torch.Tensor): super().__init__(portfolio, price_tensor) + self._inital_prices = inital_prices def solve(self): super().solve() print(self._ampl.get_variable("x_buy").get_values()) print(self._ampl.get_variable("x_sell").get_values()) + print(self._ampl.eval("display Objective;")) def _set_ampl_data(self): assets = self._portfolio.instruments asset_identifiers = [instrument.identifier for instrument in assets] instrument_holdings = np.array(list(self._portfolio.holdings.values())) price_tensor = np.array(self._simulation_tensor[:,-1,:]) + inital_prices = dict(zip(asset_identifiers, np.array(self._inital_prices.reshape(4)))) tensor_size = price_tensor.shape number_of_assets = tensor_size[0] number_of_scenarios = tensor_size[1] - price_dict = {(j+1, asset.identifier): price_tensor[asset.id][j] for asset in assets for j in range(number_of_scenarios)} self._ampl.get_set("assets").set_values(asset_identifiers) - self._ampl.param["gamma"] = -50 - self._ampl.param["risk_free_rate"] = 0.04 + self._ampl.param["risk_free_rate"] = 0.05 self._ampl.param["dt"] = 10/365 self._ampl.param["number_of_assets"] = number_of_assets self._ampl.param["number_of_scenarios"] = number_of_scenarios self._ampl.param["inital_cash"] = self._portfolio._cash self._ampl.param["inital_holdings"] = instrument_holdings + self._ampl.param["inital_prices"] = inital_prices self._ampl.param["prices"] = price_dict