Scenarios

Scenario Cube

DiffFusion.ScenarioCubeType
struct 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 type ModelValue where
    • N_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 leg
  • numeraire_context_key - the context_key of the NumeraireEntry; this label should indicate the cash flow currency.
  • discount_curve_key - a flag specifying whether prices in X are discounted prices (for XVA) or undiscounted prices (for CCR).
source

Pricing Scenarios

DiffFusion.scenariosFunction
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.

source

Scenario Cube Operations

DiffFusion.join_scenariosFunction
join_scenarios(cube1::ScenarioCube, cube2::ScenarioCube)

Join two scenario cubes along leg-axis.

source
join_scenarios(cubes::AbstractVector{ScenarioCube})

Join a list of scenario cubes along leg-axis.

source
DiffFusion.interpolate_scenariosFunction
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.

source
DiffFusion.aggregateFunction
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.

source

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_parallelFunction
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).

source
DiffFusion.scenarios_multi_threadedFunction
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).

source
DiffFusion.scenarios_distributedFunction
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.

source