{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "719d0221",
   "metadata": {},
   "source": [
    "<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1a07cd6",
   "metadata": {},
   "source": [
    "This code prices a European call option using QuantLib. It sets up market conditions including spot price, volatility, dividend rate, and risk-free rate. The code then calculates the option price and delta using the Black-Scholes-Merton model. It also demonstrates delta hedging by adjusting the stock position in response to changes in the spot price. This is useful for option pricing and risk management in financial markets."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d439df1a",
   "metadata": {},
   "outputs": [],
   "source": [
    "import QuantLib as ql"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6cd4da78",
   "metadata": {},
   "source": [
    "Set the evaluation date for the pricing model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "25131917",
   "metadata": {},
   "outputs": [],
   "source": [
    "today = ql.Date(15, 1, 2023)\n",
    "ql.Settings.instance().evaluationDate = today"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bf75bb46",
   "metadata": {},
   "source": [
    "Define the option parameters including expiry date, strike price, and type"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a50af380",
   "metadata": {},
   "outputs": [],
   "source": [
    "expiry = ql.Date(15, 7, 2023)\n",
    "strike_price = 100\n",
    "option_type = ql.Option.Call"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d1ac359b",
   "metadata": {},
   "source": [
    "Create the payoff and exercise objects for the European option"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "783d1bff",
   "metadata": {},
   "outputs": [],
   "source": [
    "payoff = ql.PlainVanillaPayoff(option_type, strike_price)\n",
    "exercise = ql.EuropeanExercise(expiry)\n",
    "european_option = ql.VanillaOption(payoff, exercise)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "61ee097c",
   "metadata": {},
   "source": [
    "Define market parameters including spot price, volatility, dividend rate, and risk-free rate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "db0a54a6",
   "metadata": {},
   "outputs": [],
   "source": [
    "spot_price = 100\n",
    "volatility = 0.2  # 20%\n",
    "dividend_rate = 0.01  # 1%\n",
    "risk_free_rate = 0.05  # 5%"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "436e4502",
   "metadata": {},
   "source": [
    "Create handles for market conditions such as spot price, volatility, dividend yield, and risk-free rate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "e283fafc",
   "metadata": {},
   "outputs": [],
   "source": [
    "spot_handle = ql.QuoteHandle(ql.SimpleQuote(spot_price))\n",
    "volatility_handle = ql.BlackVolTermStructureHandle(\n",
    "    ql.BlackConstantVol(today, ql.NullCalendar(), ql.QuoteHandle(ql.SimpleQuote(volatility)), ql.Actual365Fixed())\n",
    ")\n",
    "dividend_handle = ql.YieldTermStructureHandle(\n",
    "    ql.FlatForward(today, ql.QuoteHandle(ql.SimpleQuote(dividend_rate)), ql.Actual365Fixed())\n",
    ")\n",
    "risk_free_handle = ql.YieldTermStructureHandle(\n",
    "    ql.FlatForward(today, ql.QuoteHandle(ql.SimpleQuote(risk_free_rate)), ql.Actual365Fixed())\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "8604c96c",
   "metadata": {},
   "source": [
    "Create the Black-Scholes-Merton process using the defined market conditions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "a4d0ca38",
   "metadata": {},
   "outputs": [],
   "source": [
    "bsm_process = ql.BlackScholesMertonProcess(spot_handle, dividend_handle, risk_free_handle, volatility_handle)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f4d1e624",
   "metadata": {},
   "source": [
    "Price the option using the analytic European engine and calculate its Net Present Value (NPV)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f619b803",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Option Price: 6.56\n"
     ]
    }
   ],
   "source": [
    "european_option.setPricingEngine(ql.AnalyticEuropeanEngine(bsm_process))\n",
    "option_price = european_option.NPV()\n",
    "print(f\"Option Price: {option_price:.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c61ab297",
   "metadata": {},
   "source": [
    "Calculate the option delta, which measures sensitivity to changes in the spot price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "0b38ea69",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Option Delta: 0.58\n"
     ]
    }
   ],
   "source": [
    "delta = european_option.delta()\n",
    "print(f\"Option Delta: {delta:.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7a406a89",
   "metadata": {},
   "source": [
    "Compute the initial stock position required for delta hedging"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "ce3c6064",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Initial Stock Position: 58.08\n"
     ]
    }
   ],
   "source": [
    "stock_position = delta * spot_price\n",
    "print(f\"Initial Stock Position: {stock_position:.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d5db52f",
   "metadata": {},
   "source": [
    "Simulate a change in the spot price and update the spot handle"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "ff0ec270",
   "metadata": {},
   "outputs": [],
   "source": [
    "new_spot_price = 105\n",
    "spot_handle = ql.QuoteHandle(ql.SimpleQuote(new_spot_price))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2ef23741",
   "metadata": {},
   "source": [
    "Recalculate the option price and delta with the new spot price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "5ab13208",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "New Option Price: 6.56\n",
      "New Option Delta: 0.58\n"
     ]
    }
   ],
   "source": [
    "new_option_price = european_option.NPV()\n",
    "new_delta = european_option.delta()\n",
    "print(f\"New Option Price: {new_option_price:.2f}\")\n",
    "print(f\"New Option Delta: {new_delta:.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "f15a5f31",
   "metadata": {},
   "source": [
    "Adjust the stock position for delta hedging based on the new delta"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "976bac17",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Adjustment in Stock Position: 2.90\n"
     ]
    }
   ],
   "source": [
    "new_stock_position = new_delta * new_spot_price\n",
    "hedge_adjustment = new_stock_position - stock_position\n",
    "print(f\"Adjustment in Stock Position: {hedge_adjustment:.2f}\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "19006af5",
   "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."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "357aedc8-fef7-42d9-a5ac-0f973488a6ec",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "jupytext": {
   "cell_metadata_filter": "-all",
   "main_language": "python",
   "notebook_metadata_filter": "-all"
  },
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
