├── CITATION.md ├── LICENCE.md ├── README.md ├── notebooks ├── rbergomi.ipynb └── turbocharged.ipynb ├── papers ├── hybrid_scheme.pdf ├── pricing_under_rough.pdf ├── turbocharged_rbergomi.pdf └── volatility_is_rough.pdf ├── rbergomi ├── rbergomi.py └── utils.py ├── surface0.png └── surface1.png /CITATION.md: -------------------------------------------------------------------------------- 1 | Should you wish to refer to this repository or any of its contents, please cite the url https://github.com/ryanmccrickerd/rough_bergomi. 2 | -------------------------------------------------------------------------------- /LICENCE.md: -------------------------------------------------------------------------------- 1 | Copyright 2017 Ryan McCrickerd 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | rBergomi simulation and turbocharged pricing 2 | ============================================ 3 | 4 | A Python implementation of the rough Bergomi (rBergomi) stochastic volatility model introduced by [Bayer, Friz and Gatheral](https://ssrn.com/abstract=2554754), using the hybrid simulation scheme of [Bennedsen, Lunde and Pakkanen](https://arxiv.org/abs/1507.03004) and variance reduction pricing methods of [McCrickerd and Pakkanen](https://arxiv.org/abs/1708.02563). 5 | 6 | Example Jupyter notebooks are included which demonstrate usage. Tested with Python 3.5.2 and macOS Sierra 10.12.5. 7 | 8 | 9 | -------------------------------------------------------------------------------- /notebooks/turbocharged.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "nbpresent": { 7 | "id": "b590a017-9bad-4ff8-ac89-d1d90e1ebf09" 8 | } 9 | }, 10 | "source": [ 11 | "Turbocharged demo\n", 12 | "==" 13 | ] 14 | }, 15 | { 16 | "cell_type": "markdown", 17 | "metadata": {}, 18 | "source": [ 19 | "We demonstrate the rough Bergomi (rBergomi) price process introduced by [Bayer, Friz and Gatheral](https://ssrn.com/abstract=2554754), which we define here by" 20 | ] 21 | }, 22 | { 23 | "cell_type": "markdown", 24 | "metadata": {}, 25 | "source": [ 26 | "$$S_t := \\exp \\left\\{ \\int_0^t \\sqrt{ V_u } \\mathrm{d}B_u - \\frac{1}{2}\\int_0^t V_u \\mathrm{d}u \\right\\},\\quad B_u:=\\rho W_u^1 + \\sqrt{1 - \\rho^2}W_u^2, $$" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "$$V_t := \\xi\\ \\exp \\left\\{ \\eta Y^a_t - \\frac{\\eta^2}{2} t^{2a + 1}\\right\\}, \\quad Y_t^a := \\sqrt{2a + 1} \\int_0^t (t - u)^a \\mathrm{d}W^1_u,$$" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "for Brownian motion $(W^1, W^2)$. The *hybrid scheme* of [Bennedsen, Lunde and Pakkanen](https://arxiv.org/abs/1507.03004) is used for efficient, $\\mathcal{O}(n\\log n)$, simulation of the Volterra process, $Y_t^a$." 41 | ] 42 | }, 43 | { 44 | "cell_type": "markdown", 45 | "metadata": {}, 46 | "source": [ 47 | "From $N$ samples of the price process, $\\{S^i_t\\}_{i = 1}^N$ , we show implied volatilities, $\\hat{\\sigma}^N_{BS}(k,t)$, using estimators of the form" 48 | ] 49 | }, 50 | { 51 | "cell_type": "markdown", 52 | "metadata": {}, 53 | "source": [ 54 | "$$\\hat{\\sigma}^N_{BS}(k,t)^2 t = BS^{-1}\\left(\\hat{C}_N(k,t)\\right),\\quad \\hat{C}_N(k,t) = \\frac{1}{N}\\sum_{i = 1}^N (X_i + c Y_i) - c\\mathbb{E}[Y],$$" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "as described in [McCrickerd and Pakkanen](https://arxiv.org/abs/1708.02563). For simplicity, we just use call option estimators (rather than OTM option estimators) and do not use antithetic sampling here." 62 | ] 63 | }, 64 | { 65 | "cell_type": "markdown", 66 | "metadata": {}, 67 | "source": [ 68 | "We thus define a Base estimator here by $$X = \\max(S_t - e^k,0),\\quad Y = 0$$ and a Mixed estimator by $$X = BS\\left((1 - \\rho^2)\\int_0^t V_u\\mathrm{d}u; S^1_t,k\\right),\\quad Y = BS\\left(\\rho^2\\left(Q - \\int_0^t V_u\\mathrm{d}u\\right); S^1_t,k\\right)$$" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "where $S^1_t$ is the parallel component of the price process, defined by $$S^1_t := \\exp \\left\\{ \\rho\\int_0^t \\sqrt{ V_u } \\mathrm{d}W^1_u - \\frac{\\rho^2}{2}\\int_0^t V_u \\mathrm{d}u \\right\\}.$$" 76 | ] 77 | }, 78 | { 79 | "cell_type": "markdown", 80 | "metadata": {}, 81 | "source": [ 82 | "While most computations are hidden in the methods of the rBergomi class, we expose the Mixed estimator calculations in this notebook for transparency." 83 | ] 84 | }, 85 | { 86 | "cell_type": "markdown", 87 | "metadata": { 88 | "nbpresent": { 89 | "id": "4523a2f1-a876-4216-a222-c3e0c4d62e9a" 90 | } 91 | }, 92 | "source": [ 93 | "Change directory to folder with rBergomi scripts" 94 | ] 95 | }, 96 | { 97 | "cell_type": "code", 98 | "execution_count": 1, 99 | "metadata": { 100 | "nbpresent": { 101 | "id": "d3eb17f0-eba6-4483-b962-9fc62b4ae12b" 102 | } 103 | }, 104 | "outputs": [], 105 | "source": [ 106 | "import os\n", 107 | "os.chdir('/Users/ryanmccrickerd/desktop/phd/2016-17/rough_bergomi/rbergomi')" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": { 113 | "nbpresent": { 114 | "id": "d95b28a8-a3ad-42d8-b1de-453db5f619a8" 115 | } 116 | }, 117 | "source": [ 118 | "Import required libraries, classes and functions" 119 | ] 120 | }, 121 | { 122 | "cell_type": "code", 123 | "execution_count": 2, 124 | "metadata": { 125 | "nbpresent": { 126 | "id": "577b9e39-b12e-4ca8-9b95-fdb814c09a91" 127 | }, 128 | "scrolled": true 129 | }, 130 | "outputs": [], 131 | "source": [ 132 | "import numpy as np\n", 133 | "from matplotlib import pyplot as plt\n", 134 | "from rbergomi import rBergomi\n", 135 | "from utils import bs, bsinv\n", 136 | "vec_bsinv = np.vectorize(bsinv)\n", 137 | "% matplotlib inline" 138 | ] 139 | }, 140 | { 141 | "cell_type": "markdown", 142 | "metadata": { 143 | "nbpresent": { 144 | "id": "c235967a-8303-4e62-abf1-10e5c7229c9f" 145 | } 146 | }, 147 | "source": [ 148 | "Create instance of the rBergomi class with $n$ steps per year, $N$ paths, maximum maturity $T$ and roughness index $a$" 149 | ] 150 | }, 151 | { 152 | "cell_type": "code", 153 | "execution_count": 3, 154 | "metadata": { 155 | "collapsed": true, 156 | "nbpresent": { 157 | "id": "c6acd2d1-8354-4afc-b6ce-fe12e3358df1" 158 | } 159 | }, 160 | "outputs": [], 161 | "source": [ 162 | "rB = rBergomi(n = 312*4, N = 1000, T = 0.25, a = -0.43)" 163 | ] 164 | }, 165 | { 166 | "cell_type": "markdown", 167 | "metadata": { 168 | "nbpresent": { 169 | "id": "104e4831-a151-403d-91de-d5190e5f4001" 170 | } 171 | }, 172 | "source": [ 173 | "Fix the generator's seed for replicable results" 174 | ] 175 | }, 176 | { 177 | "cell_type": "code", 178 | "execution_count": 4, 179 | "metadata": { 180 | "collapsed": true, 181 | "nbpresent": { 182 | "id": "1ff02865-583a-4770-a987-c941f24cccc6" 183 | } 184 | }, 185 | "outputs": [], 186 | "source": [ 187 | "np.random.seed(0)" 188 | ] 189 | }, 190 | { 191 | "cell_type": "markdown", 192 | "metadata": { 193 | "nbpresent": { 194 | "id": "6edc32ba-80b0-41e0-a268-bcd279fbf478" 195 | } 196 | }, 197 | "source": [ 198 | "Generate required Brownian increments" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 5, 204 | "metadata": { 205 | "collapsed": true, 206 | "nbpresent": { 207 | "id": "d48220f4-a06c-4182-b6ea-bfdef938934b" 208 | } 209 | }, 210 | "outputs": [], 211 | "source": [ 212 | "dW1 = rB.dW1()\n", 213 | "dW2 = rB.dW2()" 214 | ] 215 | }, 216 | { 217 | "cell_type": "markdown", 218 | "metadata": { 219 | "nbpresent": { 220 | "id": "fda3303d-3c49-4b89-b4f4-049d78ded1f1" 221 | } 222 | }, 223 | "source": [ 224 | "Construct the Volterra process, $$Y_t^a := \\sqrt{2a + 1} \\int_0^t (t - u)^a \\mathrm{d}W^1_u$$" 225 | ] 226 | }, 227 | { 228 | "cell_type": "code", 229 | "execution_count": 6, 230 | "metadata": { 231 | "collapsed": true, 232 | "nbpresent": { 233 | "id": "5e7430b0-873d-4756-ab2c-f4069dc668b3" 234 | } 235 | }, 236 | "outputs": [], 237 | "source": [ 238 | "Ya = rB.Y(dW1)" 239 | ] 240 | }, 241 | { 242 | "cell_type": "markdown", 243 | "metadata": {}, 244 | "source": [ 245 | "Correlate the orthogonal increments, using $\\rho$, $$B_u:=\\rho W_u^1 + \\sqrt{1 - \\rho^2}W_u^2$$" 246 | ] 247 | }, 248 | { 249 | "cell_type": "code", 250 | "execution_count": 7, 251 | "metadata": { 252 | "collapsed": true, 253 | "nbpresent": { 254 | "id": "f95288a5-2adb-483f-8488-c6ebd08f1027" 255 | } 256 | }, 257 | "outputs": [], 258 | "source": [ 259 | "dB = rB.dB(dW1, dW2, rho = -0.9)" 260 | ] 261 | }, 262 | { 263 | "cell_type": "markdown", 264 | "metadata": { 265 | "nbpresent": { 266 | "id": "b39ab489-9218-4ba6-a971-74813f713283" 267 | } 268 | }, 269 | "source": [ 270 | "Construct the variance process, using $\\xi$ and $\\eta$, $$V_t := \\xi\\ \\exp \\left\\{ \\eta Y^a_t - \\frac{\\eta^2}{2} t^{2a + 1}\\right\\}$$" 271 | ] 272 | }, 273 | { 274 | "cell_type": "code", 275 | "execution_count": 8, 276 | "metadata": { 277 | "collapsed": true, 278 | "nbpresent": { 279 | "id": "207584be-40fb-4957-833c-0e11ab89433d" 280 | } 281 | }, 282 | "outputs": [], 283 | "source": [ 284 | "V = rB.V(Ya, xi = 0.235**2, eta = 1.9) " 285 | ] 286 | }, 287 | { 288 | "cell_type": "markdown", 289 | "metadata": { 290 | "nbpresent": { 291 | "id": "83d17e74-5d6a-4f1a-a58d-349d082fb1df" 292 | } 293 | }, 294 | "source": [ 295 | "Finally construct the price processes, $$S_t := \\exp \\left\\{ \\int_0^t \\sqrt{ V_u } \\mathrm{d}B_u - \\frac{1}{2}\\int_0^t V_u \\mathrm{d}u \\right\\},\\quad S^1_t := \\exp \\left\\{ \\rho\\int_0^t \\sqrt{ V_u } \\mathrm{d}W^1_u - \\frac{\\rho^2}{2}\\int_0^t V_u \\mathrm{d}u \\right\\}$$" 296 | ] 297 | }, 298 | { 299 | "cell_type": "code", 300 | "execution_count": 9, 301 | "metadata": { 302 | "collapsed": true, 303 | "nbpresent": { 304 | "id": "698f4b14-0398-46bb-88aa-c822fcff2ad1" 305 | } 306 | }, 307 | "outputs": [], 308 | "source": [ 309 | "S = rB.S(V, dB)\n", 310 | "S1 = rB.S1(V, dW1, rho = -0.9)" 311 | ] 312 | }, 313 | { 314 | "cell_type": "markdown", 315 | "metadata": {}, 316 | "source": [ 317 | "Now set log-strikes, $k$" 318 | ] 319 | }, 320 | { 321 | "cell_type": "code", 322 | "execution_count": 10, 323 | "metadata": {}, 324 | "outputs": [], 325 | "source": [ 326 | "k = np.array([-0.1787,0.0000,0.1041])\n", 327 | "K = np.exp(k)[np.newaxis,:]" 328 | ] 329 | }, 330 | { 331 | "cell_type": "markdown", 332 | "metadata": {}, 333 | "source": [ 334 | "and known implied volatilities for this model specification" 335 | ] 336 | }, 337 | { 338 | "cell_type": "code", 339 | "execution_count": 11, 340 | "metadata": { 341 | "collapsed": true 342 | }, 343 | "outputs": [], 344 | "source": [ 345 | "implied_vols = np.array([0.2961,0.2061,0.1576])[:,np.newaxis]" 346 | ] 347 | }, 348 | { 349 | "cell_type": "markdown", 350 | "metadata": {}, 351 | "source": [ 352 | "Compute Base call payoffs, prices, and estimated volatilities," 353 | ] 354 | }, 355 | { 356 | "cell_type": "code", 357 | "execution_count": 12, 358 | "metadata": {}, 359 | "outputs": [], 360 | "source": [ 361 | "ST = S[:,-1][:,np.newaxis]\n", 362 | "base_payoffs = np.maximum(ST - K,0)\n", 363 | "base_prices = np.mean(base_payoffs, axis = 0)[:,np.newaxis]\n", 364 | "base_vols = vec_bsinv(base_prices, 1., np.transpose(K), rB.T)" 365 | ] 366 | }, 367 | { 368 | "cell_type": "markdown", 369 | "metadata": {}, 370 | "source": [ 371 | "Do the same for the Mixed estimator, including the quadratic variation, $\\mathrm{QV} = \\int_0^t V_u \\mathrm{d}u$, and variation budget, $\\mathrm{Q}$" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 13, 377 | "metadata": {}, 378 | "outputs": [], 379 | "source": [ 380 | "QV = np.sum(V, axis = 1)[:,np.newaxis] * rB.dt\n", 381 | "Q = np.max(QV) + 1e-9 " 382 | ] 383 | }, 384 | { 385 | "cell_type": "markdown", 386 | "metadata": {}, 387 | "source": [ 388 | "$$X = BS\\left((1 - \\rho^2)\\int_0^t V_u\\mathrm{d}u; S^1_t,k\\right),\\quad Y = BS\\left(\\rho^2\\left(Q - \\int_0^t V_u\\mathrm{d}u\\right); S^1_t,k\\right)$$" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": 14, 394 | "metadata": {}, 395 | "outputs": [], 396 | "source": [ 397 | "S1T = S1[:,-1][:,np.newaxis]\n", 398 | "X = bs(S1T, K, (1 - rB.rho**2) * QV)\n", 399 | "Y = bs(S1T, K, rB.rho**2 * (Q - QV))\n", 400 | "eY = bs(1., K, rB.rho**2 * Q)\n", 401 | "\n", 402 | "# Asymptotically optimal weights\n", 403 | "c = np.zeros_like(k)[np.newaxis,:]\n", 404 | "for i in range(len(k)):\n", 405 | " cov_mat = np.cov(X[:,i], Y[:,i])\n", 406 | " c[0,i] = - cov_mat[0,1] / cov_mat[1,1]\n", 407 | "\n", 408 | "# Payoffs, prices and volatilities\n", 409 | "mixed_payoffs = X + c * (Y - eY)\n", 410 | "mixed_prices = np.mean(mixed_payoffs, axis = 0)[:,np.newaxis]\n", 411 | "mixed_vols = vec_bsinv(mixed_prices, 1., np.transpose(K), rB.T)" 412 | ] 413 | }, 414 | { 415 | "cell_type": "markdown", 416 | "metadata": {}, 417 | "source": [ 418 | "Now plot implied volatilities against Base and Mixed estimators" 419 | ] 420 | }, 421 | { 422 | "cell_type": "code", 423 | "execution_count": 15, 424 | "metadata": {}, 425 | "outputs": [ 426 | { 427 | "data": { 428 | "image/png": "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\n", 429 | "text/plain": [ 430 | "" 431 | ] 432 | }, 433 | "metadata": {}, 434 | "output_type": "display_data" 435 | } 436 | ], 437 | "source": [ 438 | "plot,axes = plt.subplots()\n", 439 | "# Add Implied, Base and Mixed vols\n", 440 | "axes.plot(k, implied_vols, 'bo', fillstyle = 'none', ms = 10, mew = 2)\n", 441 | "axes.plot(k, base_vols, 'gx', ms = 7, mew = 2)\n", 442 | "axes.plot(k, mixed_vols, 'rx', ms = 7, mew = 2)\n", 443 | "# Label figure\n", 444 | "axes.set_xlabel(r'$k$',fontsize=16)\n", 445 | "axes.set_ylabel(r'$\\sigma_{BS}(k,t=%.2f)$'%rB.T,fontsize=16)\n", 446 | "title1 = r'$\\mathrm{Base\\ vs\\ Mixed\\ estimators}$'\n", 447 | "title2 = r'$\\xi=%.3f,\\ \\eta=%.2f,\\ \\rho=%.2f,\\ \\alpha=%.2f $'\n", 448 | "axes.set_title(title1+'\\n'+title2%(rB.xi,rB.eta,rB.rho,rB.a), fontsize=16)\n", 449 | "axes.legend([r'$\\mathrm{Implied}$',r'$\\mathrm{Base}$',r'$\\mathrm{Mixed}$'], fontsize=14)\n", 450 | "# Set scale to match paper\n", 451 | "set_scale = True\n", 452 | "if set_scale:\n", 453 | " xmin,xmax = -0.25,0.15\n", 454 | " ymin,ymax = 0.14,0.34\n", 455 | " nticks = 5\n", 456 | " plt.xlim([xmin,xmax])\n", 457 | " plt.ylim([ymin,ymax])\n", 458 | " axes.xaxis.set_ticks(np.linspace(xmin,xmax,nticks))\n", 459 | " axes.yaxis.set_ticks(np.linspace(ymin,ymax,nticks))\n", 460 | "plt.grid(True)" 461 | ] 462 | }, 463 | { 464 | "cell_type": "markdown", 465 | "metadata": {}, 466 | "source": [ 467 | "Please do not attempt to draw conclusions regarding the relative performance of the Base and Mixed estimators from just one (or several) simulation(s) / seed(s) !" 468 | ] 469 | } 470 | ], 471 | "metadata": { 472 | "anaconda-cloud": {}, 473 | "kernelspec": { 474 | "display_name": "Python [default]", 475 | "language": "python", 476 | "name": "python3" 477 | }, 478 | "language_info": { 479 | "codemirror_mode": { 480 | "name": "ipython", 481 | "version": 3 482 | }, 483 | "file_extension": ".py", 484 | "mimetype": "text/x-python", 485 | "name": "python", 486 | "nbconvert_exporter": "python", 487 | "pygments_lexer": "ipython3", 488 | "version": "3.5.2" 489 | } 490 | }, 491 | "nbformat": 4, 492 | "nbformat_minor": 1 493 | } 494 | -------------------------------------------------------------------------------- /papers/hybrid_scheme.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryanmccrickerd/rough_bergomi/6a04ca5d2d0f6a45df28ae7bad9c882d537ef14e/papers/hybrid_scheme.pdf -------------------------------------------------------------------------------- /papers/pricing_under_rough.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryanmccrickerd/rough_bergomi/6a04ca5d2d0f6a45df28ae7bad9c882d537ef14e/papers/pricing_under_rough.pdf -------------------------------------------------------------------------------- /papers/turbocharged_rbergomi.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryanmccrickerd/rough_bergomi/6a04ca5d2d0f6a45df28ae7bad9c882d537ef14e/papers/turbocharged_rbergomi.pdf -------------------------------------------------------------------------------- /papers/volatility_is_rough.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryanmccrickerd/rough_bergomi/6a04ca5d2d0f6a45df28ae7bad9c882d537ef14e/papers/volatility_is_rough.pdf -------------------------------------------------------------------------------- /rbergomi/rbergomi.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from utils import * 3 | 4 | class rBergomi(object): 5 | """ 6 | Class for generating paths of the rBergomi model. 7 | """ 8 | def __init__(self, n = 100, N = 1000, T = 1.00, a = -0.4): 9 | """ 10 | Constructor for class. 11 | """ 12 | # Basic assignments 13 | self.T = T # Maturity 14 | self.n = n # Granularity (steps per year) 15 | self.dt = 1.0/self.n # Step size 16 | self.s = int(self.n * self.T) # Steps 17 | self.t = np.linspace(0, self.T, 1 + self.s)[np.newaxis,:] # Time grid 18 | self.a = a # Alpha 19 | self.N = N # Paths 20 | 21 | # Construct hybrid scheme correlation structure for kappa = 1 22 | self.e = np.array([0,0]) 23 | self.c = cov(self.a, self.n) 24 | 25 | def dW1(self): 26 | """ 27 | Produces random numbers for variance process with required 28 | covariance structure. 29 | """ 30 | rng = np.random.multivariate_normal 31 | return rng(self.e, self.c, (self.N, self.s)) 32 | 33 | def Y(self, dW): 34 | """ 35 | Constructs Volterra process from appropriately 36 | correlated 2d Brownian increments. 37 | """ 38 | Y1 = np.zeros((self.N, 1 + self.s)) # Exact integrals 39 | Y2 = np.zeros((self.N, 1 + self.s)) # Riemann sums 40 | 41 | # Construct Y1 through exact integral 42 | for i in np.arange(1, 1 + self.s, 1): 43 | Y1[:,i] = dW[:,i-1,1] # Assumes kappa = 1 44 | 45 | # Construct arrays for convolution 46 | G = np.zeros(1 + self.s) # Gamma 47 | for k in np.arange(2, 1 + self.s, 1): 48 | G[k] = g(b(k, self.a)/self.n, self.a) 49 | 50 | X = dW[:,:,0] # Xi 51 | 52 | # Initialise convolution result, GX 53 | GX = np.zeros((self.N, len(X[0,:]) + len(G) - 1)) 54 | 55 | # Compute convolution, FFT not used for small n 56 | # Possible to compute for all paths in C-layer? 57 | for i in range(self.N): 58 | GX[i,:] = np.convolve(G, X[i,:]) 59 | 60 | # Extract appropriate part of convolution 61 | Y2 = GX[:,:1 + self.s] 62 | 63 | # Finally contruct and return full process 64 | Y = np.sqrt(2 * self.a + 1) * (Y1 + Y2) 65 | return Y 66 | 67 | def dW2(self): 68 | """ 69 | Obtain orthogonal increments. 70 | """ 71 | return np.random.randn(self.N, self.s) * np.sqrt(self.dt) 72 | 73 | def dB(self, dW1, dW2, rho = 0.0): 74 | """ 75 | Constructs correlated price Brownian increments, dB. 76 | """ 77 | self.rho = rho 78 | dB = rho * dW1[:,:,0] + np.sqrt(1 - rho**2) * dW2 79 | return dB 80 | 81 | def V(self, Y, xi = 1.0, eta = 1.0): 82 | """ 83 | rBergomi variance process. 84 | """ 85 | self.xi = xi 86 | self.eta = eta 87 | a = self.a 88 | t = self.t 89 | V = xi * np.exp(eta * Y - 0.5 * eta**2 * t**(2 * a + 1)) 90 | return V 91 | 92 | def S(self, V, dB, S0 = 1): 93 | """ 94 | rBergomi price process. 95 | """ 96 | self.S0 = S0 97 | dt = self.dt 98 | rho = self.rho 99 | 100 | # Construct non-anticipative Riemann increments 101 | increments = np.sqrt(V[:,:-1]) * dB - 0.5 * V[:,:-1] * dt 102 | 103 | # Cumsum is a little slower than Python loop. 104 | integral = np.cumsum(increments, axis = 1) 105 | 106 | S = np.zeros_like(V) 107 | S[:,0] = S0 108 | S[:,1:] = S0 * np.exp(integral) 109 | return S 110 | 111 | def S1(self, V, dW1, rho, S0 = 1): 112 | """ 113 | rBergomi parallel price process. 114 | """ 115 | dt = self.dt 116 | 117 | # Construct non-anticipative Riemann increments 118 | increments = rho * np.sqrt(V[:,:-1]) * dW1[:,:,0] - 0.5 * rho**2 * V[:,:-1] * dt 119 | 120 | # Cumsum is a little slower than Python loop. 121 | integral = np.cumsum(increments, axis = 1) 122 | 123 | S = np.zeros_like(V) 124 | S[:,0] = S0 125 | S[:,1:] = S0 * np.exp(integral) 126 | return S 127 | -------------------------------------------------------------------------------- /rbergomi/utils.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | from scipy.stats import norm 3 | from scipy.optimize import brentq 4 | 5 | def g(x, a): 6 | """ 7 | TBSS kernel applicable to the rBergomi variance process. 8 | """ 9 | return x**a 10 | 11 | def b(k, a): 12 | """ 13 | Optimal discretisation of TBSS process for minimising hybrid scheme error. 14 | """ 15 | return ((k**(a+1)-(k-1)**(a+1))/(a+1))**(1/a) 16 | 17 | def cov(a, n): 18 | """ 19 | Covariance matrix for given alpha and n, assuming kappa = 1 for 20 | tractability. 21 | """ 22 | cov = np.array([[0.,0.],[0.,0.]]) 23 | cov[0,0] = 1./n 24 | cov[0,1] = 1./((1.*a+1) * n**(1.*a+1)) 25 | cov[1,1] = 1./((2.*a+1) * n**(2.*a+1)) 26 | cov[1,0] = cov[0,1] 27 | return cov 28 | 29 | def bs(F, K, V, o = 'call'): 30 | """ 31 | Returns the Black call price for given forward, strike and integrated 32 | variance. 33 | """ 34 | # Set appropriate weight for option token o 35 | w = 1 36 | if o == 'put': 37 | w = -1 38 | elif o == 'otm': 39 | w = 2 * (K > 1.0) - 1 40 | 41 | sv = np.sqrt(V) 42 | d1 = np.log(F/K) / sv + 0.5 * sv 43 | d2 = d1 - sv 44 | P = w * F * norm.cdf(w * d1) - w * K * norm.cdf(w * d2) 45 | return P 46 | 47 | def bsinv(P, F, K, t, o = 'call'): 48 | """ 49 | Returns implied Black vol from given call price, forward, strike and time 50 | to maturity. 51 | """ 52 | # Set appropriate weight for option token o 53 | w = 1 54 | if o == 'put': 55 | w = -1 56 | elif o == 'otm': 57 | w = 2 * (K > 1.0) - 1 58 | 59 | # Ensure at least instrinsic value 60 | P = np.maximum(P, np.maximum(w * (F - K), 0)) 61 | 62 | def error(s): 63 | return bs(F, K, s**2 * t, o) - P 64 | s = brentq(error, 1e-9, 1e+9) 65 | return s 66 | -------------------------------------------------------------------------------- /surface0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryanmccrickerd/rough_bergomi/6a04ca5d2d0f6a45df28ae7bad9c882d537ef14e/surface0.png -------------------------------------------------------------------------------- /surface1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ryanmccrickerd/rough_bergomi/6a04ca5d2d0f6a45df28ae7bad9c882d537ef14e/surface1.png --------------------------------------------------------------------------------