I need some guidance on valuing American style FX options (spots and forwards) using quantlib in Python. Given the following parameters:
- Domestic and foreign risk-free rates
- Current market spot and forward points for the underlying asset (maturity at option exercise date plus tenor) - as an aside, does the maturity move forward for an early exercise of the option?
- Approximate volatility of the underlying (by using historical prices)
- Strike price
- Expiration date
- Maturity date
Here is what I have tried so far:
# QuantLib date settings todayDate = ql.Date().todaysDate() ql.Settings.instance().evaluationDate = todayDate dayCount = ql.ActualActual() volatilityHandle = ql.BlackVolTermStructureHandle( ql.BlackConstantVol(todayDate, ql.NullCalendar(), ql.QuoteHandle(ql.SimpleQuote(req.Volatility)), dayCount) ) # define the option option = ql.VanillaOption( ql.PlainVanillaPayoff(ql.Option.Call, req.StrikePrice), ql.AmericanExercise(req.ExpirationDate) ) # build the process localInterestRateHandle = ql.YieldTermStructureHandle( ql.FlatForward(todayDate, req.LocalInterestRate / 100, dayCount) ) # this is the one big issue - for FX options, both the domestic and # foreign risk-free rates have to be considered, but the # BlackScholesProcess does not cater for this. # foreignInterestRateHandle = ql.YieldTermStructureHandle( # ql.FlatForward(todayDate, req.ForeignInterestRate / 100, dayCount) # ) process = ql.BlackScholesProcess( ql.QuoteHandle(ql.SimpleQuote(req.SpotPrice + req.ForwardPoints)), localInterestRateHandle, volatilityHandle, ) # set the pricing engine option.setPricingEngine(ql.MCAmericanEngine(process, "pseudorandom", timeSteps=100, requiredSamples=1000)) return GetOptionValueResponse(OptionValue=option.NPV())
The biggest issue is that (as commented), the
BlackScholesProcess does not cater for domestic and foreign RFRs. The
GarmanKohlagenProcess does work for European options, but I have not seen a similar process for American options.
For more clarity, this is the request class passed to the function:
@dataclass class GetOptionValueRequest: """The request parameters of the GetEuropeanOptionValue service.""" SpotPrice: float """The latest spot price of the underlying asset.""" ForwardPoints: float """The latest forward points of the underlying asset.""" StrikePrice: float """The strike price of the option.""" ExpirationDate: date """The expiration date of the option in days.""" LocalInterestRate: float """The risk-free interest rate of the local currency as a percentage""" ForeignInterestRate: float """The risk-free interest rate of the foreign currency as a percentage""" Volatility: float """The volatility of the underlying asset"""