# Path: esg/generator_correlated_variables.py
# def generator_correlated_variables(corr_matrix, time_horizon, fixed_seed, method = 'cholesky'):
#     np.random.seed(fixed_seed)
#     ran = np.random.standard_normal((len(corr_matrix), time_horizon))
#         
#     if method == 'cholesky':
#         c = cholesky(corr_matrix, lower = True)
#     else:
#         evals, evecs = eigh(corr_matrix)
#         c = np.dot(evecs, np.diag(np.sqrt(evals)))
#     dw = np.dot(c, ran)
#     return dw
# 
# Path: esg/model_equity/EQ_model_classes.py
# class EQ_model_base:
#     """This class is the purely abstract class for all IR models we will implement in the future
#     see https://pymotw.com/2/abc/"""
# 
#     __metaclass__=ABCMeta
# 
#     @abstractmethod
#     def add_time_horizon(self, time_horizon):
#         """This method implements the time horizon for EQ model"""
#         return
# 
#     @abstractmethod
#     def get_EQ_prices(self):
#         """This method returns equity prices per time steps and trajectories"""
#         return
# 
#     @abstractmethod
#     def add_dividend_rate(self, dividend_rate):
#         """This method implements the dividend rate per time steps and/or trajectories"""
#         return
# 
#     @abstractmethod
#     def calibrate(self, asset_data):
#         """Calibrate the IR model onto the market environment"""
#         return
# 
# 
#     @abstractmethod
#     def add_short_rate_trajectory(self, short_rate_trajectory):
#         """This method implements the short rate trajectory"""
#         return


from ..generator_correlated_variables import generator_correlated_variables
from .EQ_model_classes import EQ_model_base


    def get_EQ_prices(self, initial_value, market_equity_shock = 0.):
        """
            Method: get_EQ_prices

            Function: return
                    1. EQ_prices: (Type: array) normalised equity prices
                    2. EQ_book_value (Type: array) normalised book values of equity
                    3. EQ_income (Type: dictionary) normalised equity incomes include
                        PMVL   : (plus ou moins value latente) unrealised gains and losses
                        PVL    : (plus value latente) unrealised gains
                        MVL    : (moins value latente) unrealised losses
                        Revenu : (revenus dégagés par les actifs)
                        PVL_obligation_TF : unrealised gains of the fixed rate bonds
                        PVL_hors_obligation : unrealised losses out of the fixed rate bonds
                        MVL_obligation_TF : unrealised losses of the fixed rate bonds
                        PMVR_hors_obligation : realised gains and losses out of fixed rate bonds
                        PMVR_obligation_TF : realised gains and losses of the fixed rate bonds

                    4. performance rate and yield (return rate)
        """
        self.EQ_total_return_index = [(1.0 + market_equity_shock) * initial_value]
        self.EQ_price_index = [(1.0 + market_equity_shock) * initial_value]
        self.perf_rate = [0]
        self.return_rate = [0]
        ##########################################

        ##########################################
        for time_step in range(1, self.time_horizon):

# Path: esg/generator_correlated_variables.py
# def generator_correlated_variables(corr_matrix, time_horizon, fixed_seed, method = 'cholesky'):
#     np.random.seed(fixed_seed)
#     ran = np.random.standard_normal((len(corr_matrix), time_horizon))
#         
#     if method == 'cholesky':
#         c = cholesky(corr_matrix, lower = True)
#     else:
#         evals, evecs = eigh(corr_matrix)
#         c = np.dot(evecs, np.diag(np.sqrt(evals)))
#     dw = np.dot(c, ran)
#     return dw
# 
# Path: esg/model_equity/EQ_model_classes.py
# class EQ_model_base:
#     """This class is the purely abstract class for all IR models we will implement in the future
#     see https://pymotw.com/2/abc/"""
# 
#     __metaclass__=ABCMeta
# 
#     @abstractmethod
#     def add_time_horizon(self, time_horizon):
#         """This method implements the time horizon for EQ model"""
#         return
# 
#     @abstractmethod
#     def get_EQ_prices(self):
#         """This method returns equity prices per time steps and trajectories"""
#         return
# 
#     @abstractmethod
#     def add_dividend_rate(self, dividend_rate):
#         """This method implements the dividend rate per time steps and/or trajectories"""
#         return
# 
#     @abstractmethod
#     def calibrate(self, asset_data):
#         """Calibrate the IR model onto the market environment"""
#         return
# 
# 
#     @abstractmethod
#     def add_short_rate_trajectory(self, short_rate_trajectory):
#         """This method implements the short rate trajectory"""
#         return


# Path: esg/model_equity/GBM_constant_volatility.py
from ..generator_correlated_variables import generator_correlated_variables
from .EQ_model_classes import EQ_model_base



    def get_EQ_prices(self, initial_value, market_equity_shock = 0.):
        """
            Method: get_EQ_prices

            Function: return
                    1. EQ_prices: (Type: array) normalised equity prices
                    2. EQ_book_value (Type: array) normalised book values of equity
                    3. EQ_income (Type: dictionary) normalised equity incomes include
                        PMVL   : (plus ou moins value latente) unrealised gains and losses
                        PVL    : (plus value latente) unrealised gains
                        MVL    : (moins value latente) unrealised losses
                        Revenu : (revenus dégagés par les actifs)
                        PVL_obligation_TF : unrealised gains of the fixed rate bonds
                        PVL_hors_obligation : unrealised losses out of the fixed rate bonds
                        MVL_obligation_TF : unrealised losses of the fixed rate bonds
                        PMVR_hors_obligation : realised gains and losses out of fixed rate bonds
                        PMVR_obligation_TF : realised gains and losses of the fixed rate bonds

                    4. performance rate and yield (return rate)
        """
        self.EQ_total_return_index = [(1.0 + market_equity_shock) * initial_value]
        self.EQ_price_index = [(1.0 + market_equity_shock) * initial_value]
        self.perf_rate = [0]
        self.return_rate = [0]
        ##########################################

        ##########################################
        for time_step in range(1, self.time_horizon):

            dw = generator_correlated_variables(corr_matrix = self.corr_matrix, time_horizon = self.time_horizon, fixed_seed = self.fixed_seed)