Skip to content

Commit

Permalink
Removed SP mock model.
Browse files Browse the repository at this point in the history
  • Loading branch information
Sinbad-The-Sailor committed Feb 11, 2024
1 parent 4e18a23 commit 1f0a00d
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 56 deletions.
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,23 +35,23 @@

### **Portfolio Optimization**

For portfolio optimzation there are two paragimes which utilizes the simulation tensor. Stochastic Programming (SP) and Model Predictive Control (MPC). The main difference being SP utilizing all scenarios for one time period, while MPC considers the average scenario over multiple time periods. The implemented models yield different results and can be modified with additional constraints and asset classes to suit any investor.
For portfolio optimzation there are two paradigmes which utilizes the simulation tensor. Stochastic Programming (SP) and Model Predictive Control (MPC). The main difference being SP utilizing all scenarios for one time period, while MPC considers the average scenario over multiple time periods. The implemented models yield different results and can be modified with additional constraints and asset classes to suit any investor.

##### 1. Maximize Expected Utility Domestic Stocks (Stochastic Programming)
$$
\mbox{max} \quad \mathbb{E}\Big[ U\Big( x_1^{\text{cash}} + p_{1}^{\text{mid}} \boldsymbol{x}_{1}^{\text{hold}} \Big) \Big]
\mbox{max} \quad \mathbb{E}\Big[ U\Big( x_1^{\text{cash}} + \sum_{a \in A} p_{1,a}^{\text{mid}} x_{1,a}^{\text{hold}} \Big) \Big]
$$

$$
\boldsymbol{x}_1^{\text{hold}} = \boldsymbol{h}_0^{\text{hold}} + \boldsymbol{x}_0^{\text{buy}} - \boldsymbol{x}_0^{\text{sell}}
x_{1,a}^{\text{hold}} = h_{0,a}^{\text{hold}} + x_{0, a}^{\text{buy}} - x_{0,a}^{\text{sell}} \quad \forall a \in A
$$

$$
x_1^{\text{cash}} = \big(h_0^{\text{cash}} + p_0^{\text{mid}}(\boldsymbol{x}_0^{\text{buy}} - \boldsymbol{x}_0^{\text{sell}}) \big) e^{r \Delta t}
x_1^{\text{cash}} = \big(h_0^{\text{cash}} + \sum_{a \in A} (p_{0,a}^{\text{ask}}x_{0,a}^{\text{buy}} - p_{0,a}^{\text{bid}}x_{0,a}^{\text{sell}}) \big) e^{r \Delta t}
$$

$$
\boldsymbol{x}_0^{\text{buy}}, \boldsymbol{x}_0^{\text{sell}}, \boldsymbol{x}_1^{\text{hold}} \geq \boldsymbol{0}
x_{0, a}^{\text{buy}}, ~x_{0,a}^{\text{sell}}, ~x_{1, a}^{\text{hold}} \geq 0 \quad \forall a \in A
$$

$$
Expand Down
20 changes: 10 additions & 10 deletions run.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@
from src.abacus.utils.portfolio import Portfolio
from src.abacus.simulator.simulator import Simulator
from src.abacus.assessor.risk_assessor import RiskAssessor
from src.abacus.optimizer.optimizer import SPMaximumUtility, SPMaximumGain
from src.abacus.optimizer.optimizer import SPMaximumUtility



# Mock instrument creation...
instruments = []
for id, ticker in enumerate(sorted(TEST_YAHOO_STOCK_UNIVERSE_4)):
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')
ins = Instrument(id, ticker, "Stock", time_series)
Expand All @@ -23,7 +23,7 @@
# Simulation ...
simulator = Simulator(instruments)
simulator.calibrate()
simulator.run_simulation(time_steps=10, number_of_simulations=1)
simulator.run_simulation(time_steps=25, number_of_simulations=500)

# Portfolio creation...
holdings = 1, 1, 1, 1
Expand All @@ -36,23 +36,23 @@
# 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 = SPMaximumGain(portfolio, price_tensor, inital_prices)
optimizer = SPMaximumUtility(portfolio, simulator.price_tensor, simulator._inital_prices, gamma=1)
optimizer.solve()

print()
optimizer = SPMaximumUtility(portfolio, price_tensor, inital_prices)
optimizer = SPMaximumUtility(portfolio, simulator.price_tensor, simulator._inital_prices, gamma=-2)
optimizer.solve()


Expand Down
44 changes: 4 additions & 40 deletions src/abacus/optimizer/optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,50 +54,14 @@ def _check_initialization(self):



class SPMaximumGain(OptimizationModel):

_model_specification = OptimizationSpecifications.SP_MAXIMIZE_GAIN

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["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



class SPMaximumUtility(OptimizationModel):

_model_specification = OptimizationSpecifications.SP_MAXIMIZE_UTILITY

def __init__(self, portfolio: Portfolio, price_tensor: torch.Tensor, inital_prices: torch.Tensor):
def __init__(self, portfolio: Portfolio, price_tensor: torch.Tensor, inital_prices: torch.Tensor, gamma: float):
super().__init__(portfolio, price_tensor)
self._inital_prices = inital_prices
self._gamma = gamma

def solve(self):
super().solve()
Expand All @@ -110,7 +74,7 @@ def _set_ampl_data(self):
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))))
inital_prices = dict(zip(asset_identifiers, np.array(self._inital_prices.reshape(8))))
tensor_size = price_tensor.shape
number_of_assets = tensor_size[0]
number_of_scenarios = tensor_size[1]
Expand All @@ -119,7 +83,7 @@ def _set_ampl_data(self):
self._ampl.get_set("assets").set_values(asset_identifiers)
self._ampl.param["risk_free_rate"] = 0.05
self._ampl.param["dt"] = 10/365
self._ampl.param["gamma"] = -2
self._ampl.param["gamma"] = self._gamma
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
Expand Down
1 change: 0 additions & 1 deletion src/abacus/utils/enumerations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@

class OptimizationSpecifications(Enum):
SP_MAXIMIZE_UTILITY = "sp_maximize_utility.mod"
SP_MAXIMIZE_GAIN = "sp_maximize_gain.mod"
MPC_MAXIMIZE_UTILITY = "mpc_maximize_utility.mod"

0 comments on commit 1f0a00d

Please sign in to comment.