Eine Python-Bibliothek für mathematische Finanzen.
https://pypi.org/project/QFin/
pip install qfin
QFin wird umgestaltet, um mehr Prinzipien der objektorientierten Programmierung zu nutzen. Mehrere Module in dieser Version sind veraltet, ebenso wie die Lösungen für PDEs/SDEs (hauptsächlich im Optionsmodul).
QFin enthält jetzt ein Modul namens „Stochastik“, das maßgeblich für die Modellkalibrierung und Optionspreisgestaltung verantwortlich sein wird. Ein Cython/C++-Äquivalent zu QFin wird ebenfalls entwickelt, also bleiben Sie dran!
Stochastische Differentialgleichungen, die die zugrunde liegende Vermögensdynamik modellieren, erweitern die Klasse „StochasticModel“ und verfügen über eine Liste von Modellparametern und -funktionen für die Preisgestaltung von Vanillas, die Kalibrierung auf implizite Volatilitätsflächen und Monte-Carlo-Simulationen (besonders nützlich nach der Kalibrierung für preispfadabhängige Optionen).
Unten ist ein triviales Beispiel mit ArithmeticBrownianMotion – importieren Sie zuerst das StochasticModel ...
aus qfin.stochastics importieren ArithmeticBrownianMotion
Als nächstes initialisieren Sie das Klassenobjekt, indem Sie das Modell parametrisieren ...
# abm parametrisiert durch Bachelier vol = .3abm = ArithmeticBrownianMotion([.3])
Der abm kann nun verwendet werden, um den Preis für eine Vanilla-Call-/Put-Option (die Preise sind standardmäßig „CALL“) unter dem angegebenen Parametersatz festzulegen ...
# F0 = 101#
Mit Hilfe von Call-Put-Parität können auch Put-Preise ermittelt werden...
# F0 = 99# X = 100# T = 1abm.vanilla_pricing(99, 100, 1, "PUT")# Put-Preis: 1,0000336233656952
Eine Kalibrierung und anschließende Simulation des Prozesses ist ebenfalls möglich. Beachten Sie, dass einige Prozesse eine statische Flüchtigkeit aufweisen und nicht auf eine Ivol-Oberfläche kalibriert werden können.
Die arithmetische Brownsche Bewegung kann wie folgt simuliert werden ...
# F0 = 100# n (Schritte) = 10000# dt = 1/252# T = 1abm.simulate(100, 10000, 1/252, 1)
Ergebnisse der Simulation werden zusammen mit den Simulationseigenschaften unter dem Tupel „path_characteristics“ gespeichert: (Pfade, n, dt, T).
Unter Verwendung der gespeicherten Pfadeigenschaften können wir wie zuvor den Preis eines Calls ermitteln, indem wir jede diskontierte Pfadauszahlung (unter der Annahme eines Aktienprozesses) mit Nullsätzen mitteln. Wir können die Diskontierung wie folgt vermeiden und den Optionswert wie folgt ermitteln ...
# list of path payoffspayoffs = []# Optionsstreikpreis ), 0))# Optionswert heutenp.average(Auszahlungen)# Call-Preis: 1,0008974837343871
Wir können hier sehen, dass sich der simulierte Preis dem Preis in naher Form annähert.
Theoretische Optionspreise für nicht-dividendenzahlende Aktien sind über die Klassen BlackScholesCall und BlackScholesPut verfügbar.
from qfin.options import BlackScholesCallfrom qfin.options import BlackScholesPut# 100 – anfänglicher zugrunde liegender Vermögenswert# .3 – zugrundeliegende Vermögenswertvolatilität# 100 – Ausübungspreis der Option# 1 – Restlaufzeit (Jahr)# .01 – risikofreier Zinssatzeuro_call = BlackScholesCall(100, .3, 100, 1, .01)euro_put = BlackScholesPut(100, .3, 100, 1, .01)
print('Call-Preis: ', euro_call.price)print('Put-Preis: ', euro_put.price)
Call price: 12.361726191532611 Put price: 11.366709566449416
Es stehen partielle Ableitungen erster und einiger zweiter Ordnung des Black-Scholes-Preismodells zur Verfügung.
Partielle Ableitung erster Ordnung in Bezug auf den zugrunde liegenden Vermögenspreis.
print('Call delta: ', euro_call.delta)print('Put delta: ', euro_put.delta)
Call delta: 0.5596176923702425 Put delta: -0.4403823076297575
Partielle Ableitung zweiter Ordnung in Bezug auf den zugrunde liegenden Vermögenspreis.
print('Call gamma: ', euro_call.gamma)print('Put gamma: ', euro_put.gamma)
Call gamma: 0.018653923079008084 Put gamma: 0.018653923079008084
Partielle Ableitung erster Ordnung in Bezug auf die Volatilität des zugrunde liegenden Vermögenswerts.
print('Call vega: ', euro_call.vega)print('Put vega: ', euro_put.vega)
Call vega: 39.447933090788894 Put vega: 39.447933090788894
Partielle Ableitung erster Ordnung nach der Restlaufzeit.
print('Call theta: ', euro_call.theta)print('Put theta: ', euro_put.theta)
Call theta: -6.35319039407325 Put theta: -5.363140560324083
Die Simulation von Vermögenspfaden ist mit gängigen stochastischen Verfahren möglich.
Standardmodell zur Implementierung der geometrischen Brownschen Bewegung.
aus qfin.simulations importieren GeometricBrownianMotion# 100 – anfänglicher Preis des Basiswerts# 0 – Drift des Basiswerts (mu)# .3 – Volatilität des Basiswerts# 1/52 – Zeitschritte (dt)# 1 – Zeit bis zur Fälligkeit (annum)gbm = Geometrische Brownsche Bewegung (100, 0, .3, 1/52, 1)
print(gbm.simulated_path)
[107.0025048205179, 104.82320056538235, 102.53591127422398, 100.20213816642244, 102.04283245358256, 97.75115579923988, 95.19613943526382, 96.9876745495834, 97.46055174410736, 103.93032659279226, 107.36331603194304, 108.95104494118915, 112.42823319947456, 109.06981862825943, 109.10124426285238, 114.71465058375804, 120.00234814086286, 116.91730159923688, 118.67452601825876, 117.89233466917202, 118.93541257993591, 124.36106523035058, 121.26088015675688, 120.53641952983601, 113.73881043255554, 114.91724168548876, 112.94192281337791, 113.55773877160591, 107.49491796151044, 108.0715118831013, 113.01893111071472, 110.39204535739405, 108.63917240906524, 105.8520395233433, 116.2907247951675, 114.07340779267213, 111.06821275009212, 109.65530380775077, 105.78971667172465, 97.75385009989282, 97.84501925249452, 101.90695475825825, 106.0493833583297, 105.48266575656817, 106.62375752876223, 112.39829297429974, 111.22855058562658, 109.89796974828265, 112.78068777325248, 117.80550869036715, 118.4680557054793, 114.33258212280838]
Stochastisches Volatilitätsmodell basierend auf Hestons Artikel (1993).
aus qfin.simulations import StochasticVarianceModel# 100 – anfänglicher Preis des zugrunde liegenden Vermögenswerts# 0 – Drift des zugrunde liegenden Vermögenswerts (mu)# .01 – risikofreier Zinssatz# .05 – kontinuierliche Dividende# 2 – Zinssatz, bei dem die Varianz auf die implizite langfristige Laufzeit zurückkehrt Varianz# .25 – implizite langfristige Varianz, wenn die Zeit gegen Unendlich tendiert# -.7 – Korrelation der erzeugten Bewegung# .3 – Varianzen Volatilität# 1/52 – Zeitschritte (dt)# 1 – Zeit bis zur Fälligkeit (Jahr)svm = StochasticVarianceModel(100, 0, .01, .05, 2, .25, -.7, .3, .09, 1 /52, 1)
print(svm.simulated_path)
[98.21311553503577, 100.4491317019877, 89.78475515902066, 89.0169762497475, 90.70468848525869, 86.00821802256675, 80.74984494892573, 89.05033807013137, 88.51410029337134, 78.69736798230346, 81.90948751054125, 83.02502248913251, 83.46375102829755, 85.39018282900138, 78.97401642238059, 78.93505221741903, 81.33268688455111, 85.12156706038515, 79.6351983987908, 84.2375291273571, 82.80206517176038, 89.63659376223292, 89.22438477640516, 89.13899271995662, 94.60123239511816, 91.200165507022, 96.0578905115345, 87.45399399599378, 97.908745925816, 97.93068975065052, 103.32091104292813, 110.58066464778392, 105.21520242908348, 99.4655106985056, 106.74882010453683, 112.0058519886151, 110.20930861932342, 105.11835510815085, 113.59852610881678, 107.13315204738092, 108.36549026977205, 113.49809943785571, 122.67910031073885, 137.70966794451425, 146.13877267735612, 132.9973784430374, 129.75750117504984, 128.7467891695649, 127.13115959080305, 130.47967713110302, 129.84273088908265, 129.6411527208744]
Simulationspreise für exotische Optionen stehen unter den Annahmen der jeweiligen stochastischen Prozesse zur Verfügung. Die geometrische Brownsche Bewegung ist der zugrunde liegende stochastische Prozess, der in jeder Monte-Carlo-Simulation verwendet wird. Sollten jedoch zusätzliche Parameter bereitgestellt werden, wird der entsprechende stochastische Prozess verwendet, um jeden Abtastpfad zu generieren.
from qfin.simulations import MonteCarloCallfrom qfin.simulations import MonteCarloPut# 100 – Ausübungspreis# 1000 – Anzahl der simulierten Preispfade# .01 – risikofreier Zinssatz# 100 – anfänglicher Basiswertpreis# 0 – Basiswertdrift (mu)# .3 – Volatilität des zugrunde liegenden Vermögenswerts# 1/52 – Zeitschritte (dt)# 1 – Zeit bis zur Fälligkeit (Annum)call_option = MonteCarloCall(100, 1000, .01, 100, 0, .3, 1/52, 1)# Diese zusätzlichen Parameter generieren einen Monte-Carlo-Preis basierend auf einem stochastischen Volatilitätsprozess# 2 – Rate, bei der die Varianz zum impliziten Wert zurückkehrt Langzeitvarianz# .25 – implizite Langzeitvarianz, wenn die Zeit gegen Unendlich tendiert# -.5 – Korrelation der Bewegung generiert# .02 - kontinuierliche Dividende# .3 - Volatilität der Varianzput_option = MonteCarloPut(100, 1000, .01, 100, 0, .3, 1/52, 1, 2, .25, -.5, .02, .3 )
print(call_option.price)print(put_option.price)
12.73812121792851 23.195814963576286
from qfin.simulations import MonteCarloBinaryCallfrom qfin.simulations import MonteCarloBinaryPut# 100 – Ausübungspreis# 50 – Auszahlung der binären Option# 1000 – Anzahl der simulierten Preispfade# .01 – risikofreier Zinssatz# 100 – anfänglicher Preis des Basiswerts# 0 – Basiswert Vermögensdrift (mu)# .3 – Volatilität des zugrunde liegenden Vermögenswerts # 1/52 – Zeitschritte (dt)# 1 – Laufzeit (Jahr)binary_call = MonteCarloBinaryCall(100, 50, 1000, .01, 100, 0, .3, 1/52, 1)binary_put = MonteCarloBinaryPut(100, 50, 1000, .01 , 100, 0, .3, 1/52, 1)
print(binary_call.price)print(binary_put.price)
22.42462873441866 27.869902820039087
from qfin.simulations import MonteCarloBarrierCallfrom qfin.simulations import MonteCarloBarrierPut# 100 – Ausübungspreis# 50 – Auszahlung der binären Option# 1000 – Anzahl der simulierten Preispfade# .01 – risikofreier Zinssatz# 100 – anfänglicher Preis des Basiswerts# 0 – Basiswert Vermögensdrift (mu)# .3 – Volatilität des zugrunde liegenden Vermögenswerts# 1/52 – Zeitschritte (dt)# 1 – Restlaufzeit (Jahr)# Richtig/Falsch – Barriere ist oben oder unten# Richtig/Falsch – Barriere ist In oder Outbarrier_call = MonteCarloBarrierCall(100, 1000, 150, .01, 100, 0, .3, 1/52 , 1, up=True, out=True)barrier_put = MonteCarloBarrierCall(100, 1000, 95, .01, 100, 0, .3, 1/52, 1, up=Falsch, out=Falsch)
print(binary_call.price)print(binary_put.price)
4.895841997908933 5.565856754630819
from qfin.simulations import MonteCarloAsianCallfrom qfin.simulations import MonteCarloAsianPut# 100 – Ausübungspreis# 1000 – Anzahl der simulierten Preispfade# .01 – risikofreier Zinssatz# 100 – anfänglicher Basiswertpreis# 0 – Basiswertdrift (mu)# .3 – Volatilität des zugrunde liegenden Vermögenswerts# 1/52 – Zeitschritte (dt)# 1 – Zeit bis zur Fälligkeit (annum)asian_call = MonteCarloAsianCall(100, 1000, .01, 100, 0, .3, 1/52, 1)asian_put = MonteCarloAsianPut(100, 1000, .01, 100, 0, .3, 1/52, 1 )
print(asian_call.price)print(asian_put.price)
6.688201154529573 7.123274528125894
from qfin.simulations import MonteCarloExtendibleCallfrom qfin.simulations import MontecarloExtendiblePut# 100 – Ausübungspreis# 1000 – Anzahl der simulierten Preispfade# .01 – risikofreier Zinssatz# 100 – anfänglicher Basiswertpreis# 0 – Basiswertdrift (mu)# .3 – Volatilität des zugrunde liegenden Vermögenswerts# 1/52 – Zeitschritte (dt)# 1 – Zeit bis Laufzeit (Annum)# .5 – Verlängerung, wenn bei Ablauf kein Geld mehr vorhanden istextendible_call = MonteCarloExtendibleCall(100, 1000, .01, 100, 0, .3, 1/52, 1, .5)extendible_put = MonteCarloExtendiblePut(100, 1000, .01, 100, 0, .3, 1/52, 1, .5)
print(extendible_call.price)print(extendible_put.price)
13.60274931789973 13.20330578685724