Files
strategy-lab/to_explore/pyquantnews/56_UpsideCapture.ipynb
David Brazda e3da60c647 daily update
2024-10-21 20:57:56 +02:00

5.7 KiB

No description has been provided for this image

This code fetches historical stock prices for AAPL, WMT, and SPY, calculates daily returns, and constructs a portfolio. It defines functions to compute the annual return and upside capture ratio of the portfolio compared to a benchmark. The upside capture ratio measures the portfolio's performance relative to the benchmark when the benchmark is up. This is useful in practice for portfolio performance analysis and risk management.

In [ ]:
from openbb_terminal.sdk import openbb

Fetch historical stock prices for AAPL, WMT, and SPY starting from 2020-01-01

In [ ]:
prices = openbb.economy.index(
    ["AAPL", "WMT", "SPY"], 
    start_date="2020-01-01"
)

Calculate daily returns by taking the percentage change and dropping any NaN values

In [ ]:
returns = prices.pct_change().dropna()

Construct a portfolio's returns by summing the returns of AAPL and WMT, and selecting SPY and portfolio columns

In [ ]:
data = returns.assign(
    port=returns[["AAPL", "WMT"]].sum(axis=1)
)[["SPY", "port"]]

Compute annualized return for a series of returns

In [ ]:
def annual_return(returns):
    """Compute annualized return.
    
    This function calculates the annualized return of a series of returns.
    
    Parameters
    ----------
    returns : pd.Series
        Series of daily returns.
    
    Returns
    -------
    float
        Annualized return.
    """
    
    # Calculate the number of years by dividing total days by 252 (trading days in a year)
    num_years = len(returns) / 252
    
    # Calculate the annualized return using the geometric average
    return (returns + 1).prod() ** (1 / num_years) - 1

Compute upside capture ratio comparing portfolio returns to benchmark returns

In [ ]:
def upside_capture(port_returns, bench_returns):
    """Compute upside capture ratio.
    
    This function calculates the upside capture ratio of portfolio returns 
    compared to benchmark returns.
    
    Parameters
    ----------
    port_returns : pd.Series
        Series of portfolio returns.
    bench_returns : pd.Series
        Series of benchmark returns.
    
    Returns
    -------
    float
        Upside capture ratio.
    """
    
    # Filter portfolio and benchmark returns where benchmark returns are positive
    mask = bench_returns > 0
    port_returns = port_returns[mask]
    bench_returns = bench_returns[mask]
    
    # Calculate the upside capture ratio by dividing annualized portfolio return by annualized benchmark return
    return (
        annual_return(port_returns) 
        / annual_return(bench_returns)
    )

Calculate the upside capture ratio for the constructed portfolio compared to SPY

In [ ]:
upside_capture(data.port, data.SPY)

PyQuant News is where finance practitioners level up with Python for quant finance, algorithmic trading, and market data analysis. Looking to get started? Check out the fastest growing, top-selling course to get started with Python for quant finance. For educational purposes. Not investment advise. Use at your own risk.