{"id":13739596,"url":"https://github.com/RomanMichaelPaolucci/Q-Fin","last_synced_at":"2025-05-08T19:34:27.304Z","repository":{"id":44982738,"uuid":"360181241","full_name":"romanmichaelpaolucci/Q-Fin","owner":"romanmichaelpaolucci","description":"A Python library for mathematical finance","archived":false,"fork":false,"pushed_at":"2023-10-31T17:32:45.000Z","size":134,"stargazers_count":396,"open_issues_count":1,"forks_count":54,"subscribers_count":11,"default_branch":"main","last_synced_at":"2024-11-15T09:43:51.080Z","etag":null,"topics":["mathematical-finance","option-pricing","python","quantitative-finance"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/romanmichaelpaolucci.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2021-04-21T13:29:51.000Z","updated_at":"2024-11-05T15:16:38.000Z","dependencies_parsed_at":"2024-01-25T03:13:51.633Z","dependency_job_id":null,"html_url":"https://github.com/romanmichaelpaolucci/Q-Fin","commit_stats":null,"previous_names":["romanmichaelpaolucci/q-fin"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romanmichaelpaolucci%2FQ-Fin","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romanmichaelpaolucci%2FQ-Fin/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romanmichaelpaolucci%2FQ-Fin/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/romanmichaelpaolucci%2FQ-Fin/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/romanmichaelpaolucci","download_url":"https://codeload.github.com/romanmichaelpaolucci/Q-Fin/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253135516,"owners_count":21859660,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["mathematical-finance","option-pricing","python","quantitative-finance"],"created_at":"2024-08-03T04:00:35.617Z","updated_at":"2025-05-08T19:34:26.929Z","avatar_url":"https://github.com/romanmichaelpaolucci.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":["Financial Instruments and Pricing","金融工具与定价"],"readme":"# Q-Fin\nA Python library for mathematical finance.\n\n## Installation\nhttps://pypi.org/project/QFin/\n```\npip install qfin\n```\n\n# Version '0.1.20'\nQFin is being reconstructed to leverage more principals of object-oriented programming.  Several modules in this version are deprecated along with the solutions to PDEs/SDEs (mainly in the options module).\n\nQFin now contains a module called 'stochastics' which will be largely responsible for model calibration and option pricing.  A Cython/C++ equivalent to QFin is also being constructed so stay tuned! \n\n# Option Pricing \u003ci\u003e(\u003e= 0.1.20)\u003c/i\u003e\n\nStochastic differential equations that model underlying asset dynamics extend the 'StochasticModel' class and posses a list of model parameters and functions for pricing vanillas, calibrating to implied volatility surfaces, and Monte Carlo simulations (particularly useful after calibration for pricing path dependent options).\n\nBelow is a trivial example using ArithmeticBrownianMotion - first import the StochasticModel...\n```Python\nfrom qfin.stochastics import ArithmeticBrownianMotion\n```\nNext initialize the class object by parameterizing the model...\n```Python\n# abm parameterized by Bachelier vol = .3\nabm = ArithmeticBrownianMotion([.3])\n```\nThe abm may now be used to price a vanilla call/put option (prices default to \"CALL\") under the given parameter set...\n```Python\n# F0 = 101\n# X = 100\n# T = 1\nabm.vanilla_pricing(101, 100, 1, \"CALL\")\n# Call Price: 1.0000336233656906\n```\nUsing call-put parity put prices may also be obtained...\n```Python\n# F0 = 99\n# X = 100\n# T = 1\nabm.vanilla_pricing(99, 100, 1, \"PUT\")\n# Put Price: 1.0000336233656952\n```\nCalibration and subsequent simulation of the process is also available - do note that some processes have a static volatility and can't be calibrated to an ivol surface.\n\nThe arithmetic Brownian motion may be simulated as follows...\n\n```Python\n# F0 = 100\n# n (steps) = 10000\n# dt = 1/252\n# T = 1\nabm.simulate(100, 10000, 1/252, 1)\n```\nResults of the simulation along with the simulation characteristics are stored under the tuple 'path_characteristics' : (paths, n, dt, T).  \n\nUsing the stored path characteristics we may find the price of a call just as before by averaging each discounted path payoff (assuming a stock process) with zero-rates we can avoid discounting as follows and find the option value as follows...\n\n```Python\n# list of path payoffs\npayoffs = []\n# option strike price\nX = 99\n\n# iteration through terminal path values to identify payoff\nfor path in abm.path_characteristics[0]:\n    # appending CALL payoff\n    payoffs.append(max((path[-1] - X), 0))\n\n# option value today\nnp.average(payoffs)\n\n# Call Price:  1.0008974837343871\n```\nWe can see here that the simulated price is converging to the price in close-form.\n\n# Option Pricing \u003ci\u003e(deprecated \u003c= 0.0.20) \u003c/i\u003e\n\n### \u003ca href=\"https://medium.com/swlh/deriving-the-black-scholes-model-5e518c65d0bc\"\u003e Black-Scholes Pricing\u003c/a\u003e\nTheoretical options pricing for non-dividend paying stocks is available via the BlackScholesCall and BlackScholesPut classes.\n\n```Python\nfrom qfin.options import BlackScholesCall\nfrom qfin.options import BlackScholesPut\n# 100 - initial underlying asset price\n# .3 - asset underlying volatility\n# 100 - option strike price\n# 1 - time to maturity (annum)\n# .01 - risk free rate of interest\neuro_call = BlackScholesCall(100, .3, 100, 1, .01)\neuro_put = BlackScholesPut(100, .3, 100, 1, .01)\n```\n\n```Python\nprint('Call price: ', euro_call.price)\nprint('Put price: ', euro_put.price)\n```\n\n```\nCall price:  12.361726191532611\nPut price:  11.366709566449416\n```\n\n### Option Greeks\nFirst-order and some second-order partial derivatives of the Black-Scholes pricing model are available.\n\n#### Delta\nFirst-order partial derivative with respect to the underlying asset price.\n```Python\nprint('Call delta: ', euro_call.delta)\nprint('Put delta: ', euro_put.delta)\n```\n```\nCall delta:  0.5596176923702425\nPut delta:  -0.4403823076297575\n```\n\n#### Gamma\nSecond-order partial derivative with respect to the underlying asset price.\n```Python\nprint('Call gamma: ', euro_call.gamma)\nprint('Put gamma: ', euro_put.gamma)\n```\n```\nCall gamma:  0.018653923079008084\nPut gamma:  0.018653923079008084\n```\n\n#### Vega\nFirst-order partial derivative with respect to the underlying asset volatility.\n```Python\nprint('Call vega: ', euro_call.vega)\nprint('Put vega: ', euro_put.vega)\n```\n```\nCall vega:  39.447933090788894\nPut vega:  39.447933090788894\n```\n\n#### Theta\nFirst-order partial derivative with respect to the time to maturity.\n```Python\nprint('Call theta: ', euro_call.theta)\nprint('Put theta: ', euro_put.theta)\n```\n```\nCall theta:  -6.35319039407325\nPut theta:  -5.363140560324083\n```\n\n# Stochastic Processes\nSimulating asset paths is available using common stochastic processes.\n\n### \u003ca href=\"https://towardsdatascience.com/geometric-brownian-motion-559e25382a55\"\u003e Geometric Brownian Motion \u003c/a\u003e\nStandard model for implementing geometric Brownian motion.\n```Python\nfrom qfin.simulations import GeometricBrownianMotion\n# 100 - initial underlying asset price\n# 0 - underlying asset drift (mu)\n# .3 - underlying asset volatility\n# 1/52 - time steps (dt)\n# 1 - time to maturity (annum)\ngbm = GeometricBrownianMotion(100, 0, .3, 1/52, 1)\n```\n\n```Python\nprint(gbm.simulated_path)\n```\n\n```\n[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]\n```\n\n### \u003ca href=\"https://towardsdatascience.com/stochastic-volatility-pricing-in-python-931f4b03d793\"\u003e Stochastic Variance Process \u003c/a\u003e\nStochastic volatility model based on Heston's paper (1993).\n```Python\nfrom qfin.simulations import StochasticVarianceModel\n# 100 - initial underlying asset price\n# 0 - underlying asset drift (mu)\n# .01 - risk free rate of interest\n# .05 - continuous dividend\n# 2 - rate in which variance reverts to the implied long run variance\n# .25 - implied long run variance as time tends to infinity\n# -.7 - correlation of motion generated\n# .3 - Variance's volatility\n# 1/52 - time steps (dt)\n# 1 - time to maturity (annum)\nsvm = StochasticVarianceModel(100, 0, .01, .05, 2, .25, -.7, .3, .09, 1/52, 1)\n```\n\n```Python\nprint(svm.simulated_path)\n```\n\n```\n[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]\n```\n\n# Simulation Pricing\n\n### \u003ca href=\"https://medium.com/swlh/python-for-pricing-exotics-3a2bfab5ff66\"\u003e Exotic Options \u003c/a\u003e\nSimulation pricing for exotic options is available under the assumptions associated with the respective stochastic processes.  Geometric Brownian motion is the base underlying stochastic process used in each Monte Carlo simulation.  However, should additional parameters be provided, the appropriate stochastic process will be used to generate each sample path.\n\n#### Vanilla Options\n```Python\nfrom qfin.simulations import MonteCarloCall\nfrom qfin.simulations import MonteCarloPut\n# 100 - strike price\n# 1000 - number of simulated price paths\n# .01 - risk free rate of interest\n# 100 - initial underlying asset price\n# 0 - underlying asset drift (mu)\n# .3 - underlying asset volatility\n# 1/52 - time steps (dt)\n# 1 - time to maturity (annum)\ncall_option = MonteCarloCall(100, 1000, .01, 100, 0, .3, 1/52, 1)\n# These additional parameters will generate a Monte Carlo price based on a stochastic volatility process\n# 2 - rate in which variance reverts to the implied long run variance\n# .25 - implied long run variance as time tends to infinity\n# -.5 - correlation of motion generated\n# .02 - continuous dividend\n# .3 - Variance's volatility\nput_option = MonteCarloPut(100, 1000, .01, 100, 0, .3, 1/52, 1, 2, .25, -.5, .02, .3)\n```\n\n```Python\nprint(call_option.price)\nprint(put_option.price)\n```\n\n```\n12.73812121792851\n23.195814963576286\n```\n\n#### Binary Options\n```Python\nfrom qfin.simulations import MonteCarloBinaryCall\nfrom qfin.simulations import MonteCarloBinaryPut\n# 100 - strike price\n# 50 - binary option payout\n# 1000 - number of simulated price paths\n# .01 - risk free rate of interest\n# 100 - initial underlying asset price\n# 0 - underlying asset drift (mu)\n# .3 - underlying asset volatility \n# 1/52 - time steps (dt)\n# 1 - time to maturity (annum)\nbinary_call = MonteCarloBinaryCall(100, 50, 1000, .01, 100, 0, .3, 1/52, 1)\nbinary_put = MonteCarloBinaryPut(100, 50, 1000, .01, 100, 0, .3, 1/52, 1)\n```\n\n```Python\nprint(binary_call.price)\nprint(binary_put.price)\n```\n\n```\n22.42462873441866\n27.869902820039087\n```\n\n#### Barrier Options\n```Python\nfrom qfin.simulations import MonteCarloBarrierCall\nfrom qfin.simulations import MonteCarloBarrierPut\n# 100 - strike price\n# 50 - binary option payout\n# 1000 - number of simulated price paths\n# .01 - risk free rate of interest\n# 100 - initial underlying asset price\n# 0 - underlying asset drift (mu)\n# .3 - underlying asset volatility\n# 1/52 - time steps (dt)\n# 1 - time to maturity (annum)\n# True/False - Barrier is Up or Down\n# True/False - Barrier is In or Out\nbarrier_call = MonteCarloBarrierCall(100, 1000, 150, .01, 100, 0, .3, 1/52, 1, up=True, out=True)\nbarrier_put = MonteCarloBarrierCall(100, 1000, 95, .01, 100, 0, .3, 1/52, 1, up=False, out=False)\n```\n\n```Python\nprint(binary_call.price)\nprint(binary_put.price)\n```\n\n```\n4.895841997908933\n5.565856754630819\n```\n\n#### Asian Options\n```Python\nfrom qfin.simulations import MonteCarloAsianCall\nfrom qfin.simulations import MonteCarloAsianPut\n# 100 - strike price\n# 1000 - number of simulated price paths\n# .01 - risk free rate of interest\n# 100 - initial underlying asset price\n# 0 - underlying asset drift (mu)\n# .3 - underlying asset volatility\n# 1/52 - time steps (dt)\n# 1 - time to maturity (annum)\nasian_call = MonteCarloAsianCall(100, 1000, .01, 100, 0, .3, 1/52, 1)\nasian_put = MonteCarloAsianPut(100, 1000, .01, 100, 0, .3, 1/52, 1)\n```\n\n```Python\nprint(asian_call.price)\nprint(asian_put.price)\n```\n\n```\n6.688201154529573\n7.123274528125894\n```\n\n#### Extendible Options\n```Python\nfrom qfin.simulations import MonteCarloExtendibleCall\nfrom qfin.simulations import MontecarloExtendiblePut\n# 100 - strike price\n# 1000 - number of simulated price paths\n# .01 - risk free rate of interest\n# 100 - initial underlying asset price\n# 0 - underlying asset drift (mu)\n# .3 - underlying asset volatility\n# 1/52 - time steps (dt)\n# 1 - time to maturity (annum)\n# .5 - extension if out of the money at expiration\nextendible_call = MonteCarloExtendibleCall(100, 1000, .01, 100, 0, .3, 1/52, 1, .5)\nextendible_put = MonteCarloExtendiblePut(100, 1000, .01, 100, 0, .3, 1/52, 1, .5)\n```\n\n```Python\nprint(extendible_call.price)\nprint(extendible_put.price)\n```\n\n```\n13.60274931789973\n13.20330578685724\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRomanMichaelPaolucci%2FQ-Fin","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRomanMichaelPaolucci%2FQ-Fin","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRomanMichaelPaolucci%2FQ-Fin/lists"}