|
4 | 4 | "cell_type": "markdown",
|
5 | 5 | "metadata": {},
|
6 | 6 | "source": [
|
7 |
| - "# Basket option implementation based on normal model" |
| 7 | + "# Basket option implementation with Bachelier model CV" |
8 | 8 | ]
|
9 | 9 | },
|
10 | 10 | {
|
|
24 | 24 | "outputs": [],
|
25 | 25 | "source": [
|
26 | 26 | "import numpy as np\n",
|
| 27 | + "import pyfeng as pf\n", |
| 28 | + "\n", |
27 | 29 | "#import option_models as opt\n",
|
28 |
| - "from option_models import basket\n", |
29 |
| - "from option_models import bsm\n", |
30 |
| - "from option_models import normal" |
| 30 | + "from option_models import basket" |
31 | 31 | ]
|
32 | 32 | },
|
33 |
| - { |
34 |
| - "cell_type": "code", |
35 |
| - "execution_count": null, |
36 |
| - "metadata": {}, |
37 |
| - "outputs": [], |
38 |
| - "source": [] |
39 |
| - }, |
40 | 33 | {
|
41 | 34 | "cell_type": "code",
|
42 | 35 | "execution_count": 3,
|
|
49 | 42 | "\n",
|
50 | 43 | "spot = np.ones(4) * 100\n",
|
51 | 44 | "vol = np.ones(4) * 0.4\n",
|
52 |
| - "weights = np.array([0, 1, 0, 0])\n", |
| 45 | + "weights = np.array([1, 0, 0, 0])\n", |
53 | 46 | "divr = np.zeros(4)\n",
|
54 | 47 | "intr = 0\n",
|
55 | 48 | "cor_m = 0.5*np.identity(4) + 0.5\n",
|
|
89 | 82 | "name": "stdout",
|
90 | 83 | "output_type": "stream",
|
91 | 84 | "text": [
|
92 |
| - "[0 1 0 0]\n", |
93 |
| - "26.92956987643586\n" |
| 85 | + "[1 0 0 0]\n", |
| 86 | + "26.570984651213593\n" |
94 | 87 | ]
|
95 | 88 | }
|
96 | 89 | ],
|
|
111 | 104 | "name": "stdout",
|
112 | 105 | "output_type": "stream",
|
113 | 106 | "text": [
|
114 |
| - "26.92956987643586 26.570845957870503\n" |
| 107 | + "26.570984651213593 26.570845957870503\n" |
115 | 108 | ]
|
116 | 109 | }
|
117 | 110 | ],
|
118 | 111 | "source": [
|
119 | 112 | "# Compare the price to normal model formula\n",
|
120 | 113 | "\n",
|
121 |
| - "norm1 = normal.NormalModel(vol=40)\n", |
122 |
| - "price_norm = norm1.price(strike=120, spot=100, texp=texp, cp=1)\n", |
| 114 | + "norm1 = pf.Norm(sigma=40)\n", |
| 115 | + "price_norm = norm1.price(strike, spot[0], texp, cp=1)\n", |
123 | 116 | "print(price_basket, price_norm)"
|
124 | 117 | ]
|
125 | 118 | },
|
|
136 | 129 | " [0.9999 1. 0.9999 0.9999]\n",
|
137 | 130 | " [0.9999 0.9999 1. 0.9999]\n",
|
138 | 131 | " [0.9999 0.9999 0.9999 1. ]]\n",
|
139 |
| - "26.761395615904505 26.570845957870503\n" |
| 132 | + "26.57211110181949 26.570845957870503\n" |
140 | 133 | ]
|
141 | 134 | }
|
142 | 135 | ],
|
|
188 | 181 | {
|
189 | 182 | "data": {
|
190 | 183 | "text/plain": [
|
191 |
| - "array([[1. , 0.5, 0.5, 0.5],\n", |
192 |
| - " [0.5, 1. , 0.5, 0.5],\n", |
193 |
| - " [0.5, 0.5, 1. , 0.5],\n", |
194 |
| - " [0.5, 0.5, 0.5, 1. ]])" |
| 184 | + "(array([0.25, 0.25, 0.25, 0.25]),\n", |
| 185 | + " array([[1. , 0.5, 0.5, 0.5],\n", |
| 186 | + " [0.5, 1. , 0.5, 0.5],\n", |
| 187 | + " [0.5, 0.5, 1. , 0.5],\n", |
| 188 | + " [0.5, 0.5, 0.5, 1. ]]))" |
195 | 189 | ]
|
196 | 190 | },
|
197 | 191 | "execution_count": 9,
|
|
200 | 194 | }
|
201 | 195 | ],
|
202 | 196 | "source": [
|
203 |
| - "cor_m" |
| 197 | + "weights, cor_m" |
204 | 198 | ]
|
205 | 199 | },
|
206 | 200 | {
|
|
212 | 206 | "name": "stdout",
|
213 | 207 | "output_type": "stream",
|
214 | 208 | "text": [
|
215 |
| - "28.168716545630815 28.0073695\n" |
| 209 | + "28.22782882893394 28.0073695\n" |
216 | 210 | ]
|
217 | 211 | }
|
218 | 212 | ],
|
|
280 | 274 | "price_basket = basket.basket_price_mc(strike, spot, vol, weights, texp, cor_m, bsm=True)"
|
281 | 275 | ]
|
282 | 276 | },
|
| 277 | + { |
| 278 | + "cell_type": "code", |
| 279 | + "execution_count": 13, |
| 280 | + "metadata": {}, |
| 281 | + "outputs": [ |
| 282 | + { |
| 283 | + "name": "stdout", |
| 284 | + "output_type": "stream", |
| 285 | + "text": [ |
| 286 | + "0.0 28.713486748445934\n" |
| 287 | + ] |
| 288 | + } |
| 289 | + ], |
| 290 | + "source": [ |
| 291 | + "bsm1 = pf.Bsm(sigma=vol[0])\n", |
| 292 | + "price_bsm = bsm1.price(strike, spot[0], texp, cp=1)\n", |
| 293 | + "print(price_basket, price_bsm)" |
| 294 | + ] |
| 295 | + }, |
283 | 296 | {
|
284 | 297 | "cell_type": "markdown",
|
285 | 298 | "metadata": {},
|
|
289 | 302 | },
|
290 | 303 | {
|
291 | 304 | "cell_type": "code",
|
292 |
| - "execution_count": 13, |
| 305 | + "execution_count": 14, |
293 | 306 | "metadata": {},
|
294 | 307 | "outputs": [],
|
295 | 308 | "source": [
|
|
300 | 313 | "weights = np.array([1, -1])\n",
|
301 | 314 | "divr = np.array([1, 1])*0.05\n",
|
302 | 315 | "intr = 0.1\n",
|
303 |
| - "cor_m = np.array([[1, 0.5], [0.5, 1]])\n", |
| 316 | + "cor = 0.5\n", |
| 317 | + "cor_m = np.array([[1, cor], [cor, 1]])\n", |
304 | 318 | "texp = 1\n",
|
305 | 319 | "strike = 0\n",
|
306 | 320 | "price_exact = 8.5132252"
|
307 | 321 | ]
|
308 | 322 | },
|
309 | 323 | {
|
310 | 324 | "cell_type": "code",
|
311 |
| - "execution_count": 14, |
| 325 | + "execution_count": 15, |
312 | 326 | "metadata": {},
|
313 | 327 | "outputs": [
|
314 | 328 | {
|
315 | 329 | "name": "stdout",
|
316 | 330 | "output_type": "stream",
|
317 | 331 | "text": [
|
318 |
| - "8.348852807225292 8.5132252\n" |
| 332 | + "8.317680907159142 8.5132252\n" |
319 | 333 | ]
|
320 | 334 | }
|
321 | 335 | ],
|
|
337 | 351 | },
|
338 | 352 | {
|
339 | 353 | "cell_type": "code",
|
340 |
| - "execution_count": 15, |
| 354 | + "execution_count": 16, |
341 | 355 | "metadata": {},
|
342 |
| - "outputs": [], |
| 356 | + "outputs": [ |
| 357 | + { |
| 358 | + "data": { |
| 359 | + "text/plain": [ |
| 360 | + "0.0" |
| 361 | + ] |
| 362 | + }, |
| 363 | + "execution_count": 16, |
| 364 | + "metadata": {}, |
| 365 | + "output_type": "execute_result" |
| 366 | + } |
| 367 | + ], |
343 | 368 | "source": [
|
344 | 369 | "# Once the implementation is finished the BSM model price should also work\n",
|
345 | 370 | "price_spread = basket.basket_price_mc(\n",
|
346 |
| - " strike, spot, vol*spot, weights, texp, cor_m, intr=intr, divr=divr, bsm=True)" |
| 371 | + " strike, spot, vol*spot, weights, texp, cor_m, intr=intr, divr=divr, bsm=True)\n", |
| 372 | + "price_spread" |
347 | 373 | ]
|
348 | 374 | },
|
349 | 375 | {
|
350 | 376 | "cell_type": "code",
|
351 |
| - "execution_count": 16, |
| 377 | + "execution_count": 17, |
352 | 378 | "metadata": {},
|
353 | 379 | "outputs": [
|
354 | 380 | {
|
355 | 381 | "name": "stdout",
|
356 | 382 | "output_type": "stream",
|
357 | 383 | "text": [
|
358 |
| - "8.5132252295455 0.0\n" |
| 384 | + "8.513225229545505 0.0\n" |
359 | 385 | ]
|
360 | 386 | }
|
361 | 387 | ],
|
362 | 388 | "source": [
|
363 | 389 | "# You also test Kirk's approximation\n",
|
364 |
| - "price_kirk = basket.spread_price_kirk(strike, spot, vol, texp, 0.5, intr, divr)\n", |
| 390 | + "kirk = pf.BsmSpreadKirk(vol, cor=cor, divr=divr, intr=intr)\n", |
| 391 | + "price_kirk = kirk.price(strike, spot, texp)\n", |
365 | 392 | "print(price_kirk, price_spread)"
|
366 | 393 | ]
|
367 | 394 | },
|
|
375 | 402 | },
|
376 | 403 | {
|
377 | 404 | "cell_type": "code",
|
378 |
| - "execution_count": 17, |
| 405 | + "execution_count": 18, |
379 | 406 | "metadata": {},
|
380 | 407 | "outputs": [],
|
381 | 408 | "source": [
|
|
392 | 419 | },
|
393 | 420 | {
|
394 | 421 | "cell_type": "code",
|
395 |
| - "execution_count": 18, |
| 422 | + "execution_count": 19, |
396 | 423 | "metadata": {},
|
397 | 424 | "outputs": [
|
398 | 425 | {
|
|
401 | 428 | "0.0"
|
402 | 429 | ]
|
403 | 430 | },
|
404 |
| - "execution_count": 18, |
| 431 | + "execution_count": 19, |
405 | 432 | "metadata": {},
|
406 | 433 | "output_type": "execute_result"
|
407 | 434 | }
|
|
413 | 440 | },
|
414 | 441 | {
|
415 | 442 | "cell_type": "code",
|
416 |
| - "execution_count": 19, |
| 443 | + "execution_count": 20, |
417 | 444 | "metadata": {},
|
418 | 445 | "outputs": [],
|
419 | 446 | "source": [
|
|
425 | 452 | },
|
426 | 453 | {
|
427 | 454 | "cell_type": "code",
|
428 |
| - "execution_count": 20, |
| 455 | + "execution_count": 21, |
429 | 456 | "metadata": {},
|
430 | 457 | "outputs": [
|
431 | 458 | {
|
|
439 | 466 | "source": [
|
440 | 467 | "print(price_basket)"
|
441 | 468 | ]
|
442 |
| - }, |
443 |
| - { |
444 |
| - "cell_type": "code", |
445 |
| - "execution_count": null, |
446 |
| - "metadata": {}, |
447 |
| - "outputs": [], |
448 |
| - "source": [] |
449 | 469 | }
|
450 | 470 | ],
|
451 | 471 | "metadata": {
|
452 | 472 | "anaconda-cloud": {},
|
453 | 473 | "kernelspec": {
|
454 |
| - "display_name": "Python 3", |
| 474 | + "display_name": "Python 3 (ipykernel)", |
455 | 475 | "language": "python",
|
456 | 476 | "name": "python3"
|
457 | 477 | },
|
|
465 | 485 | "name": "python",
|
466 | 486 | "nbconvert_exporter": "python",
|
467 | 487 | "pygments_lexer": "ipython3",
|
468 |
| - "version": "3.8.5" |
| 488 | + "version": "3.8.11" |
469 | 489 | }
|
470 | 490 | },
|
471 | 491 | "nbformat": 4,
|
|
0 commit comments