diff --git a/src/DiffFusion.jl b/src/DiffFusion.jl index 407d0e79..f9434371 100644 --- a/src/DiffFusion.jl +++ b/src/DiffFusion.jl @@ -69,6 +69,8 @@ include("serialisation/Serialisations.jl") include("serialisation/Array.jl") include("serialisation/Termstructures.jl") include("serialisation/Models.jl") +include("serialisation/RebuildModels.jl") +include("serialisation/RebuildTermstructures.jl") module Examples using DiffFusion diff --git a/src/serialisation/RebuildModels.jl b/src/serialisation/RebuildModels.jl new file mode 100644 index 00000000..225f9953 --- /dev/null +++ b/src/serialisation/RebuildModels.jl @@ -0,0 +1,300 @@ + +""" +This file contains methods to extract term structures and re-build models. + +Methods are intended to be used for sensitivity calculations. For that +purpose we need to identify model parameters as inputs to the valuation +function. +""" + +""" + model_parameters(m::GaussianHjmModel) + +Extract model parameters from GaussianHjmModel. +""" +function model_parameters(m::GaussianHjmModel) + d = Dict{String, Any}() + d["type"] = typeof(m) + d["alias"] = m.alias + d["delta"] = m.delta + d["chi"] = m.chi + d["sigma_f"] = m.sigma_T.sigma_f + if isnothing(m.correlation_holder) + d["correlation_holder"] = nothing + else + d["correlation_holder"] = m.correlation_holder.alias + end + if isnothing(m.quanto_model) + d["quanto_model"] = nothing + else + d["quanto_model"] = m.quanto_model.alias + end + # we add another dict layer to allow combining models and ts. + return Dict(m.alias => d) +end + + +""" + model_parameters(m::LognormalAssetModel) + +Extract model parameters from LognormalAssetModel. +""" +function model_parameters(m::LognormalAssetModel) + d = Dict{String, Any}() + d["type"] = typeof(m) + d["alias"] = m.alias + d["sigma_x"] = m.sigma_x + d["correlation_holder"] = m.correlation_holder.alias # LognormalAssetModel must have correlation_holder + if isnothing(m.quanto_model) # quanto model is optional + d["quanto_model"] = nothing + else + d["quanto_model"] = m.quanto_model.alias + end + # we add another dict layer to allow combining models and ts. + return Dict(m.alias => d) +end + + +""" + model_parameters(m::SimpleModel) + +Extract model parameters from SimpleModel. +""" +function model_parameters(m::SimpleModel) + d = Dict{String, Any}() + # meta date + d[m.alias] = Dict( + "type" => typeof(m), + "alias" => m.alias, + "models" => [ m.alias for m in m.models ], + ) + # model data + for model in m.models + if hasproperty(model, :correlation_holder) && !isnothing(model.correlation_holder) + d[model.correlation_holder.alias] = model.correlation_holder + end + end + for model in m.models + d[model.alias] = model_parameters(model)[model.alias] + end + return d +end + + + +""" + build_model( + alias::String, + param_dict::Dict, + model_dict::Dict, + ) + +Re-build a model from model parameters dictionary. + +Alias identifies the model which is to be build. Input parameter +term structures are stored in param_dict. The model_dict is used +to reference quanto models. +""" +function build_model( + alias::String, + param_dict::Dict, + model_dict::Dict, + ) + @assert(haskey(param_dict, alias)) + m_dict = param_dict[alias] + @assert(haskey(m_dict, "type")) + if m_dict["type"] == GaussianHjmModel + if isnothing(m_dict["correlation_holder"]) + ch = nothing + else + ch = param_dict[m_dict["correlation_holder"]] + end + if isnothing(m_dict["quanto_model"]) + quanto_model = nothing + else + quanto_model = model_dict[m_dict["quanto_model"]] + end + return gaussian_hjm_model( + m_dict["alias"], + m_dict["delta"], + m_dict["chi"], + m_dict["sigma_f"], + ch, + quanto_model, + ) + end + if m_dict["type"] == LognormalAssetModel + ch = param_dict[m_dict["correlation_holder"]] # LognormalAssetModel requires correlation_holder + if isnothing(m_dict["quanto_model"]) + quanto_model = nothing + else + quanto_model = model_dict[m_dict["quanto_model"]] + end + return lognormal_asset_model( + m_dict["alias"], + m_dict["sigma_x"], + ch, + quanto_model, + ) + end + if m_dict["type"] == SimpleModel + simple_model_dict = Dict{String, Any}() + for a in m_dict["models"] + # here the order of models is relevant + simple_model_dict[a] = build_model(a, param_dict, simple_model_dict) + end + models = [ simple_model_dict[a] for a in m_dict["models"] ] + return simple_model( + m_dict["alias"], + models + ) + end +end + + +"We specify how to split aliases from volatilities." +const _split_alias_identifyer = " " + +""" + _get_labels_and_values( + alias::AbstractString, + param_key::AbstractString, + m_dict::Dict, + ) + +Extract labels and values from model dictionary. +""" +function _get_labels_and_values( + alias::AbstractString, + param_key::AbstractString, + m_dict::Dict, + ) + # + param_times = m_dict[param_key].times + param_values = m_dict[param_key].values + param_labels = [ + alias * _split_alias_identifyer * + param_key * _split_alias_identifyer * + string(i) * _split_alias_identifyer * + (@sprintf("%.2f", param_times[j])) + for i in 1:size(param_values)[1], j in 1:size(param_values)[2] + ] + return (vec(permutedims(param_labels)), vec(permutedims(param_values))) +end + +""" + _unique_strings(s::AbstractVector) + +Remove duplicates. + +We use a dedicated function to flag it as non-differentiable +and avoid errors from unique(.) function. +""" +_unique_strings(s::AbstractVector) = unique(s) + +""" + _restructure_parameters( + param_labels::AbstractVector, + param_values::AbstractVector, + ) + +Split and re-structure parameters from vector. +""" +function _restructure_parameters( + param_labels::AbstractVector, + param_values::AbstractVector, + ) + # + alias_vec = [ + split(s, _split_alias_identifyer)[1] + for s in param_labels + ] + param_key_vec = [ + split(s, _split_alias_identifyer)[2] + for s in param_labels + ] + alias_dict = Dict{AbstractString, Any}() + alias_vec_unique = _unique_strings(alias_vec) + for alias in alias_vec_unique + param_keys = param_key_vec[ alias_vec .== alias ] + param_dict = Dict{AbstractString, Any}() + param_keys_unique = _unique_strings(param_keys) + for param_key in param_keys_unique + values = param_values[(alias_vec.==alias) .& (param_key_vec.==param_key)] + param_dict[param_key] = values + end + alias_dict[alias] = param_dict + end + return alias_dict +end + + +""" + model_volatility_values( + alias::String, + param_dict::Dict, + ) + +Extract volatility labels and values from model parameters. +""" +function model_volatility_values( + alias::String, + param_dict::Dict, + ) + # + @assert(haskey(param_dict, alias)) + m_dict = param_dict[alias] + # + @assert(haskey(m_dict, "type")) + if m_dict["type"] == GaussianHjmModel + return _get_labels_and_values(alias, "sigma_f", m_dict) + end + if m_dict["type"] == LognormalAssetModel + return _get_labels_and_values(alias, "sigma_x", m_dict) + end + if m_dict["type"] == SimpleModel + vol_labels_values = [ + model_volatility_values(a, param_dict) + for a in m_dict["models"] + ] + vol_labels = vcat([lv[1] for lv in vol_labels_values]...) + vol_values = vcat([lv[2] for lv in vol_labels_values]...) + return (vol_labels, vol_values) + end + error("Unknown model type in m_dict.") +end + + +""" + model_parameters!( + param_dict::Dict, + param_labels::AbstractVector, + param_values::AbstractVector, + ) + +Re-build model parameter dictionary from volatility labels and values. +""" +function model_parameters!( + param_dict::Dict, + param_labels::AbstractVector, + param_values::AbstractVector, + ) + # + param_value_dict = _restructure_parameters(param_labels, param_values) + for (m_alias, p_dict) in param_value_dict + @assert m_alias in keys(param_dict) + for (param_key, value_vector) in p_dict + @assert param_key in keys(param_dict[m_alias]) + ts = param_dict[m_alias][param_key] + # the following methodology must revert _get_labels_and_values(...) + ts_size = size(ts.values) + value_matrix = reshape(param_value_dict[m_alias][param_key], (ts_size[2],ts_size[1])) + value_matrix = permutedims(value_matrix) + # + @assert isa(ts, BackwardFlatVolatility) # deal with other cases later... + ts_new = backward_flat_volatility(ts.alias, ts.times, value_matrix) + param_dict[m_alias][param_key] = ts_new # re-set (and activate) term structure + end + end + return param_dict +end diff --git a/src/serialisation/RebuildTermstructures.jl b/src/serialisation/RebuildTermstructures.jl new file mode 100644 index 00000000..4864fe33 --- /dev/null +++ b/src/serialisation/RebuildTermstructures.jl @@ -0,0 +1,119 @@ +""" +This file contains methods to extract term structure values and re-build +term structure dictionaries. + +Methods are intended to be used for sensitivity calculations. For that +purpose we need to identify structure values as inputs to the valuation +function. +""" + + +""" + _get_labels_and_values(ts::FlatForward) + +Extract labels and values from FlatForward. +""" +function _get_labels_and_values(ts::FlatForward) + param_labels = [ + alias(ts) * _split_alias_identifyer * + string(typeof(ts)) * _split_alias_identifyer * + "rate" + ] + param_values = [ ts.rate ] + return ( param_labels, param_values ) +end + + +""" + _get_labels_and_values(ts::ZeroCurve) + +Extract labels and values from ZeroCurve. +""" +function _get_labels_and_values(ts::ZeroCurve) + param_labels = [ + alias(ts) * _split_alias_identifyer * + string(typeof(ts)) * _split_alias_identifyer * + (@sprintf("%.2f", t)) + for t in ts.times + ] + return ( param_labels, ts.values ) +end + + +""" + _get_labels_and_values(ts::PiecewiseFlatParameter) + +Extract labels and values from PiecewiseFlatParameter. +""" +function _get_labels_and_values(ts::PiecewiseFlatParameter) + @assert(size(ts.values)[1] == 1) # we need to deal with multi-factor parameters separately + param_labels = [ + alias(ts) * _split_alias_identifyer * + string(typeof(ts)) * _split_alias_identifyer * + (@sprintf("%.2f", t)) + for t in ts.times + ] + return ( param_labels, ts.values[1,:] ) +end + + +""" + termstructure_values(ts_dict::AbstractDict) + +Extract term structure labels and values from term structure dictionary +""" +function termstructure_values(ts_dict::AbstractDict) + ts_labels_values = [ _get_labels_and_values(ts) for ts in values(ts_dict) ] + ts_labels = vcat([lv[1] for lv in ts_labels_values]...) + ts_values = vcat([lv[2] for lv in ts_labels_values]...) + return (ts_labels, ts_values) +end + + +""" + termstructure_dictionary!( + ts_dict::AbstractDict, + ts_labels::AbstractVector, + ts_values::AbstractVector, + ) + +Re-build term structure dictionary from labels and values. +""" +function termstructure_dictionary!( + ts_dict::AbstractDict, + ts_labels::AbstractVector, + ts_values::AbstractVector, + ) + # + ts_value_dict = _restructure_parameters(ts_labels, ts_values) + for (ts_alias, ts_dict_) in ts_value_dict + @assert ts_alias in keys(ts_dict) + @assert length(keys(ts_dict_)) == 1 + ts_type_string = first(keys(ts_dict_)) + @assert string(typeof(ts_dict[ts_alias])) == ts_type_string + # + values = ts_dict_[ts_type_string] + if isa(ts_dict[ts_alias], FlatForward) + @assert size(values) == (1,) + ts_dict[ts_alias] = flat_forward(ts_dict[ts_alias].alias, values[1]) + continue + end + if isa(ts_dict[ts_alias], ZeroCurve) + ts_dict[ts_alias] = zero_curve(ts_dict[ts_alias].alias, ts_dict[ts_alias].times, values) + continue + end + if isa(ts_dict[ts_alias], BackwardFlatParameter) + ts_dict[ts_alias] = backward_flat_parameter(ts_dict[ts_alias].alias, ts_dict[ts_alias].times, values) + continue + end + if isa(ts_dict[ts_alias], ForwardFlatParameter) + ts_dict[ts_alias] = forward_flat_parameter(ts_dict[ts_alias].alias, ts_dict[ts_alias].times, values) + continue + end + # + # Add further term structures here. + # + error("Termstructure type " * string(typeof(ts_dict[ts_alias])) * " not supported.") + end + return ts_dict +end diff --git a/test/unittests/serialisation/rebuild_models.jl b/test/unittests/serialisation/rebuild_models.jl new file mode 100644 index 00000000..e34fa03f --- /dev/null +++ b/test/unittests/serialisation/rebuild_models.jl @@ -0,0 +1,197 @@ + +using DiffFusion +using Test + +@testset "Extract term structures and rebuild models." begin + + ch_full = DiffFusion.correlation_holder("Full") + # + DiffFusion.set_correlation!(ch_full, "EUR_f_1", "EUR_f_2", 0.8) + DiffFusion.set_correlation!(ch_full, "EUR_f_2", "EUR_f_3", 0.8) + DiffFusion.set_correlation!(ch_full, "EUR_f_1", "EUR_f_3", 0.5) + # + DiffFusion.set_correlation!(ch_full, "USD_f_1", "USD_f_2", 0.50) + # + DiffFusion.set_correlation!(ch_full, "EUR-USD_x", "EUR_f_1", -0.30) + DiffFusion.set_correlation!(ch_full, "EUR-USD_x", "EUR_f_2", -0.30) + DiffFusion.set_correlation!(ch_full, "EUR-USD_x", "EUR_f_3", -0.30) + # + DiffFusion.set_correlation!(ch_full, "EUR-USD_x", "USD_f_1", -0.20) + DiffFusion.set_correlation!(ch_full, "EUR-USD_x", "USD_f_2", -0.20) + # + DiffFusion.set_correlation!(ch_full, "USD_f_1", "EUR_f_1", 0.30) + DiffFusion.set_correlation!(ch_full, "USD_f_2", "EUR_f_2", 0.30) + # + DiffFusion.set_correlation!(ch_full, "EUR-USD_x", "SXE50_x", 0.70) + + setup_models(ch) = begin + sigma_fx = DiffFusion.flat_volatility("EUR-USD", 0.15) + fx_model = DiffFusion.lognormal_asset_model("EUR-USD", sigma_fx, ch, nothing) + + sigma_fx = DiffFusion.flat_volatility("SXE50", 0.10) + eq_model = DiffFusion.lognormal_asset_model("SXE50-EUR", sigma_fx, ch, fx_model) + + delta_dom = DiffFusion.flat_parameter([ 1., 7., 15. ]) + chi_dom = DiffFusion.flat_parameter([ 0.01, 0.10, 0.30 ]) + times_dom = [ 0. ] + values_dom = [ 50. 60. 70. ]' * 1.0e-4 + sigma_f_dom = DiffFusion.backward_flat_volatility("USD",times_dom,values_dom) + hjm_model_dom = DiffFusion.gaussian_hjm_model("USD",delta_dom,chi_dom,sigma_f_dom,ch,nothing) + + delta_for = DiffFusion.flat_parameter([ 1., 10. ]) + chi_for = DiffFusion.flat_parameter([ 0.01, 0.15 ]) + times_for = [ 0. ] + values_for = [ 80. 90. ]' * 1.0e-4 + sigma_f_for = DiffFusion.backward_flat_volatility("EUR",times_for,values_for) + hjm_model_for = DiffFusion.gaussian_hjm_model("EUR",delta_for,chi_for,sigma_f_for,ch,fx_model) + + return [ hjm_model_dom, fx_model, hjm_model_for, eq_model ] + end + + hybrid_model_full = DiffFusion.simple_model("Std", setup_models(ch_full)) + + @testset "Extract model parameters" begin + full_model = hybrid_model_full + usd_model = full_model.models[1] + eur_usd_model = full_model.models[2] + eur_model = full_model.models[3] + sxe50_model = full_model.models[4] + # + d = DiffFusion.model_parameters(usd_model) + @test length(d) == 1 + @test haskey(d, DiffFusion.alias(usd_model)) + d = d[DiffFusion.alias(usd_model)] + for (a, b) in zip(keys(d), ["correlation_holder", "quanto_model", "chi", "sigma_f", "type", "delta", "alias"]) + @test a == b + end + # + d = DiffFusion.model_parameters(eur_usd_model) + @test length(d) == 1 + @test haskey(d, DiffFusion.alias(eur_usd_model)) + d = d[DiffFusion.alias(eur_usd_model)] + for (a, b) in zip(keys(d), ["quanto_model", "sigma_x", "type", "correlation_holder", "alias"]) + @test a == b + end + # + d = DiffFusion.model_parameters(full_model) + for (a, b) in zip(keys(d), ["EUR", "Std", "Full", "EUR-USD", "SXE50-EUR", "USD"]) + @test a == b + end + end + + @testset "Re-build models" begin + full_model = hybrid_model_full + usd_model = full_model.models[1] + eur_usd_model = full_model.models[2] + eur_model = full_model.models[3] + sxe50_model = full_model.models[4] + # + param_dict = DiffFusion.model_parameters(full_model) + model_dict = Dict{String, Any}() + # + model = DiffFusion.build_model(DiffFusion.alias(usd_model), param_dict, model_dict) + @test string(model) == string(usd_model) + # + model = DiffFusion.build_model(DiffFusion.alias(eur_usd_model), param_dict, model_dict) + @test string(model) == string(eur_usd_model) + # + @test_throws KeyError DiffFusion.build_model(DiffFusion.alias(eur_model), param_dict, model_dict) + model_dict[DiffFusion.alias(eur_usd_model)] = eur_usd_model + model = DiffFusion.build_model(DiffFusion.alias(eur_model), param_dict, model_dict) + @test string(model) == string(eur_model) + # + model_dict = Dict{String, Any}() + @test_throws KeyError DiffFusion.build_model(DiffFusion.alias(sxe50_model), param_dict, model_dict) + model_dict[DiffFusion.alias(eur_usd_model)] = eur_usd_model + model = DiffFusion.build_model(DiffFusion.alias(sxe50_model), param_dict, model_dict) + @test string(model) == string(sxe50_model) + # + model_dict = Dict{String, Any}() + model = DiffFusion.build_model(DiffFusion.alias(full_model), param_dict, model_dict) + @test string(model) == string(full_model) + end + + + @testset "Extract model volatilities and re-build model." begin + full_model = hybrid_model_full + usd_model = full_model.models[1] + eur_usd_model = full_model.models[2] + eur_model = full_model.models[3] + sxe50_model = full_model.models[4] + # + delim = DiffFusion._split_alias_identifyer + # + d = DiffFusion.model_parameters(usd_model) + (l, v) = DiffFusion.model_volatility_values(usd_model.alias, d) + @test l == [ + "USD" * delim * "sigma_f" * delim * "1" * delim * "0.00", + "USD" * delim * "sigma_f" * delim * "2" * delim * "0.00", + "USD" * delim * "sigma_f" * delim * "3" * delim * "0.00", + ] + @test v == [0.005, 0.006, 0.007] + d1 = deepcopy(d) + d2 = DiffFusion.model_parameters!(d, l, v) + for (key, param) in d1["USD"] + @test string(param) == string(d2["USD"][key]) + end + # + d = DiffFusion.model_parameters(eur_usd_model) + (l, v) = DiffFusion.model_volatility_values(eur_usd_model.alias, d) + @test l == ["EUR-USD" * delim * "sigma_x" * delim * "1" * delim * "0.00"] + @test v == [0.15] + d1 = deepcopy(d) + d2 = DiffFusion.model_parameters!(d, l, v) + for (key, param) in d1["EUR-USD"] + @test string(param) == string(d2["EUR-USD"][key]) + end + # + d = DiffFusion.model_parameters(full_model) + (l, v) = DiffFusion.model_volatility_values(full_model.alias, d) + @test l == [ + "USD" * delim * "sigma_f" * delim * "1" * delim * "0.00", + "USD" * delim * "sigma_f" * delim * "2" * delim * "0.00", + "USD" * delim * "sigma_f" * delim * "3" * delim * "0.00", + "EUR-USD" * delim * "sigma_x" * delim * "1" * delim * "0.00", + "EUR" * delim * "sigma_f" * delim * "1" * delim * "0.00", + "EUR" * delim * "sigma_f" * delim * "2" * delim * "0.00", + "SXE50-EUR" * delim * "sigma_x" * delim * "1" * delim * "0.00", + ] + @test v == [50.0*1e-4, 60.0*1e-4, 70.0*1e-4, 0.15, 80.0*1e-4, 90.0*1e-4, 0.10] + d1 = deepcopy(d) + d2 = DiffFusion.model_parameters!(d, l, v) + # + model1 = DiffFusion.build_model(DiffFusion.alias(full_model), d1, Dict{String, Any}()) + model2 = DiffFusion.build_model(DiffFusion.alias(full_model), d2, Dict{String, Any}()) + @test string(model1) == string(model2) + @test string(model2) == string(full_model) + end + + @testset "Test term structure dimensions." begin + full_model = hybrid_model_full + usd_model = full_model.models[1] + eur_usd_model = full_model.models[2] + eur_model = full_model.models[3] + sxe50_model = full_model.models[4] + # + d = DiffFusion.model_parameters(usd_model) + ts = d["USD"]["sigma_f"] + ts = DiffFusion.backward_flat_volatility(ts.alias, [1.0, 2.0, 3.0, 4.0], rand(3,4)) + d["USD"]["sigma_f"] = ts + (l, v) = DiffFusion.model_volatility_values(usd_model.alias, d) + d1 = deepcopy(d) + d2 = DiffFusion.model_parameters!(d, l, v) + @test d1["USD"]["sigma_f"].values == d2["USD"]["sigma_f"].values + # + d = DiffFusion.model_parameters(eur_usd_model) + ts = d["EUR-USD"]["sigma_x"] + ts = DiffFusion.backward_flat_volatility(ts.alias, [1.0, 2.0, 3.0, 4.0], rand(1,4)) + d["EUR-USD"]["sigma_x"] = ts + (l, v) = DiffFusion.model_volatility_values(eur_usd_model.alias, d) + d1 = deepcopy(d) + d2 = DiffFusion.model_parameters!(d, l, v) + @test d1["EUR-USD"]["sigma_x"].values == d2["EUR-USD"]["sigma_x"].values + # println(l) + # println(v) + end + +end diff --git a/test/unittests/serialisation/rebuild_termstructures.jl b/test/unittests/serialisation/rebuild_termstructures.jl new file mode 100644 index 00000000..9f4370fc --- /dev/null +++ b/test/unittests/serialisation/rebuild_termstructures.jl @@ -0,0 +1,66 @@ +using DiffFusion +using Test + +@testset "Extract term structures and rebuild term structure dictionary." begin + + @testset "Extract and rebuild" begin + delim = DiffFusion._split_alias_identifyer + ts_vector = [ + DiffFusion.flat_forward("yc/flat_forward", 0.01), + DiffFusion.zero_curve("yc/zero_curve", [ 1.0, 10.0 ], [ 0.02, 0.03 ]), + DiffFusion.backward_flat_parameter("pa/backward_flat_parameter", [ 0.0 ], [ 1.0 ]), + DiffFusion.forward_flat_parameter("pa/forward_flat_parameter", [0.0, 2.0], [ 0.10, 0.15] ), + ] + ts_dict = Dict{String,DiffFusion.Termstructure}(((DiffFusion.alias(ts_), ts_) for ts_ in ts_vector)) + # + (l, v) = DiffFusion.termstructure_values(ts_dict) + labels = [ + "yc/flat_forward" * delim * "DiffFusion.FlatForward" * delim * "rate", + "yc/zero_curve" * delim * "DiffFusion.ZeroCurve" * delim * "1.00", + "yc/zero_curve" * delim * "DiffFusion.ZeroCurve" * delim * "10.00", + "pa/backward_flat_parameter" * delim * "DiffFusion.BackwardFlatParameter" * delim * "0.00", + "pa/forward_flat_parameter" * delim * "DiffFusion.ForwardFlatParameter" * delim * "0.00", + "pa/forward_flat_parameter" * delim * "DiffFusion.ForwardFlatParameter" * delim * "2.00" + ] + values = [0.01, 0.02, 0.03, 1.0, 0.1, 0.15] + @test l == labels + @test v == values + # + d1 = deepcopy(ts_dict) + d2 = DiffFusion.termstructure_dictionary!(ts_dict, l, v) + @test string(d1) == string(d2) + #println(l) + #println(v) + end + + @testset "Extract and rebuild with permutation" begin + delim = DiffFusion._split_alias_identifyer + ts_vector = [ + DiffFusion.flat_forward("yc/flat_forward", 0.01), + DiffFusion.zero_curve("yc/zero_curve", [ 1.0, 10.0 ], [ 0.02, 0.03 ]), + DiffFusion.backward_flat_parameter("pa/backward_flat_parameter", [ 0.0 ], [ 1.0 ]), + DiffFusion.forward_flat_parameter("pa/forward_flat_parameter", [0.0, 2.0], [ 0.10, 0.15] ), + ] + ts_dict = Dict{String,DiffFusion.Termstructure}(((DiffFusion.alias(ts_), ts_) for ts_ in ts_vector)) + # + (l, v) = DiffFusion.termstructure_values(ts_dict) + labels = [ + "pa/forward_flat_parameter" * delim * "DiffFusion.ForwardFlatParameter" * delim * "0.00", + "pa/forward_flat_parameter" * delim * "DiffFusion.ForwardFlatParameter" * delim * "2.00", + "pa/backward_flat_parameter" * delim * "DiffFusion.BackwardFlatParameter" * delim * "0.00", + "yc/zero_curve" * delim * "DiffFusion.ZeroCurve" * delim * "1.00", + "yc/zero_curve" * delim * "DiffFusion.ZeroCurve" * delim * "10.00", + "yc/flat_forward" * delim * "DiffFusion.FlatForward" * delim * "rate", + ] + values = [ 0.1, 0.15, 1.0, 0.02, 0.03, 0.01,] + @test l != labels + @test v != values + # + d1 = deepcopy(ts_dict) + d2 = DiffFusion.termstructure_dictionary!(ts_dict, l, v) + @test string(d1) == string(d2) + #println(l) + #println(v) + end + +end diff --git a/test/unittests/serialisation/serialisation.jl b/test/unittests/serialisation/serialisation.jl index 62b3fa39..14ddbfe9 100644 --- a/test/unittests/serialisation/serialisation.jl +++ b/test/unittests/serialisation/serialisation.jl @@ -8,5 +8,8 @@ using Test include("models.jl") include("objects.jl") include("termstructures.jl") + # + include("rebuild_models.jl") + include("rebuild_termstructures.jl") end