I am having trouble using QuantLib with Python to calculate American options with discrete dividends. I am using Anaconda, Spyder, Python 3.6, and the most recent version of QuantLib. I created functions in pricingfunctions.py, which streamline the building process for pricing options and the greeks based on the code on this webpage - http://www.bnikolic.co.uk/blog/ql-american-disc-dividend.html:
import QuantLib as ql
#%%
def create_american_process(valuation_date, rf_rate, spot, ivol):
#set calendar & day count
calendar = ql.UnitedStates()
day_counter = ql.ActualActual()
#set evaluation date
ql.Settings.instance().evaluation_date = valuation_date
#set rate & vol curves
rate_ts = ql.FlatForward(valuation_date, ql.QuoteHandle(rf_rate),
day_counter)
vol_ts = ql.BlackConstantVol(valuation_date, calendar,
ql.QuoteHandle(ivol), day_counter)
#create process
process = ql.BlackScholesProcess(ql.QuoteHandle(spot),
ql.YieldTermStructureHandle(rate_ts),
ql.BlackVolTermStructureHandle(vol_ts))
return process
#%%
def american_px_greeks(valuation_date, expiry, call_or_put, strike, div_dates,
div_values, time_steps, process):
#create instance as call or put
if call_or_put.lower() == 'call':
option_type = ql.Option.Call
elif call_or_put.lower() == 'put':
option_type = ql.Option.Put
else:
raise ValueError("The call_or_put value must be call or put.")
#set exercise and payoff
exercise = ql.AmericanExercise(valuation_date, expiry)
payoff = ql.PlainVanillaPayoff(option_type, strike)
#create option instance
option = ql.DividendVanillaOption(payoff, exercise, div_dates, div_values)
#set mesh size for finite difference engine
grid_points = time_steps - 1
#create engine
engine = ql.FDDividendAmericanEngine(process, time_steps, grid_points)
option.setPricingEngine(engine)
return option
#%%
def print_option_results(option):
print("NPV: ", option.NPV())
print("Delta: ", option.delta())
print("Gamma: ", option.gamma())
return None
Then I run the below script, but the outputs for NPV, Delta and Gamma are all 0.0, which is wrong. The NPV should be in the 12 to 13 range, and the Delta close to 0.50, while Gamma is negligible. I am not sure what is wrong. Any insights are much appreciated. Thanks
import QuantLib as ql
from pricingfunctions import create_american_process
from pricingfunctions import american_px_greeks
from pricingfunctions import print_option_results
#%%
#parameters
vol = 0.25
strike = 100
spot = ql.SimpleQuote(100)
rf_rate = ql.SimpleQuote(0.01)
ivol = ql.SimpleQuote(vol)
call_or_put = 'call'
div_dates = [ql.Date(14, 5, 2014), ql.Date(14, 8, 2014), ql.Date(14, 11, 2014)]
div_values = [1.0, 1.0, 1.0]
expiry = ql.Date(15, 1, 2016)
valuation_date = ql.Date(17, 4, 2014)
time_steps = 456
process_test = create_american_process(valuation_date, rf_rate, spot, ivol)
option_test = american_px_greeks(valuation_date, expiry, call_or_put, strike, div_dates, div_values, time_steps, process_test)
print_option_results(option_test)
AttributeError: No constructor defined
I can't callql.FDDividendAmericanEngine
$\endgroup$