Пример #1
0
def dfToZeroCurve(df_rates, dtSettlement, daycounter=Actual365Fixed()):
    """
    Convert a panda data frame into a QL zero curve
    """

    dates = [dateToQLDate(dt) for dt in df_rates.index]
    dates.insert(0, dateToQLDate(dtSettlement))
    dates.append(dates[-1] + 365 * 2)
    vx = list(df_rates.values)
    vx.insert(0, vx[0])
    vx.append(vx[-1])
    return ZeroCurve(dates, vx, daycounter)
Пример #2
0
def df_to_zero_curve(rates, settlement_date, daycounter=Actual365Fixed()):
    """ Converts a pandas data frame into a QL zero curve. """

    dates = [pydate_to_qldate(dt) for dt in rates.index]
    dates.insert(0, pydate_to_qldate(settlement_date))

    # arbitrarily extend the curve a few years to provide flat
    # extrapolation
    dates.append(dates[-1] + 365 * 2)

    values = rates.values.tolist()
    values.insert(0, values[0])
    values.append(values[-1])

    return ZeroCurve(dates, values, daycounter)
Пример #3
0
    def test_DAX_calibration(self):

        # this example is taken from A. Sepp
        # Pricing European-Style Options under Jump Diffusion Processes
        # with Stochstic Volatility: Applications of Fourier Transform
        # http://math.ut.ee/~spartak/papers/stochjumpvols.pdf

        settlement_date = Date(5, July, 2002)

        self.settings.evaluation_date = settlement_date

        daycounter = Actual365Fixed()
        calendar = TARGET()

        t = [13, 41, 75, 165, 256, 345, 524, 703]
        r = [0.0357,0.0349,0.0341,0.0355,0.0359,0.0368,0.0386,0.0401]

        dates = [settlement_date] + [settlement_date + val for val in t]
        rates = [0.0357] + r

        risk_free_ts = ZeroCurve(dates, rates, daycounter)
        dividend_ts = FlatForward(
            settlement_date, forward=0.0, daycounter=daycounter
        )

        v = [
            0.6625,0.4875,0.4204,0.3667,0.3431,0.3267,0.3121,0.3121,
            0.6007,0.4543,0.3967,0.3511,0.3279,0.3154,0.2984,0.2921,
            0.5084,0.4221,0.3718,0.3327,0.3155,0.3027,0.2919,0.2889,
            0.4541,0.3869,0.3492,0.3149,0.2963,0.2926,0.2819,0.2800,
            0.4060,0.3607,0.3330,0.2999,0.2887,0.2811,0.2751,0.2775,
            0.3726,0.3396,0.3108,0.2781,0.2788,0.2722,0.2661,0.2686,
            0.3550,0.3277,0.3012,0.2781,0.2781,0.2661,0.2661,0.2681,
            0.3428,0.3209,0.2958,0.2740,0.2688,0.2627,0.2580,0.2620,
            0.3302,0.3062,0.2799,0.2631,0.2573,0.2533,0.2504,0.2544,
            0.3343,0.2959,0.2705,0.2540,0.2504,0.2464,0.2448,0.2462,
            0.3460,0.2845,0.2624,0.2463,0.2425,0.2385,0.2373,0.2422,
            0.3857,0.2860,0.2578,0.2399,0.2357,0.2327,0.2312,0.2351,
            0.3976,0.2860,0.2607,0.2356,0.2297,0.2268,0.2241,0.2320
        ]

        s0 = SimpleQuote(4468.17)
        strikes = [
            3400, 3600, 3800, 4000, 4200, 4400, 4500, 4600, 4800, 5000, 5200,
            5400, 5600
        ]

        options = []

        for s, strike in enumerate(strikes):
            for m in range(len(t)):
                vol = SimpleQuote(v[s * 8 + m])
                # round to weeks
                maturity = Period((int)((t[m] + 3) / 7.), Weeks)
                options.append(
                    HestonModelHelper(
                        maturity, calendar, s0.value, strike, vol,
                        risk_free_ts, dividend_ts,
                        ImpliedVolError
                    )
                )

        v0    = 0.1
        kappa = 1.0
        theta = 0.1
        sigma = 0.5
        rho   = -0.5

        process = HestonProcess(
            risk_free_ts, dividend_ts, s0, v0, kappa, theta, sigma, rho
        )

        model = HestonModel(process)

        engine = AnalyticHestonEngine(model, 64)

        for option in options:
            option.set_pricing_engine(engine)

        om = LevenbergMarquardt(1e-8, 1e-8, 1e-8)

        model.calibrate(
            options, om, EndCriteria(400, 40, 1.0e-8, 1.0e-8, 1.0e-8)
        )

        sse = 0
        for i in range(len(strikes) * len(t)):
            diff = options[i].calibration_error() * 100.0
            sse += diff * diff

        expected = 177.2  # see article by A. Sepp.
        self.assertAlmostEqual(expected, sse, delta=1.0)