@@ -59,26 +59,37 @@ function sde_problem(::LognormalDynamics, s::BlackScholesExact, market::BlackSch
59
59
return NoiseProblem (noise, tspan; s. kwargs... )
60
60
end
61
61
62
+ function antithetic_sde_problem (d:: LognormalDynamics , s:: SimulationStrategy , m:: BlackScholesInputs , tspan, normal_sol)
63
+ s_flipped = @set s. seeds = normal_sol. seeds
64
+ m_flipped = @set m. sigma = - m. sigma
65
+ return sde_problem (d, s_flipped, m_flipped, tspan)
66
+ end
67
+
62
68
function sde_problem (:: HestonDynamics , :: EulerMaruyama , m:: HestonInputs , tspan)
63
69
@assert is_flat (m. rate) " Heston simulation requires flat rate curve"
64
70
rate = zero_rate (m. rate, 0.0 )
65
71
return HestonProblem (rate, m. κ, m. θ, m. σ, m. ρ, [m. spot, m. V0], tspan)
66
72
end
67
73
74
+ function antithetic_sde_problem (d:: PriceDynamics , s:: EulerMaruyama , m:: AbstractMarketInputs , tspan, normal_sol:: CustomEnsembleSolution )
75
+ base_prob = original_sol. solutions[1 ]. prob
76
+
77
+ antithetic_modify = function (_base_prob, _seed, i)
78
+ sol = original_sol. solutions[i]
79
+ flipped_noise = NoiseGrid (sol. W. t, - sol. W. W)
80
+ return remake (_base_prob; noise= flipped_noise)
81
+ end
82
+
83
+ return CustomEnsembleProblem (base_prob, normal_sol. seeds, antithetic_modify)
84
+ end
85
+
68
86
function sde_problem (:: HestonDynamics , strategy:: HestonBroadieKaya , m:: HestonInputs , tspan)
69
87
@assert is_flat (m. rate) " Heston simulation requires flat rate curve"
70
88
rate = zero_rate (m. rate, 0.0 )
71
89
noise = HestonNoise (rate, m. κ, m. θ, m. σ, m. ρ, 0.0 , [log (m. spot), m. V0], Z0= nothing ; strategy. kwargs... )
72
90
return NoiseProblem (noise, tspan)
73
91
end
74
92
75
- function antithetic_sde_problem (d:: PriceDynamics , s:: SimulationStrategy , m:: AbstractMarketInputs , tspan, seeds)
76
- s_flipped = @set s. seeds = seeds
77
- m_flipped = @set m. sigma = - m. sigma
78
- return sde_problem (d, s_flipped, m_flipped, tspan)
79
- end
80
-
81
-
82
93
# ------------------ Marginal Laws (optional) ------------------
83
94
84
95
function marginal_law (:: LognormalDynamics , m:: BlackScholesInputs , t)
@@ -134,15 +145,14 @@ function simulate_paths(method::MonteCarlo, market_inputs::I, T) where {I <: Abs
134
145
end
135
146
136
147
# Step 2: simulate antithetic paths using same seeds, flipped sigma
137
- seeds = normal_sol. seeds
138
- antithetic_prob = antithetic_sde_problem (dynamics, strategy, market_inputs, tspan, seeds)
148
+ antithetic_prob = antithetic_sde_problem (dynamics, strategy, market_inputs, tspan, normal_sol)
139
149
antithetic_sol = montecarlo_solution (antithetic_prob, strategy)
140
150
141
151
# Step 3: combine both solutions
142
152
combined_paths = vcat (normal_sol. solutions, antithetic_sol. solutions)
143
153
144
154
# Create new EnsembleSolution with merged paths
145
- return CustomEnsembleSolution (combined_paths, seeds)
155
+ return CustomEnsembleSolution (combined_paths, normal_sol . seeds)
146
156
end
147
157
148
158
function solve (prob:: PricingProblem{VanillaOption{European, C, Spot}, I} , method:: MonteCarlo ) where {C, I <: AbstractMarketInputs }
0 commit comments