def batesdetjump_calibration(df_option, dtTrade=None, df_rates=None, ival=None): # array of option helpers hh = heston_helpers(df_option, dtTrade, df_rates, ival) options = hh['options'] spot = hh['spot'] risk_free_ts = df_to_zero_curve(df_rates['R'], dtTrade) dividend_ts = df_to_zero_curve(df_rates['D'], dtTrade) v0 = .02 if ival is None: ival = { 'v0': v0, 'kappa': 3.7, 'theta': v0, 'sigma': 1.0, 'rho': -.6, 'lambda': .1, 'nu': -.5, 'delta': 0.3 } process = BatesProcess(risk_free_ts, dividend_ts, spot, ival['v0'], ival['kappa'], ival['theta'], ival['sigma'], ival['rho'], ival['lambda'], ival['nu'], ival['delta']) model = BatesDetJumpModel(process) engine = BatesDetJumpEngine(model, 64) for option in options: option.set_pricing_engine(engine) om = LevenbergMarquardt() model.calibrate(options, om, EndCriteria(400, 40, 1.0e-8, 1.0e-8, 1.0e-8)) print('BatesDetJumpModel calibration:') print( 'v0: %f kappa: %f theta: %f sigma: %f\nrho: %f lambda: %f nu: %f \ delta: %f\nkappaLambda: %f thetaLambda: %f' % (model.v0, model.kappa, model.theta, model.sigma, model.rho, model.Lambda, model.nu, model.delta, model.kappaLambda, model.thetaLambda)) calib_error = (1.0 / len(options)) * sum( [pow(o.calibration_error(), 2) for o in options]) print('SSE: %f' % calib_error) return merge_df(df_option, options, 'BatesDetJump')
def batesdetjump_calibration(df_option, dtTrade=None, df_rates=None, ival=None): # array of option helpers hh = heston_helpers(df_option, dtTrade, df_rates, ival) options = hh['options'] spot = hh['spot'] risk_free_ts = df_to_zero_curve(df_rates['R'], dtTrade) dividend_ts = df_to_zero_curve(df_rates['D'], dtTrade) v0 = .02 if ival is None: ival = {'v0': v0, 'kappa': 3.7, 'theta': v0, 'sigma': 1.0, 'rho': -.6, 'lambda': .1, 'nu': -.5, 'delta': 0.3} process = BatesProcess( risk_free_ts, dividend_ts, spot, ival['v0'], ival['kappa'], ival['theta'], ival['sigma'], ival['rho'], ival['lambda'], ival['nu'], ival['delta']) model = BatesDetJumpModel(process) engine = BatesDetJumpEngine(model, 64) for option in options: option.set_pricing_engine(engine) om = LevenbergMarquardt() model.calibrate( options, om, EndCriteria(400, 40, 1.0e-8, 1.0e-8, 1.0e-8) ) print('BatesDetJumpModel calibration:') print('v0: %f kappa: %f theta: %f sigma: %f\nrho: %f lambda: %f nu: %f \ delta: %f\nkappaLambda: %f thetaLambda: %f' % (model.v0, model.kappa, model.theta, model.sigma, model.rho, model.Lambda, model.nu, model.delta, model.kappaLambda, model.thetaLambda)) calib_error = (1.0 / len(options)) * sum( [pow(o.calibration_error(), 2) for o in options]) print('SSE: %f' % calib_error) return merge_df(df_option, options, 'BatesDetJump')
def test_simulate_batesDetJumpModel(self): model = BatesDetJumpModel(self.bates_process) paths = 4 steps = 10 horizon = 1 seed = 12345 tolerance = 1.e-3 res = simulateBatesDetJumpModel(model, paths, steps, horizon, seed) time = res[0, :] time_expected = np.arange(0, 1.1, .1) simulations = res[1:, :].T np.testing.assert_array_almost_equal(time, time_expected, decimal=4)
def test_bates_det_jump(self): # this looks like a bug in QL: # Bates Det Jump model does not have sigma as parameter, yet # changing sigma changes the result! settlement_date = today() self.settings.evaluation_date = settlement_date daycounter = ActualActual() exercise_date = settlement_date + 6 * Months payoff = PlainVanillaPayoff(Put, 1290) exercise = EuropeanExercise(exercise_date) option = VanillaOption(payoff, exercise) risk_free_ts = flat_rate(0.02, daycounter) dividend_ts = flat_rate(0.04, daycounter) spot = 1290 ival = {'delta': 3.6828677022272715e-06, 'kappa': 19.02581428347027, 'kappaLambda': 1.1209758060939223, 'lambda': 0.06524550732595163, 'nu': -1.8968106563601956, 'rho': -0.7480898462264719, 'sigma': 1.0206363887835108, 'theta': 0.01965384459461113, 'thetaLambda': 0.028915397380738218, 'v0': 0.06566800935242285} process = BatesProcess( risk_free_ts, dividend_ts, SimpleQuote(spot), ival['v0'], ival['kappa'], ival['theta'], ival['sigma'], ival['rho'], ival['lambda'], ival['nu'], ival['delta']) model = BatesDetJumpModel(process, ival['kappaLambda'], ival['thetaLambda']) engine = BatesDetJumpEngine(model, 64) option.set_pricing_engine(engine) calc_1 = option.net_present_value ival['sigma'] = 1.e-6 process = BatesProcess( risk_free_ts, dividend_ts, SimpleQuote(spot), ival['v0'], ival['kappa'], ival['theta'], ival['sigma'], ival['rho'], ival['lambda'], ival['nu'], ival['delta']) model = BatesDetJumpModel(process, ival['kappaLambda'], ival['thetaLambda']) engine = BatesDetJumpEngine(model, 64) option.set_pricing_engine(engine) calc_2 = option.net_present_value if(abs(calc_1-calc_2) > 1.e-5): print('calc 1 %f calc 2 %f' % (calc_1, calc_2)) self.assertNotEqual(calc_1, calc_2)