1
$\begingroup$

I need some guidance on valuing American style FX options (spots and forwards) using quantlib in Python. Given the following parameters:

  1. Domestic and foreign risk-free rates
  2. 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?
  3. Approximate volatility of the underlying (by using historical prices)
  4. Strike price
  5. Expiration date
  6. 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"""
$\endgroup$
1
  • 2
    $\begingroup$ What have you tried so far? Adding your coding attempt to your post may help people here help you. $\endgroup$
    – amdopt
    Jul 20, 2023 at 12:14

1 Answer 1

3
$\begingroup$

The GarmanKohlagenProcess manages both foreign and domestic curves and can be passed to every engine that asks for a GeneralizedBlackScholesProcess.

I wouldn't choose MCAmericanEngine, though; it uses a Longstaff-Schwarz simulation, and you probably don't need that complexity and the calculation time it requires. You're probably better off using either a binomial tree (with an engine like BinomialCRRVanillaEngine, or one of the others listed here) or a finite-difference model (with the FdBlackScholesVanillaEngine).

However, I'm afraid that VanillaOption only models spot options.

$\endgroup$
6
  • $\begingroup$ Thanks so much for you feedback Luigi, much appreciated. In short, if I understand you correctly I can use the GarmanKohlagenProcess for American Spot Options (VanillaOption), and that you recommend one of the Binomial engines or the FdBlackScholesVanillaEngine? $\endgroup$
    – bouwerp
    Jul 25, 2023 at 18:09
  • $\begingroup$ Also, I just want to confirm: Can the European and Barrier option types model forward contracts? $\endgroup$
    – bouwerp
    Jul 26, 2023 at 6:54
  • 1
    $\begingroup$ Your first comment: correct. $\endgroup$ Jul 26, 2023 at 12:49
  • 1
    $\begingroup$ Your second comment: no. There's a ForwardVanillaOption class, but I'm not sure it does what you mean; it models an option whose strike is to be determined at some future date based on the value of the underlying. $\endgroup$ Jul 26, 2023 at 12:50
  • $\begingroup$ OK thanks - so basically only spot underlying assets can be priced currently. $\endgroup$
    – bouwerp
    Jul 27, 2023 at 7:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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