Downside protection - Sortino Ratio

Published: 23 April 2024| Version 1 | DOI: 10.17632/84hmnv4285.1
Sunil Maria Benedict


This code generates sample data for portfolio returns and calculates various risk measures and ratios commonly used in financial analysis. Let's break down each component: Portfolio Returns: Synthetic portfolio returns data is generated using the normal distribution with a mean of 0.08 and a standard deviation of 0.15 for 100 time periods. Risk-Adjusted Returns (Sharpe Ratio): The Sharpe Ratio is calculated as the ratio of the excess return of the portfolio over the risk-free rate to the standard deviation of the portfolio returns. Portfolio Volatility: The standard deviation of the portfolio returns is calculated, representing the volatility of the portfolio. Maximum Drawdown (MDD): The maximum drawdown is computed as the maximum loss from a peak value to a trough value during a specific time period. Downside Protection (Sortino Ratio): The Sortino Ratio is similar to the Sharpe Ratio but focuses on downside risk, using only negative returns in the denominator. Visualization: The results are visualized using matplotlib. Four subplots are created: Portfolio Returns over time Drawdown over time Histogram of Portfolio Returns Cumulative Returns over time Each subplot provides insights into different aspects of the portfolio's performance and risk characteristics. Overall, this code provides a comprehensive analysis of portfolio risk and return metrics, along with visualizations to aid in understanding and interpretation.


Steps to reproduce

import numpy as np import matplotlib.pyplot as plt # Generate sample data for portfolio returns np.random.seed(0) portfolio_returns = np.random.normal(loc=0.08, scale=0.15, size=100) # Risk-Adjusted Returns (Sharpe Ratio) risk_free_rate = 0.03 sharpe_ratio = (np.mean(portfolio_returns) - risk_free_rate) / np.std(portfolio_returns) print("Sharpe Ratio:", sharpe_ratio) # Portfolio Volatility portfolio_volatility = np.std(portfolio_returns) print("Portfolio Volatility:", portfolio_volatility) # Maximum Drawdown (MDD) peak_values = np.maximum.accumulate(np.cumsum(portfolio_returns)) drawdown = peak_values - np.cumsum(portfolio_returns) max_drawdown = np.max(drawdown) print("Maximum Drawdown:", max_drawdown) # Downside Protection (Sortino Ratio) downside_returns = portfolio_returns[portfolio_returns < 0] sortino_ratio = (np.mean(portfolio_returns) - risk_free_rate) / np.std(downside_returns) print("Sortino Ratio:", sortino_ratio) # Visualize the results fig, axs = plt.subplots(2, 2, figsize=(12, 8)) # Plot portfolio returns axs[0, 0].plot(portfolio_returns, color='blue') axs[0, 0].set_title('Portfolio Returns') axs[0, 0].set_xlabel('Time') axs[0, 0].set_ylabel('Returns') # Plot drawdown axs[0, 1].plot(drawdown, color='red') axs[0, 1].set_title('Drawdown') axs[0, 1].set_xlabel('Time') axs[0, 1].set_ylabel('Drawdown') # Plot histogram of portfolio returns axs[1, 0].hist(portfolio_returns, bins=20, color='green', edgecolor='black') axs[1, 0].set_title('Histogram of Portfolio Returns') axs[1, 0].set_xlabel('Returns') axs[1, 0].set_ylabel('Frequency') # Plot cumulative returns cumulative_returns = np.cumsum(portfolio_returns) axs[1, 1].plot(cumulative_returns, color='orange') axs[1, 1].set_title('Cumulative Returns') axs[1, 1].set_xlabel('Time') axs[1, 1].set_ylabel('Cumulative Returns') plt.tight_layout()


United International Business Schools


Risk Management, Visual Analytics, Portfolio Analysis, Modeling of Portfolios, Volatility