fundedness 0.2.2__py3-none-any.whl → 0.2.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of fundedness might be problematic. Click here for more details.

@@ -139,22 +139,22 @@ class MarketModel(BaseModel):
139
139
 
140
140
  def expected_portfolio_return(
141
141
  self,
142
- stock_weight: float,
143
- bond_weight: Optional[float] = None,
144
- ) -> float:
142
+ stock_weight: float | np.ndarray,
143
+ bond_weight: float | np.ndarray | None = None,
144
+ ) -> float | np.ndarray:
145
145
  """Calculate expected return for a portfolio.
146
146
 
147
147
  Args:
148
- stock_weight: Weight in stocks (0-1)
148
+ stock_weight: Weight in stocks (0-1), scalar or array
149
149
  bond_weight: Weight in bonds (remainder is cash if not specified)
150
150
 
151
151
  Returns:
152
- Expected annual real return
152
+ Expected annual real return (scalar or array matching input)
153
153
  """
154
154
  if bond_weight is None:
155
155
  bond_weight = 1 - stock_weight
156
156
 
157
- cash_weight = max(0, 1 - stock_weight - bond_weight)
157
+ cash_weight = np.maximum(0, 1 - stock_weight - bond_weight)
158
158
 
159
159
  return (
160
160
  stock_weight * self.stock_return
@@ -164,25 +164,36 @@ class MarketModel(BaseModel):
164
164
 
165
165
  def portfolio_volatility(
166
166
  self,
167
- stock_weight: float,
168
- bond_weight: Optional[float] = None,
169
- ) -> float:
167
+ stock_weight: float | np.ndarray,
168
+ bond_weight: float | np.ndarray | None = None,
169
+ ) -> float | np.ndarray:
170
170
  """Calculate portfolio volatility.
171
171
 
172
172
  Args:
173
- stock_weight: Weight in stocks (0-1)
173
+ stock_weight: Weight in stocks (0-1), scalar or array
174
174
  bond_weight: Weight in bonds (remainder is cash if not specified)
175
175
 
176
176
  Returns:
177
- Annual portfolio volatility
177
+ Annual portfolio volatility (scalar or array matching input)
178
178
  """
179
179
  if bond_weight is None:
180
180
  bond_weight = 1 - stock_weight
181
181
 
182
- cash_weight = max(0, 1 - stock_weight - bond_weight)
183
- weights = np.array([stock_weight, bond_weight, cash_weight, 0])
182
+ cash_weight = np.maximum(0, 1 - stock_weight - bond_weight)
184
183
 
185
184
  cov = self.get_covariance_matrix()
186
- portfolio_variance = weights @ cov @ weights
187
185
 
188
- return np.sqrt(portfolio_variance)
186
+ # Handle both scalar and array inputs
187
+ if isinstance(stock_weight, np.ndarray):
188
+ # Vectorized computation for array inputs
189
+ # weights shape: (n_samples, 4)
190
+ weights = np.column_stack([stock_weight, bond_weight, cash_weight, np.zeros_like(stock_weight)])
191
+ # cov @ weights.T has shape (4, n_samples)
192
+ # We want sum of weights[i] * (cov @ weights[i]) for each i
193
+ # This is equivalent to diag(weights @ cov @ weights.T)
194
+ portfolio_variance = np.einsum('ij,jk,ik->i', weights, cov, weights)
195
+ return np.sqrt(portfolio_variance)
196
+ else:
197
+ weights = np.array([stock_weight, bond_weight, cash_weight, 0])
198
+ portfolio_variance = weights @ cov @ weights
199
+ return np.sqrt(portfolio_variance)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fundedness
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: A Python financial planning toolkit with CEFR calculations, Monte Carlo simulations, and beautiful visualizations
5
5
  Project-URL: Homepage, https://github.com/engineerinvestor/financial-health-calculator
6
6
  Project-URL: Documentation, https://engineerinvestor.github.io/financial-health-calculator/
