Hey,
I wanted to simulate a geometric Brownian Motion of the form
where B(t) is just some standard Brownian Motion.
Or expressed as a SDE, I want to simulate the solution
with \mu=\beta+\frac{\delta^2}{2} and \sigma=\delta.
(The latter formulation as an SDE might be more consistent to the parameters in the SciML implementation of a Geometric Brownian Motion.)
However, I want to condition this on start and endpoint, so simulate a Geometric Brownian Bridge.
What I did at first was to simulate standard Brownian Bridges and apply the linear transform and exponential function to it, for example with the below code
using Plots
using DifferentialEquations
using Distributions
using Random
# package of SciML for Noise Processes including Brownian Bridges
using DiffEqNoiseProcess
# step size of the solver
dt = 0.01
# conditions for the Brownian bridges
t0 = 0.0
tend = 10.0
W0 = 0.0
Wend = 4.0
# parameters for the linear transformation
beta = 0.1
delta = 0.1
# first simulate a Brownian Bridge and apply linear transform and exponential by hand
function BB_to_GBB(beta, delta, BB)
GBB = [exp(beta*(i-1)*dt+delta*BB.u[i]) for i in eachindex(BB.u)]
return GBB
end
SimpleBB = BrownianBridge(t0, tend, W0, Wend)
BBprob = NoiseProblem(SimpleBB, (t0, tend))
BBensemble_prob = EnsembleProblem(BBprob)
BBensemble_sol = solve(BBensemble_prob, trajectories = 1000, dt = dt)
TransBBmean = mean([BB_to_GBB(beta, delta, BBensemble_sol[i]) for i in eachindex(BBensemble_sol)]);
plot(t0:dt:tend+dt, TransBBmean)
This works nicely and the mean process looks as I would expect it, some kind of exponentially looking curve between beginning and endpoint.
I then found that the DiffEqNoiseProcess.jl
package also has a function for directly simulating Brownian Bridges. So I tried this
GB0 = exp(beta*t0+delta*W0)
GBend = exp(beta*tend+delta*Wend)
# reformulate to get the parameters of the SDE expression
mu = beta+delta^2/2
GBB = GeometricBrownianBridge(mu, delta, t0, tend, GB0, GBend)
GBBprob = NoiseProblem(GBB, (t0, tend))
GBBensemble_prob = EnsembleProblem(GBBprob)
GBBensemble_sol = solve(GBBensemble_prob, trajectories = 1000, dt = dt)
GBBmean = mean([GBBensemble_sol[i].u for i in eachindex(GBBensemble_sol)]);
plt = plot(t0:dt:tend+dt, GBBmean)
plot!(plt, t0:dt:tend+dt, TransBBmean)
But as you can see from the plot, the mean is now just a linear interpolation between start and endpoint. For me this is what I would expect from a normal Brownian bridge but not the Geometric. Moreover, I would expect the two simulation approaches to be equivalent, so the plots should be the same.
Maybe someone can help me whether I got something wrong conceptually or in my implementation.
Unfortunately, there is no documentation for the GeometricBrownianBridge
function, so maybe I am just using it wrong.
Would appreciate any help on this.
Thanks
Vincent