diff --git a/run.py b/run.py index c775a45..3148d3e 100644 --- a/run.py +++ b/run.py @@ -57,7 +57,7 @@ print() optimizer = MPCMaximumUtility(portfolio, simulator.return_tensor, gamma=1) -optimizer.solve() +# optimizer.solve() print("OK!") diff --git a/src/abacus/optimizer/optimizer.py b/src/abacus/optimizer/optimizer.py index a02aa00..7ac843d 100644 --- a/src/abacus/optimizer/optimizer.py +++ b/src/abacus/optimizer/optimizer.py @@ -95,6 +95,8 @@ def _set_ampl_data(self): class MPCMaximumUtility(OptimizationModel): + # TODO: Follow Boyd et al (https://doi.org/10.1007/s10479-018-2947-3) for transaction costs and risk aversion. + _model_specification = OptimizationSpecifications.MPC_MAXIMIZE_UTILITY def __init__(self, portfolio: Portfolio, return_tensor: torch.Tensor, gamma: float): diff --git a/src/abacus/simulator/simulator.py b/src/abacus/simulator/simulator.py index 53e157b..5dfa1a9 100644 --- a/src/abacus/simulator/simulator.py +++ b/src/abacus/simulator/simulator.py @@ -5,6 +5,7 @@ from src.abacus.utils.instrument import Instrument from src.abacus.utils.exceptions import ParameterError +from src.abacus.utils.enumerations import DataTypes from src.abacus.simulator.model_selector import ModelSelector from src.abacus.config import VINE_COPULA_FAMILIES, VINE_COPULA_NUMBER_OF_THREADS @@ -22,6 +23,21 @@ def __init__(self, instruments: list[Instrument]): self._return_tensor = None self._price_tensor = None + @property + def covariance_matrix(self, data_type: DataTypes=DataTypes.LOG_RETURNS) -> torch.Tensor: + # TODO: Add explanation of stacking here. + # TODO: Ensure working under odd data length inputs. + # TODO: Add input for price through enum. + # TODO: Consider making static. + # TODO: Consider check for symmetric and positive semi definiteness. + if data_type == DataTypes.LOG_RETURNS: + instrument_data = [instrument.log_returns_tensor for instrument in self._instruments] + elif data_type == DataTypes.ART_RETURNS: + instrument_data = [instrument.art_returns_tensor for instrument in self._instruments] + else: + raise NotImplementedError(f"Data type {data_type} not supported to build covariance matrix.") + return torch.cov(torch.stack(instrument_data)) + @property def return_tensor(self) -> torch.Tensor: self._check_calibration() diff --git a/src/abacus/utils/enumerations.py b/src/abacus/utils/enumerations.py index 0deb7a5..a4bfe2f 100644 --- a/src/abacus/utils/enumerations.py +++ b/src/abacus/utils/enumerations.py @@ -1,7 +1,12 @@ # -*- coding: utf-8 -*- -from enum import Enum +from enum import Enum, auto class OptimizationSpecifications(Enum): SP_MAXIMIZE_UTILITY = "sp_maximize_utility.mod" MPC_MAXIMIZE_UTILITY = "mpc_maximize_utility.mod" + +class DataTypes(Enum): + LOG_RETURNS = auto(), + ART_RETURNS = auto(), + PRICES = auto(),