|
1 | | -# PDE Solvers |
| 1 | +# PDESolvers ૮₍ ˶•⤙•˶ ₎ა |
2 | 2 |
|
3 | | -This repository contains a collection of numerical solvers for solving Partial Differential Equations (PDEs). As of now, it covers the following equations: |
| 3 | +A Python package for solving partial differential equations (PDEs), including the one-dimensional heat equation and the Black-Scholes equation, using numerical methods such as explicit and Crank-Nicolson finite difference schemes. Features include built-in plotting, benchmarking and support for financial applications such as option pricing. |
4 | 4 |
|
5 | | -- **1D Heat Equation** |
6 | | -- **Black-Scholes Equation** |
| 5 | +## 📦 Installation |
| 6 | +The pdesolvers package can be installed using pip. To install the package, run the following command: |
| 7 | +``` |
| 8 | +pip install pdesolvers |
| 9 | +``` |
| 10 | +Updating the package to its latest version can be done with: |
| 11 | +``` |
| 12 | +pip install --upgrade pdesolvers |
| 13 | +``` |
7 | 14 |
|
8 | | -Additional features include: |
9 | | -- **Geometric brownian motion** : used to simulate multiple price paths, given the current price of an asset |
10 | | - |
11 | | -It includes two key components: |
| 15 | +## 🧩 Supported Features |
| 16 | +### Solvers |
| 17 | +- ✅ **Explicit method** |
| 18 | +- ✅ **Crank-Nicolson method** |
12 | 19 |
|
13 | | -- **Python Library**: A general-purpose solver for PDEs implemented using numerical methods. |
14 | | -- **CUDA Library**: A GPU-accelerated version of the solvers for faster and efficient computations. |
| 20 | +### Equations |
| 21 | +- ✅ **1D Heat Equation** |
| 22 | +- ✅ **Black-Scholes Equation for vanilla European options** |
15 | 23 |
|
16 | | -Numerical Methods used to solve partial differential equations: |
17 | | -- **Explicit Method** |
18 | | -- **Crank-Nicolson Method** |
| 24 | +### Pricing Methods |
| 25 | +- ✅ **Monte Carlo Pricing** |
| 26 | +- ✅ **Analytical Black-Scholes formula** |
19 | 27 |
|
20 | | -## Requirements |
| 28 | +## 📁 Project Structure |
| 29 | +```plaintext |
| 30 | +PDESolvers/ |
| 31 | +├── pdesolvers/ # Main Python package |
| 32 | +│ ├── enums/ # Enum definitions (e.g., option types, greeks) |
| 33 | +│ ├── optionspricing/ # Modules for Monte Carlo and Black-Scholes pricing |
| 34 | +│ ├── pdes/ # PDE definitions (HeatEquation, BlackScholesEquation, etc.) |
| 35 | +│ ├── solution/ # Solution classes (Solution1D, SolutionBlackScholes, etc.) |
| 36 | +│ ├── solvers/ # Explicit, Crank-Nicolson, etc. |
| 37 | +│ ├── tests/ # Unit tests for Python components |
| 38 | +│ ├── utils/ # Helper functions |
| 39 | +│ ├── __init__.py # Makes it a package |
| 40 | +├── GPUSolver/ # GPU-accelerated module |
| 41 | +│ ├── cpu/ # CPU-side implementations (C++) |
| 42 | +│ ├── gpu/ # CUDA kernels and GPU logic |
| 43 | +│ ├── tests/ # Tests for GPU and C++ logic |
| 44 | +``` |
21 | 45 |
|
22 | | -### Python Library |
| 46 | +## 📊 Export Options |
| 47 | +Use **_export=True_** flags in plotting functions or benchmarking methods to export: |
| 48 | +- **PDF**: Save plots as PDF files. |
| 49 | +- **CSV**: Save benchmark results as CSV files. |
23 | 50 |
|
24 | | -- NumPy |
25 | | -- SciPy |
26 | | -- Matplotlib for visualizations |
| 51 | +## 🚀 Usage |
| 52 | +To use the package, you can import the desired modules and classes and create an instance of the solvers. |
27 | 53 |
|
28 | | -Install the required python packages: |
29 | | -```bash |
30 | | -pip install -r requirements.txt |
| 54 | +### Example usage of the 1D heat equation solver |
| 55 | +```python |
| 56 | +from pdesolvers import HeatEquation, Heat1DExplicitSolver, Heat1DCNSolver |
| 57 | +import numpy as np |
| 58 | + |
| 59 | +equation = (HeatEquation(1, 100,30,10000, 0.01) |
| 60 | + .set_initial_temp(lambda x: np.sin(np.pi * x) + 5) |
| 61 | + .set_left_boundary_temp(lambda t: 20 * np.sin(np.pi * t) + 5) |
| 62 | + .set_right_boundary_temp(lambda t: t + 5)) |
| 63 | + |
| 64 | +solution1 = Heat1DCNSolver(equation).solve() |
| 65 | +solution2 = Heat1DExplicitSolver(equation).solve() |
| 66 | + |
| 67 | +result = solution1.get_result() |
| 68 | +solution1.plot() |
| 69 | +``` |
| 70 | + |
| 71 | +### Example usage of the Black-Scholes equation solver |
| 72 | +```python |
| 73 | +from pdesolvers import BlackScholesEquation, BlackScholesExplicitSolver, BlackScholesCNSolver, OptionType, Greeks |
| 74 | + |
| 75 | +equation = BlackScholesEquation(OptionType.EUROPEAN_CALL, 300, 295, 0.05, 0.2, 1, 100, 10000) |
| 76 | + |
| 77 | +solution1 = BlackScholesExplicitSolver(equation).solve() |
| 78 | +solution2 = BlackScholesCNSolver(equation).solve() |
| 79 | + |
| 80 | +solution1.plot() |
| 81 | +solution1.plot_greek(Greeks.GAMMA) |
| 82 | +solution2.get_execution_time() |
| 83 | +``` |
| 84 | + |
| 85 | +### Example usage of Monte Carlo Pricing |
| 86 | +```python |
| 87 | +from pdesolvers import MonteCarloPricing, OptionType |
| 88 | + |
| 89 | +pricing = MonteCarloPricing(OptionType.EUROPEAN_CALL, 300, 290, 0.05, 0.2, 1, 365, 1000, 78) |
| 90 | +option_price = pricing.get_monte_carlo_option_price() |
| 91 | + |
| 92 | +pricing.plot_price_paths() |
| 93 | +pricing.plot_distribution_of_payoff() |
| 94 | +pricing.plot_distribution_of_final_prices() |
| 95 | +``` |
| 96 | + |
| 97 | +### Example usage of Analytical Black-Scholes formula |
| 98 | +```python |
| 99 | +from pdesolvers import BlackScholesFormula, OptionType |
| 100 | + |
| 101 | +pricing = BlackScholesFormula(OptionType.EUROPEAN_CALL, 300, 290, 0.05, 0.2, 1) |
| 102 | +option_price = pricing.get_black_scholes_merton_price() |
| 103 | +``` |
| 104 | + |
| 105 | +### Using Real Historical Data |
| 106 | +```python |
| 107 | +from pdesolvers import HistoricalStockData, MonteCarloPricing, OptionType |
| 108 | + |
| 109 | +ticker = 'NVDA' |
| 110 | + |
| 111 | +historical_data = HistoricalStockData(ticker) |
| 112 | +historical_data.fetch_stock_data( "2024-02-28","2025-02-28") |
| 113 | + |
| 114 | +sigma, mu = historical_data.estimate_metrics() |
| 115 | +initial_price = historical_data.get_initial_stock_price() |
| 116 | +closing_prices = historical_data.get_closing_prices() |
| 117 | + |
| 118 | +pricing = MonteCarloPricing(OptionType.EUROPEAN_CALL, initial_price, 160, mu, sigma, 1, len(closing_prices), 1000, 78) |
| 119 | + |
| 120 | +pricing.plot_price_paths(export=True) |
| 121 | +``` |
| 122 | +> 📝 **Note:** You don't necessarily need to use the HistoricalStockData class — you're free to use raw yfinance data directly. |
| 123 | +Use the built-in tools only if you want to estimate metrics like volatility or mean return. |
| 124 | + |
| 125 | +### 📊 Comparing Interpolated Grid Solutions |
| 126 | +```python |
| 127 | +from pdesolvers import BlackScholesEquation, BlackScholesExplicitSolver, BlackScholesCNSolver, OptionType |
| 128 | + |
| 129 | +equation1 = BlackScholesEquation(OptionType.EUROPEAN_CALL, S_max=300, K=100, r=0.05, sigma=0.2, expiry=1, s_nodes=100, t_nodes=1000) |
| 130 | +equation2 = BlackScholesEquation(OptionType.EUROPEAN_CALL, S_max=300, K=100, r=0.05, sigma=0.2, expiry=1) |
| 131 | + |
| 132 | +solution1 = BlackScholesExplicitSolver(equation1).solve() |
| 133 | +solution2 = BlackScholesCNSolver(equation1).solve() |
| 134 | + |
| 135 | +error = solution1 - solution2 |
| 136 | +``` |
| 137 | + |
| 138 | +### 📊 Additional Benchmarks |
| 139 | +```python |
| 140 | +from pdesolvers import MonteCarloPricing, BlackScholesFormula, OptionType |
| 141 | + |
| 142 | +num_simulations_list = [ 20, 50, 100, 250, 500, 1000, 2500] |
| 143 | + |
| 144 | +pricing_1 = BlackScholesFormula(OptionType.EUROPEAN_CALL, 300, 290, 0.05, 0.2, 1) |
| 145 | +pricing_2 = MonteCarloPricing(OptionType.EUROPEAN_CALL, 300, 290, 0.05, 0.2, 1, 365, 1000000, 78) |
| 146 | + |
| 147 | +bs_price = pricing_1.get_black_scholes_merton_price() |
| 148 | +monte_carlo_price = pricing_2.get_monte_carlo_option_price() |
| 149 | + |
| 150 | +pricing_2.get_benchmark_errors(bs_price, num_simulations_list=num_simulations_list) |
| 151 | +pricing_2.plot_convergence_analysis(bs_price, num_simulations_list=num_simulations_list, export=True) |
| 152 | +``` |
| 153 | +> 📝 **Note:** The export flag used in the example above will save the plot as a PDF file in the current working directory. |
| 154 | +
|
| 155 | +## 🧠 Limitations |
| 156 | +- The package currently supports only one-dimensional PDEs. |
| 157 | +- Currently limited to vanilla European options. |
| 158 | +- GPU acceleration only implemented for finite difference methods. |
| 159 | + |
| 160 | +> 📝 **Note:** The Python and C++/CUDA libraries are currently developed as separate components and are not integrated. The Python library can be used independently via PyPI, while the GPU-accelerated solvers are available as a standalone C++/CUDA project. |
| 161 | +
|
| 162 | +## 🔒 License |
| 163 | +This project is licensed under the Apache License 2.0. See the [LICENSE](./LICENSE.md) file for details. |
0 commit comments