max_drawdown
Calculate maximum drawdown to assess portfolio risk by identifying the largest peak-to-trough decline in investment value.
Instructions
Calculates Maximum Drawdown.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Implementation Reference
- tools/risk_engine.py:62-75 (handler)The core handler function implementing the max_drawdown tool. It retrieves portfolio data, computes daily returns weighted by position values, calculates cumulative returns, identifies the peak-to-trough maximum drawdown, and returns it as a formatted string.def max_drawdown() -> str: """Calculates Maximum Drawdown.""" data, weights = _get_portfolio_data() if data is None: return "Portfolio is empty." returns = data.pct_change().dropna() port_returns = returns.dot(weights) cumulative_returns = (1 + port_returns).cumprod() peak = cumulative_returns.expanding(min_periods=1).max() drawdown = (cumulative_returns / peak) - 1 max_dd = drawdown.min() return f"Maximum Drawdown: {max_dd:.2%}"
- server.py:380-383 (registration)The registration block where max_drawdown is included in the list of risk engine tools passed to register_tools, which applies the @mcp.tool() decorator to make it available in the MCP server.register_tools( [portfolio_risk, var, max_drawdown, monte_carlo_simulation], "Risk Engine" )
- tools/risk_engine.py:10-30 (helper)Supporting helper function that fetches current portfolio positions, downloads historical price data using yfinance, and computes value-based weights for the portfolio. Called by max_drawdown.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
- server.py:14-14 (registration)Import statement bringing the max_drawdown function into the MCP server module for subsequent registration.from tools.risk_engine import portfolio_risk, var, max_drawdown, monte_carlo_simulation