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()
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}}")