Für implizite Volatilität und die Black Shoals-Gleichung Black–Scholes model - Wikipedia
Informationen zum Lesen der von Ihnen verwendeten Daten Vom Lesen von Pandas mit Informationen wie dem theoretischen Preis der Nikkei-Durchschnittsoption bis zur Gestaltung des Nachtfluges
Überprüfung
[Volatility \ -Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%9C%E3%83%A9%E3%83%86%E3%82%A3%E3%83%AA% E3% 83% 86% E3% 82% A3 # .E3.82.A4.E3.83.B3.E3.83.97.E3.83.A9.E3.82.A4.E3.83.89.E3.83.BB .E3.83.9C.E3.83.A9.E3.83.86.E3.82.A3.E3.83.AA.E3.83.86.E3.82.A3)
Gleichungen für $ \ sigma $ (beachten Sie, dass $ C (K, T) $ eine Funktion von $ \ sigma $ ist) Marktpreis $ = C (K, T) $ Das durch Lösen erhaltene $ \ sigma $ wird implizite Volatilität genannt.
Wie Sie sehen können, wird C (K, T) berechnet, um σ zu finden, was der Marktpreis ist. Da C (K, T) jedoch nicht einfach gelöst werden kann, [Rooting-Algorithmus](https: //ja.wikipedia) .org / wiki /% E6% B1% 82% E6% A0% B9% E3% 82% A2% E3% 83% AB% E3% 82% B4% E3% 83% AA% E3% 82% BA% E3% Verwenden Sie 83% A0) usw., um die implizite Volatilität zu ermitteln.
Eine davon ist Bisektionsmethode \ -Wikipedia.
Die in C ++ implementierte war überwältigend schneller als die verschiedenen Einfallsreichtümer in Python, und ich denke, es war Cythons Anstrengung. Darüber hinaus verfügt C ++ noch über Kapazitätsreserven wie Thread-Parallelisierung, diesmal ...!
Im Fall von Windwos liest Pythons Multi-Prozess jedes Mal die Keras-Bibliothek, was schlecht ist, aber selbst die einzeln ausgeführte Version ohne dies dauerte ungefähr 35 Sekunden.
Die Umkehrfunktion mit ANN ist schnell, aber ungenau. Ich denke, dem Design von NN sind Grenzen gesetzt. (Vielleicht ist es unmöglich, wenn Sie nicht so etwas wie WGAN / StackGAN machen)
Artikel | Data Handling | Optimize | BS_Vectorized | Proc | Time[sec] |
---|---|---|---|---|---|
Optimierungsberechnung mit Scipy(Numerische Lösung) / pandas.apply - Single Process | Pd.apply | minimize_scalar(Scipy) | No | Single | 2.8061 |
Optimierungsberechnung mit Scipy(Numerische Lösung) /ndarray Skalarfunktionsoptimierung x Schleife:Funktionsvektorisierung- Single Process | Pd->np | minimize_scalar(Scipy) | Yes | Single | 3.2068 |
Optimierungsberechnung mit Scipy(Numerische Lösung) /Optimierung der ndarray-Vektorfunktion:Funktionsvektorisierung- Single Process | Pd->np | root(Scipy) | Yes | Single | 0.6706 |
ndarray Optimierung Cython/Optimierung der ndarray-Vektorfunktion- Single Process | Pd->np(CyPy) | root(Scipy) | Yes | Single | 0.6860 |
ndarray Optimierung Cython/Optimierungsvektor für die Skalarfunktion von ndarray- Single Process | Pd->np(CyPy) | VectBisection(Cython) | Yes | Single | 0.4848 |
Optimierungsberechnung mit Scipy(Numerische Lösung) / pandas.apply + Multi Process | Pd->Split(Pdx8)->np(CyPy) | VectBisection(Cython) | Yes | MultiProc | 128.3856 |
Erlernen der Umkehrfunktion mit ANN ⇒ Verwendung als Konferenzmodul(Keras) | Pd->np->ANN | N/A | Yes | Single | 0.1526 |
Mit Swig(C++Implementierung)/Einfache Wiederholung- Single Process | Pd->np->C++(Swig) | Bisection(C++) | No | Single | 0.0010 |
# -*- coding: utf-8 -*-
import pandas as pd
import numpy as np
from keras.models import load_model
from datetime import datetime
import dateutil
import scipy.optimize
from scipy.stats import norm
#Cython-Version
from BS_Cy import *
#Swig Version
from _BS import *
import multiprocessing as mp
import time
import matplotlib.pyplot as plt
maturity = 19.75/245.
def strip(text):
try:
return text.strip()
except AttributeError:
return text
def BS_norm(F225, Strike, maturity, vol, call):
volSQM = vol * (maturity ** .5)
d1 = np.log(F225/Strike) / volSQM + volSQM/2
d2 = d1 - volSQM
return (F225 * norm.cdf(d1) - Strike*norm.cdf(d2)) if call else \
(Strike * norm.cdf(-d2) - F225*norm.cdf(-d1))
def BS_norm_vect(F225, Strike, maturity, vol, call):
volSQM = vol * (maturity ** .5)
d1 = np.log(F225/Strike) / volSQM + volSQM/2
d2 = d1 - volSQM
Call = F225 * norm.cdf(d1) - Strike*norm.cdf(d2)
Put = Strike * norm.cdf(-d2) - F225*norm.cdf(-d1)
premium = Call * call + Put * np.logical_not(call)
return premium
def myapply(x):
res = scipy.optimize.minimize_scalar(
lambda vol:
(
BS_norm(x['F225_PRICE'], x['STRIKE'], maturity, vol, x['CALL'])
- x['OP_PRICE']
)**2,
method='Bounded', bounds =(0.01, 0.5),
options={'maxiter': 50, 'xatol': 1e-04})
x['vol1'] = res.x
return x
def myapply_vect(F225, Strike, price, call):
x = []
for i in range(len(F225)):
res = scipy.optimize.minimize_scalar(
lambda vol:
( BS_norm_vect(F225[i], Strike[i], maturity, vol,call[i]) - price[i] )**2,
method='Bounded', bounds =(0.01, 0.5),
options={'maxiter': 50, 'xatol': 1e-04})
x.append(res.x)
return x
def myapply_vect2(F225, Strike, price, call):
res = scipy.optimize.root(
lambda vol:( BS_norm_vect(F225, Strike, maturity, vol,call) - price),
np.ones_like(F225)*.3)
return res.x
def pworker(df):
df['vol6'] = cy_apply2(df['F225_PRICE'].values, df['STRIKE'].values,
df['OP_PRICE'].values, df['CALL'].values)
return df
if __name__ == '__main__':
# #Datenaufbereitung
# [Informationen wie Option theoretischer Preis\|Japan Exchange Group](http://www.jpx.co.jp/markets/derivatives/option-price/01.html)Schlusskursdaten am 10. Februar 2017 erhalten von.
#Es gibt verschiedene Posten, aber den Basiswert für den Vertrag vom März 2017: Es werden nur die Optionstransaktionsdaten von Nikkei 225 verwendet.
#
# ##Lesen Sie Daten in Pandas
# 1.Erhöhen und benennen Sie den Header selbst basierend auf den Headerinformationen, die getrennt vom Datenkörper verteilt werden
# 2.Schneiden Sie beim Laden Leerzeichen in Textdaten
#Headername(Nach Variablenname)
#Produktcode,Produktart,Vertragsmonat,Ausübungspreis,Reservieren
#Put-Option:Bestandscode,Schlusskurs,Reservieren,Theoretischer Preis,Volatilität
#Anrufoptionen:Bestandscode,Schlusskurs,Reservieren,Theoretischer Preis,Volatilität
#Schlusskurs des zugrunde liegenden Vermögenswerts,Kriterien Volatilität
colName = ("CODE","TYPE","MATURITY","STRIKE", "RSV",
"PUT_CODE", "PUT_PRICE", "PUT_RSV", "PUT_TPRICE", "PUT_VOLATILITY",
"CALL_CODE","CALL_PRICE","CALL_RSV","CALL_TPRICE","CALL_VOLATILITY",
"F225_PRICE", "Base_VOL")
df = pd.read_csv('./ose20170210tp.csv',names=colName,
converters = {'CODE' : strip,
'TYPE' : strip})
#Es wird nur die Option Nikkei 225 für den Vertrag vom März 2017 extrahiert. Übrigens habe ich unnötige Spalten gelöscht und es war erfrischend.
df = df.query("MATURITY == 201703 & CODE==\"NK225E\"") .drop(['RSV','PUT_RSV','CALL_RSV','PUT_CODE','CALL_CODE','CODE','TYPE','MATURITY'], 1)
# *Da PUT und CALL getrennt sind, normalisieren Sie die Daten.
# *Wenn die CALL-Spalte TRUE ist, handelt es sich um CALL-Daten, und wenn es sich um FALSE handelt, handelt es sich um PUT-Daten.
# *Der Ausübungspreis wird ebenfalls auf 14000 Yen oder mehr und weniger als 22000 Yen eingegrenzt
df_p = df[["STRIKE","PUT_PRICE","PUT_TPRICE", "PUT_VOLATILITY","F225_PRICE", "Base_VOL"]] .rename(columns={'PUT_PRICE': 'OP_PRICE', 'PUT_TPRICE':'OP_TPRICE', 'PUT_VOLATILITY':'OP_VOL'})
df_p['CALL'] = False
df_c = df[["STRIKE","CALL_PRICE","CALL_TPRICE", "CALL_VOLATILITY","F225_PRICE", "Base_VOL"]] .rename(columns={'CALL_PRICE': 'OP_PRICE', 'CALL_TPRICE':'OP_TPRICE', 'CALL_VOLATILITY':'OP_VOL'})
df_c['CALL'] = True
df = df_p.append(df_c).query("OP_PRICE > 1.0 & STRIKE < 22000 & STRIKE >= 14000")
del (df_p,df_c)
tmp_df = df
loop_num = 10
text = 'Time elapsed: %.2f seconds'
result_time = []
result_Col = np.array([["Data Handling","Optimize","BS_Vectorized","Proc","Time[sec]"]])
result_con = np.array([["Pd.apply",
"Pd->np",
"Pd->np",
"Pd->np(CyPy)",
"Pd->np(CyPy)",
"Pd->Split(Pd x 8)->np(CyPy)",
"Pd->np->ANN",
"Pd->np->C++(Swig)"
]])
result_opt = np.array([["minimize_scalar(Scipy)",
"minimize_scalar(Scipy)",
"root(Scipy)",
"root(Scipy)",
"Vect Bisection(Cython)",
"Vect Bisection(Cython)",
"N/A",
"Bisection(C++)"
]])
result_Vect = np.array([["No",
"Yes",
"Yes",
"Yes",
"Yes",
"Yes",
"Yes",
"No"
]])
result_Proc = np.array([["Single",
"Single",
"Single",
"Single",
"Single",
"Multi Proc",
"Single",
"Single"
]])
# 1.Optimierungsberechnung mit Scipy(Numerische Lösung) / pandas.apply - Single Process
time_start = time.time()
for i in range(loop_num):
tmp_df = df.apply(myapply, axis=1)
result_time.append((time.time() - time_start))
# 2.Optimierungsberechnung mit Scipy(Numerische Lösung) /ndarray Schleife:Funktionsvektorisierung- Single Process
time_start = time.time()
for i in range(loop_num):
tmp_df['vol2'] = myapply_vect(df['F225_PRICE'].values, df['STRIKE'].values,
df['OP_PRICE'].values, df['CALL'].values)
result_time.append((time.time() - time_start))
# 3.Optimierungsberechnung mit Scipy(Numerische Lösung) /ndarray Vektor:Funktionsvektorisierung- Single Process
time_start = time.time()
for i in range(loop_num):
tmp_df['vol3'] = myapply_vect2(df['F225_PRICE'].values, df['STRIKE'].values,
df['OP_PRICE'].values, df['CALL'].values)
result_time.append((time.time() - time_start))
# 4. Cython - Root
time_start = time.time()
for i in range(loop_num):
tmp_df['vol4'] = cy_apply1(df['F225_PRICE'].values, df['STRIKE'].values,
df['OP_PRICE'].values, df['CALL'].values)
result_time.append((time.time() - time_start))
# 5. Cython - My Bisection
time_start = time.time()
for i in range(loop_num):
tmp_df['vol5'] = cy_apply2(df['F225_PRICE'].values, df['STRIKE'].values,
df['OP_PRICE'].values, df['CALL'].values)
result_time.append((time.time() - time_start))
# 6. Multi Process
time_start = time.time()
for i in range(loop_num):
p = mp.Pool(processes=8)
split_dfs = np.array_split(df,8)
pool_results = p.map(pworker, split_dfs)
p.close()
p.join()
tmp_df = pd.concat(pool_results, axis=0)
result_time.append((time.time() - time_start))
# 7. ANN
model = load_model('./model.h5')
a = np.array([df['STRIKE'].values/df['F225_PRICE'].values])
b = np.array([np.ones_like(df['F225_PRICE'].values)*maturity/(40./245.)])
c = np.array([(df['OP_PRICE'].values/df['F225_PRICE'].values/0.25)**0.25])
X = np.vstack((a,b,c)).transpose()
time_start = time.time()
for i in range(loop_num):
tmp_df['vol7'] = 0.4*model.predict(X)+0.1
result_time.append((time.time() - time_start))
# 8. Swig C++
tmpmpmp=np.ones_like(df['F225_PRICE'].values).astype(np.float32)
time_start = time.time()
for i in range(loop_num):
tmpmpmp = Swig_Apply_PY(df['F225_PRICE'].values, df['STRIKE'].values,
df['OP_PRICE'].values, df['CALL'].values.astype(dtype=np.int32),tmpmpmp.shape[0])
tmp_df['vol8'] = tmpmpmp
result_time.append((time.time() - time_start))
result_time = np.array([result_time])
print(np.vstack((result_con, result_opt, result_Vect, result_Proc,result_time)).transpose())
Recommended Posts