portfolio_risk
Calculate annualized portfolio volatility to assess investment risk using Monte Carlo simulations for quantitative finance analysis.
Instructions
Returns annualized volatility of the portfolio.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- tools/risk_engine.py:32-43 (handler)The core handler function for the 'portfolio_risk' tool. Computes portfolio returns from current positions, calculates covariance matrix, and derives annualized volatility.def portfolio_risk() -> str: """Returns annualized volatility of the portfolio.""" data, weights = _get_portfolio_data() if data is None: return "Portfolio is empty." returns = data.pct_change().dropna() cov_matrix = returns.cov() * 252 port_variance = np.dot(weights.T, np.dot(cov_matrix, weights)) port_volatility = np.sqrt(port_variance) return f"Annualized Portfolio Volatility: {port_volatility:.2%}"
- server.py:380-383 (registration)MCP tool registration block where portfolio_risk is registered via the register_tools helper function, which applies @mcp.tool() decorator.register_tools( [portfolio_risk, var, max_drawdown, monte_carlo_simulation], "Risk Engine" )
- tools/risk_engine.py:10-30 (helper)Supporting helper function that retrieves portfolio positions, fetches historical price data, and computes value-based weights for risk calculations.def _get_portfolio_data(lookback: str = "1y"): portfolio = get_positions() positions = portfolio.get("positions", {}) if not positions: return None, None tickers = list(positions.keys()) weights = np.array(list(positions.values())) # This is qty, need value weights # Fetch data data = yf.download(tickers, period=lookback, progress=False)['Close'] if isinstance(data, pd.Series): data = data.to_frame(name=tickers[0]) # Calculate current value weights current_prices = data.iloc[-1] values = current_prices * pd.Series(positions) total_value = values.sum() weights = values / total_value return data, weights