示例#1
0
def test_FinEquityForward():

    valueDate = FinDate(13, 2, 2018)
    expiryDate = valueDate.addMonths(12)

    stockPrice = 130.0
    forwardPrice = 125.0  # Locked
    discountRate = 0.05
    dividendRate = 0.02

    ###########################################################################

    expiryDate = valueDate.addMonths(12)
    notional = 100.0

    discountCurve = FinDiscountCurveFlat(valueDate, discountRate)
    dividendCurve = FinDiscountCurveFlat(valueDate, dividendRate)

    equityForward = FinEquityForward(expiryDate, forwardPrice, notional,
                                     FinLongShort.LONG)

    testCases.header("SPOT FX", "FX FWD", "VALUE_BS")

    fwdPrice = equityForward.forward(valueDate, stockPrice, discountCurve,
                                     dividendCurve)

    fwdValue = equityForward.value(valueDate, stockPrice, discountCurve,
                                   dividendCurve)

    print(stockPrice, fwdPrice, fwdValue)
    testCases.print(stockPrice, fwdPrice, fwdValue)
示例#2
0
    def build_vol_surface(self, value_date):
        """Builds the implied volatility surface for a particular value date and calculates the benchmark strikes etc.

        Before we do any sort of interpolation later, we need to build the implied_vol vol surface.

        Parameters
        ----------
        value_date : str
            Value date (need to have market data for this date)

        asset : str
            Asset name

        depo_tenor : str
            Depo tenor to use

            default - '1M'

        field : str
            Market data field to use

            default - 'close'
        """

        self._value_date = self._market_util.parse_date(value_date)

        value_fin_date = self._findate(self._value_date)

        date_index = self._market_df.index == value_date

        # TODO: add whole rates curve
        dom_discount_curve = FinDiscountCurveFlat(value_fin_date,
                                                  self._domCCRate[date_index])
        for_discount_curve = FinDiscountCurveFlat(value_fin_date,
                                                  self._forCCRate[date_index])

        self._dom_discount_curve = dom_discount_curve
        self._for_discount_curve = for_discount_curve

        self._spot = float(self._spot_history[date_index][0])

        # New implementation in FinancePy also uses 10d for interpolation
        self._fin_fx_vol_surface = FinFXVolSurface(
            value_fin_date,
            self._spot,
            self._asset,
            self._asset[0:3],
            dom_discount_curve,
            for_discount_curve,
            self._tenors.copy(),
            self._atm_vols[date_index][0],
            self._market_strangle25DeltaVols[date_index][0],
            self._risk_reversal25DeltaVols[date_index][0],
            self._market_strangle10DeltaVols[date_index][0],
            self._risk_reversal10DeltaVols[date_index][0],
            self._alpha,
            atmMethod=self._atm_method,
            deltaMethod=self._delta_method,
            volatilityFunctionType=self._vol_function_type,
            finSolverType=self._solver)
示例#3
0
def test_FinEquityChooserOptionHaug():
    ''' Following example in Haug Page 130 '''

    valueDate = FinDate(1, 1, 2015)
    chooseDate = FinDate(2, 4, 2015)
    callExpiryDate = FinDate(1, 7, 2015)
    putExpiryDate = FinDate(2, 8, 2015)
    callStrike = 55.0
    putStrike = 48.0
    stockPrice = 50.0
    volatility = 0.35
    interestRate = 0.10
    dividendYield = 0.05

    model = FinModelBlackScholes(volatility)
    discountCurve = FinDiscountCurveFlat(valueDate, interestRate)
    dividendCurve = FinDiscountCurveFlat(valueDate, dividendYield)

    chooserOption = FinEquityChooserOption(chooseDate, callExpiryDate,
                                           putExpiryDate, callStrike,
                                           putStrike)

    v = chooserOption.value(valueDate, stockPrice, discountCurve,
                            dividendCurve, model)

    v_mc = chooserOption.valueMC(valueDate, stockPrice, discountCurve,
                                 dividendCurve, model, 20000)

    v_haug = 6.0508
    testCases.header("", "", "", "", "", "")
    testCases.print("FINANCEPY", v, "HAUG", v_haug, "MC", v_mc)
def test_FinEquityCliquetOption():

    startDate = FinDate(1, 1, 2014)
    finalExpiryDate = FinDate(1, 1, 2017)
    freqType = FinFrequencyTypes.QUARTERLY
    optionType = FinOptionTypes.EUROPEAN_CALL

    cliquetOption = FinEquityCliquetOption(startDate,
                                           finalExpiryDate,
                                           optionType,
                                           freqType)

    valueDate = FinDate(1, 1, 2015)
    stockPrice = 100.0
    volatility = 0.20
    interestRate = 0.05
    dividendYield = 0.02
    model = FinModelBlackScholes(volatility)
    discountCurve = FinDiscountCurveFlat(valueDate, interestRate)
    dividendCurve = FinDiscountCurveFlat(valueDate, dividendYield)

    v = cliquetOption.value(valueDate,
                            stockPrice,
                            discountCurve,
                            dividendCurve,
                            model)

    testCases.header("LABEL", "VALUE")
    testCases.print("FINANCEPY", v)
示例#5
0
def test_FinFXMktVolSurface4(verboseCalibration):

    # USDJPY Example from Paper by Uwe Wystup using Tables 4
    #        print("USDJPY EXAMPLE WYSTUP")

    valueDate = FinDate(20, 1, 2009)

    forName = "USD"
    domName = "JPY"
    forCCRate = 0.003525  # USD
    domCCRate = 0.0042875  # JPY

    domDiscountCurve = FinDiscountCurveFlat(valueDate, domCCRate)
    forDiscountCurve = FinDiscountCurveFlat(valueDate, forCCRate)

    currencyPair = forName + domName
    spotFXRate = 90.68

    tenors = ['1M']
    atmVols = [21.00]
    marketStrangle25DeltaVols = [0.184]
    riskReversal25DeltaVols = [-5.30]

    notionalCurrency = forName

    atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
    deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ

    fxMarket = FinFXVolSurface(valueDate, spotFXRate, currencyPair,
                               notionalCurrency, domDiscountCurve,
                               forDiscountCurve, tenors, atmVols,
                               marketStrangle25DeltaVols,
                               riskReversal25DeltaVols, atmMethod, deltaMethod)

    fxMarket.checkCalibration(verboseCalibration)
