{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "79ea368d",
   "metadata": {},
   "source": [
    "<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "58225e34",
   "metadata": {},
   "source": [
    "This code calculates the Omega ratio for financial returns, a performance metric that captures more information about the distribution of returns than traditional metrics like the Sharpe ratio. It uses stock price data from Yahoo Finance to compute daily returns for a specific stock (AAPL). The Omega ratio is calculated by dividing the sum of positive returns above a threshold by the absolute sum of negative returns below that threshold. This metric is useful for assessing the risk and return profile of investments, especially those with non-normal return distributions. The code also visualizes the rolling Omega ratio and basic statistical properties of the returns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "3a954243",
   "metadata": {},
   "outputs": [],
   "source": [
    "import yfinance as yf\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a375f9fa",
   "metadata": {},
   "source": [
    "Download the stock data for AAPL from Yahoo Finance for the specified date range"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "e3430b66",
   "metadata": {},
   "outputs": [],
   "source": [
    "data = yf.download(\"AAPL\", start=\"2020-01-01\", end=\"2021-12-31\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "294330b3",
   "metadata": {},
   "source": [
    "Calculate daily returns from the adjusted closing prices"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4133cec7",
   "metadata": {
    "lines_to_next_cell": 1
   },
   "outputs": [],
   "source": [
    "returns = data[\"Adj Close\"].pct_change()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "68e174db",
   "metadata": {},
   "source": [
    "Calculate the Omega ratio of a strategy's returns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aa288ad4",
   "metadata": {
    "lines_to_next_cell": 1
   },
   "outputs": [],
   "source": [
    "def omega_ratio(returns, required_return=0.0):\n",
    "    \"\"\"Determines the Omega ratio of a strategy.\n",
    "    \n",
    "    Parameters\n",
    "    ----------\n",
    "    returns : pd.Series or np.ndarray\n",
    "        Daily returns of the strategy, noncumulative.\n",
    "    required_return : float, optional\n",
    "        Minimum acceptance return of the investor. Threshold over which to\n",
    "        consider positive vs negative returns. It will be converted to a\n",
    "        value appropriate for the period of the returns. E.g. An annual minimum\n",
    "        acceptable return of 100 will translate to a minimum acceptable\n",
    "        return of 0.018.\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    omega_ratio : float\n",
    "\n",
    "    Note\n",
    "    -----\n",
    "    See https://en.wikipedia.org/wiki/Omega_ratio for more details.\n",
    "    \"\"\"\n",
    "\n",
    "    # Convert the required return to a daily return threshold\n",
    "\n",
    "    return_threshold = (1 + required_return) ** (1 / 252) - 1\n",
    "\n",
    "    # Calculate the difference between returns and the return threshold\n",
    "\n",
    "    returns_less_thresh = returns - return_threshold\n",
    "\n",
    "    # Calculate the numerator as the sum of positive returns above the threshold\n",
    "\n",
    "    numer = sum(returns_less_thresh[returns_less_thresh > 0.0])\n",
    "\n",
    "    # Calculate the denominator as the absolute sum of negative returns below the threshold\n",
    "\n",
    "    denom = -1.0 * sum(returns_less_thresh[returns_less_thresh < 0.0])\n",
    "\n",
    "    # Return the Omega ratio if the denominator is positive; otherwise, return NaN\n",
    "\n",
    "    if denom > 0.0:\n",
    "        return numer / denom\n",
    "    else:\n",
    "        return np.nan"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc63495d",
   "metadata": {},
   "source": [
    "Calculate the Omega ratio for the given returns and required return"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da67b3ba",
   "metadata": {},
   "outputs": [],
   "source": [
    "omega_ratio(returns, 0.07)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9e89e93b",
   "metadata": {},
   "source": [
    "Compute and plot the rolling 30-day Omega ratio of the returns"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ba112f43",
   "metadata": {},
   "outputs": [],
   "source": [
    "returns.rolling(30).apply(omega_ratio).plot()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "33e329c8",
   "metadata": {},
   "source": [
    "Plot a histogram of the daily returns to visualize their distribution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "1bad9e37",
   "metadata": {},
   "outputs": [],
   "source": [
    "returns.hist(bins=50)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cc2176f5",
   "metadata": {},
   "source": [
    "Calculate and display the skewness of the returns distribution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "85b6eba5",
   "metadata": {},
   "outputs": [],
   "source": [
    "returns.skew()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2cd3f659",
   "metadata": {},
   "source": [
    "Calculate and display the kurtosis of the returns distribution"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "025b51fc",
   "metadata": {},
   "outputs": [],
   "source": [
    "returns.kurtosis()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9f4bae70",
   "metadata": {},
   "source": [
    "<a href=\"https://pyquantnews.com/\">PyQuant News</a> 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 <a href=\"https://gettingstartedwithpythonforquantfinance.com/\">get started with Python for quant finance</a>. For educational purposes. Not investment advise. Use at your own risk."
   ]
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
