Scenarios
Scenario Cube
DiffFusion.ScenarioCube — Type
struct ScenarioCube
X::AbstractArray
times::AbstractVector
leg_aliases::AbstractVector
numeraire_context_key::String
discount_curve_key::Union{String,Nothing}
endA 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 typeModelValuewhereN_1is number of Monte Carlo paths,N_2is number of time steps,N_3is 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 inXare discounted prices (for XVA) or undiscounted prices (for CCR).
Pricing Scenarios
DiffFusion.scenarios — Function
scenarios(
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 — Function
join_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 — Function
interpolate_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 — Function
concatenate_scenarios(cubes::AbstractVector{ScenarioCube})Concatenate a list of scenarios along time axis.
DiffFusion.aggregate — Function
aggregate(
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 — Function
scenarios_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 — Function
scenarios_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 — Function
scenarios_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.