def test_example():

    expiryDate = FinDate(1, 1, 2021)
    strikePrice = 105.0
    optionTypeCall = FinOptionTypes.EUROPEAN_CALL
    optionTypePut = FinOptionTypes.EUROPEAN_PUT
    lookbackCall = FinEquityFixedLookbackOption(expiryDate, optionTypeCall,
                                                strikePrice)
    lookbackPut = FinEquityFixedLookbackOption(expiryDate, optionTypePut,
                                               strikePrice)

    valueDate = FinDate(1, 1, 2020)
    interestRate = 0.10
    stockPrice = 100.0
    dividendYield = 0.0
    stockMinMax = 100.0

    discountCurve = FinDiscountCurveFlat(valueDate, interestRate)
    dividendCurve = FinDiscountCurveFlat(valueDate, dividendYield)

    volatilities = [0.30]

    testCases.header("VALUE")
    for vol in volatilities:
        v = lookbackCall.value(valueDate, stockPrice, discountCurve,
                               dividendCurve, vol, stockMinMax)
        testCases.print(v)
示例#7
0
def test_FinEquityChooserOptionMatlab():
    '''https://fr.mathworks.com/help/fininst/chooserbybls.html '''

    valueDate = FinDate(1, 6, 2007)
    chooseDate = FinDate(31, 8, 2007)
    callExpiryDate = FinDate(2, 12, 2007)
    putExpiryDate = FinDate(2, 12, 2007)
    callStrike = 60.0
    putStrike = 60.0
    stockPrice = 50.0
    volatility = 0.20
    interestRate = 0.10
    dividendYield = 0.05

    model = FinModelBlackScholes(volatility)

    discountCurve = FinDiscountCurveFlat(valueDate, interestRate)
    dividendCurve = FinDiscountCurveFlat(valueDate, dividendYield)

    chooserOption = FinEquityChooserOption(chooseDate, callExpiryDate,
                                           putExpiryDate, callStrike,
                                           putStrike)

    v = chooserOption.value(valueDate, stockPrice, discountCurve,
                            dividendCurve, model)

    v_mc = chooserOption.valueMC(valueDate, stockPrice, discountCurve,
                                 dividendCurve, model, 20000)

    v_matlab = 8.9308
    testCases.header("", "", "", "", "", "")
    testCases.print("FINANCEPY", v, "MATLAB", v_matlab, "MC", v_mc)
示例#8
0
def test_FinEquityChooserOptionDerivicom():
    '''http://derivicom.com/support/finoptionsxl/index.html?complex_chooser.htm '''

    valueDate = FinDate(1, 1, 2007)
    chooseDate = FinDate(1, 2, 2007)
    callExpiryDate = FinDate(1, 4, 2007)
    putExpiryDate = FinDate(1, 5, 2007)
    callStrike = 40.0
    putStrike = 35.0
    stockPrice = 38.0
    volatility = 0.20
    interestRate = 0.08
    dividendYield = 0.0625

    model = FinModelBlackScholes(volatility)
    discountCurve = FinDiscountCurveFlat(valueDate, interestRate)
    dividendCurve = FinDiscountCurveFlat(valueDate, dividendYield)

    chooserOption = FinEquityChooserOption(chooseDate, callExpiryDate,
                                           putExpiryDate, callStrike,
                                           putStrike)

    v = chooserOption.value(valueDate, stockPrice, discountCurve,
                            dividendCurve, model)

    v_mc = chooserOption.valueMC(valueDate, stockPrice, discountCurve,
                                 dividendCurve, model, 20000)

    v_derivicom = 1.0989
    testCases.header("", "", "", "", "", "")
    testCases.print("FINANCEPY", v, "DERIVICOM", v_derivicom, "MC", v_mc)
示例#9
0
def test_FinFXMktVolSurface3(verboseCalibration):

    # EURUSD Example from Paper by Uwe Wystup using Tables 4
    #        print("EURUSD EXAMPLE WYSTUP")

    valueDate = FinDate(20, 1, 2009)

    forName = "EUR"
    domName = "USD"
    forCCRate = 0.020113  # EUR
    domCCRate = 0.003525  # USD

    domDiscountCurve = FinDiscountCurveFlat(valueDate, domCCRate)
    forDiscountCurve = FinDiscountCurveFlat(valueDate, forCCRate)

    currencyPair = forName + domName
    spotFXRate = 1.3088

    tenors = ['1M']
    atmVols = [21.6215]
    marketStrangle25DeltaVols = [0.7375]
    riskReversal25DeltaVols = [-0.50]

    notionalCurrency = forName

    atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
    deltaMethod = FinFXDeltaMethod.SPOT_DELTA

    fxMarket = FinFXVolSurface(valueDate, spotFXRate, currencyPair,
                               notionalCurrency, domDiscountCurve,
                               forDiscountCurve, tenors, atmVols,
                               marketStrangle25DeltaVols,
                               riskReversal25DeltaVols, atmMethod, deltaMethod)

    fxMarket.checkCalibration(verboseCalibration)
