{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "fa749e17",
   "metadata": {},
   "source": [
    "<div style=\"background-color:#000;\"><img src=\"pqn.png\"></img></div>"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "58737b4a",
   "metadata": {},
   "source": [
    "This code simulates stock returns using Geometric Brownian Motion (GBM) and calculates the premium for a barrier option. It defines a function to simulate GBM paths based on initial stock price, drift, volatility, and other parameters. The code then generates multiple simulated price paths, checks if the maximum value of each path exceeds a barrier, and calculates the option payoff accordingly. Lastly, it discounts the payoffs to present value and computes the average premium. This is useful for pricing exotic financial derivatives and analyzing risk."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ecc8c484",
   "metadata": {
    "lines_to_next_cell": 1
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "748351bc",
   "metadata": {
    "lines_to_next_cell": 1
   },
   "outputs": [],
   "source": [
    "def simulate_gbm(s_0, mu, sigma, T, N, n_sims=10**3, random_seed=42):\n",
    "    \"\"\"\n",
    "    Function used for simulating stock returns using Geometric Brownian Motion.\n",
    "\n",
    "    Parameters\n",
    "    ------------\n",
    "    s_0 : float\n",
    "        Initial stock price\n",
    "    mu : float\n",
    "        Drift coefficient\n",
    "    sigma : float\n",
    "        Diffusion coefficient\n",
    "    T : float\n",
    "        Length of the forecast horizon, same unit as dt\n",
    "    N : int\n",
    "        Number of time increments in the forecast horizon\n",
    "    n_sims : int\n",
    "        Number of simulation paths\n",
    "    random_seed : int\n",
    "        Random seed for reproducibility\n",
    "\n",
    "    Returns\n",
    "    -----------\n",
    "    S_t : np.ndarray\n",
    "        Matrix (size: n_sims x (T+1)) containing the simulation results.\n",
    "        Rows represent sample paths, while columns point of time.\n",
    "    \"\"\"\n",
    "\n",
    "    # Set random seed for reproducibility\n",
    "    np.random.seed(random_seed)\n",
    "\n",
    "    # Calculate time increment\n",
    "    dt = T / N\n",
    "\n",
    "    # Generate normally distributed random values for the Wiener process\n",
    "    dW = np.random.normal(scale=np.sqrt(dt), size=(n_sims, N + 1))\n",
    "\n",
    "    # Simulate the evolution of the process using GBM formula\n",
    "    S_t = s_0 * np.exp(np.cumsum((mu - 0.5 * sigma**2) * dt + sigma * dW, axis=1))\n",
    "    S_t[:, 0] = s_0\n",
    "\n",
    "    return S_t"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "e67fab55",
   "metadata": {},
   "source": [
    "Define initial stock price, drift, volatility, time horizon, and number of increments"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "96268bc8",
   "metadata": {},
   "outputs": [],
   "source": [
    "S_0 = 55\n",
    "r = 0.06\n",
    "sigma = 0.2\n",
    "T = 1\n",
    "N = 252"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "be23773e",
   "metadata": {},
   "source": [
    "Define barrier level and strike price for the option"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "30090621",
   "metadata": {},
   "outputs": [],
   "source": [
    "BARRIER = 65\n",
    "K = 60"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "126163f8",
   "metadata": {},
   "source": [
    "Generate GBM simulations for the given parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "227001bf",
   "metadata": {},
   "outputs": [],
   "source": [
    "gbm_sims = simulate_gbm(s_0=S_0, mu=r, sigma=sigma, T=T, N=N)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "6c5abfb3",
   "metadata": {},
   "source": [
    "Plot the simulated price paths and the barrier level"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b718dafd",
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.axhline(y=BARRIER, color='r', linestyle='-')\n",
    "plt.xlim(0, N)\n",
    "plt.plot(gbm_sims.T, linewidth=0.25)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "58aed041",
   "metadata": {},
   "source": [
    "Calculate the maximum value per path to determine if the barrier was breached"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "7fc85776",
   "metadata": {},
   "outputs": [],
   "source": [
    "max_value_per_path = np.max(gbm_sims, axis=1)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "589b129d",
   "metadata": {},
   "source": [
    "Calculate the payoff of the barrier option based on the barrier breach condition"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "685b4103",
   "metadata": {},
   "outputs": [],
   "source": [
    "payoff = np.where(\n",
    "    max_value_per_path > BARRIER, \n",
    "    np.maximum(0, gbm_sims[:, -1] - K), \n",
    "    0\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "74527d4a",
   "metadata": {},
   "source": [
    "Calculate the discount factor and the average premium for the option"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "0c654f62",
   "metadata": {},
   "outputs": [],
   "source": [
    "discount_factor = np.exp(-r * T)\n",
    "premium = discount_factor * np.mean(payoff)\n",
    "premium"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "51efd6b6",
   "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
}
