Exemple #1
0
def tuning():
    times = 5
    metric = 'RMSE'
    optimizer = differential_evolution
    actual_puts = np.ndarray([])

    spot = 1200
    t = .76
    r = .008
    q = r
    is_call = True

    logfile = open(f'{root_dir}/params/time_benchmark_{datetime.now()}.log', 'w')

    for n in [1, 10, 25, 50, 100, 200]:
        strikes = np.array([i * 50 + 500 for i in range(n)])
        args = (spot, strikes, t, r, q, is_call)
        market = EvalArgs.from_tuple((spot, strikes, t, r, q, is_call))
        call_prices = FFT(model='vg', args=args).price((0.838288226409, -0.188041460262, 0.179096605713))

        def bs_func():
            GenPricer(model='bs', market=market, use_fft=False) \
                .optimize_pars(metric=metric, optimizer=optimizer, bounds=par_bounds['bs'],
                               actual_puts=actual_puts, actual_calls=call_prices,
                               polish=True)

        t0 = time()
        unit = td_decorator(func=bs_func, times=times, seconds=True, log_each=True)()
        hf.log_print(f'BS unit time for {n} strike(s): {unit}, real time: {(time() - t0) / times}', logfile)
        for model in ['heston', 'vg', 'ls']:
            def func():
                GenPricer(model=model, market=market, use_fft=True) \
                    .optimize_pars(metric=metric, optimizer=optimizer, bounds=par_bounds[model],
                                   actual_puts=actual_puts, actual_calls=call_prices,
                                   polish=True, disp=True, maxiter=50)
            t0 = time()
            hf.log_print(f"{model}: {td_decorator(func=func, times=times, seconds=True, log_each=True)() / unit}"
                         f" units, real time: {time() - t0}", logfile)
        hf.log_print("\n", logfile)

    logfile.close()
Exemple #2
0
def test_r():

    # noinspection PyShadowingNames
    def prepare_args(a: List[str]) -> tuple:
        spot = float(a[0])
        strike = float(a[1])
        tau = float(a[2])
        r = float(a[3])
        q = float(a[4])
        is_call = True if a[5] == 'TRUE' else False
        return spot, strike, tau, r, q, is_call

    def params2tuple(params: tuple) -> tuple:
        return params + tuple(None for _ in range(5 - len(params)))

    cases = read_r_data()

    names = ['model', 'p1', 'p2', 'p3', 'p4', 'p5',
             'spot', 'strike', 't', 'r', 'q', 'is call',
             'R answer', 'Python answer', 'diff', 'rel diff', 'is correct']

    with open('sanity_log.txt', 'w') as log, open('sanity.csv', 'w') as out:
        out.write('; '.join(names) + "\n")

        for i, case in enumerate(cases):
            correct = True
            model = str(case[0])
            data = case[1:-1]
            answer = float(case[-1])
            if model.lower() == "heston":
                # func = he.price_heston
                pars = tuple(map(lambda x: float(x), data[:5]))
                args = prepare_args(data[5:])
            elif model.lower() == "vg":
                # func = vg.price_vg
                pars = tuple(map(lambda x: float(x), data[:3]))
                args = prepare_args(data[3:])
            elif model.lower() == "ls":
                # func = ls.price_ls
                pars = tuple(map(lambda x: float(x), data[:2]))
                args = prepare_args(data[2:])
            else:
                raise Exception(f"Can't recognise model {model}")
            market = EvalArgs.from_tuple(args)
            pricer = GenPricer(model=model.lower(), market=market, use_fft=True)
            # calculated = float(func(pars, args))
            calculated = pricer.price_call(pars) if market.is_call else pricer.price_put(pars)
            assert len(calculated) == 1
            diff = abs(answer - calculated)
            if diff > 1e-2 * answer and diff > 1e-3 and not (answer < 0 and calculated == 0):
                correct = False
                log.write(f"Sanity test failed with case: {', '.join(case)}\n"
                          f"\tR answer: {answer}\n"
                          f"\tPython answer: {calculated}\n"
                          f"\tDiff: {diff}\n\n")
                log.flush()

            p1, p2, p3, p4, p5 = params2tuple(params=pars)
            spot, strike, t, r, q, is_call = args
            row = f'{model};{p1};{p2};{p3};{p4};{p5};{spot};{strike};{t};{r};{q};' \
                  f'{is_call};{answer};{calculated};{diff};' \
                  f'{diff / answer if answer != 0 else "Inf"};{"+" if correct else "-"}\n'
            out.write(row)
            out.flush()

            if i % 1000 == 0:
                print(f"{i / len(cases):.{3}}")