예제 #1
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")

        valuation_date = Date(10, 4, 2020)

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

        dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
        for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

        currency_pair = forName + domName
        spot_fx_rate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atm_vols = [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

        notional_currency = forName

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

        fxMarketPlus = FXVolSurfacePlus(valuation_date,
                                        spot_fx_rate,
                                        currency_pair,
                                        notional_currency,
                                        dom_discount_curve,
                                        for_discount_curve,
                                        tenors,
                                        atm_vols,
                                        marketStrangle25DeltaVols,
                                        riskReversal25DeltaVols,
                                        marketStrangle10DeltaVols,
                                        riskReversal10DeltaVols,
                                        alpha,
                                        atmMethod,
                                        deltaMethod,
                                        vol_functionType)

        fxMarketPlus.check_calibration(False)
예제 #2
0
def test_FinFXMktVolSurface2(verboseCalibration):

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

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

    valuation_date = Date(10, 4, 2020)

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

    dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

    currency_pair = forName + domName
    spot_fx_rate = 90.72

    tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
    atm_vols = [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

    notional_currency = forName

    atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL_PREM_ADJ
    deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ
    vol_functionType = VolFunctionTypes.CLARK5

    fxMarketPlus = FXVolSurfacePlus(
        valuation_date, spot_fx_rate, currency_pair, notional_currency,
        dom_discount_curve, for_discount_curve, tenors, atm_vols,
        marketStrangle25DeltaVols, riskReversal25DeltaVols,
        marketStrangle10DeltaVols, riskReversal10DeltaVols, alpha, atmMethod,
        deltaMethod, vol_functionType)

    #        fxMarketPlus.check_calibration(True)

    if PLOT_GRAPHS:
        fxMarketPlus.plot_vol_curves()

        plt.figure()

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

        for i in range(0, len(dbns)):
            plt.plot(dbns[i]._x, dbns[i]._densitydx)
            plt.title(vol_functionType)
            print("SUM:", dbns[i].sum())
예제 #3
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")

        valuation_date = Date(10, 4, 2020)

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

        dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
        for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

        currency_pair = forName + domName
        spot_fx_rate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atm_vols = [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
        ]

        notional_currency = forName

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

        fxMarketPlus = FXVolSurfacePlus(
            valuation_date, spot_fx_rate, currency_pair, notional_currency,
            dom_discount_curve, for_discount_curve, tenors, atm_vols,
            marketStrangle25DeltaVols, riskReversal25DeltaVols,
            marketStrangle10DeltaVols, riskReversal10DeltaVols, alpha,
            atmMethod, deltaMethod, vol_functionType)

        fxMarketPlus.check_calibration(False)

        if 1 == 0:  # PLOT_GRAPHS:

            fxMarketPlus.plot_vol_curves()

            plt.figure()

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

            for i in range(0, len(dbns)):
                plt.plot(dbns[i]._x, dbns[i]._densitydx)
                plt.title(vol_functionType)
                print("SUM:", dbns[i].sum())
예제 #4
0
def test_FinFXMktVolSurface2(capsys):
    # Example from Book extract by Iain Clarke using Tables 3.3 and 3.4
    # print("EURJPY EXAMPLE CLARK")

    valuation_date = Date(10, 4, 2020)

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

    dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

    currency_pair = forName + domName
    spot_fx_rate = 90.72

    tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
    atm_vols = [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

    notional_currency = forName

    atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL_PREM_ADJ
    deltaMethod = FinFXDeltaMethod.SPOT_DELTA_PREM_ADJ
    vol_functionType = VolFunctionTypes.CLARK5

    fxMarketPlus = FXVolSurfacePlus(
        valuation_date, spot_fx_rate, currency_pair, notional_currency,
        dom_discount_curve, for_discount_curve, tenors, atm_vols,
        marketStrangle25DeltaVols, riskReversal25DeltaVols,
        marketStrangle10DeltaVols, riskReversal10DeltaVols, alpha, atmMethod,
        deltaMethod, vol_functionType)

    # Fails with default stricter tolerance
    fxMarketPlus.check_calibration(verboseCalibration, tol=0.2)
    captured = capsys.readouterr()
    assert captured.out == ""
예제 #5
0
def test_FinFXMktVolSurface3(capsys):
    # Example from Book extract by Iain Clark using Tables 4.4 and 4.5
    # where we examine the calibration to a full surface in Chapter 4

    valuation_date = Date(10, 4, 2020)

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

    dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
    for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

    currency_pair = forName + domName
    spot_fx_rate = 1.3465

    tenors = ['1Y', '2Y']
    atm_vols = [18.250, 17.677]
    marketStrangle25DeltaVols = [0.95, 0.85]
    riskReversal25DeltaVols = [-0.60, -0.562]
    marketStrangle10DeltaVols = [3.806, 3.208]
    riskReversal10DeltaVols = [-1.359, -1.208]

    notional_currency = forName

    # I HAVE NO YET MADE DELTA METHOD A VECTOR FOR EACH TERM AS I WOULD
    # NEED TO DO AS DESCRIBED IN CLARK PAGE 70

    atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
    deltaMethod = FinFXDeltaMethod.FORWARD_DELTA  # THIS IS DIFFERENT
    vol_functionType = VolFunctionTypes.CLARK5
    alpha = 0.5  # FIT WINGS AT 10D if ALPHA = 1.0

    fxMarketPlus = FXVolSurfacePlus(
        valuation_date, spot_fx_rate, currency_pair, notional_currency,
        dom_discount_curve, for_discount_curve, tenors, atm_vols,
        marketStrangle25DeltaVols, riskReversal25DeltaVols,
        marketStrangle10DeltaVols, riskReversal10DeltaVols, alpha, atmMethod,
        deltaMethod, vol_functionType)

    fxMarketPlus.check_calibration(verboseCalibration)
    captured = capsys.readouterr()
    assert captured.out == ""
예제 #6
0
def test_FinFXMktVolSurface4(verboseCalibration):

    ###########################################################################
    # Here I remove the 25D Vols
    ###########################################################################

    if 1 == 1:

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

        valuation_date = Date(10, 4, 2020)

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

        dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
        for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

        currency_pair = forName + domName
        spot_fx_rate = 1.3465

        tenors = ['1M', '2M', '3M', '6M', '1Y', '2Y']
        atm_vols = [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]

        marketStrangle25DeltaVols = None
        riskReversal25DeltaVols = None

        notional_currency = forName

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

        fxMarketPlus = FXVolSurfacePlus(valuation_date,
                                        spot_fx_rate,
                                        currency_pair,
                                        notional_currency,
                                        dom_discount_curve,
                                        for_discount_curve,
                                        tenors,
                                        atm_vols,
                                        marketStrangle25DeltaVols,
                                        riskReversal25DeltaVols,
                                        marketStrangle10DeltaVols,
                                        riskReversal10DeltaVols,
                                        alpha,
                                        atmMethod,
                                        deltaMethod,
                                        vol_functionType)

        fxMarketPlus.check_calibration(False)

        years = [1.0/12.0, 2./12., 0.25, 0.5, 1.0, 2.0]

        dates = valuation_date.add_years(years)

        deltas = np.linspace(0.10, 0.90, 17)

        if 1 == 1:
            volSurface = []
            for delta in deltas:
                volSmile = []
                for dt in dates:
                    (vol, k) = fxMarketPlus.volatility_from_delta_date(delta, dt)
                    volSmile.append(vol*100.0)
                    print(delta, k, dt, vol*100.0)

                volSurface.append(volSmile)

            fig = plt.figure()
            ax = fig.add_subplot(111, projection='3d')
            X, Y = np.meshgrid(years, deltas)
            zs = np.array(volSurface)
            Z = zs.reshape(X.shape)

            ax.plot_surface(X, Y, Z)

            ax.set_xlabel('Years')
            ax.set_ylabel('Delta')
            ax.set_zlabel('Volatility')
            plt.title("EURUSD Volatility Surface")
            plt.show()
예제 #7
0
def test_FinFXMktVolSurface3(verboseCalibration):

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

    if 1 == 1:

        # Example from Book extract by Iain Clark using Tables 4.4 and 4.5
        # where we examine the calibration to a full surface in Chapter 4

        valuation_date = Date(10, 4, 2020)

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

        dom_discount_curve = DiscountCurveFlat(valuation_date, domCCRate)
        for_discount_curve = DiscountCurveFlat(valuation_date, forCCRate)

        currency_pair = forName + domName
        spot_fx_rate = 1.3465

        tenors = ['1Y', '2Y']
        atm_vols = [18.250, 17.677]
        marketStrangle25DeltaVols = [0.95, 0.85]
        riskReversal25DeltaVols = [-0.60, -0.562]
        marketStrangle10DeltaVols = [3.806, 3.208]
        riskReversal10DeltaVols = [-1.359, -1.208]

        notional_currency = forName

        # I HAVE NO YET MADE DELTA METHOD A VECTOR FOR EACH TERM AS I WOULD
        # NEED TO DO AS DESCRIBED IN CLARK PAGE 70

        atmMethod = FinFXATMMethod.FWD_DELTA_NEUTRAL
        deltaMethod = FinFXDeltaMethod.FORWARD_DELTA  # THIS IS DIFFERENT
        vol_functionType = VolFunctionTypes.CLARK5
        alpha = 0.5  # FIT WINGS AT 10D if ALPHA = 1.0

        fxMarketPlus = FXVolSurfacePlus(valuation_date,
                                        spot_fx_rate,
                                        currency_pair,
                                        notional_currency,
                                        dom_discount_curve,
                                        for_discount_curve,
                                        tenors,
                                        atm_vols,
                                        marketStrangle25DeltaVols,
                                        riskReversal25DeltaVols,
                                        marketStrangle10DeltaVols,
                                        riskReversal10DeltaVols,
                                        alpha,
                                        atmMethod,
                                        deltaMethod,
                                        vol_functionType)

        fxMarketPlus.check_calibration(False)

        if 1 == 0:  # PLOT_GRAPHS:

            fxMarketPlus.plot_vol_curves()

            plt.figure()

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

            for i in range(0, len(dbns)):
                plt.plot(dbns[i]._x, dbns[i]._densitydx)
                plt.title(vol_functionType)
                print("SUM:", dbns[i].sum())

        # Test interpolation

        years = [1.0, 1.5, 2.0]
        dates = valuation_date.add_years(years)

        strikes = np.linspace(1.0, 2.0, 20)

        if 1 == 1:
            volSurface = []
            for k in strikes:
                volSmile = []
                for dt in dates:
                    vol = fxMarketPlus.volatility_from_strike_date(k, dt)
                    volSmile.append(vol*100.0)

                    print(k, dt, vol*100.0)
                volSurface.append(volSmile)

            fig = plt.figure()
            ax = fig.add_subplot(111, projection='3d')
            X, Y = np.meshgrid(years, strikes)
            zs = np.array(volSurface)
            Z = zs.reshape(X.shape)

            ax.plot_surface(X, Y, Z)

            ax.set_xlabel('Years')
            ax.set_ylabel('Strikes')
            ax.set_zlabel('Volatility')

            plt.show()

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

        deltas = np.linspace(0.10, 0.90, 17)

        if 1 == 1:
            volSurface = []
            for delta in deltas:
                volSmile = []
                for dt in dates:
                    (vol, k) = fxMarketPlus.volatility_from_delta_date(delta, dt)
                    volSmile.append(vol*100.0)
                    print(delta, k, dt, vol*100.0)

                volSurface.append(volSmile)

            fig = plt.figure()
            ax = fig.add_subplot(111, projection='3d')
            X, Y = np.meshgrid(years, deltas)
            zs = np.array(volSurface)
            Z = zs.reshape(X.shape)

            ax.plot_surface(X, Y, Z)

            ax.set_xlabel('Years')
            ax.set_ylabel('Delta')
            ax.set_zlabel('Volatility')
            plt.title("EURUSD Volatility Surface")
            plt.show()