0
$\begingroup$

I am trying to price binary option using MC Simulation and Python QuantLib Library. The price of the option matches with the Analytical Engine. However, I am not sure how to incorporate the Heaviside Function to calculate the payoff (1 if St > K; 0 otherwise). Here is the code for the same:

import QuantLib as ql
today = ql.Date().todaysDate()
initialValue = 40
riskFreeTS = ql.YieldTermStructureHandle(ql.FlatForward(today, 0.01, ql.Actual365Fixed()))
dividendTS = ql.YieldTermStructureHandle(ql.FlatForward(today, 0.02, ql.Actual365Fixed()))
volatility = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(today, ql.NullCalendar(), 0.2, ql.Actual365Fixed()))

process = ql.BlackScholesMertonProcess(ql.QuoteHandle(ql.SimpleQuote(40)), riskFreeTS, dividendTS, volatility)
steps = 2
rng = "pseudorandom" # could use "lowdiscrepancy"
numPaths = 500000
option_type = ql.Option.Call
strike_price = 40

maturity_date = ql.Date(2, 4, 2021)
exercise = ql.EuropeanExercise(maturity_date)
payoff=ql.PlainVanillaPayoff(ql.Option.Call, strike_price)
binary_option = ql.VanillaOption(payoff, exercise)

engine = ql.MCEuropeanEngine(process, rng, steps, requiredSamples=numPaths)

Run with Monte Carlo

binary_option.setPricingEngine(engine)
price = binary_option.NPV()
print("Monte Carlo Price: {}".format(price))

Run with Analytic Engine

engine = ql.AnalyticEuropeanEngine(process)
binary_option.setPricingEngine(engine)
print("Analytic Price: {}".format(binary_option.NPV()))

The output is:

Monte Carlo Price: 2.5199444258975885

Analytic Price: 2.5135333959120034
$\endgroup$
1
$\begingroup$

You will need to change the payoff from:

payoff = ql.PlainVanillaPayoff(ql.Option.Call, strike_price)

to

payoff = ql.CashOrNothingPayoff(ql.Option.Call, strike_price, 1)
$\endgroup$
2
  • $\begingroup$ It is showing the following error: runfile('C:/Users/nitin.kapai/Documents/Exam_v1/QuantLib Code/Binary_Options_MC_Simulation_QuantLib.py', wdir='C:/Users/nitin.kapai/Documents/Exam_v1/QuantLib Code') Traceback (most recent call last): File "C:\Users\nitin.kapai\Documents\Exam_v1\QuantLib Code\Binary_Options_MC_Simulation_QuantLib.py", line 34, in <module> price = binary_option.NPV() File "C:\Users\nitin.kapai\Anaconda3\lib\site-packages\QuantLib\QuantLib.py", line 9172, in NPV return _QuantLib.Instrument_NPV(self) RuntimeError: non-plain payoff given $\endgroup$ – Desi_Quant Sep 4 '20 at 12:24
  • $\begingroup$ I am adding my code to the "Answer Your Question" section $\endgroup$ – Desi_Quant Sep 4 '20 at 12:26
0
$\begingroup$
import QuantLib as ql

today = ql.Date().todaysDate()

initialValue = 40

riskFreeTS = ql.YieldTermStructureHandle(ql.FlatForward(today, 0.01, ql.Actual365Fixed()))

dividendTS = ql.YieldTermStructureHandle(ql.FlatForward(today, 0.02, ql.Actual365Fixed()))

volatility = ql.BlackVolTermStructureHandle(ql.BlackConstantVol(today, ql.NullCalendar(), 0.2, ql.Actual365Fixed()))


process = ql.BlackScholesMertonProcess(ql.QuoteHandle(ql.SimpleQuote(40)), riskFreeTS, dividendTS, volatility)

steps = 2

rng = "pseudorandom" # could use "lowdiscrepancy"

numPaths = 500000

option_type = ql.Option.Call

strike_price = 40

maturity_date = ql.Date(2, 4, 2021)

exercise = ql.EuropeanExercise(maturity_date)

payoff = ql.CashOrNothingPayoff(ql.Option.Call, strike_price, 1)

binary_option = ql.VanillaOption(payoff, exercise)

engine = ql.MCEuropeanEngine(process, rng, steps, requiredSamples=numPaths)

#Run with Monte Carlo

binary_option.setPricingEngine(engine)

price = binary_option.NPV()

print("Monte Carlo Price: {}".format(price))

# Run with Analytic Engine

engine = ql.AnalyticEuropeanEngine(process)

binary_option.setPricingEngine(engine)

print("Analytic Price: {}".format(binary_option.NPV()))
$\endgroup$
4
  • $\begingroup$ I initially started with this version of code where I used CashorNothingPayoff, but it was throwing an error. Then I used PlainVanillaPayoff which was getting compiled. $\endgroup$ – Desi_Quant Sep 4 '20 at 12:38
  • $\begingroup$ Hiya... so this is annoying. QL has an engine called ql.MCDigitalEngine which is what you need, but it's not available in the Python port yet. In the mean time, if you need a numerical pricer you could try the finite difference pricer again, which DOES work for digitals... try this (works for me and generates a price of 0.4793): #Run with FD tGrid, xGrid = 2000, 200 engine = ql.FdBlackScholesVanillaEngine(process, tGrid, xGrid) binary_option.setPricingEngine(engine) price = binary_option.NPV() print("FD Price: {}".format(price)) $\endgroup$ – StackG Sep 4 '20 at 12:44
  • $\begingroup$ Wow that code does not look good in comment format, but add some line breaks and it should work! $\endgroup$ – StackG Sep 4 '20 at 12:44
  • $\begingroup$ Yep that works! Thanks StackG!! $\endgroup$ – Desi_Quant Sep 4 '20 at 12:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.