{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import os, sys\n", "import numpy as np\n", "import pandas as pd\n", "import datetime as dt\n", "\n", "from IPython.display import display\n", "from math import log, exp, sqrt, pow, erf, pi\n", "from scipy.stats import norm\n", "\n", "import ezvis3d as v3d" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## BlackScholes functions\n", "\n", "The outputs below are computed from the following inputs\n", "\n", "+ Inputs\n", "\n", "| Input | Symbol | Variable |\n", "|:---|:---:|:---:|\n", "| Spot in currency | $$S$$ | S |\n", "| Strike in the same unit as Spot | $$K$$ | K |\n", "| Maturity in years | $$T$$ | T |\n", "| Volatility in % e.g. 15%=0.15 | $$\\sigma$$ | v |\n", "| Risk free interest rate in % e.g. 1.5%=0.015 | $$r$$ | r |\n", "| Continuous dividend rate in % e.g. 2%=0.02 | $$q$$ | q |\n", " \n", "+ Outputs\n", "\n", "\n", "| **Option** | **Call** | **Put** |\n", "| :--------: |:--------:|:-------:|\n", "| $$Payoff$$ | $$Max(0, S-K)$$ | $$Max(0, K-S)$$ |\n", "| $$Value=V$$ | $$Se^{-qT}N(d_1)-Ke^{-rT}N(d_2)$$ | $$Ke^{-rT}N(-d_2)-Se^{-qT}N(-d_1)$$ |\n", "| $$\\Delta=\\frac{\\partial V}{\\partial S}$$ | $$e^{-qT}N(d_1)$$ | $$-e^{-qT}N(-d_1)$$ |\n", "| $$\\Gamma=\\frac{\\partial \\Delta}{\\partial S}$$ | $$e^{-qT}\\frac{N'(d_1)}{S\\sigma\\sqrt{T}}$$ | $$e^{-qT}\\frac{N'(d_1)}{S\\sigma\\sqrt{T}}$$ |\n", "| $$\\nu=\\frac{\\partial V}{\\partial \\sigma}$$ | $$Se^{-qT}N'(d_1)\\sqrt{T}=Ke^{-rT}N'(d_2)\\sqrt{T}$$ | $$Se^{-qT}N'(d_1)\\sqrt{T}=Ke^{-rT}N'(d_2)\\sqrt{T}$$ |\n", "| $$\\Theta=-\\frac{\\partial V}{\\partial T}$$ | $$-e^{qT}\\frac{SN'(d_1)\\sigma}{2\\sqrt{T}}-rKe^{-rT}N(d_2)+qSe^{-qT}N(d_1)$$ | $$-e^{qT}\\frac{SN'(d_1)\\sigma}{2\\sqrt{T}}+rKe^{-rT}N(-d_2)-qSe^{-qT}N(-d_1)$$ |\n", "| $$\\rho=\\frac{\\partial V}{\\partial r}$$ | $$KTe^{-rT}N(d_2)$$ | $$-KTe^{-rT}N(-d_2)$$ |\n", "| $$Voma=\\frac{\\partial\\nu}{\\partial \\sigma}$$ | $$Se^{-qT}N'(d_1)\\sqrt{T}\\frac{d_1 d_2}{\\sigma}$$ | $$Se^{-qT}N'(d_1)\\sqrt{T}\\frac{d_1 d_2}{\\sigma}$$ |\n", "\n", "+ with\n", "\n", "$$\\frac{\\partial V}{\\partial t} + rS\\frac{\\partial V}{\\partial S} + \\frac{1}{2}\\sigma^2S^2\\frac{\\partial^2 V}{\\partial S^2}=rV$$\n", "\n", "$$d_1=\\frac{\\log(S/K) + (r-q +\\sigma^2/2)T}{\\sigma \\sqrt{T}}$$\n", "\n", "$$d_2=\\frac{\\log(S/K) + (r-q -\\sigma^2/2)T}{\\sigma \\sqrt{T}}=d_1 - \\sigma \\sqrt{T - t}$$\n", "\n", "$$N(x)=\\frac{1}{\\sqrt{2\\pi}}\\int_{-\\infty}^{x} e^{-\\frac{t^{2}}{2}}dt$$\n", "\n", "$$N'(x)=\\frac{1}{\\sqrt{2\\pi}}e^{-\\frac{x^{2}}{2}}$$" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": true }, "outputs": [], "source": [ "def N(x):\n", " return (1.0 + erf(x / sqrt(2.0))) / 2.0\n", "\n", "def Nprime(x):\n", " return exp(-x*x / 2.0) / sqrt(2.0 * pi)\n", "\n", "# BlackScholes formula and Greeks - Call option\n", "def BS_Greeks_Call(S, K, T, v, r, q):\n", " sqrt_T = sqrt(T)\n", " d1 = (log(S/K) + (r -q + v**2) * T) / (v *sqrt_T)\n", " d2 = d1 - v * sqrt_T\n", " N_d1 = N(d1)\n", " N_prime_d1 = Nprime(d1)\n", " N_d2 = N(d2)\n", " N_prime_d2 = Nprime(d2)\n", " PV = exp(-r * T)\n", " PV_K = K * PV\n", " D = exp(-q * T)\n", " value = N_d1 * S * D - N_d2 * PV_K\n", " \n", " delta = D * N_d1\n", " gamma = D * N_prime_d1 / (S * v * sqrt_T)\n", " vega = S *D * N_prime_d1 * sqrt_T\n", " theta = -D * S * N_prime_d1 * v / (2 * sqrt_T) - r * PV_K * N_d2 + q * S * D * N_d1\n", " rho = PV_K * T * N_d2\n", " voma = S * D * N_prime_d1 * sqrt_T * d1 * d2 / v\n", "\n", " payoff = max(0, S - K)\n", " PV_payoff = PV * payoff\n", " \n", " return {'d1': d1,\n", " 'd2': d2,\n", " 'N_d1_call': N_d1,\n", " 'N_d2_call': N_d2,\n", " 'N_prime_d1': N_prime_d1,\n", " 'N_prime_d2': N_prime_d2,\n", " 'PV': PV,\n", " 'PV_K': PV_K,\n", " 'D': D,\n", " 'value': value,\n", " 'delta': delta,\n", " 'gamma': gamma,\n", " 'vega': vega,\n", " 'theta': theta,\n", " 'rho': rho,\n", " 'voma': voma,\n", " 'payoff': payoff,\n", " 'PV_payoff': PV_payoff}\n", "\n", "# S = 100.0\n", "# K = 100.0\n", "# T = 5.0\n", "# vol = 0.25\n", "# r = 0.02\n", "# q = 0.03\n", "# typ = +1\n", "# BS_Greeks_Call(S, K, T, vol, r, q)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# BlackScholes formula and Greeks - Put option\n", "def BS_Greeks_Put(S, K, T, v, r, q):\n", " sqrt_T = sqrt(T)\n", " d1 = (1 / (v *sqrt_T)) * (log(S/K) + (r -q + v*v) * T)\n", " d2 = d1 - v * sqrt_T\n", " N_minus_d1 = N(-d1)\n", " N_prime_d1 = Nprime(d1)\n", " N_minus_d2 = N(-d2)\n", " N_prime_d2 = Nprime(d2)\n", " PV = exp(-r * T)\n", " PV_K = K * PV\n", " D = exp(-q * T)\n", " value = N_minus_d2 * PV_K - N_minus_d1 * S * D\n", " \n", " delta = - D * N_minus_d1\n", " gamma = D * N_prime_d1 / (S * v * sqrt_T)\n", " vega = S * D * N_prime_d1 * sqrt_T\n", " theta = -D * S * N_prime_d1 * v / (2 * sqrt_T) + r * PV_K * N_minus_d2 - q * S * D * N_minus_d1\n", " rho = - PV_K * T * N_minus_d2\n", " voma = S * D * N_prime_d1 * sqrt_T * d1 *d2 / v\n", "\n", " payoff = max(0, K - S)\n", " PV_payoff = PV * payoff\n", "\n", " return {'d1': d1,\n", " 'd2': d2,\n", " 'N_d1_put': N_minus_d1,\n", " 'N_d2_put': N_minus_d2,\n", " 'N_prime_d1': N_prime_d1,\n", " 'N_prime_d2': N_prime_d2,\n", " 'PV': PV,\n", " 'PV_K': PV_K,\n", " 'D': D,\n", " 'value': value,\n", " 'delta': delta,\n", " 'gamma': gamma,\n", " 'vega': vega,\n", " 'theta': theta,\n", " 'rho': rho,\n", " 'voma': voma,\n", " 'payoff': payoff,\n", " 'PV_payoff': PV_payoff}\n", "\n", "\n", "\n", "# S = 100.0\n", "# K = 100.0\n", "# T = 5.0\n", "# vol = 0.25\n", "# r = 0.02\n", "# q = 0.03\n", "# typ = +1\n", "# BS_Greeks_Put(S, K, T, vol, r, q)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plotting\n", "+ Compute one output (z) as a function of 2 variables (x, y) among S, K, T, v, r, q while the others are kept fixed\n", "+ The output must be a key in the dictionary returned by functions `BS_Greeks_Put()` or `BS_Greeks_Call()`\n", "+ Pass argument `save=True` to function `plot()` as standalone HTML doc under ./saved" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# S=Spot, K=Strike, T=mat, v=vol, r=rate, q=div rate\n", "S = 100 \n", "K = 100\n", "T = 3\n", "v = 15 / 100.0\n", "r = 2 / 100.0\n", "q = 1 / 100.0\n", "\n", "x_var = 'Spot' # --------------------- choose x axis name\n", "y_var = 'Maturity' # ----------------- choose y axis name\n", "z = 'value' # ------------------------ choose z axis\n", "\n", "def func(x, y):\n", " S_loc, K_loc, T_loc, v_loc, r_loc, q_loc = S, K, T, v, r, q\n", " S_loc = x #-------------- choose x axis\n", " T_loc = y #-------------- choose y axis\n", " res = BS_Greeks_Call(S_loc, K_loc, T_loc, v_loc, r_loc, q_loc)\n", " return res[z]\n", "\n", "x_min, x_max, x_num = 0.05, 200, 50 # ---------------- choose x axis boundaries\n", "y_min, y_max, y_num = 0.05, 10, 50 # ----------------- choose y axis boundaries\n", "\n", "x_rng = np.linspace(x_min, x_max, x_num)\n", "y_rng = np.linspace(y_min, y_max, y_num)\n", "li_data = [{'x': x, 'y': y, 'z': func(x, y)}\n", " for y in y_rng\n", " for x in x_rng]\n", "df_data = pd.DataFrame(li_data)\n", "\n", "g = v3d.Vis3d()\n", "g.width = '700px'\n", "g.height = '700px'\n", "g.style = 'surface'\n", "g.showPerspective = True\n", "g.showGrid = True\n", "g.showShadow = False\n", "g.keepAspectRatio = False\n", "g.verticalRatio = 0.8\n", "g.xLabel = x_var\n", "g.yLabel = y_var\n", "g.zLabel = z\n", "g.cameraPosition = {'horizontal' : 0.9,\n", " 'vertical': 0.5,\n", " 'distance': 1.8}\n", "\n", "g.plot(df_data, center=True, save=False)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "d1 as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "d2 as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "N_d1_call as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "N_d2_call as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "PV_K as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "value as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "delta as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "gamma as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "vega as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "theta as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "rho as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "voma as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "payoff as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" }, { "name": "stdout", "output_type": "stream", "text": [ "PV_payoff as a function of Spot and Maturity\n" ] }, { "data": { "text/html": [ "\n", "
\n", " " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# S=Spot, K=Strike, T=mat, v=vol, r=rate, q=div rate\n", "S = 100 \n", "K = 100\n", "T = 3\n", "v = 15 / 100.0\n", "r = 2 / 100.0\n", "q = 1 / 100.0\n", "\n", "x_var = 'Spot' # --------------------- choose x axis name\n", "y_var = 'Maturity' # ----------------- choose y axis name\n", "\n", "def func(x, y):\n", " S_loc, K_loc, T_loc, v_loc, r_loc, q_loc = S, K, T, v, r, q\n", " S_loc = x #-------------- choose x axis\n", " T_loc = y #-------------- choose y axis\n", " res = BS_Greeks_Call(S_loc, K_loc, T_loc, v_loc, r_loc, q_loc)\n", " return res\n", "\n", "x_min, x_max, x_num = 0.05, 200, 50 # ----------------- choose x axis boundaries\n", "y_min, y_max, y_num = 0.05, 10, 50 # ----------------- choose y axis boundaries\n", "\n", "x_rng = np.linspace(x_min, x_max, x_num)\n", "y_rng = np.linspace(y_min, y_max, y_num)\n", "li_data = [{'x': x, 'y': y, 'z': func(x, y)}\n", " for y in y_rng\n", " for x in x_rng]\n", "\n", "for z in ['d1', 'd2', 'N_d1_call', 'N_d2_call', 'PV_K', 'value', 'delta',\n", " 'gamma', 'vega', 'theta', 'rho', 'voma', 'payoff', 'PV_payoff']:\n", " li_data_z = [{'x': e['x'], 'y': e['y'], 'z': e['z'][z]} for e in li_data]\n", " df_data = pd.DataFrame(li_data_z)\n", "\n", " g = v3d.Vis3d()\n", " g.width = '400px'\n", " g.height = '400px'\n", " g.style = 'surface'\n", " g.showPerspective = True\n", " g.showGrid = True\n", " g.showShadow = False\n", " g.keepAspectRatio = False\n", " g.verticalRatio = 0.8\n", " g.xLabel = x_var\n", " g.yLabel = y_var\n", " g.zLabel = z\n", " g.cameraPosition = {'horizontal' : 0.9,\n", " 'vertical': 0.4,\n", " 'distance': 1.8}\n", "\n", " print('{} as a function of {} and {}'.format(z, x_var, y_var))\n", " display(g.plot(df_data, center=True, save=False))\n", " " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Annex: Create Markdown" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "| **Option** | **Call** | **Put** |\n", "| :--------: |:--------:|:-------:|\n", "| $$Payoff$$ | $$Max(0, S-K)$$ | $$Max(0, K-S)$$ |\n", "| $$Value=V$$ | $$Se^{-qT}N(d_1)-Ke^{-rT}N(d_2)$$ | $$Ke^{-rT}N(-d_2)-Se^{-qT}N(-d_1)$$ |\n", "| $$\\Delta=\\frac{\\partial V}{\\partial S}$$ | $$e^{-qT}N(d_1)$$ | $$-e^{-qT}N(-d_1)$$ |\n", "| $$\\Gamma=\\frac{\\partial \\Delta}{\\partial S}$$ | $$e^{-qT}\\frac{N'(d_1)}{S\\sigma\\sqrt{T}}$$ | $$e^{-qT}\\frac{N'(d_1)}{S\\sigma\\sqrt{T}}$$ |\n", "| $$\\nu=\\frac{\\partial V}{\\partial \\sigma}$$ | $$Se^{-qT}N'(d_1)\\sqrt{T}=Ke^{-rT}N'(d_2)\\sqrt{T}$$ | $$Se^{-qT}N'(d_1)\\sqrt{T}=Ke^{-rT}N'(d_2)\\sqrt{T}$$ |\n", "| $$\\Theta=-\\frac{\\partial V}{\\partial T}$$ | $$-e^{qT}\\frac{SN'(d_1)\\sigma}{2\\sqrt{T}}-rKe^{-rT}N(d_2)+qSe^{-qT}N(d_1)$$ | $$-e^{qT}\\frac{SN'(d_1)\\sigma}{2\\sqrt{T}}+rKe^{-rT}N(-d_2)-qSe^{-qT}N(-d_1)$$ |\n", "| $$\\rho=\\frac{\\partial V}{\\partial r}$$ | $$KTe^{-rT}N(d_2)$$ | $$-KTe^{-rT}N(-d_2)$$ |\n", "| $$Voma=\\frac{\\partial\\nu}{\\partial \\sigma}$$ | $$Se^{-qT}N'(d_1)\\sqrt{T}\\frac{d_1 d_2}{\\sigma}$$ | $$Se^{-qT}N'(d_1)\\sqrt{T}\\frac{d_1 d_2}{\\sigma}$$ |\n", "\n" ] } ], "source": [ "from jinja2 import Environment\n", "\n", "ref_template_1 = \"\"\"\n", "| **Option** | **Call** | **Put** |\n", "| :--------: |:--------:|:-------:|\n", "{% for x in output_data %}| $${{x[0]}}$$ | $${{x[1]}}$$ | $${{x[2]}}$$ |\n", "{% endfor %}\n", "\"\"\"\n", "\n", "ref_data_1 = [\n", "\t[r'Payoff', r'Max(0, S-K)', r'Max(0, K-S)'],\n", "\t[r\"Value=V\", r\"Se^{-qT}N(d_1)-Ke^{-rT}N(d_2)\", r'Ke^{-rT}N(-d_2)-Se^{-qT}N(-d_1)'],\n", "\t[r\"\\Delta=\\frac{\\partial V}{\\partial S}\", r\"e^{-qT}N(d_1)\", r'-e^{-qT}N(-d_1)'],\n", "\t[r\"\\Gamma=\\frac{\\partial \\Delta}{\\partial S}\", r\"e^{-qT}\\frac{N'(d_1)}{S\\sigma\\sqrt{T}}\", r\"e^{-qT}\\frac{N'(d_1)}{S\\sigma\\sqrt{T}}\"],\n", "\t[r\"\\nu=\\frac{\\partial V}{\\partial \\sigma}\", r\"Se^{-qT}N'(d_1)\\sqrt{T}=Ke^{-rT}N'(d_2)\\sqrt{T}\", r\"Se^{-qT}N'(d_1)\\sqrt{T}=Ke^{-rT}N'(d_2)\\sqrt{T}\"],\n", "\t[r\"\\Theta=-\\frac{\\partial V}{\\partial T}\", r\"-e^{qT}\\frac{SN'(d_1)\\sigma}{2\\sqrt{T}}-rKe^{-rT}N(d_2)+qSe^{-qT}N(d_1)\", r\"-e^{qT}\\frac{SN'(d_1)\\sigma}{2\\sqrt{T}}+rKe^{-rT}N(-d_2)-qSe^{-qT}N(-d_1)\"],\n", "\t[r\"\\rho=\\frac{\\partial V}{\\partial r}\", r\"KTe^{-rT}N(d_2)\", r\"-KTe^{-rT}N(-d_2)\"],\n", "\t[r\"Voma=\\frac{\\partial\\nu}{\\partial \\sigma}\", r\"Se^{-qT}N'(d_1)\\sqrt{T}\\frac{d_1 d_2}{\\sigma}\", r\"Se^{-qT}N'(d_1)\\sqrt{T}\\frac{d_1 d_2}{\\sigma}\"],\n", "]\n", "\n", "res = Environment().from_string(ref_template_1).render(output_data=ref_data_1)\n", "print(res)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "$$\\frac{\\partial V}{\\partial t} + rS\\frac{\\partial V}{\\partial S} + \\frac{1}{2}\\sigma^2S^2\\frac{\\partial^2 V}{\\partial S^2}=rV$$\n", "\n", "$$d_1=\\frac{\\log(S/K) + (r-q +\\sigma^2/2)T}{\\sigma \\sqrt{T}}$$\n", "\n", "$$d_2=\\frac{\\log(S/K) + (r-q -\\sigma^2/2)T}{\\sigma \\sqrt{T}}=d_1 - \\sigma \\sqrt{T - t}$$\n", "\n", "$$N(x)=\\frac{1}{\\sqrt{2\\pi}}\\int_{-\\infty}^{x} e^{-\\frac{t^{2}}{2}}dt$$\n", "\n", "$$N'(x)=\\frac{1}{\\sqrt{2\\pi}}e^{-\\frac{x^{2}}{2}}$$\n", "\n" ] } ], "source": [ "from jinja2 import Environment\n", "\n", "ref_template_2 = \"\"\"\n", "{% for x in output_data %}\n", "$${{x[0]}}$$\n", "{% endfor %}\n", "\"\"\"\n", "\n", "ref_data_2 = [\n", "\t[r\"\\frac{\\partial V}{\\partial t} + rS\\frac{\\partial V}{\\partial S} + \\frac{1}{2}\\sigma^2S^2\\frac{\\partial^2 V}{\\partial S^2}=rV\"],\n", "\t[r\"d_1=\\frac{\\log(S/K) + (r-q +\\sigma^2/2)T}{\\sigma \\sqrt{T}}\"],\n", "\t[r\"d_2=\\frac{\\log(S/K) + (r-q -\\sigma^2/2)T}{\\sigma \\sqrt{T}}=d_1 - \\sigma \\sqrt{T - t}\"],\n", "\t[r\"N(x)=\\frac{1}{\\sqrt{2\\pi}}\\int_{-\\infty}^{x} e^{-\\frac{t^{2}}{2}}dt\"],\n", "\t[r\"N'(x)=\\frac{1}{\\sqrt{2\\pi}}e^{-\\frac{x^{2}}{2}}\"]\n", "]\n", "\n", "\n", "res = Environment().from_string(ref_template_2).render(output_data=ref_data_2)\n", "print(res)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.6.3" } }, "nbformat": 4, "nbformat_minor": 1 }