Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 6 additions & 5 deletions pdesolvers/optionspricing/monte_carlo.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def plot_price_paths(self, closing_prices=None, export=False):
raise RuntimeError("Plots cannot be generated because the simulation has not been run yet.")

plt.rcParams['font.family'] = 'monospace'
plt.rcParams['font.size'] = 10
plt.rcParams['font.size'] = 18

t = self.__generate_grid()

Expand Down Expand Up @@ -193,7 +193,7 @@ def plot_distribution_of_final_prices(self, export=False):
raise RuntimeError("Plots cannot be generated because the simulation has not been run yet.")

plt.rcParams['font.family'] = 'monospace'
plt.rcParams['font.size'] = 10
plt.rcParams['font.size'] = 18

final_prices = self.__S[:, -1]

Expand All @@ -205,7 +205,8 @@ def plot_distribution_of_final_prices(self, export=False):

if export:
plt.savefig("monte_carlo_prices.pdf", format="pdf", bbox_inches="tight", pad_inches=0.2)
plt.show()

plt.show()

def plot_distribution_of_payoff(self, export=False):
"""
Expand All @@ -217,7 +218,7 @@ def plot_distribution_of_payoff(self, export=False):
raise RuntimeError("Plots cannot be generated because the simulation has not been run yet.")

plt.rcParams['font.family'] = 'monospace'
plt.rcParams['font.size'] = 10
plt.rcParams['font.size'] = 18

plt.figure(figsize=(10, 6))
plt.hist(self.__payoff, bins=50, edgecolor='darkblue', alpha=0.5, color='blue', density=True)
Expand All @@ -244,7 +245,7 @@ def plot_convergence_analysis(self, analytical_solution, num_simulations_list=No
errors = self.get_benchmark_errors(analytical_solution, num_simulations_list, export=export)

plt.rcParams['font.family'] = 'monospace'
plt.rcParams['font.size'] = 10
plt.rcParams['font.size'] = 18

fig, ax = plt.subplots(figsize=(10,6))
ax.plot(num_simulations_list, errors, 'bo-', linewidth=2)
Expand Down
53 changes: 52 additions & 1 deletion pdesolvers/tests/test_options_pricing.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from unittest.mock import patch

from pdesolvers.optionspricing.monte_carlo import MonteCarloPricing
from pdesolvers.optionspricing.black_scholes_formula import BlackScholesFormula
from pdesolvers.enums.enums import OptionType, Greeks

@pytest.fixture
Expand All @@ -17,6 +18,16 @@ def mc_pricing_params():
'sim': 5
}

@pytest.fixture
def bs_pricing_params():
return {
'S0': 100.0,
'strike_price': 100.0,
'r': 0.05,
'sigma': 0.2,
'expiry': 1.0
}

class TestMonteCarlo:

@patch('pdesolvers.optionspricing.monte_carlo.MonteCarloPricing.simulate_gbm')
Expand Down Expand Up @@ -83,11 +94,51 @@ def test_check_simulate_gbm_initial_values(self, mc_pricing_params):

assert (results[:,0] == mc_pricing_params['S0']).all()

def test_check_get_execution_time_raises_exception_when_no_simulation_is_run(self, mc_pricing_params):
def test_check_get_execution_time_raises_error_when_no_simulation_is_run(self, mc_pricing_params):

test_mc = MonteCarloPricing(
OptionType.EUROPEAN_CALL, **mc_pricing_params
)

with pytest.raises(RuntimeError, match="Execution time is not available because the simulation has not been run yet."):
test_mc.get_execution_time()

def test_check_plot_payoff_raises_error_when_no_simulation_is_run(self, mc_pricing_params):

test_mc = MonteCarloPricing(
OptionType.EUROPEAN_CALL, **mc_pricing_params
)

with pytest.raises(RuntimeError, match="Plots cannot be generated because the simulation has not been run yet."):
test_mc.plot_distribution_of_payoff()

def test_check_plot_price_distribution_raises_error_when_no_simulation_is_run(self, mc_pricing_params):

test_mc = MonteCarloPricing(
OptionType.EUROPEAN_CALL, **mc_pricing_params
)

with pytest.raises(RuntimeError, match="Plots cannot be generated because the simulation has not been run yet."):
test_mc.plot_distribution_of_final_prices()

def test_check_plot_price_paths_raises_error_when_no_simulation_is_run(self, mc_pricing_params):

test_mc = MonteCarloPricing(
OptionType.EUROPEAN_CALL, **mc_pricing_params
)

with pytest.raises(RuntimeError, match="Plots cannot be generated because the simulation has not been run yet."):
test_mc.plot_price_paths()

def test_check_plot_convergence_raises_error_when_no_list_supplied(self, mc_pricing_params, bs_pricing_params):

test_mc = MonteCarloPricing(
OptionType.EUROPEAN_CALL, **mc_pricing_params
)

results = test_mc.simulate_gbm()

price = BlackScholesFormula(OptionType.EUROPEAN_CALL, **bs_pricing_params)

with pytest.raises(ValueError, match="Number of simulations need to be defined."):
test_mc.plot_convergence_analysis(price)
5 changes: 4 additions & 1 deletion playground/brownian_motion.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ def plot(self):
t = self.__generate_grid()
B = self.__get_paths()

plt.rcParams['font.family'] = 'monospace'
plt.rcParams['font.size'] = 18

plt.figure(figsize=(10,6))
for i in range(self.__sim):
plt.plot(t, B[i], color='grey', alpha=0.3)
Expand All @@ -55,7 +58,7 @@ def plot(self):


def main():
BrownianMotion(T=1, time_steps=365, sim=200).simulate_bm().plot()
BrownianMotion(T=1, time_steps=365, sim=100).simulate_bm().plot()

if __name__ == "__main__":
main()
3 changes: 3 additions & 0 deletions playground/export.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash

mv /Users/chemardes/Documents/repos/PDESolvers/playground/brownian_plot.pdf /Users/chemardes/Documents/school/gpu-project/report/GPU-Accelerated\ Solution\ for\ BSE/figures/
38 changes: 38 additions & 0 deletions playground/plot_results_csv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os

def plot_option_surface(file_path):
# Expand file path if using ~
file_path = os.path.expanduser(file_path)

# Load data
df = pd.read_csv(file_path, header=None)
print(f"Data shape: {df.shape}")

# Process data
grid_data = df.values.T

# Create coordinate grids
price_grid = np.linspace(0, 300, grid_data.shape[0])
time_grid = np.linspace(0, 1, grid_data.shape[1])
X, Y = np.meshgrid(time_grid, price_grid)

# Create plot
fig = plt.figure(figsize=(10, 6))
ax = fig.add_subplot(111, projection='3d')
surf = ax.plot_surface(X, Y, grid_data, cmap='viridis')

# Add labels and colorbar
ax.set_xlabel('Time')
ax.set_ylabel('Asset Price')
ax.set_zlabel('Option Value')
ax.set_title('Option Value Surface Plot')
fig.colorbar(surf, shrink=0.5, aspect=5)

return fig, ax

if __name__ == "__main__":
fig, ax = plot_option_surface('~/Downloads/out.csv')
plt.show()