I am trying to calculate the price of an american option. The code works fine for some options but for an deep out of the money call, I get the above error. Below is my code that I am trying to run.
I am new to QuantLib so any pointers to resolve the issue, will be of great help. I see the error comes at the very last statement when calculating the NPV, but not sure how to resolve, if I need to tweak anything in my code?
def calc_scn_price(p_und_price,p_strike,p_imp_vol,p_op_type,p_exp_date,p_und_bbg_tckr,p_div_yield):
t_date = dt.datetime.today() day_count = ql.Actual365Fixed() calendar = ql.UnitedStates() calculation_date = ql.Date(t_date.day,t_date.month,t_date.year)
#print("Input to pricer :::",800,' Strike: ',1600.0,' Implied Vol: ',57.82902561325027,' Option Type: ','Call'," Exp Date: ","2021-09-17 00:00:00"," Underlier Ticker: ","TSLA US Equity")
# Settings for evaluation
ql.Settings.instance().evaluationDate = calculation_date
# Risk free rate
v_rfr = 0.0169
v_matur_dt = ql.Date(p_exp_date.day, p_exp_date.month, p_exp_date.year)
# Option Type
if p_op_type == 'Call':
v_op_type = ql.Option.Call
elif p_op_type == 'Put':
v_op_type = ql.Option.Put
else:
raise ValueError("Option Type must be only Call or Put")
# Setup the option
payoff = ql.PlainVanillaPayoff(v_op_type, float(p_strike))
settlement = calculation_date # Assume the transaction happens today since it is an American option
am_excercise = ql.AmericanExercise(settlement, v_matur_dt)
american_option = ql.VanillaOption(payoff, am_excercise)
# ***********Setup Black Scholes Process*********#
S = ql.QuoteHandle(ql.SimpleQuote(p_und_price)) # Underlier Spot Price
r = ql.YieldTermStructureHandle(ql.FlatForward(calculation_date, v_rfr, day_count)) # Risk free rate
v_div_yield = p_div_yield
#v_bbg = blp.bdp(tickers=p_und_bbg_tckr, flds=['PX_LAST','EQY_DVD_YLD_IND'])
#print("Here \n",v_bbg,p_und_bbg_tckr,v_bbg['px_last'].tolist()[0])
# dividend yield - fetch from bbg
#print(v_div_yield)
dividend_yield = ql.YieldTermStructureHandle(ql.FlatForward(calculation_date, float(v_div_yield), day_count))
sigma = ql.BlackVolTermStructureHandle(
ql.BlackConstantVol(calculation_date, calendar, p_imp_vol, day_count))
bsm_process = ql.BlackScholesMertonProcess(S, dividend_yield, r, sigma)
# Use derived implied vol to calculate scenario Option price
am_steps = 800
# Run the engine
binomial_engine = ql.BinomialVanillaEngine(bsm_process, "crr", am_steps)
american_option.setPricingEngine(binomial_engine)
v_op_price = american_option.NPV()
#print(v_op_price)
return v_op_price