@@ -57,6 +57,7 @@ Description-Content-Type: text/markdown
57
57
  [![PyPI version](https://img.shields.io/pypi/v/fundedness.svg)](https://pypi.org/project/fundedness/)
58
58
  [![Python versions](https://img.shields.io/pypi/pyversions/fundedness.svg)](https://pypi.org/project/fundedness/)
59
59
  [![Documentation](https://img.shields.io/badge/docs-mkdocs-blue.svg)](https://engineerinvestor.github.io/financial-health-calculator/)
60
+ [![Streamlit App](https://static.streamlit.io/badges/streamlit_badge_black_white.svg)](https://financial-health-calculator.streamlit.app/)
60
61
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
61
62
  [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/engineerinvestor/financial-health-calculator/blob/main/examples/01_cefr_basics.ipynb)
62
63
 
@@ -16,7 +16,7 @@ fundedness/models/__init__.py,sha256=EyW6tGUI9T6QMbIfzsG3igqg5--DtZHSTAuMX6foOiA
16
16
  fundedness/models/assets.py,sha256=ZKgxl4YaqdRVfDErL9weRhh4St_azo8ruN4g15T3IsQ,5013
17
17
  fundedness/models/household.py,sha256=t64FjvO0uQJemddLtCPpK3NNYdZCXU6KjA1VZshaqEk,4671
18
18
  fundedness/models/liabilities.py,sha256=iqGl5RU841k1clGOwnFParUvxzCJclq2JzNJoNPywuo,3416
19
- fundedness/models/market.py,sha256=c3jskREsB7m_mjzuBwJ7oo6hlvLmR423t0JT8_a50eg,5551
19
+ fundedness/models/market.py,sha256=JAUt-MM__yM_v-FsgKwJj7rXC0yh6oFUv5JLoob58OE,6388
20
20
  fundedness/models/simulation.py,sha256=0jtIJWISDL-TlKVjr6KxcRfAj5Mrbp-VNyA4Bu7IUfU,2224
21
21
  fundedness/models/tax.py,sha256=0XhoBNZqfRqF1_acakrkYgMS5L6Pknq-TloQQBrFw1U,3859
22
22
  fundedness/models/utility.py,sha256=0AoJdccTb2hKBrTz5LExm8SrSsaWhhBf7y2NNaUzWQ0,4678
@@ -37,7 +37,7 @@ fundedness/withdrawals/guardrails.py,sha256=rZKVojKbl9LLJLi9LlK1I2JXb537MN_AbZfn
37
37
  fundedness/withdrawals/merton_optimal.py,sha256=mSxRAKGx8sr_YdlhQMtIvnojqfuG0MiYtBp18xboLHs,9269
38
38
  fundedness/withdrawals/rmd_style.py,sha256=E5FfrUYxFJwULKxzxbtZFLoLspLzUUomTQRUWLGLDpg,6373
39
39
  fundedness/withdrawals/vpw.py,sha256=aajHLAkHfsxh33uGRgzv0ozVuZREG-EmARJgWOU6mis,4389
40
- fundedness-0.2.2.dist-info/METADATA,sha256=Ed_jtXtLDw3oezja6dsiajlQEcG1UjJodESowZcr0Qk,10878
41
- fundedness-0.2.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
42
- fundedness-0.2.2.dist-info/entry_points.txt,sha256=Oh-Hg08i044YHuSHViCdfoD8CenIGcKrVuUVysvN9sY,51
43
- fundedness-0.2.2.dist-info/RECORD,,
40
+ fundedness-0.2.3.dist-info/METADATA,sha256=Ipd2Dp503muIicXo4VF4zTqpWwuUM_2OTyuAwIbuJ78,11017
41
+ fundedness-0.2.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
42
+ fundedness-0.2.3.dist-info/entry_points.txt,sha256=Oh-Hg08i044YHuSHViCdfoD8CenIGcKrVuUVysvN9sY,51
43
+ fundedness-0.2.3.dist-info/RECORD,,