示例#10
0
def test_FinFXMktVolSurface5(verboseCalibration):

    ###########################################################################
    # Here I remove the 10D Vols
    ###########################################################################
    
    if 1 == 1:

        # Example from Book extract by Iain Clark using Tables 3.3 and 3.4
        # print("EURUSD EXAMPLE CLARK")

        valueDate = FinDate(10, 4, 2020)

        forName = "EUR"
        domName = "USD"
        forCCRate = 0.03460  # EUR
        domCCRate = 0.02940  # USD

        domDiscountCurve = FinDiscountCurveFlat(valueDate, domCCRate)
        forDiscountCurve = FinDiscountCurveFlat(valueDate, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atmVols = [21.00, 21.00, 20.750, 19.400, 18.250, 17.677]
        marketStrangle25DeltaVols = [0.65, 0.75, 0.85, 0.90, 0.95, 0.85]
        riskReversal25DeltaVols = [-0.20, -0.25, -0.30, -0.50, -0.60, -0.562]
        marketStrangle10DeltaVols = [2.433, 2.83, 3.228, 3.485, 3.806, 3.208]
        riskReversal10DeltaVols = [-1.258, -1.297, -1.332, -1.408, -1.359, -1.208]

        marketStrangle10DeltaVols = None
        riskReversal10DeltaVols = None
        
        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA
        volFunctionType = FinVolFunctionTypes.CLARK
        alpha = 0.50 # FIT WINGS AT 10D if ALPHA = 1.0

        fxMarketPlus = FinFXVolSurfacePlus(valueDate,
                                       spotFXRate,
                                       currencyPair,
                                       notionalCurrency,
                                       domDiscountCurve,
                                       forDiscountCurve,
                                       tenors,
                                       atmVols,
                                       marketStrangle25DeltaVols,
                                       riskReversal25DeltaVols,
                                       marketStrangle10DeltaVols,
                                       riskReversal10DeltaVols,
                                       alpha,
                                       atmMethod,
                                       deltaMethod, 
                                       volFunctionType)

        fxMarketPlus.checkCalibration(False)
示例#11
0
def test_FinFXMktVolSurface1(verboseCalibration):

    ###########################################################################

    if 1 == 1:

        # Example from Book extract by Iain Clark using Tables 3.3 and 3.4
        # print("EURUSD EXAMPLE CLARK")

        valueDate = FinDate(10, 4, 2020)

        forName = "EUR"
        domName = "USD"
        forCCRate = 0.03460  # EUR
        domCCRate = 0.02940  # USD

        domDiscountCurve = FinDiscountCurveFlat(valueDate, domCCRate)
        forDiscountCurve = FinDiscountCurveFlat(valueDate, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atmVols = [21.00, 21.00, 20.750, 19.400, 18.250, 17.677]
        marketStrangle25DeltaVols = [0.65, 0.75, 0.85, 0.90, 0.95, 0.85]
        riskReversal25DeltaVols = [-0.20, -0.25, -0.30, -0.50, -0.60, -0.562]
        marketStrangle10DeltaVols = [2.433, 2.83, 3.228, 3.485, 3.806, 3.208]
        riskReversal10DeltaVols = [
            -1.258, -1.297, -1.332, -1.408, -1.359, -1.208
        ]

        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA
        volFunctionType = FinVolFunctionTypes.CLARK5
        alpha = 0.5  # FIT WINGS AT 10D if ALPHA = 1.0

        fxMarketPlus = FinFXVolSurfacePlus(
            valueDate, spotFXRate, currencyPair, notionalCurrency,
            domDiscountCurve, forDiscountCurve, tenors, atmVols,
            marketStrangle25DeltaVols, riskReversal25DeltaVols,
            marketStrangle10DeltaVols, riskReversal10DeltaVols, alpha,
            atmMethod, deltaMethod, volFunctionType)

        fxMarketPlus.checkCalibration(False)

        if 1 == 0:  # PLOT_GRAPHS:

            fxMarketPlus.plotVolCurves()

            plt.figure()

            dbns = fxMarketPlus.impliedDbns(0.5, 2.0, 1000)

            for i in range(0, len(dbns)):
                plt.plot(dbns[i]._x, dbns[i]._densitydx)
                plt.title(volFunctionType)
                print("SUM:", dbns[i].sum())
示例#12
0
def test_FinFXMktVolSurface2(verboseCalibration):

    #print("==============================================================")

    # Example from Book extract by Iain Clarke using Tables 3.3 and 3.4
    # print("EURJPY EXAMPLE CLARK")

    valueDate = FinDate(10, 4, 2020)

    forName = "EUR"
    domName = "JPY"
    forCCRate = 0.0294  # EUR
    domCCRate = 0.0171  # USD

    domDiscountCurve = FinDiscountCurveFlat(valueDate, domCCRate)
    forDiscountCurve = FinDiscountCurveFlat(valueDate, forCCRate)

    currencyPair = forName + domName
    spotFXRate = 90.72

    tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
    atmVols = [21.50, 20.50, 19.85, 18.00, 15.95, 14.009]
    marketStrangle25DeltaVols = [0.35, 0.325, 0.300, 0.225, 0.175, 0.100]
    riskReversal25DeltaVols = [-8.350, -8.650, -8.950, -9.250, -9.550, -9.500]
    marketStrangle10DeltaVols = [3.704, 4.047, 4.396, 4.932, 5.726, 5.709]
    riskReversal10DeltaVols = [
        -15.855, -16.467, -17.114, -17.882, -18.855, -18.217
    ]
    alpha = 0.50  # Equally fit 10 and 25 Delta

    notionalCurrency = forName

    atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL_PREM_ADJ
    deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ
    volFunctionType = FinVolFunctionTypes.CLARK5

    fxMarketPlus = FinFXVolSurfacePlus(
        valueDate, spotFXRate, currencyPair, notionalCurrency,
        domDiscountCurve, forDiscountCurve, tenors, atmVols,
        marketStrangle25DeltaVols, riskReversal25DeltaVols,
        marketStrangle10DeltaVols, riskReversal10DeltaVols, alpha, atmMethod,
        deltaMethod, volFunctionType)

    #        fxMarketPlus.checkCalibration(True)

    if PLOT_GRAPHS:
        fxMarketPlus.plotVolCurves()

        plt.figure()

        dbns = fxMarketPlus.impliedDbns(30, 120, 1000)

        for i in range(0, len(dbns)):
            plt.plot(dbns[i]._x, dbns[i]._densitydx)
            plt.title(volFunctionType)
            print("SUM:", dbns[i].sum())
示例#13
0
def test_FinFXVanillaOptionWystupExample2():

    # Example Bloomberg Pricing at
    # https://stackoverflow.com/questions/48778712/fx-vanilla-call-price-in-quantlib-doesnt-match-bloomberg

    valueDate = FinDate(13, 2, 2018)
    expiryDate = FinDate(13, 2, 2019)

    # In BS the FX rate is the price in domestic of one unit of foreign
    # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR
    # DOM = USD , FOR = EUR
    ccy1 = "EUR"
    ccy2 = "USD"
    ccy1CCRate = 0.0396  # EUR
    ccy2CCRate = 0.0357  # USD

    currencyPair = ccy1 + ccy2  # Always ccy1ccy2
    spotFXRate = 0.9090
    strikeFXRate = 0.9090
    volatility = 0.12

    notional = 1000000.0

    domDiscountCurve = FinDiscountCurveFlat(valueDate, ccy2CCRate)
    forDiscountCurve = FinDiscountCurveFlat(valueDate, ccy1CCRate)

    model = FinFXModelBlackScholes(volatility)

    # Two examples to show that changing the notional currency and notional
    # keeps the value unchanged
    notional = 1000000.0
    callOption = FinFXVanillaOption(expiryDate,
                                    strikeFXRate,
                                    currencyPair,
                                    FinOptionTypes.EUROPEAN_PUT,
                                    notional,
                                    "EUR", 2)

    value = callOption.value(
            valueDate,
            spotFXRate,
            domDiscountCurve,
            forDiscountCurve,
            model)

    delta = callOption.delta(
            valueDate,
            spotFXRate,
            domDiscountCurve,
            forDiscountCurve,
            model)

    testCases.header("value", "delta")
    testCases.print(value, delta)
def test_FinFXVanillaOptionWystupExample1():

    # Example from Book extract by Uwe Wystup with results in Table 1.2
    # https://mathfinance.com/wp-content/uploads/2017/06/FXOptionsStructuredProducts2e-Extract.pdf

    # Not exactly T=1.0 but close so don't exact exact agreement
    # (in fact I do not get exact agreement even if I do set T=1.0)
    valueDate = FinDate(13, 2, 2018)
    expiryDate = FinDate(13, 2, 2019)

    # In BS the FX rate is the price in domestic of one unit of foreign
    # In case of EURUSD = 1.3 the domestic currency is USD and foreign is EUR
    # DOM = USD , FOR = EUR
    ccy1 = "EUR"
    ccy2 = "USD"
    ccy1CCRate = 0.030  # EUR
    ccy2CCRate = 0.025  # USD

    currencyPair = ccy1 + ccy2  # Always ccy1ccy2
    spotFXRate = 1.20
    strikeFXRate = 1.250
    volatility = 0.10

    notional = 1000000.0

    domDiscountCurve = FinDiscountCurveFlat(valueDate, ccy2CCRate)
    forDiscountCurve = FinDiscountCurveFlat(valueDate, ccy1CCRate)

    model = FinFXModelBlackScholes(volatility)

    # Two examples to show that changing the notional currency and notional
    # keeps the value unchanged
    notional = 1000000.0
    callOption = FinFXVanillaOption(expiryDate, strikeFXRate, currencyPair,
                                    FinOptionTypes.EUROPEAN_CALL, notional,
                                    "EUR", 2)

    value = callOption.value(1.0, spotFXRate, domDiscountCurve,
                             forDiscountCurve, model)

    notional = 1250000.0
    callOption = FinFXVanillaOption(expiryDate, strikeFXRate, currencyPair,
                                    FinOptionTypes.EUROPEAN_CALL, notional,
                                    "USD", 2)

    value = callOption.value(valueDate, spotFXRate, domDiscountCurve,
                             forDiscountCurve, model)

    delta = callOption.delta(valueDate, spotFXRate, domDiscountCurve,
                             forDiscountCurve, model)

    testCases.header("value", "delta")
    testCases.print(value, delta)
示例#15
0
def test_FinFXMktVolSurface1():

    ###########################################################################

    if 1 == 1:

        # Example from Book extract by Iain Clarke using Tables 3.3 and 3.4
        # print("EURUSD EXAMPLE CLARKE")

        valueDate = FinDate(10, 4, 2020)

        forName = "EUR"
        domName = "USD"
        forCCRate = 0.03460  # EUR
        domCCRate = 0.02940  # USD

        domDiscountCurve = FinDiscountCurveFlat(valueDate, domCCRate)
        forDiscountCurve = FinDiscountCurveFlat(valueDate, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atmVols = [21.00, 21.00, 20.750, 19.400, 18.250, 17.677]
        marketStrangle25DeltaVols = [0.65, 0.75, 0.85, 0.90, 0.95, 0.85]
        riskReversal25DeltaVols = [-0.20, -0.25, -0.30, -0.50, -0.60, -0.562]

        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA

        fxMarket = FinFXVolSurface(valueDate,
                                   spotFXRate,
                                   currencyPair,
                                   notionalCurrency,
                                   domDiscountCurve,
                                   forDiscountCurve,
                                   tenors,
                                   atmVols,
                                   marketStrangle25DeltaVols,
                                   riskReversal25DeltaVols,
                                   atmMethod,
                                   deltaMethod)

#        fxMarket.checkCalibration(True)

        if PLOT_GRAPHS:
            fxMarket.plotVolCurves()

        dbns = fxMarket.impliedDbns(0.5, 2.5, 1000)
示例#16
0
def test_FinFXMktVolSurface2(verboseCalibration):

        #print("==============================================================")

        # Example from Book extract by Iain Clarke using Tables 3.3 and 3.4
        # print("EURJPY EXAMPLE CLARKE")

        valueDate = FinDate(10, 4, 2020)

        forName = "EUR"
        domName = "JPY"
        forCCRate = 0.0294  # EUR
        domCCRate = 0.0171  # USD

        domDiscountCurve = FinDiscountCurveFlat(valueDate, domCCRate)
        forDiscountCurve = FinDiscountCurveFlat(valueDate, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 90.72

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atmVols = [21.50, 20.50, 19.85, 18.00, 15.95, 14.009]
        marketStrangle25DeltaVols = [0.35, 0.325, 0.300, 0.225, 0.175, 0.100]
        riskReversal25DeltaVols = [-8.350, -8.650, -8.950, -9.250, -9.550, -9.500]
        marketStrangle10DeltaVols = [3.704, 4.047, 4.396, 4.932, 5.726, 5.709]
        riskReversal10DeltaVols = [-15.855, -16.467, -17.114, -17.882, -18.855, -18.217]

        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL_PREM_ADJ
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ

        fxMarket = FinFXVolSurfacePlus(valueDate,
                                       spotFXRate,
                                       currencyPair,
                                       notionalCurrency,
                                       domDiscountCurve,
                                       forDiscountCurve,
                                       tenors,
                                       atmVols,
                                       marketStrangle25DeltaVols,
                                       riskReversal25DeltaVols,
                                       marketStrangle10DeltaVols,
                                       riskReversal10DeltaVols,
                                       atmMethod,
                                       deltaMethod)

        fxMarket.checkCalibration(verboseCalibration)
示例#17
0
def testBlackModelCheck():

    # Checking Andersen paper using Black's model
    # Used to check swaption price below - we have Ts = 1 and Te = 4
    # Expect a price around 122 cents which is what I find.

    valuationDate = FinDate(1, 1, 2020)
    liborCurve = FinDiscountCurveFlat(valuationDate, 0.06,
                                      FinFrequencyTypes.SEMI_ANNUAL)

    settlementDate = FinDate(1, 1, 2020)
    exerciseDate = FinDate(1, 1, 2021)
    maturityDate = FinDate(1, 1, 2024)

    fixedCoupon = 0.06
    fixedFrequencyType = FinFrequencyTypes.SEMI_ANNUAL
    fixedDayCountType = FinDayCountTypes.THIRTY_E_360_ISDA
    notional = 100.0

    # Pricing a PAY
    swaptionType = FinSwapTypes.PAY
    swaption = FinIborSwaption(settlementDate, exerciseDate, maturityDate,
                               swaptionType, fixedCoupon, fixedFrequencyType,
                               fixedDayCountType, notional)

    model = FinModelBlack(0.20)
    v = swaption.value(valuationDate, liborCurve, model)
    testCases.header("LABEL", "VALUE")
    testCases.print("BLACK'S MODEL PRICE:", v * 100)
def test_FinEquityCliquetOptionHaug():
    ''' Following example in Haug Page 130 '''

    startDate = FinDate(1, 1, 2015)
    finalExpiryDate = FinDate(1, 1, 2017)
    freqType = FinFrequencyTypes.QUARTERLY
    optionType = FinOptionTypes.EUROPEAN_CALL

    cliquetOption = FinEquityCliquetOption(startDate,
                                           finalExpiryDate,
                                           optionType,
                                           freqType)

    valueDate = FinDate(1, 8, 2016)
    stockPrice = 50.0
    volatility = 0.35
    interestRate = 0.10
    dividendYield = 0.05
    model = FinModelBlackScholes(volatility)
    discountCurve = FinDiscountCurveFlat(valueDate, interestRate)

    v = cliquetOption.value(valueDate,
                            stockPrice,
                            discountCurve,
                            dividendYield,
                            model)

    testCases.header("LABEL", "VALUE")
    testCases.print("FINANCEPY", v)
示例#19
0
def test_FinBondOptionAmericanConvergenceONE():

    # Build discount curve
    settlementDate = FinDate(1, 12, 2019)
    discountCurve = FinDiscountCurveFlat(settlementDate, 0.05)

    # Bond details
    maturityDate = FinDate(1, 9, 2025)
    issueDate = FinDate(1, 9, 2016)
    coupon = 0.05
    freqType = FinFrequencyTypes.SEMI_ANNUAL
    accrualType = FinDayCountTypes.ACT_ACT_ICMA
    bond = FinBond(issueDate, maturityDate, coupon, freqType, accrualType)

    # Option Details
    expiryDate = FinDate(1, 12, 2020)
    strikePrice = 100.0
    face = 100.0

    testCases.header("TIME", "N", "PUT_AMER", "PUT_EUR", "CALL_AME",
                     "CALL_EUR")

    timeSteps = range(30, 100, 10)

    for numTimeSteps in timeSteps:

        sigma = 0.20
        a = 0.1

        start = time.time()

        optionType = FinOptionTypes.AMERICAN_PUT
        bondOption1 = FinBondOption(bond, expiryDate, strikePrice, face,
                                    optionType)
        model1 = FinModelRatesBK(sigma, a, numTimeSteps)
        v1put = bondOption1.value(settlementDate, discountCurve, model1)

        optionType = FinOptionTypes.EUROPEAN_PUT
        bondOption2 = FinBondOption(bond, expiryDate, strikePrice, face,
                                    optionType)
        model2 = FinModelRatesBK(sigma, a, numTimeSteps)
        v2put = bondOption2.value(settlementDate, discountCurve, model2)

        optionType = FinOptionTypes.AMERICAN_CALL
        bondOption1 = FinBondOption(bond, expiryDate, strikePrice, face,
                                    optionType)
        model1 = FinModelRatesBK(sigma, a, numTimeSteps)
        v1call = bondOption1.value(settlementDate, discountCurve, model1)

        optionType = FinOptionTypes.EUROPEAN_CALL
        bondOption2 = FinBondOption(bond, expiryDate, strikePrice, face,
                                    optionType)
        model2 = FinModelRatesBK(sigma, a, numTimeSteps)
        v2call = bondOption2.value(settlementDate, discountCurve, model2)

        end = time.time()

        period = end - start

        testCases.print(period, numTimeSteps, v1put, v2put, v1call, v2call)
示例#20
0
def test_OIS():

    startDate = FinDate(2018, 11, 30)
    endDate = FinDate(2028, 6, 20)

    endDate = startDate.addMonths(60)
    oisRate = 0.04
    isPayer = True
    fixedFreq = FinFrequencyTypes.ANNUAL
    fixedDayCount = FinDayCountTypes.ACT_ACT_ISDA
    floatFreq = FinFrequencyTypes.ANNUAL
    floatDayCount = FinDayCountTypes.ACT_ACT_ISDA
    notional = ONE_MILLION

    ois = FinOIS(startDate, endDate, oisRate, fixedFreq, fixedDayCount,
                 floatFreq, floatDayCount, isPayer, notional)

    valueDate = FinDate(2018, 11, 30)
    marketRate = 0.05
    indexCurve = FinDiscountCurveFlat(valueDate, marketRate,
                                      FinFrequencyTypes.ANNUAL)

    v = ois.value(startDate, indexCurve)
    testCases.header("LABEL", "VALUE")
    testCases.print("SWAP_VALUE", v)
示例#21
0
def test_FinLiborCapletHull():

    #  Hull Page 703, example 29.3
    todayDate = FinDate(20, 6, 2019)
    valuationDate = todayDate
    maturityDate = valuationDate.addTenor("2Y")
    liborCurve = FinDiscountCurveFlat(valuationDate, 0.070,
                                      FinFrequencyTypes.QUARTERLY,
                                      FinDayCountTypes.THIRTY_E_360)

    k = 0.08
    capFloorType = FinLiborCapFloorTypes.CAP
    capFloor = FinLiborCapFloor(valuationDate, maturityDate, capFloorType, k,
                                None, FinFrequencyTypes.QUARTERLY,
                                FinDayCountTypes.THIRTY_E_360)

    # Value cap using a single flat cap volatility
    model = FinModelBlack(0.20)
    capFloor.value(valuationDate, liborCurve, model)

    # Value cap by breaking it down into caplets using caplet vols
    capletStartDate = valuationDate.addTenor("1Y")
    capletEndDate = capletStartDate.addTenor("3M")

    vCaplet = capFloor.valueCapletFloorLet(valuationDate, capletStartDate,
                                           capletEndDate, liborCurve, model)

    # Cannot match Hull due to dates being adjusted
    testCases.header("CORRECT PRICE", "MODEL PRICE")
    testCases.print(517.29, vCaplet)
def test_OIS():

    # Here I follow the example in
    # https://blog.deriscope.com/index.php/en/excel-quantlib-overnight-index-swap

    startDate = FinDate(30, 11, 2018)
    endDate = FinDate(30, 11, 2023)

    endDate = startDate.addMonths(60)
    oisRate = 0.04
    swapType = FinSwapTypes.PAYER
    fixedFreq = FinFrequencyTypes.ANNUAL
    fixedDayCount = FinDayCountTypes.ACT_360
    floatFreq = FinFrequencyTypes.ANNUAL
    floatDayCount = FinDayCountTypes.ACT_360
    notional = ONE_MILLION

    ois = FinOIRSwap(startDate, endDate, swapType, oisRate, fixedFreq,
                     fixedDayCount, floatFreq, floatDayCount, notional)

    valueDate = FinDate(2018, 11, 30)
    marketRate = 0.05
    indexCurve = FinDiscountCurveFlat(valueDate, marketRate,
                                      FinFrequencyTypes.ANNUAL)

    v = ois.value(startDate, [], [], indexCurve, indexCurve)
    testCases.header("LABEL", "VALUE")
    testCases.print("SWAP_VALUE", v)

    print(v)
示例#23
0
def test_FinFloatIborLeg():

    effectiveDate = FinDate(28, 10, 2020)
    maturityDate = FinDate(28, 10, 2025)

    spread = 0.0
    freqType = FinFrequencyTypes.ANNUAL
    dayCountType = FinDayCountTypes.THIRTY_360_BOND
    notional = 10.0 * ONE_MILLION
    legPayRecType = FinSwapTypes.PAY
    calendarType = FinCalendarTypes.TARGET
    busDayAdjustType = FinBusDayAdjustTypes.FOLLOWING
    dateGenRuleType = FinDateGenRuleTypes.BACKWARD
    paymentLag = 0
    principal = 0.0

    swapFloatLeg = FinFloatLeg(effectiveDate, maturityDate, legPayRecType,
                               spread, freqType, dayCountType, notional,
                               principal, paymentLag, calendarType,
                               busDayAdjustType, dateGenRuleType)

    liborCurve = FinDiscountCurveFlat(effectiveDate, 0.05)

    firstFixing = 0.03

    v = swapFloatLeg.value(effectiveDate, liborCurve, liborCurve, firstFixing)
示例#24
0
def test_FinFXMktVolSurface2():

        #print("==============================================================")

        # Example from Book extract by Iain Clarke using Tables 3.3 and 3.4
        #print("EURJPY EXAMPLE CLARKE")

        valueDate = FinDate(10, 4, 2020)

        forName = "EUR"
        domName = "JPY"
        forCCRate = 0.0294  # EUR
        domCCRate = 0.0171  # USD

        domDiscountCurve = FinDiscountCurveFlat(valueDate, domCCRate)
        forDiscountCurve = FinDiscountCurveFlat(valueDate, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 90.72

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atmVols = [21.50, 21.00, 19.85, 18.00, 15.95, 14.009]
        marketStrangle25DeltaVols = [0.35, 0.325, 0.30, 0.225, 0.175, 0.10]
        riskReversal25DeltaVols = [-8.35, -8.65, -8.95, -9.25, -9.550, -9.500]

        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL_PREM_ADJ
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ

        fxMarket = FinFXVolSurface(valueDate,
                                   spotFXRate,
                                   currencyPair,
                                   notionalCurrency,
                                   domDiscountCurve,
                                   forDiscountCurve,
                                   tenors,
                                   atmVols,
                                   marketStrangle25DeltaVols,
                                   riskReversal25DeltaVols,
                                   atmMethod,
                                   deltaMethod)

#        fxMarket.checkCalibration(True)

        if PLOT_GRAPHS:
            fxMarket.plotVolCurves()
def testFinModelBlackScholes():

    valueDate = FinDate(8, 5, 2015)
    expiryDate = FinDate(15, 1, 2016)

    strikePrice = 130.0
    stockPrice = 127.62
    volatility = 0.20
    interestRate = 0.001
    dividendYield = 0.0163

    optionType = FinOptionTypes.AMERICAN_CALL
    euOptionType = FinOptionTypes.EUROPEAN_CALL

    amOption = FinEquityAmericanOption(expiryDate, strikePrice, optionType)

    ameuOption = FinEquityAmericanOption(expiryDate, strikePrice, euOptionType)

    euOption = FinEquityVanillaOption(expiryDate, strikePrice, euOptionType)

    discountCurve = FinDiscountCurveFlat(valueDate, interestRate,
                                         FinFrequencyTypes.CONTINUOUS,
                                         FinDayCountTypes.ACT_365F)

    numStepsPerYear = 400

    modelTree = FinModelBlackScholes(volatility,
                                     FinModelBlackScholesTypes.CRR_TREE,
                                     {'numStepsPerYear': numStepsPerYear})

    v = amOption.value(valueDate, stockPrice, discountCurve, dividendYield,
                       modelTree)
    #    print(v)

    modelApprox = FinModelBlackScholes(volatility,
                                       FinModelBlackScholesTypes.BARONE_ADESI,
                                       None)

    v = amOption.value(valueDate, stockPrice, discountCurve, dividendYield,
                       modelApprox)

    #    print(v)

    v = ameuOption.value(valueDate, stockPrice, discountCurve, dividendYield,
                         modelTree)

    #    print(v)

    v = euOption.value(valueDate, stockPrice, discountCurve, dividendYield,
                       modelTree)

    #    print(v)

    amTreeValue = []
    amBAWValue = []
    euTreeValue = []
    euAnalValue = []
    volatility = 0.20
示例#26
0
def test_FinFXMktVolSurface1(verboseCalibration):

    ###########################################################################

    if 1 == 1:

        # Example from Book extract by Iain Clarke using Tables 3.3 and 3.4
        # print("EURUSD EXAMPLE CLARKE")

        valueDate = FinDate(10, 4, 2020)

        forName = "EUR"
        domName = "USD"
        forCCRate = 0.03460  # EUR
        domCCRate = 0.02940  # USD

        domDiscountCurve = FinDiscountCurveFlat(valueDate, domCCRate)
        forDiscountCurve = FinDiscountCurveFlat(valueDate, forCCRate)

        currencyPair = forName + domName
        spotFXRate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atmVols = [21.00, 21.00, 20.750, 19.400, 18.250, 17.677]
        marketStrangle25DeltaVols = [0.65, 0.75, 0.85, 0.90, 0.95, 0.85]
        riskReversal25DeltaVols = [-0.20, -0.25, -0.30, -0.50, -0.60, -0.562]

        notionalCurrency = forName

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.SPOT_DELTA

        # EXPLORE AND TEST DIFFERENT CATEGORICAL PARAMETERS
        for atmMethod in FinFXATMMethod:
            for deltaMethod in FinFXDeltaMethod:
                for volFunctionType in FinVolFunctionTypes:

                    fxMarket = FinFXVolSurface(
                        valueDate, spotFXRate, currencyPair, notionalCurrency,
                        domDiscountCurve, forDiscountCurve, tenors, atmVols,
                        marketStrangle25DeltaVols, riskReversal25DeltaVols,
                        atmMethod, deltaMethod, volFunctionType)

                    fxMarket.checkCalibration(verboseCalibration)
示例#27
0
def test_FinEquityVarianceSwap():

    startDate = FinDate(20, 3, 2018)
    tenor = "3M"
    strike = 0.3 * 0.3

    volSwap = FinEquityVarianceSwap(startDate, tenor, strike)

    valuationDate = FinDate(20, 3, 2018)
    stockPrice = 100.0
    dividendYield = 0.0
    dividendCurve = FinDiscountCurveFlat(valuationDate, dividendYield)

    maturityDate = startDate.addMonths(3)

    atmVol = 0.20
    atmK = 100.0
    skew = -0.02 / 5.0  # defined as dsigma/dK
    strikes = np.linspace(50.0, 135.0, 18)
    vols = volSkew(strikes, atmVol, atmK, skew)
    volCurve = FinEquityVolCurve(valuationDate, maturityDate, strikes, vols)

    strikeSpacing = 5.0
    numCallOptions = 10
    numPutOptions = 10
    r = 0.05

    discountCurve = FinDiscountCurveFlat(valuationDate, r)

    useForward = False

    testCases.header("LABEL", "VALUE")

    k1 = volSwap.fairStrike(valuationDate, stockPrice, dividendCurve, volCurve,
                            numCallOptions, numPutOptions, strikeSpacing,
                            discountCurve, useForward)

    testCases.print("REPLICATION VARIANCE:", k1)

    k2 = volSwap.fairStrikeApprox(valuationDate, stockPrice, strikes, vols)
    testCases.print("DERMAN SKEW APPROX for K:", k2)
示例#28
0
def test_FinFixedOIS():

    # Here I follow the example in
    # https://blog.deriscope.com/index.php/en/excel-quantlib-overnight-index-swap

    effectiveDate = FinDate(30, 11, 2018)
    endDate = FinDate(30, 11, 2023)

    endDate = effectiveDate.addMonths(60)
    oisRate = 0.04
    fixedLegType = FinSwapTypes.PAY
    fixedFreqType = FinFrequencyTypes.ANNUAL
    fixedDayCount = FinDayCountTypes.ACT_360
    floatFreqType = FinFrequencyTypes.ANNUAL
    floatDayCount = FinDayCountTypes.ACT_360
    floatSpread = 0.0
    notional = ONE_MILLION
    paymentLag = 1

    ois = FinOIS(effectiveDate, endDate, fixedLegType, oisRate, fixedFreqType,
                 fixedDayCount, notional, paymentLag, floatSpread,
                 floatFreqType, floatDayCount)

    #    print(ois)

    valueDate = effectiveDate
    marketRate = 0.05
    oisCurve = FinDiscountCurveFlat(valueDate, marketRate,
                                    FinFrequencyTypes.ANNUAL)

    v = ois.value(effectiveDate, oisCurve)

    #    print(v)

    #    ois._fixedLeg.printValuation()
    #    ois._floatLeg.printValuation()

    testCases.header("LABEL", "VALUE")
    testCases.print("SWAP_VALUE", v)
def test_FinBondEmbeddedOptionQUANTLIB():

    # Based on example at the nice blog on Quantlib at
    # http://gouthamanbalaraman.com/blog/callable-bond-quantlib-python.html
    # I get a price of 68.97 for 1000 time steps which is higher than the
    # 68.38 found in blog article. But this is for 40 grid points.
    # Note also that a basis point vol of 0.120 is 12% which is VERY HIGH!

    valuationDate = FinDate(16, 8, 2016)
    settlementDate = valuationDate.addWeekDays(3)

    ###########################################################################

    discountCurve = FinDiscountCurveFlat(valuationDate, 0.035,
                                         FinFrequencyTypes.SEMI_ANNUAL)

    ###########################################################################

    issueDate = FinDate(15, 9, 2010)
    maturityDate = FinDate(15, 9, 2022)
    coupon = 0.025
    freqType = FinFrequencyTypes.QUARTERLY
    accrualType = FinDayCountTypes.ACT_ACT_ICMA
    bond = FinBond(issueDate, maturityDate, coupon, freqType, accrualType)

    ###########################################################################
    # Set up the call and put times and prices
    ###########################################################################

    nextCallDate = FinDate(15, 9, 2016)
    callDates = [nextCallDate]
    callPrices = [100.0]

    for i in range(1, 24):
        nextCallDate = nextCallDate.addMonths(3)
        callDates.append(nextCallDate)
        callPrices.append(100.0)

    putDates = []
    putPrices = []

    # the value used in blog of 12% bp vol is unrealistic
    sigma = 0.12  # basis point volatility
    a = 0.03

    puttableBond = FinBondEmbeddedOption(issueDate, maturityDate, coupon,
                                         freqType, accrualType, callDates,
                                         callPrices, putDates, putPrices)

    testCases.header("BOND PRICE", "PRICE")
    v = bond.cleanPriceFromDiscountCurve(settlementDate, discountCurve)
    testCases.print("Bond Pure Price:", v)

    testCases.header("TIME", "NumTimeSteps", "BondWithOption", "BondPure")
    timeSteps = range(100, 1000, 100)
    values = []
    for numTimeSteps in timeSteps:
        model = FinModelRatesHW(sigma, a, numTimeSteps)
        start = time.time()
        v = puttableBond.value(settlementDate, discountCurve, model)
        end = time.time()
        period = end - start
        testCases.print(period, numTimeSteps, v['bondwithoption'],
                        v['bondpure'])
        values.append(v['bondwithoption'])

    if plotGraphs:
        plt.figure()
        plt.title("Puttable Bond Price Convergence")
        plt.plot(timeSteps, values)
def test_FinEquityBasketOption():

    import time

    valueDate = FinDate(2015, 1, 1)
    expiryDate = FinDate(2016, 1, 1)
    volatility = 0.30
    interestRate = 0.05
    discountCurve = FinDiscountCurveFlat(valueDate, interestRate)

    ##########################################################################
    # Homogeneous Basket
    ##########################################################################

    numAssets = 5
    volatilities = np.ones(numAssets) * volatility
    dividendYields = np.ones(numAssets) * 0.01
    stockPrices = np.ones(numAssets) * 100

    betaList = np.linspace(0.0, 0.999999, 11)

    testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME")

    for beta in betaList:
        for numPaths in [10000]:
            callOption = FinEquityBasketOption(expiryDate, 100.0,
                                               FinOptionTypes.EUROPEAN_CALL,
                                               numAssets)
            betas = np.ones(numAssets) * beta
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()
            v = callOption.value(valueDate, stockPrices, discountCurve,
                                 dividendYields, volatilities, corrMatrix)

            vMC = callOption.valueMC(valueDate, stockPrices, discountCurve,
                                     dividendYields, volatilities, corrMatrix,
                                     numPaths)
            end = time.time()
            duration = end - start
            testCases.print(numPaths, beta, v, vMC, duration)

    ##########################################################################
    # INHomogeneous Basket
    ##########################################################################

    numAssets = 5
    volatilities = np.array([0.3, 0.2, 0.25, 0.22, 0.4])
    dividendYields = np.array([0.01, 0.02, 0.04, 0.01, 0.02])
    stockPrices = np.array([100, 105, 120, 100, 90])

    betaList = np.linspace(0.0, 0.999999, 11)

    testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME")

    for beta in betaList:

        for numPaths in [10000]:

            callOption = FinEquityBasketOption(expiryDate, 100.0,
                                               FinOptionTypes.EUROPEAN_CALL,
                                               numAssets)
            betas = np.ones(numAssets) * beta
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()

            v = callOption.value(valueDate, stockPrices, discountCurve,
                                 dividendYields, volatilities, corrMatrix)

            vMC = callOption.valueMC(valueDate, stockPrices, discountCurve,
                                     dividendYields, volatilities, corrMatrix,
                                     numPaths)

            end = time.time()
            duration = end - start
            testCases.print(numPaths, beta, v, vMC, duration)

    ##########################################################################
    # Homogeneous Basket
    ##########################################################################

    numAssets = 5
    volatilities = np.ones(numAssets) * volatility
    dividendYields = np.ones(numAssets) * 0.01
    stockPrices = np.ones(numAssets) * 100
    betaList = np.linspace(0.0, 0.999999, 11)

    testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME")

    for beta in betaList:
        for numPaths in [10000]:
            callOption = FinEquityBasketOption(expiryDate, 100.0,
                                               FinOptionTypes.EUROPEAN_PUT,
                                               numAssets)
            betas = np.ones(numAssets) * beta
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()
            v = callOption.value(valueDate, stockPrices, discountCurve,
                                 dividendYields, volatilities, corrMatrix)
            vMC = callOption.valueMC(valueDate, stockPrices, discountCurve,
                                     dividendYields, volatilities, corrMatrix,
                                     numPaths)
            end = time.time()
            duration = end - start
            testCases.print(numPaths, beta, v, vMC, duration)

    ##########################################################################
    # INHomogeneous Basket
    ##########################################################################

    numAssets = 5
    volatilities = np.array([0.3, 0.2, 0.25, 0.22, 0.4])
    dividendYields = np.array([0.01, 0.02, 0.04, 0.01, 0.02])
    stockPrices = np.array([100, 105, 120, 100, 90])
    betaList = np.linspace(0.0, 0.999999, 11)

    testCases.header("NumPaths", "Beta", "Value", "ValueMC", "TIME")

    for beta in betaList:

        for numPaths in [10000]:

            callOption = FinEquityBasketOption(expiryDate, 100.0,
                                               FinOptionTypes.EUROPEAN_PUT,
                                               numAssets)
            betas = np.ones(numAssets) * beta
            corrMatrix = betaVectorToCorrMatrix(betas)

            start = time.time()
            v = callOption.value(valueDate, stockPrices, discountCurve,
                                 dividendYields, volatilities, corrMatrix)
            vMC = callOption.valueMC(valueDate, stockPrices, discountCurve,
                                     dividendYields, volatilities, corrMatrix,
                                     numPaths)
            end = time.time()
            duration = end - start
            testCases.print(numPaths, beta, v, vMC, duration)