Оптимизация Scipy с использованием локального и глобального решателя в Python, заменяя модель глубокого обучения в качестве цены - PullRequest
0 голосов
/ 21 января 2020

Привет, ребята, я пишу свою MS c диссертацию, и я застрял в проблеме, связанной с кодом, который я создаю для этого. Цель моей работы - повысить скорость калибровки финансовой модели (в моем случае Heston Model for European Option), используя в качестве оценщика искусственные нейронные сети. Моя проблема заключается в решении задачи оптимизации, необходимой для калибровки параметров, которые я должен предоставить в качестве входных данных для обучаемой сети. Я использовал Keras для обучения сети, поэтому я обучил свою модель. Сейчас я пытаюсь настроить оптимизацию, используя этот код в качестве примера, но я не могу понять, как и когда мне нужно изменить код, чтобы заменить его ценой Quantlib, как ранее обучался ANN Pricer. Вот код, Кто-то может мне помочь, пожалуйста?

Этот пример используется в качестве базового.

def setup_helpers(engine, expiration_dates, strikes, 
                  data, ref_date, spot, yield_ts, 
                  dividend_ts):
    heston_helpers = []
    grid_data = []
    for i, date in enumerate(expiration_dates):
        for j, s in enumerate(strikes):
            t = (date - ref_date )
            p = ql.Period(t, ql.Days)
            vols = data[i][j]
            helper = ql.HestonModelHelper(
                p, calendar, spot, s, 
                ql.QuoteHandle(ql.SimpleQuote(vols)),
                yield_ts, dividend_ts)
            helper.setPricingEngine(engine) # here you set the engine for the computation. 
            heston_helpers.append(helper) #here you compute the price for the option. 
            grid_data.append((date, s))
    return heston_helpers, grid_data

def cost_function_generator(model, helpers,norm=False):
    def cost_function(params):
        params_ = ql.Array(list(params))
        model.setParams(params_)
        error = [h.calibrationError() for h in helpers]
        if norm:
            return np.sqrt(np.sum(np.abs(error)))
        else:
            return error
    return cost_function

def calibration_report(helpers, grid_data, detailed=False):
    avg = 0.0
    if detailed:
        print ("%15s %25s %15s %15s %20s" % (
            "Strikes", "Expiry", "Market Value", 
             "Model Value", "Relative Error (%)"))
        print("="*100)
    for i, opt in enumerate(helpers):
        err = (opt.modelValue()/opt.marketValue() - 1.0)
        date,strike = grid_data[i]
        if detailed:
            print ("%15.2f %25s %14.5f %15.5f %20.7f " % (
                strike, str(date), opt.marketValue(), 
                opt.modelValue(), 
                100.0*(opt.modelValue()/opt.marketValue() - 1.0)))
        avg += abs(err)
    avg = avg*100.0/len(helpers)
    if detailed: print("-"*100)
    summary = "Average Abs Error (%%) : %5.9f" % (avg)
    print(summary)
    return avg

def setup_model(_yield_ts, _dividend_ts, _spot, 
                init_condition=(0.05,1,0.2,0.1,0.05)):
    v_bar, kappa, gamma, rho, v0 = init_condition
    process = ql.HestonProcess(_yield_ts, _dividend_ts, 
                           ql.QuoteHandle(ql.SimpleQuote(_spot)), 
                           v0, kappa, v_bar, gamma, rho)
    model = ql.HestonModel(process)
    engine = ql.AnalyticHestonEngine(model) 
    return model, engine
summary= []

После определения этих функций здесь вызывается оптимизация:

# Local Optimizer: Levenberg-Marquardt 
from scipy.optimize import root

model2, engine2 = setup_model(
    yield_ts, dividend_ts, spot, 
    init_condition=(0.05,1,0.2,0.1,0.05))
heston_helpers2, grid_data2 = setup_helpers(
    engine2, expiration_dates, strikes, IV,
    calculation_date, spot, yield_ts, dividend_ts
)
initial_condition = list(model2.params())
%%time
cost_function = cost_function_generator(model2, heston_helpers2)
sol = root(cost_function, initial_condition, method='lm')
v_bar, kappa, gamma, rho, v0 = model2.params()
print ("v_bar = %f, kappa = %f, gamma = %f, rho = %f, v0 = %f" % \
    (v_bar, kappa, gamma, rho, v0))
error = calibration_report(heston_helpers2, grid_data2, detailed=True)
summary.append(["Scipy LM1", error] + list(model2.params()))

Это код, в котором я позвоните в обученную сеть, чтобы оценить, используя 3 параметра, заданные apriori (moneyness, expiry, r_free) и другие 5 параметров, которые я должен откалибровать.

def pricer(x,moneyness,expiry,r_free):
  corr_proc = x[0]
  mean_rev = x[1]
  l_ave_var = x[2]
  vol_vol = x[3]
  init_var = x[4]
  array_par = np.array([[moneyness, expiry, r_free, corr_proc, mean_rev, l_ave_var, vol_vol, init_var]])
  Pred_value = Final_model.predict(array_par, verbose=1)
  return Pred_value

Спасибо заранее всем, кто может мне помочь. MS

...