| 187 | } |
| 188 | |
| 189 | pub fn _initialise( |
| 190 | &mut self, |
| 191 | asset_prices: &DMatrix<f64>, |
| 192 | resample_by: Option<&str>, |
| 193 | expected_asset_returns: Option<&DMatrix<f64>>, |
| 194 | covariance_matrix: Option<&DMatrix<f64>>, |
| 195 | ) -> Result<(), ClaError> { |
| 196 | if let Some(exp) = expected_asset_returns { |
| 197 | self.expected_returns = normalize_expected_returns(exp)?; |
| 198 | } else if self.calculate_expected_returns == "mean" { |
| 199 | let exp = |
| 200 | ReturnsEstimation::calculate_mean_historical_returns(asset_prices, resample_by)?; |
| 201 | self.expected_returns = |
| 202 | normalize_expected_returns(&DMatrix::from_column_slice(exp.len(), 1, &exp))?; |
| 203 | } else if self.calculate_expected_returns == "exponential" { |
| 204 | let exp = ReturnsEstimation::calculate_exponential_historical_returns( |
| 205 | asset_prices, |
| 206 | resample_by, |
| 207 | 500, |
| 208 | )?; |
| 209 | self.expected_returns = |
| 210 | normalize_expected_returns(&DMatrix::from_column_slice(exp.len(), 1, &exp))?; |
| 211 | } else { |
| 212 | return Err(ClaError::UnknownReturns(self.calculate_expected_returns.clone())); |
| 213 | } |
| 214 | |
| 215 | if covariance_matrix.is_some() { |
| 216 | self.cov_matrix = covariance_matrix.unwrap().clone_owned(); |
| 217 | } else { |
| 218 | let returns = ReturnsEstimation::calculate_returns(asset_prices, resample_by)?; |
| 219 | self.cov_matrix = covariance(&returns); |
| 220 | } |
| 221 | |
| 222 | let bounds = build_bounds(self.expected_returns.nrows(), &self.weight_bounds)?; |
| 223 | self.lower_bounds = bounds.iter().map(|b| b.0).collect(); |
| 224 | self.upper_bounds = bounds.iter().map(|b| b.1).collect(); |
| 225 | self.weights.clear(); |
| 226 | self.lambdas.clear(); |
| 227 | self.gammas.clear(); |
| 228 | self.free_weights.clear(); |
| 229 | Ok(()) |
| 230 | } |
| 231 | |
| 232 | pub fn _compute_lambda( |
| 233 | &self, |