diff options
| author | Shivesh Mandalia <mail@shivesh.org> | 2021-09-27 02:02:52 +0100 |
|---|---|---|
| committer | Shivesh Mandalia <mail@shivesh.org> | 2021-09-27 02:02:52 +0100 |
| commit | d572d11f65543eed4d79a7eedb1b761ff86a339c (patch) | |
| tree | fd19d8bece2fa2d69a0e7b6f7565ba76e9161860 /gen.py | |
| parent | da67665b62c75fe10a1494e3bc7d944963127fc0 (diff) | |
| download | MCOptionPricing-master.tar.gz MCOptionPricing-master.zip | |
Diffstat (limited to 'gen.py')
| -rw-r--r-- | gen.py | 243 |
1 files changed, 243 insertions, 0 deletions
@@ -0,0 +1,243 @@ +#! /usr/bin/env python3 +# author : S. Mandalia +# shivesh.mandalia@outlook.com +# +# date : May 20, 2020 + + +""" +Exotic options by Monte Carlo. + +Generate fake data. + +""" + +import random +from typing import List + +import numpy as np + +from utils.engine import PricingEngine +from utils.path import PathGenerator +from utils.payoff import AsianArithmeticPayOff, DiscreteBarrierPayOff +from utils.payoff import VanillaPayOff + + +__all__ = ['vanilla', 'asian', 'barrier'] + + +NGEN = 13 +# NGEN = 10 +NTRIALS = 1e5 + + +def vanilla() -> None: + """Generate Vanilla option fake data.""" + outfile = './vanilla.csv' + + with open(outfile, 'w') as f: + s = 'ID,Spot,Strike,Risk-Free Rate,Years to Expiry,Volatility,' \ + 'Option Right,Price\n' + f.write(s) + + idx = 0 + for ndx in range(NGEN): + if (ndx + 1) % 10 == 0: + print('{0} / {1}'.format(ndx + 1, NGEN)) + + for right in ('Call', 'Put'): + S, K, T, r, vol = np.random.random(5) + S *= 300 + K *= 300 + r = r * 1E-2 - 5E-3 + T *= 3 + vol += 1E-4 + + path = PathGenerator(S=S, r=r, div=0., vol=vol) + payoff = VanillaPayOff(K=K, option_right=right) + engine = PricingEngine(payoff=payoff, path=path) + + # Price + result = engine.price(T=[0, T], ntrials=NTRIALS) + s = '{0},{1:.6g},{2:.6g},{3:.6g},{4:.6g},{5:.6g},{6},' \ + '{7:.6g}\n'.format( + idx, S, K, r, T, vol, right, result.price + ) + f.write(s) + idx += 1 + + +def asian() -> None: + """Generate Asian option fake data.""" + outfile = './asian.csv' + + with open(outfile, 'w') as f: + s = 'ID,Spot,Strike,Risk-Free Rate,Years to Expiry,Volatility,' \ + 'Option Right,Averaging Days,Price\n' + f.write(s) + + idx = 0 + for right in ('Call', 'Put'): + idy = 0 + while idy < NGEN: + S, K, T, r, vol = np.random.random(5) + S *= 300 + K *= 300 + r = r * 1E-2 - 5E-3 + T *= 1 + vol += 1E-4 + + path = PathGenerator(S=S, r=r, div=0., vol=vol) + payoff = AsianArithmeticPayOff(K=K, option_right=right) + engine = PricingEngine(payoff=payoff, path=path) + + # (i) an Asian call option with maturity in T year(s) and + # 30 days averaging. + ad = 30 + n = int(T * 365 // ad) + if n > 1: + # f_start = (T * 365 - n * ad) + # t = [(x * ad) + f_start for x in range(n + 1)] + t = [(x * ad / 365.) for x in range(n + 1)] + + # Price + result = engine.price(T=t, ntrials=NTRIALS) + if abs(result.price) < 1E-5: + continue + s = '{0},{1:.6g},{2:.6g},{3:.6g},{4:.6g},{5:.6g},{6},{7},' \ + '{8:.6g}\n'.format( + idx, S, K, r, T, vol, right, ad, result.price + ) + f.write(s) + idx += 1 + idy += 1 + + # # (ii) an Asian call option with maturity in T year(s) and + # # 90 days averaging. + # ad = 90 + # n = int(T * 365 // ad) + # f_start = (T * 365 - n * ad) + # t = [(x * ad) + f_start for x in range(n + 1)] + # + # # Price + # result = engine.price(T=t, ntrials=NTRIALS) + # s = '{0},{1:.6g},{2:.6g},{3:.6g},{4:.6g},{5:.6g},{6},{7},' \ + # '{8:.6g}\n'.format( + # idx, S, K, r, T, vol, right, ad, result.price + # ) + # f.write(s) + # idx += 1 + + # (iii) an Asian call option with maturity in T year(s) and + # 7 days averaging. + ad = 7 + n = int(T * 365 // ad) + if n > 1: + # f_start = (T * 365 - n * ad) + # t = [(x * ad) + f_start for x in range(n + 1)] + t = [(x * ad / 365.) for x in range(n + 1)] + + # Price + result = engine.price(T=t, ntrials=NTRIALS) + if abs(result.price) < 1E-5: + continue + s = '{0},{1:.6g},{2:.6g},{3:.6g},{4:.6g},{5:.6g},{6},{7},' \ + '{8:.6g}\n'.format( + idx, S, K, r, T, vol, right, ad, result.price + ) + f.write(s) + idx += 1 + idy += 1 + + +def barrier() -> None: + """Generate barrier option fake data.""" + outfile = './barrier.csv' + + with open(outfile, 'w') as f: + s = 'ID,Spot,Strike,Risk-Free Rate,Years to Expiry,Volatility,' \ + 'Option Right,Barrier Value,Barrier UpDown,Barrier InOut,Mesh Spacing,Price\n' + f.write(s) + + idx = 0 + for right in ('Call', 'Put'): + for b_inout in ('In', 'Out'): + for b_updown in ('Up', 'Down'): + idy = 0 + while idy < NGEN: + B, S, K, T, r, vol = np.random.random(6) + B *= 300 + S *= 300 + K *= 300 + r = r * 1E-2 - 5E-3 + T *= 1 + vol += 1E-4 + + path = PathGenerator(S=S, r=r, div=0., vol=vol) + payoff = DiscreteBarrierPayOff( + K=K, option_right=right, B=B, + barrier_updown=b_updown, barrier_inout=b_inout + ) + engine = PricingEngine(payoff=payoff, path=path) + + # (i) Monthly barrier dates. + bd = 30 + n = int(T * 365 // bd) + if n > 1: + t = [(x * bd / 365.) for x in range(n + 1)] + + # Price + result = engine.price(T=t, ntrials=NTRIALS) + if abs(result.price) < 1E-5: + continue + s = '{0},{1:.6g},{2:.6g},{3:.6g},{4:.6g},{5:.6g},{6},{7:.6g},{8},' \ + '{9},{10},{11:.6g}\n'.format( + idx, S, K, r, T, vol, right, B, b_updown, + b_inout, bd, result.price + ) + f.write(s) + idx += 1 + idy += 1 + + # (i) Weekly barrier dates. + bd = 7 + n = int(T * 365 // bd) + if n > 1: + t = [(x * bd / 365.) for x in range(n + 1)] + + # Price + result = engine.price(T=t, ntrials=NTRIALS) + if abs(result.price) < 1E-5: + continue + s = '{0},{1:.6g},{2:.6g},{3:.6g},{4:.6g},{5:.6g},{6},{7:.6g},{8},' \ + '{9},{10},{11:.6g}\n'.format( + idx, S, K, r, T, vol, right, B, b_updown, + b_inout, bd, result.price + ) + f.write(s) + idx += 1 + idy += 1 + + +def main() -> None: + random.seed(1) + + # Pricing Vanilla options + # vanilla() + + # Pricing Asian options + asian() + + # Pricing discrete barrier options + # barrier() + + print('==================') + print('Shivesh Mandalia https://shivesh.org/') + print('==================') + + +main.__doc__ = __doc__ + + +if __name__ == '__main__': + main() |
