Scenarios
Scenario Cube
DiffFusion.ScenarioCube
— Typestruct ScenarioCube
X::AbstractArray
times::AbstractVector
leg_aliases::AbstractVector
numeraire_context_key::String
discount_curve_key::Union{String,Nothing}
end
A ScenarioCube represents the result of MC pricing results of a list of product legs and is calculated for a list of observation times.
Elements are
X
- tensor of size (N_1
,N_2
,N_3
) and typeModelValue
whereN_1
is number of Monte Carlo paths,N_2
is number of time steps,N_3
is number of legs.
times
- a vector representing observation times.leg_aliases
- a list of aliases (identifiers) corresponding to each legnumeraire_context_key
- the context_key of theNumeraireEntry
; this label should indicate the cash flow currency.discount_curve_key
- a flag specifying whether prices inX
are discounted prices (for XVA) or undiscounted prices (for CCR).
Pricing Scenarios
DiffFusion.scenarios
— Functionscenarios(
legs::AbstractVector,
times::AbstractVector,
path::Path,
discount_curve_key::Union{String,Nothing};
with_progress_bar::Bool = true,
)
Calculate ScenarioCube
for a vector of CashFlowLeg
objects and a vector of scenario observation times
.
Scenario Cube Operations
DiffFusion.join_scenarios
— Functionjoin_scenarios(cube1::ScenarioCube, cube2::ScenarioCube)
Join two scenario cubes along leg-axis.
join_scenarios(cubes::AbstractVector{ScenarioCube})
Join a list of scenario cubes along leg-axis.
DiffFusion.interpolate_scenarios
— Functioninterpolate_scenarios(
t::ModelTime,
cube::ScenarioCube,
)
Interpolation scenarios along time axis.
We implement linear interpolation with flat extrapolation.
Other interpolations, e.g., piece-wise flat or Brownian Bridge should be incorporated here.
DiffFusion.concatenate_scenarios
— Functionconcatenate_scenarios(cubes::AbstractVector{ScenarioCube})
Concatenate a list of scenarios along time axis.
DiffFusion.aggregate
— Functionaggregate(
scens::ScenarioCube,
average_paths::Bool=true,
aggregate_legs::Bool=true,
)
Average paths and aggregate legs in ScenarioCube.
scens
is the input ScenarioCube
.
If average_paths
is true then reduce scenario cube along path axis. Otherwise, keep individual paths.
If aggregate_legs
is true then reduce scenario cube along the axis of legs. Otherwise, keep individual legs.
Scenario Generation Using Parallel Computations
We implement various strategies for parallelisation of scenario generation: multi-threading multi-processing and a mixed approach.
It turns out that Julia's garbage collection impedes scaling properties of multi-threaded scenario generation. Parallel garbage collection introduced with Julia 1.10 does not seem to help.
Fortunately, multi-processing can be used efficiently for scenario generation. This circumvents the garbage collection limitation.
We also find that a combination of multi-processing and multi-threading can be most efficient. With such a mixed approach we can leverage the lower overhead from multi-threading and mitigate the impact of single-threaded garbage collection.
DiffFusion.scenarios_parallel
— Functionscenarios_parallel(
legs::AbstractVector,
times::AbstractVector,
path::DiffFusion.Path,
discount_curve_key::Union{String,Nothing},
)
Combined multi-processing (distributed) and multi-threaded calculation of ScenarioCube
for a vector of CashFlowLeg
objects and a vector of scenario observation times
.
Multi-processing is implemented via Distributed
module. The number of processes can be controlled via -p
argument when calling julia
.
For each distributed process, multi-threading is implemented via Threads.@threads
.
Number of threads used for parallel calculation is specified by the environment variable JULIA_NUM_THREADS
or the -t
argument when calling julia
.
It is recommended to use this method in conjunction with thread pinning via ThreadPinning.jl
and pinthreads(:cores)
.
Moreover, to avoid over-subscription in conjunction with BLAS it is recommended to set LinearAlgebra.BLAS.set_num_threads(1)
.
DiffFusion.scenarios_multi_threaded
— Functionscenarios_multi_threaded(
legs::AbstractVector,
times::AbstractVector,
path::Path,
discount_curve_key::Union{String,Nothing};
with_progress_bar::Bool = true,
)
Multi-threaded calculation of ScenarioCube
for a vector of CashFlowLeg
objects and a vector of scenario observation times
.
Multi-threading is implemented via Base.Threads
and the Threads.@threads
macro.
Number of threads used for parallel calculation is specified by the environment variable JULIA_NUM_THREADS
or the -t
argument when calling julia
.
It is recommended to use this method in conjunction with thread pinning via ThreadPinning.jl
and pinthreads(:cores)
.
Moreover, to avoid over-subscription in conjunction with BLAS it is recommended to set LinearAlgebra.BLAS.set_num_threads(1)
.
DiffFusion.scenarios_distributed
— Functionscenarios_distributed(
legs::AbstractVector,
times::AbstractVector,
path::DiffFusion.Path,
discount_curve_key::Union{String,Nothing},
)
Multi-processing (distributed) calculation of ScenarioCube
for a vector of CashFlowLeg
objects and a vector of scenario observation times
.
Multi-processing is implemented via Distributed
module. The number of processes can be controlled via -p
argument when calling julia
.