MCPcopy Create free account
hub / github.com/Open-Quant/openquant / allocate

Method allocate

crates/openquant/src/cla.rs:123–187  ·  view source on GitHub ↗
(
        &mut self,
        asset_prices: Option<AssetPricesInput<'_>>,
        expected_asset_returns: Option<&DMatrix<f64>>,
        covariance_matrix: Option<&DMatrix<f64>>,
        resample_by: O

Source from the content-addressed store, hash-verified

121 }
122
123 pub fn allocate(
124 &mut self,
125 asset_prices: Option<AssetPricesInput<'_>>,
126 expected_asset_returns: Option<&DMatrix<f64>>,
127 covariance_matrix: Option<&DMatrix<f64>>,
128 resample_by: Option<&str>,
129 solution: Option<&str>,
130 ) -> Result<(), ClaError> {
131 if asset_prices.is_none() && expected_asset_returns.is_none() && covariance_matrix.is_none()
132 {
133 return Err(ClaError::MissingInputs);
134 }
135 if let Some(AssetPricesInput::RawMatrix(_)) = asset_prices {
136 return Err(ClaError::InvalidAssetPrices("Asset prices matrix must be a dataframe"));
137 }
138 if let Some(AssetPricesInput::Prices(prices)) = asset_prices {
139 if prices.index.len() != prices.data.nrows() || prices.index.is_empty() {
140 return Err(ClaError::InvalidAssetPrices("Asset prices index must be datetime"));
141 }
142 self._initialise(&prices.data, resample_by, expected_asset_returns, covariance_matrix)?;
143 } else if let (Some(exp), Some(cov)) = (expected_asset_returns, covariance_matrix) {
144 self.expected_returns = normalize_expected_returns(exp)?;
145 self.cov_matrix = cov.clone_owned();
146 self.lower_bounds = vec![0.0; self.expected_returns.nrows()];
147 self.upper_bounds = vec![1.0; self.expected_returns.nrows()];
148 self.weights.clear();
149 self.lambdas.clear();
150 self.gammas.clear();
151 self.free_weights.clear();
152 } else {
153 return Err(ClaError::MissingInputs);
154 }
155
156 let solution = solution.unwrap_or("cla_turning_points");
157 let bounds = build_bounds(self.expected_returns.nrows(), &self.weight_bounds)?;
158 match solution {
159 "cla_turning_points" | "min_volatility" => {
160 let w = solve_min_vol(&self.cov_matrix, &bounds)?;
161 self.weights = vec![w];
162 }
163 "max_sharpe" => {
164 let exp = self.expected_returns.column(0).iter().copied().collect::<Vec<_>>();
165 let w = solve_max_sharpe(&self.cov_matrix, &exp, 0.0, &bounds)?;
166 self.weights = vec![w];
167 }
168 "efficient_frontier" => {
169 let w = solve_min_vol(&self.cov_matrix, &bounds)?;
170 let points = 100;
171 self.weights = vec![w; points];
172 self.efficient_frontier_means = Vec::with_capacity(points);
173 self.efficient_frontier_sigma = Vec::with_capacity(points);
174 for weights in self.weights.iter() {
175 let mean = dot(weights, self.expected_returns.column(0).as_slice());
176 let sigma = quad_risk(&self.cov_matrix, weights).sqrt();
177 self.efficient_frontier_means.push(mean);
178 self.efficient_frontier_sigma.push(sigma);
179 }
180 }

Callers

nothing calls this directly

Calls 10

lenMethod · 0.80
is_emptyMethod · 0.80
_initialiseMethod · 0.80
clearMethod · 0.80
build_boundsFunction · 0.70
solve_min_volFunction · 0.70
solve_max_sharpeFunction · 0.70
dotFunction · 0.70
quad_riskFunction · 0.70

Tested by

no test coverage detected