From a2f756a3f01b6723061824d0d075173e37beb83c Mon Sep 17 00:00:00 2001 From: rhandal-pfn <168500787+rhandal-pfn@users.noreply.github.com> Date: Tue, 27 Aug 2024 18:43:37 +0900 Subject: [PATCH] feat: merton's martingale for drift (#625) * feat: martingale of merton jump prices * test correction for stock prices * test std change based on mean distribution * lint fix * feat: martingale of merton jump prices * test correction for stock prices * test std change based on mean distribution * lint fix * kou's jump model * Revert "Merge pull request #4 from rhandal-pfn/merton_jump_martingale" This reverts commit b41e7451983789117a08abb5a0600a43aa7e51db, reversing changes made to 303e03a477260715e8c06d803550e2d7e19af8b6. remove kou's model from this PR * lint fix * lint fix-2 --- pfhedge/stochastic/merton_jump.py | 6 +++++- tests/stochastic/test_merton_jump.py | 12 ++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pfhedge/stochastic/merton_jump.py b/pfhedge/stochastic/merton_jump.py index 5e62066e..40ed95a1 100644 --- a/pfhedge/stochastic/merton_jump.py +++ b/pfhedge/stochastic/merton_jump.py @@ -105,7 +105,11 @@ def generate_merton_jump( randn = engine(*(n_paths, n_steps), dtype=dtype, device=device) randn[:, 0] = 0.0 drift = ( - (mu - (sigma ** 2) / 2 - jump_per_year * (jump_mean + jump_std ** 2 / 2)) + ( + mu + - (sigma ** 2) / 2 + - jump_per_year * (math.exp(jump_mean + jump_std ** 2 / 2) - 1) + ) * dt * torch.arange(n_steps).to(randn) ) diff --git a/tests/stochastic/test_merton_jump.py b/tests/stochastic/test_merton_jump.py index 88b06beb..f3c00c3d 100644 --- a/tests/stochastic/test_merton_jump.py +++ b/tests/stochastic/test_merton_jump.py @@ -54,15 +54,15 @@ def test_generate_brownian_mean_no_jump_std(device: str = "cpu"): output = generate_merton_jump( n_paths, n_steps, - jump_per_year=1000, + jump_per_year=68.2, # default value jump_std=0.0, jump_mean=0.1, device=torch.device(device), ) assert output.size() == torch.Size((n_paths, n_steps)) - result = output[:, -1].log().mean() - expect = torch.zeros_like(result) - std = 0.2 * sqrt(1 / n_paths) + result = output[:, -1].mean() + expect = torch.ones_like(result) + std = 0.4 * sqrt(1 / n_paths) assert_close(result, expect, atol=3 * std, rtol=0) @@ -272,8 +272,8 @@ def test_generate_merton_jump_sobol_mean(device: str = "cpu"): n_paths, n_steps, engine=engine, jump_per_year=0, device=torch.device(device) ) assert output.size() == torch.Size((n_paths, n_steps)) - result = output[:, -1].log().mean() - expect = torch.zeros_like(result).to(device) + result = output[:, -1].mean() + expect = torch.ones_like(result).to(device) std = 0.2 * sqrt(1 / n_paths) assert_close(result, expect, atol=10 * std, rtol=0)