Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functions for Year-on-Year coupons with convexity adjustments #69

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/DiffFusion.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ include("models/futures/MarkovFutureModels.jl")

include("models/asset/AssetVolatility.jl")
include("models/asset/AssetCalibration.jl")
include("models/inflation/ConvexityAdjustment.jl")

include("simulations/RandomNumbers.jl")
include("simulations/Simulation.jl")
Expand All @@ -75,6 +76,9 @@ include("payoffs/AssetOptions.jl")
include("products/Cashflows.jl")
include("products/AssetOptionFlows.jl")
include("products/RatesCoupons.jl")
include("products/RelativeReturnCoupon.jl")
include("products/RelativeReturnIndexCoupon.jl")

include("products/CashFlowLeg.jl")
include("products/SwaptionLeg.jl")
include("products/MtMCashFlowLeg.jl")
Expand Down
38 changes: 38 additions & 0 deletions src/models/hybrid/CompositeModel.jl
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,44 @@ function asset_variance(
end


"""
log_asset_convexity_adjustment(
m::CompositeModel,
dom_alias::String,
for_alias::String,
ast_alias::String,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
)

Calculate the YoY convexity adjustment term for OU models.

Returns a scalar quantity.
"""
function log_asset_convexity_adjustment(
m::CompositeModel,
dom_alias::String,
for_alias::String,
ast_alias::String,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
)
return log_asset_convexity_adjustment(
m.models[m.model_dict[dom_alias]],
m.models[m.model_dict[for_alias]],
m.models[m.model_dict[ast_alias]],
t,
T0,
T1,
T2,
)
end


"""
state_dependent_Theta(m::CompositeModel)

Expand Down
134 changes: 134 additions & 0 deletions src/models/inflation/ConvexityAdjustment.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@

"Wrap function definitions for ν1² to avoid name collisions."
function _variance_t_T0(
dom_model::GaussianHjmModel,
for_model::GaussianHjmModel,
ch::CorrelationHolder,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
)
#
Σdx = Sigma_T(dom_model, t, T1) # T1!
Σdz = Sigma_T(dom_model, t, T0) # T0!
Σf = Sigma_T(for_model, t, T0)
Gd = G_hjm(dom_model, T1, T2)
Gf = G_hjm(for_model, T0, T1)
Γ = correlation(ch, vcat(factor_alias(dom_model),factor_alias(for_model)))
ΣT(u) = hcat(
Gd' * Σdx(u)[1:end-1,:] + Σdz(u)[end:end,:],
Gf' * Σf(u)[1:end-1,:],
)
f(u) = (ΣT(u) * Γ * ΣT(u)')[1,1] # matrix-matrix multiplications
return _scalar_integral(f, t, T0, parameter_grid([dom_model, for_model]))
end

"Wrap function definitions for ν2² to avoid name collisions."
function _variance_T0_T1(
dom_model::GaussianHjmModel,
for_model::GaussianHjmModel,
ast_model::LognormalAssetModel,
ch::CorrelationHolder,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
)
#
Σd = Sigma_T(dom_model, t, T1) # t!
Σf = Sigma_T(for_model, T0, T1)
Σfd = Sigma_T(ast_model, T0, T1)
Gd = G_hjm(dom_model, T1, T2)
Γ = correlation(ch, vcat(
factor_alias(dom_model),
factor_alias(for_model),
factor_alias(ast_model),
))
ΣT(u) = hcat(
Gd' * Σd(u)[1:end-1,:],
Σf(u)[end:end,:],
- Σfd(u),
)
f(u) = (ΣT(u) * Γ * ΣT(u)')[1,1] # matrix-matrix multiplications
return _scalar_integral(f, T0, T1, parameter_grid([dom_model, for_model, ast_model]))
end

"Wrap function definitions for ν3² to avoid name collisions."
function _variance_T1_T2(
dom_model::GaussianHjmModel,
ch::CorrelationHolder,
T1::ModelTime,
T2::ModelTime,
)
#
Σd = Sigma_T(dom_model, T1, T2)
Γ = correlation(ch, factor_alias(dom_model))
ΣT(u) = Σd(u)[end:end,:]
f(u) = (ΣT(u) * Γ * ΣT(u)')[1,1] # matrix-matrix multiplications
return _scalar_integral(f, T1, T2, parameter_grid(dom_model))
end



"""
log_asset_convexity_adjustment(
dom_model::GaussianHjmModel,
for_model::GaussianHjmModel,
ast_model::LognormalAssetModel,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
)

Calculate convexity adjustment for year-on-year coupons of tradeable assets.
"""
function log_asset_convexity_adjustment(
dom_model::GaussianHjmModel,
for_model::GaussianHjmModel,
ast_model::LognormalAssetModel,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
)
# common terms
yd = func_y(dom_model, t)
yf = func_y(for_model, t)
ch = dom_model.correlation_holder # better check that this is the same as for the other models
# deterministic components
G = G_hjm(dom_model, t, T2)
μ1 = 0.5 * G' * yd * G
#
G1 = G_hjm(for_model, t, T1)
G0 = G_hjm(for_model, t, T0)
μ2 = 0.5 * (G1' * yf * G1 - G0' * yf * G0)
#
G0 = G_hjm(dom_model, t, T0)
G1 = G_hjm(dom_model, t, T1)
μ3 = 0.5 * (G0' * yd * G0 - G1' * yd * G1)
#
μ4 = -Theta(dom_model, t, T0)[end] # re-factor to avoid Θx calculation
#
μ5 = -G_hjm(for_model, T0, T1)' * Theta(for_model, t, T0)[1:end-1]
#
μ6 = -Theta(for_model, T0, T1)[end]
#
μ7 = -G_hjm(dom_model, T1, T2)' * Theta(dom_model, t, T1)[1:end-1]
#
μ8 = -Theta(dom_model, T1, T2)[end]
#
μ9 = Theta(ast_model, T0, T1)[1]
#
μ = μ1 + μ2 + μ3 + μ4 + μ5 + μ6 + μ7 + μ8 + μ9
# variance components
ν1² = _variance_t_T0(dom_model, for_model, ch, t, T0, T1, T2)
ν2² = _variance_T0_T1(dom_model, for_model, ast_model, ch, t, T0, T1, T2)
ν3² = _variance_T1_T2(dom_model, ch, T1, T2)
#
ν² = ν1² + ν2² + ν3²
#
return μ + 0.5 * ν²
end

96 changes: 95 additions & 1 deletion src/paths/PathMethods.jl
Original file line number Diff line number Diff line change
Expand Up @@ -553,4 +553,98 @@ function asset_variance(
T,
SX,
)
end
end


"""
asset_convexity_adjustment(
p::Path,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
key::String
)

Return the convexity adjustment for a YoY asset payoff.
"""
function asset_convexity_adjustment(
p::Path,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
key::String
)
#
(context_key, ts_key_1, ts_key_2, op) = context_keys(key)
@assert op in (_empty_context_key, "-")
entry = p.context.assets[context_key]
#
@assert t <= T0
@assert T0 <= T1
@assert T1 <= T2
# TODO: specialise for deterministic models
@assert !isnothing(entry.domestic_model_alias)
@assert !isnothing(entry.foreign_model_alias)
@assert !isnothing(entry.asset_model_alias)
#
ca = log_asset_convexity_adjustment(
p.sim.model,
entry.domestic_model_alias,
entry.foreign_model_alias,
entry.asset_model_alias,
t,
T0,
T1,
T2,
)
return exp(ca) * ones(length(p))
end


"""
index_convexity_adjustment(
p::Path,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
key::String
)

Return the convexity adjustment for a YoY index payoff.
"""
function index_convexity_adjustment(
p::Path,
t::ModelTime,
T0::ModelTime,
T1::ModelTime,
T2::ModelTime,
key::String
)
#
(context_key, ts_key_1, ts_key_2, op) = context_keys(key)
@assert op in (_empty_context_key,)
entry = p.context.forward_indices[context_key]
#
@assert t <= T0
@assert T0 <= T1
@assert T1 <= T2
# TODO: specialise for deterministic models
@assert !isnothing(entry.domestic_model_alias)
@assert !isnothing(entry.foreign_model_alias)
@assert !isnothing(entry.asset_model_alias)
#
ca = log_asset_convexity_adjustment(
p.sim.model,
entry.domestic_model_alias,
entry.foreign_model_alias,
entry.asset_model_alias,
t,
T0,
T1,
T2,
)
return exp(ca) * ones(length(p))
end
Loading
Loading