diff --git a/.gitignore b/.gitignore index 2c272fa..68352df 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,6 @@ docs/site/ # It records a fixed state of all packages used by the project. As such, it should not be # committed for packages, but should be committed for applications that require a static # environment. -*Manifest.toml +Manifest.toml settings.json \ No newline at end of file diff --git a/Project.toml b/Project.toml index 21a2a4d..23a6b57 100644 --- a/Project.toml +++ b/Project.toml @@ -9,18 +9,16 @@ Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" FinanceCore = "b9b1ffdd-6612-4b69-8227-7663be06e089" FinanceModels = "77f2ae65-bdde-421f-ae9d-22f1af19dd76" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" -MuladdMacro = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" [compat] -Distributions = "0.24,0.25" +Distributions = "0.25" FinanceCore = "^2" FinanceModels = "^4" ForwardDiff = "^0.10" -MuladdMacro = "^0.2" PrecompileTools = "^1" QuadGK = "^2" Reexport = "^1.2" diff --git a/README.md b/README.md index df8ba24..b014599 100644 --- a/README.md +++ b/README.md @@ -35,21 +35,20 @@ A collection of common functions/manipulations used in Actuarial Calculations. - `accum_offset` to calculate accumulations like survivorship from a mortality vector - `spread` will calculate the spread needed between two yield curves to equate a set of cashflows -### Options Pricing -- `eurocall` and `europut` for Black-Scholes option prices (note: API may change for this in future) - ### Risk Measures - Calculate risk measures for a given vector of risks: - - `CTE` for the Conditional Tail Expectation, or - - `VaR` for the percentile/Value at Risk. + - `CTE` for the Conditional Tail Expectation + - `VaR` for the percentile/Value at Risk + - `WangTransform` for the Wang Transformation + - `ProportionalHazard` for proportional hazards + - `DualPower` for dual power measure ### Insurance mechanics - `duration`: - Calculate the duration given an issue date and date (a.k.a. policy duration) - ### Typed Rates - functions which return a rate/yield will return a `FinanceCore.Rate` object. E.g. `irr(cashflows)` will return a `Rate(0.05,Periodic(1))` instead of just a `0.05` (`float64`) to convey the compounding frequency. This is compatible across the JuliaActuary ecosystem and can be used anywhere you would otherwise use a simple floating point rate. diff --git a/docs/Manifest.toml b/docs/Manifest.toml deleted file mode 100644 index 477bb08..0000000 --- a/docs/Manifest.toml +++ /dev/null @@ -1,1288 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -[[ADTypes]] -git-tree-sha1 = "5d2e21d7b0d8c22f67483ef95ebdc39c0e6b6003" -uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "0.2.4" - -[[ANSIColoredPrinters]] -git-tree-sha1 = "574baf8110975760d391c710b6341da1afa48d8c" -uuid = "a4c015fc-c6ff-483c-b24f-f7ea428134e9" -version = "0.0.1" - -[[AbstractTrees]] -git-tree-sha1 = "faa260e4cb5aba097a73fab382dd4b5819d8ec8c" -uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" -version = "0.4.4" - -[[AccessibleOptimization]] -deps = ["AccessorsExtra", "ConstructionBase", "DataPipes", "Optimization", "Reexport", "Statistics"] -git-tree-sha1 = "ddd0a1f18f7426b7d4ca365b70af5857338e0c52" -uuid = "d88a00a0-4a21-4fe4-a515-e2123c37b885" -version = "0.1.1" - -[[Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Test"] -git-tree-sha1 = "a7055b939deae2455aa8a67491e034f735dd08d3" -uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.33" - - [Accessors.extensions] - AccessorsAxisKeysExt = "AxisKeys" - AccessorsIntervalSetsExt = "IntervalSets" - AccessorsStaticArraysExt = "StaticArrays" - AccessorsStructArraysExt = "StructArrays" - - [Accessors.weakdeps] - AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - Requires = "ae029012-a4dd-5104-9daa-d747884805df" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" - -[[AccessorsExtra]] -deps = ["Accessors", "CompositionsBase", "ConstructionBase", "DataPipes", "InverseFunctions", "LinearAlgebra", "Reexport"] -git-tree-sha1 = "c2a58d4646d16312dfb63552f383165f59fbc4b5" -uuid = "33016aad-b69d-45be-9359-82a41f556fd4" -version = "0.1.55" - - [AccessorsExtra.extensions] - DictionariesExt = "Dictionaries" - DistributionsExt = "Distributions" - DomainSetsExt = "DomainSets" - StaticArraysExt = "StaticArrays" - StructArraysExt = "StructArrays" - TestExt = "Test" - URIsExt = "URIs" - - [AccessorsExtra.weakdeps] - Dictionaries = "85a47980-9c8c-11e8-2b9f-f7ca1fa99fb4" - Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" - DomainSets = "5b8099bc-c8ec-5219-889f-1d9e522a28bf" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" - Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - URIs = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4" - -[[ActuaryUtilities]] -deps = ["Dates", "Distributions", "FinanceCore", "FinanceModels", "ForwardDiff", "MuladdMacro", "PrecompileTools", "QuadGK", "Reexport", "StatsBase"] -path = "/Users/alec/.julia/dev/ActuaryUtilities" -uuid = "bdd23359-8b1c-4f88-b89b-d11982a786f4" -version = "4.2.0" - -[[Adapt]] -deps = ["LinearAlgebra", "Requires"] -git-tree-sha1 = "02f731463748db57cc2ebfbd9fbc9ce8280d3433" -uuid = "79e6a3ab-5dfb-504d-930d-738a2a938a0e" -version = "3.7.1" -weakdeps = ["StaticArrays"] - - [Adapt.extensions] - AdaptStaticArraysExt = "StaticArrays" - -[[ArgCheck]] -git-tree-sha1 = "a3a402a35a2f7e0b87828ccabbd5ebfbebe356b4" -uuid = "dce04be8-c92d-5529-be00-80e4d2c0e197" -version = "2.3.0" - -[[ArgTools]] -uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f" -version = "1.1.1" - -[[ArrayInterface]] -deps = ["Adapt", "LinearAlgebra", "Requires", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "f83ec24f76d4c8f525099b2ac475fc098138ec31" -uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.4.11" - - [ArrayInterface.extensions] - ArrayInterfaceBandedMatricesExt = "BandedMatrices" - ArrayInterfaceBlockBandedMatricesExt = "BlockBandedMatrices" - ArrayInterfaceCUDAExt = "CUDA" - ArrayInterfaceGPUArraysCoreExt = "GPUArraysCore" - ArrayInterfaceStaticArraysCoreExt = "StaticArraysCore" - ArrayInterfaceTrackerExt = "Tracker" - - [ArrayInterface.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - CUDA = "052768ef-5323-5732-b1bb-66c8b64840ba" - GPUArraysCore = "46192b85-c4d5-4398-a991-12ede77f4527" - StaticArraysCore = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - -[[ArrayInterfaceCore]] -deps = ["LinearAlgebra", "SnoopPrecompile", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "e5f08b5689b1aad068e01751889f2f615c7db36d" -uuid = "30b0a656-2188-435a-8636-2ec0e6a096e2" -version = "0.1.29" - -[[ArrayLayouts]] -deps = ["FillArrays", "LinearAlgebra"] -git-tree-sha1 = "9a731850434825d183af39c6e6cd0a1c32dd7e20" -uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a" -version = "1.4.2" -weakdeps = ["SparseArrays"] - - [ArrayLayouts.extensions] - ArrayLayoutsSparseArraysExt = "SparseArrays" - -[[Artifacts]] -uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" - -[[BSplineKit]] -deps = ["ArrayLayouts", "BandedMatrices", "FastGaussQuadrature", "LinearAlgebra", "PrecompileTools", "Random", "Reexport", "SparseArrays", "Static", "StaticArrays", "StaticArraysCore"] -git-tree-sha1 = "e8c349b71f1cde3faad14bb09d3fc5a3b287eeb8" -uuid = "093aae92-e908-43d7-9660-e50ee39d5a0a" -version = "0.16.5" - -[[BandedMatrices]] -deps = ["ArrayLayouts", "FillArrays", "LinearAlgebra", "PrecompileTools"] -git-tree-sha1 = "8f32ba3789b29880901748dce28f7d5c1d4ae86a" -uuid = "aae01518-5342-5314-be14-df237901396f" -version = "1.1.0" -weakdeps = ["SparseArrays"] - - [BandedMatrices.extensions] - BandedMatricesSparseArraysExt = "SparseArrays" - -[[BangBang]] -deps = ["Compat", "ConstructionBase", "InitialValues", "LinearAlgebra", "Requires", "Setfield", "Tables"] -git-tree-sha1 = "e28912ce94077686443433c2800104b061a827ed" -uuid = "198e06fe-97b7-11e9-32a5-e1d131e6ad66" -version = "0.3.39" - - [BangBang.extensions] - BangBangChainRulesCoreExt = "ChainRulesCore" - BangBangDataFramesExt = "DataFrames" - BangBangStaticArraysExt = "StaticArrays" - BangBangStructArraysExt = "StructArrays" - BangBangTypedTablesExt = "TypedTables" - - [BangBang.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" - TypedTables = "9d95f2ec-7b3d-5a63-8d20-e2491e220bb9" - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[Baselet]] -git-tree-sha1 = "aebf55e6d7795e02ca500a689d326ac979aaf89e" -uuid = "9718e550-a3fa-408a-8086-8db961cd8217" -version = "0.1.1" - -[[BitTwiddlingConvenienceFunctions]] -deps = ["Static"] -git-tree-sha1 = "0c5f81f47bbbcf4aea7b2959135713459170798b" -uuid = "62783981-4cbd-42fc-bca8-16325de8dc4b" -version = "0.1.5" - -[[CPUSummary]] -deps = ["CpuId", "IfElse", "PrecompileTools", "Static"] -git-tree-sha1 = "601f7e7b3d36f18790e2caf83a882d88e9b71ff1" -uuid = "2a0fbf3d-bb9c-48f3-b0a9-814d99fd7ab9" -version = "0.2.4" - -[[Calculus]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "f641eb0a4f00c343bbc32346e1217b86f3ce9dad" -uuid = "49dc2e85-a5d0-5ad3-a950-438e2897f1b9" -version = "0.5.1" - -[[ChainRulesCore]] -deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "e0af648f0692ec1691b5d094b8724ba1346281cf" -uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.18.0" -weakdeps = ["SparseArrays"] - - [ChainRulesCore.extensions] - ChainRulesCoreSparseArraysExt = "SparseArrays" - -[[CloseOpenIntervals]] -deps = ["Static", "StaticArrayInterface"] -git-tree-sha1 = "70232f82ffaab9dc52585e0dd043b5e0c6b714f1" -uuid = "fb6a15b2-703c-40df-9091-08a04967cfa9" -version = "0.1.12" - -[[ColorSchemes]] -deps = ["ColorTypes", "ColorVectorSpace", "Colors", "FixedPointNumbers", "PrecompileTools", "Random"] -git-tree-sha1 = "67c1f244b991cad9b0aa4b7540fb758c2488b129" -uuid = "35d6a980-a343-548e-a6ea-1d62b119f2f4" -version = "3.24.0" - -[[ColorTypes]] -deps = ["FixedPointNumbers", "Random"] -git-tree-sha1 = "eb7f0f8307f71fac7c606984ea5fb2817275d6e4" -uuid = "3da002f7-5984-5a60-b8a6-cbb66c0b333f" -version = "0.11.4" - -[[ColorVectorSpace]] -deps = ["ColorTypes", "FixedPointNumbers", "LinearAlgebra", "Requires", "Statistics", "TensorCore"] -git-tree-sha1 = "a1f44953f2382ebb937d60dafbe2deea4bd23249" -uuid = "c3611d14-8923-5661-9e6a-0046d554d3a4" -version = "0.10.0" -weakdeps = ["SpecialFunctions"] - - [ColorVectorSpace.extensions] - SpecialFunctionsExt = "SpecialFunctions" - -[[Colors]] -deps = ["ColorTypes", "FixedPointNumbers", "Reexport"] -git-tree-sha1 = "fc08e5930ee9a4e03f84bfb5211cb54e7769758a" -uuid = "5ae59095-9a9b-59fe-a467-6f913c188581" -version = "0.12.10" - -[[Combinatorics]] -git-tree-sha1 = "08c8b6831dc00bfea825826be0bc8336fc369860" -uuid = "861a8166-3701-5b0c-9a16-15d98fcdc6aa" -version = "1.0.2" - -[[CommonSolve]] -git-tree-sha1 = "0eee5eb66b1cf62cd6ad1b460238e60e4b09400c" -uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" -version = "0.2.4" - -[[CommonSubexpressions]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" -uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.0" - -[[Compat]] -deps = ["UUIDs"] -git-tree-sha1 = "8a62af3e248a8c4bad6b32cbbe663ae02275e32c" -uuid = "34da2185-b29b-5c13-b0c7-acf172513d20" -version = "4.10.0" -weakdeps = ["Dates", "LinearAlgebra"] - - [Compat.extensions] - CompatLinearAlgebraExt = "LinearAlgebra" - -[[CompilerSupportLibraries_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae" -version = "1.0.5+0" - -[[CompositionsBase]] -git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad" -uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b" -version = "0.1.2" -weakdeps = ["InverseFunctions"] - - [CompositionsBase.extensions] - CompositionsBaseInverseFunctionsExt = "InverseFunctions" - -[[ConsoleProgressMonitor]] -deps = ["Logging", "ProgressMeter"] -git-tree-sha1 = "3ab7b2136722890b9af903859afcf457fa3059e8" -uuid = "88cd18e8-d9cc-4ea6-8889-5259c0d15c8b" -version = "0.1.2" - -[[ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "c53fc348ca4d40d7b371e71fd52251839080cbc9" -uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.4" -weakdeps = ["IntervalSets", "StaticArrays"] - - [ConstructionBase.extensions] - ConstructionBaseIntervalSetsExt = "IntervalSets" - ConstructionBaseStaticArraysExt = "StaticArrays" - -[[Contour]] -git-tree-sha1 = "d05d9e7b7aedff4e5b51a029dced05cfb6125781" -uuid = "d38c429a-6771-53c6-b99e-75d170b6e991" -version = "0.6.2" - -[[CpuId]] -deps = ["Markdown"] -git-tree-sha1 = "fcbb72b032692610bfbdb15018ac16a36cf2e406" -uuid = "adafc99b-e345-5852-983c-f28acb93d879" -version = "0.3.1" - -[[Crayons]] -git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15" -uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f" -version = "4.1.1" - -[[DataAPI]] -git-tree-sha1 = "8da84edb865b0b5b0100c0666a9bc9a0b71c553c" -uuid = "9a962f9c-6df0-11e9-0e5d-c546b8b5ee8a" -version = "1.15.0" - -[[DataPipes]] -git-tree-sha1 = "7ee371c4d2ec6e3f735b48c5782ece9a2808c809" -uuid = "02685ad9-2d12-40c3-9f73-c6aeda6a7ff5" -version = "0.3.11" - -[[DataStructures]] -deps = ["Compat", "InteractiveUtils", "OrderedCollections"] -git-tree-sha1 = "3dbd312d370723b6bb43ba9d02fc36abade4518d" -uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8" -version = "0.18.15" - -[[DataValueInterfaces]] -git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6" -uuid = "e2d170a0-9d28-54be-80f0-106bbe20a464" -version = "1.0.0" - -[[Dates]] -deps = ["Printf"] -uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" - -[[DayCounts]] -deps = ["Dates"] -git-tree-sha1 = "cb81cac5f32b71d4e127f4d1bea6fd6049e729b2" -uuid = "44e31299-2c53-5a9b-9141-82aa45d7972f" -version = "0.1.0" - -[[DefineSingletons]] -git-tree-sha1 = "0fba8b706d0178b4dc7fd44a96a92382c9065c2c" -uuid = "244e2a9f-e319-4986-a169-4d1fe445cd52" -version = "0.1.2" - -[[DiffResults]] -deps = ["StaticArraysCore"] -git-tree-sha1 = "782dd5f4561f5d267313f23853baaaa4c52ea621" -uuid = "163ba53b-c6d8-5494-b064-1a9d43ac40c5" -version = "1.1.0" - -[[DiffRules]] -deps = ["IrrationalConstants", "LogExpFunctions", "NaNMath", "Random", "SpecialFunctions"] -git-tree-sha1 = "23163d55f885173722d1e4cf0f6110cdbaf7e272" -uuid = "b552c78f-8df3-52c6-915a-8e097449b14b" -version = "1.15.1" - -[[Distances]] -deps = ["LinearAlgebra", "Statistics", "StatsAPI"] -git-tree-sha1 = "5225c965635d8c21168e32a12954675e7bea1151" -uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7" -version = "0.10.10" -weakdeps = ["ChainRulesCore", "SparseArrays"] - - [Distances.extensions] - DistancesChainRulesCoreExt = "ChainRulesCore" - DistancesSparseArraysExt = "SparseArrays" - -[[Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[Distributions]] -deps = ["FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns", "Test"] -git-tree-sha1 = "3d5873f811f582873bb9871fc9c451784d5dc8c7" -uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.102" - - [Distributions.extensions] - DistributionsChainRulesCoreExt = "ChainRulesCore" - DistributionsDensityInterfaceExt = "DensityInterface" - - [Distributions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d" - -[[DocStringExtensions]] -deps = ["LibGit2"] -git-tree-sha1 = "2fb1e02f2b635d0845df5d7c167fec4dd739b00d" -uuid = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae" -version = "0.9.3" - -[[Documenter]] -deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "Dates", "DocStringExtensions", "Downloads", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "Test", "Unicode"] -git-tree-sha1 = "662fb21ae7fad33e044c2b59ece832fdce32c171" -uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.1.2" - -[[Downloads]] -deps = ["ArgTools", "FileWatching", "LibCURL", "NetworkOptions"] -uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" -version = "1.6.0" - -[[DualNumbers]] -deps = ["Calculus", "NaNMath", "SpecialFunctions"] -git-tree-sha1 = "5837a837389fccf076445fce071c8ddaea35a566" -uuid = "fa6b7ba4-c1ee-5f82-b5fc-ecf0adba8f74" -version = "0.6.8" - -[[EnumX]] -git-tree-sha1 = "bdb1942cd4c45e3c678fd11569d5cccd80976237" -uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56" -version = "1.0.4" - -[[ExprTools]] -git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec" -uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04" -version = "0.1.10" - -[[FastGaussQuadrature]] -deps = ["LinearAlgebra", "SpecialFunctions", "StaticArrays"] -git-tree-sha1 = "93ff6a4d5e7bfe27732259bfabbdd19940d8af1f" -uuid = "442a2c76-b920-505d-bb47-c5924d526838" -version = "1.0.0" - -[[FileWatching]] -uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" - -[[FillArrays]] -deps = ["LinearAlgebra", "Random"] -git-tree-sha1 = "35f0c0f345bff2c6d636f95fdb136323b5a796ef" -uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.7.0" -weakdeps = ["SparseArrays", "Statistics"] - - [FillArrays.extensions] - FillArraysSparseArraysExt = "SparseArrays" - FillArraysStatisticsExt = "Statistics" - -[[FinanceCore]] -deps = ["Dates", "LoopVectorization", "Roots"] -git-tree-sha1 = "8da22299e7d4f1b5fe0c2d5b00f6fca125f46456" -uuid = "b9b1ffdd-6612-4b69-8227-7663be06e089" -version = "2.0.2" - -[[FinanceModels]] -deps = ["AccessibleOptimization", "Accessors", "BSplineKit", "Dates", "Distributions", "FinanceCore", "IntervalSets", "LinearAlgebra", "Optimization", "OptimizationMetaheuristics", "OptimizationOptimJL", "PrecompileTools", "Reexport", "StaticArrays", "Transducers", "UnicodePlots"] -git-tree-sha1 = "3fa32cb6360050c92edb979125c5eae92188538a" -uuid = "77f2ae65-bdde-421f-ae9d-22f1af19dd76" -version = "4.1.0" - - [FinanceModels.extensions] - FinanceModelsMakieCoreExt = "MakieCore" - - [FinanceModels.weakdeps] - MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" - -[[FiniteDiff]] -deps = ["ArrayInterface", "LinearAlgebra", "Requires", "Setfield", "SparseArrays"] -git-tree-sha1 = "c6e4a1fbe73b31a3dea94b1da449503b8830c306" -uuid = "6a86dc24-6348-571c-b903-95158fe2bd41" -version = "2.21.1" - - [FiniteDiff.extensions] - FiniteDiffBandedMatricesExt = "BandedMatrices" - FiniteDiffBlockBandedMatricesExt = "BlockBandedMatrices" - FiniteDiffStaticArraysExt = "StaticArrays" - - [FiniteDiff.weakdeps] - BandedMatrices = "aae01518-5342-5314-be14-df237901396f" - BlockBandedMatrices = "ffab5731-97b5-5995-9138-79e8c1846df0" - StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" - -[[FixedPointNumbers]] -deps = ["Statistics"] -git-tree-sha1 = "335bfdceacc84c5cdf16aadc768aa5ddfc5383cc" -uuid = "53c48c17-4a7d-5ca2-90c5-79b7896eea93" -version = "0.8.4" - -[[ForwardDiff]] -deps = ["CommonSubexpressions", "DiffResults", "DiffRules", "LinearAlgebra", "LogExpFunctions", "NaNMath", "Preferences", "Printf", "Random", "SpecialFunctions"] -git-tree-sha1 = "cf0fe81336da9fb90944683b8c41984b08793dad" -uuid = "f6369f11-7733-5829-9624-2563aa707210" -version = "0.10.36" -weakdeps = ["StaticArrays"] - - [ForwardDiff.extensions] - ForwardDiffStaticArraysExt = "StaticArrays" - -[[FunctionWrappers]] -git-tree-sha1 = "d62485945ce5ae9c0c48f124a84998d755bae00e" -uuid = "069b7b12-0de2-55c6-9aab-29f3d0a68a2e" -version = "1.1.3" - -[[FunctionWrappersWrappers]] -deps = ["FunctionWrappers"] -git-tree-sha1 = "b104d487b34566608f8b4e1c39fb0b10aa279ff8" -uuid = "77dc65aa-8811-40c2-897b-53d922fa7daf" -version = "0.1.3" - -[[Future]] -deps = ["Random"] -uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820" - -[[GPUArraysCore]] -deps = ["Adapt"] -git-tree-sha1 = "2d6ca471a6c7b536127afccfa7564b5b39227fe0" -uuid = "46192b85-c4d5-4398-a991-12ede77f4527" -version = "0.1.5" - -[[HostCPUFeatures]] -deps = ["BitTwiddlingConvenienceFunctions", "IfElse", "Libdl", "Static"] -git-tree-sha1 = "eb8fed28f4994600e29beef49744639d985a04b2" -uuid = "3e5b6fbb-0976-4d2c-9146-d79de83f2fb0" -version = "0.1.16" - -[[HypergeometricFunctions]] -deps = ["DualNumbers", "LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] -git-tree-sha1 = "f218fe3736ddf977e0e772bc9a586b2383da2685" -uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a" -version = "0.3.23" - -[[IOCapture]] -deps = ["Logging", "Random"] -git-tree-sha1 = "d75853a0bdbfb1ac815478bacd89cd27b550ace6" -uuid = "b5f81e59-6552-4d32-b1f0-c071b021bf89" -version = "0.2.3" - -[[IfElse]] -git-tree-sha1 = "debdd00ffef04665ccbb3e150747a77560e8fad1" -uuid = "615f187c-cbe4-4ef1-ba3b-2fcf58d6d173" -version = "0.1.1" - -[[InitialValues]] -git-tree-sha1 = "4da0f88e9a39111c2fa3add390ab15f3a44f3ca3" -uuid = "22cec73e-a1b8-11e9-2c92-598750a2cf9c" -version = "0.3.1" - -[[InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[IntervalSets]] -deps = ["Dates", "Random"] -git-tree-sha1 = "3d8866c029dd6b16e69e0d4a939c4dfcb98fac47" -uuid = "8197267c-284f-5f27-9208-e0e47529a953" -version = "0.7.8" -weakdeps = ["Statistics"] - - [IntervalSets.extensions] - IntervalSetsStatisticsExt = "Statistics" - -[[InverseFunctions]] -deps = ["Test"] -git-tree-sha1 = "68772f49f54b479fa88ace904f6127f0a3bb2e46" -uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.12" - -[[IrrationalConstants]] -git-tree-sha1 = "630b497eafcc20001bba38a4651b327dcfc491d2" -uuid = "92d709cd-6900-40b7-9082-c6be49f344b6" -version = "0.2.2" - -[[IteratorInterfaceExtensions]] -git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856" -uuid = "82899510-4779-5014-852e-03e436cf321d" -version = "1.0.0" - -[[JLLWrappers]] -deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" -uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.5.0" - -[[JMcDM]] -deps = ["Requires"] -git-tree-sha1 = "bc05847a1f32adf0a403ee27addb6daae0a72e38" -uuid = "358108f5-d052-4d0a-8344-d5384e00c0e5" -version = "0.7.8" - -[[JSON]] -deps = ["Dates", "Mmap", "Parsers", "Unicode"] -git-tree-sha1 = "31e996f0a15c7b280ba9f76636b3ff9e2ae58c9a" -uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6" -version = "0.21.4" - -[[LayoutPointers]] -deps = ["ArrayInterface", "LinearAlgebra", "ManualMemory", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "88b8f66b604da079a627b6fb2860d3704a6729a1" -uuid = "10f19ff3-798f-405d-979b-55457f8fc047" -version = "0.1.14" - -[[LazilyInitializedFields]] -git-tree-sha1 = "410fe4739a4b092f2ffe36fcb0dcc3ab12648ce1" -uuid = "0e77f7df-68c5-4e49-93ce-4cd80f5598bf" -version = "1.2.1" - -[[Lazy]] -deps = ["MacroTools"] -git-tree-sha1 = "1370f8202dac30758f3c345f9909b97f53d87d3f" -uuid = "50d2b5c4-7a5e-59d5-8109-a42b560f39c0" -version = "0.15.1" - -[[LeftChildRightSiblingTrees]] -deps = ["AbstractTrees"] -git-tree-sha1 = "fb6803dafae4a5d62ea5cab204b1e657d9737e7f" -uuid = "1d6d02ad-be62-4b6b-8a6d-2f90e265016e" -version = "0.2.0" - -[[LibCURL]] -deps = ["LibCURL_jll", "MozillaCACerts_jll"] -uuid = "b27032c2-a3e7-50c8-80cd-2d36dbcbfd21" -version = "0.6.3" - -[[LibCURL_jll]] -deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll", "Zlib_jll", "nghttp2_jll"] -uuid = "deac9b47-8bc7-5906-a0fe-35ac56dc84c0" -version = "7.84.0+0" - -[[LibGit2]] -deps = ["Base64", "NetworkOptions", "Printf", "SHA"] -uuid = "76f85450-5226-5b5a-8eaa-529ad045b433" - -[[LibSSH2_jll]] -deps = ["Artifacts", "Libdl", "MbedTLS_jll"] -uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8" -version = "1.10.2+0" - -[[Libdl]] -uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb" - -[[LineSearches]] -deps = ["LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "Printf"] -git-tree-sha1 = "7bbea35cec17305fc70a0e5b4641477dc0789d9d" -uuid = "d3d80556-e9d4-5f37-9878-2ab0fcc64255" -version = "7.2.0" - -[[LinearAlgebra]] -deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"] -uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" - -[[LogExpFunctions]] -deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"] -git-tree-sha1 = "7d6dd4e9212aebaeed356de34ccf262a3cd415aa" -uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688" -version = "0.3.26" - - [LogExpFunctions.extensions] - LogExpFunctionsChainRulesCoreExt = "ChainRulesCore" - LogExpFunctionsChangesOfVariablesExt = "ChangesOfVariables" - LogExpFunctionsInverseFunctionsExt = "InverseFunctions" - - [LogExpFunctions.weakdeps] - ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" - ChangesOfVariables = "9e997f8a-9a97-42d5-a9f1-ce6bfc15e2c0" - InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[LoggingExtras]] -deps = ["Dates", "Logging"] -git-tree-sha1 = "c1dd6d7978c12545b4179fb6153b9250c96b0075" -uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36" -version = "1.0.3" - -[[LoopVectorization]] -deps = ["ArrayInterface", "ArrayInterfaceCore", "CPUSummary", "CloseOpenIntervals", "DocStringExtensions", "HostCPUFeatures", "IfElse", "LayoutPointers", "LinearAlgebra", "OffsetArrays", "PolyesterWeave", "PrecompileTools", "SIMDTypes", "SLEEFPirates", "Static", "StaticArrayInterface", "ThreadingUtilities", "UnPack", "VectorizationBase"] -git-tree-sha1 = "c88a4afe1703d731b1c4fdf4e3c7e77e3b176ea2" -uuid = "bdcacae8-1622-11e9-2a5c-532679323890" -version = "0.12.165" -weakdeps = ["ChainRulesCore", "ForwardDiff", "SpecialFunctions"] - - [LoopVectorization.extensions] - ForwardDiffExt = ["ChainRulesCore", "ForwardDiff"] - SpecialFunctionsExt = "SpecialFunctions" - -[[MacroTools]] -deps = ["Markdown", "Random"] -git-tree-sha1 = "9ee1618cbf5240e6d4e0371d6f24065083f60c48" -uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" -version = "0.5.11" - -[[ManualMemory]] -git-tree-sha1 = "bcaef4fc7a0cfe2cba636d84cda54b5e4e4ca3cd" -uuid = "d125e4d3-2237-4719-b19c-fa641b8a4667" -version = "0.1.8" - -[[MarchingCubes]] -deps = ["PrecompileTools", "StaticArrays"] -git-tree-sha1 = "c8e29e2bacb98c9b6f10445227a8b0402f2f173a" -uuid = "299715c1-40a9-479a-aaf9-4a633d36f717" -version = "0.1.8" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[MarkdownAST]] -deps = ["AbstractTrees", "Markdown"] -git-tree-sha1 = "465a70f0fc7d443a00dcdc3267a497397b8a3899" -uuid = "d0879d2d-cac2-40c8-9cee-1863dc0c7391" -version = "0.1.2" - -[[MbedTLS_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1" -version = "2.28.2+0" - -[[Metaheuristics]] -deps = ["Distances", "JMcDM", "LinearAlgebra", "Pkg", "Printf", "Random", "Reexport", "Requires", "SearchSpaces", "SnoopPrecompile", "Statistics"] -git-tree-sha1 = "fda08e881de2665d0a4cfbaf98dd6d24b9439142" -uuid = "bcdb8e00-2c21-11e9-3065-2b553b22f898" -version = "3.3.3" - -[[MicroCollections]] -deps = ["BangBang", "InitialValues", "Setfield"] -git-tree-sha1 = "629afd7d10dbc6935ec59b32daeb33bc4460a42e" -uuid = "128add7d-3638-4c79-886c-908ea0c25c34" -version = "0.1.4" - -[[Missings]] -deps = ["DataAPI"] -git-tree-sha1 = "f66bdc5de519e8f8ae43bdc598782d35a25b1272" -uuid = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28" -version = "1.1.0" - -[[Mmap]] -uuid = "a63ad114-7e13-5084-954f-fe012c677804" - -[[MozillaCACerts_jll]] -uuid = "14a3606d-f60d-562e-9121-12d972cd8159" -version = "2022.10.11" - -[[MuladdMacro]] -git-tree-sha1 = "cac9cc5499c25554cba55cd3c30543cff5ca4fab" -uuid = "46d2c3a1-f734-5fdb-9937-b9b9aeba4221" -version = "0.2.4" - -[[NLSolversBase]] -deps = ["DiffResults", "Distributed", "FiniteDiff", "ForwardDiff"] -git-tree-sha1 = "a0b464d183da839699f4c79e7606d9d186ec172c" -uuid = "d41bc354-129a-5804-8e4c-c37616107c6c" -version = "7.8.3" - -[[NaNMath]] -deps = ["OpenLibm_jll"] -git-tree-sha1 = "0877504529a3e5c3343c6f8b4c0381e57e4387e4" -uuid = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3" -version = "1.0.2" - -[[NetworkOptions]] -uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908" -version = "1.2.0" - -[[OffsetArrays]] -deps = ["Adapt"] -git-tree-sha1 = "2ac17d29c523ce1cd38e27785a7d23024853a4bb" -uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881" -version = "1.12.10" - -[[OpenBLAS_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"] -uuid = "4536629a-c528-5b80-bd46-f80d51c5b363" -version = "0.3.21+4" - -[[OpenLibm_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "05823500-19ac-5b8b-9628-191a04bc5112" -version = "0.8.1+0" - -[[OpenSpecFun_jll]] -deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "13652491f6856acfd2db29360e1bbcd4565d04f1" -uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" -version = "0.5.5+0" - -[[Optim]] -deps = ["Compat", "FillArrays", "ForwardDiff", "LineSearches", "LinearAlgebra", "NLSolversBase", "NaNMath", "Parameters", "PositiveFactorizations", "Printf", "SparseArrays", "StatsBase"] -git-tree-sha1 = "01f85d9269b13fedc61e63cc72ee2213565f7a72" -uuid = "429524aa-4258-5aef-a3af-852621145aeb" -version = "1.7.8" - -[[Optimization]] -deps = ["ADTypes", "ArrayInterface", "ConsoleProgressMonitor", "DocStringExtensions", "LinearAlgebra", "Logging", "LoggingExtras", "Pkg", "Printf", "ProgressLogging", "Reexport", "Requires", "SciMLBase", "SparseArrays", "TerminalLoggers"] -git-tree-sha1 = "1aa7ffea6e171167e9cae620d749e16d5874414a" -uuid = "7f7a1694-90dd-40f0-9382-eb1efda571ba" -version = "3.19.3" - - [Optimization.extensions] - OptimizationEnzymeExt = "Enzyme" - OptimizationFiniteDiffExt = "FiniteDiff" - OptimizationForwardDiffExt = "ForwardDiff" - OptimizationMTKExt = "ModelingToolkit" - OptimizationReverseDiffExt = "ReverseDiff" - OptimizationSparseDiffExt = ["SparseDiffTools", "Symbolics", "ReverseDiff"] - OptimizationTrackerExt = "Tracker" - OptimizationZygoteExt = "Zygote" - - [Optimization.weakdeps] - Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" - FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41" - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - ModelingToolkit = "961ee093-0014-501f-94e3-6117800e7a78" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - SparseDiffTools = "47a9eef4-7e08-11e9-0b38-333d64bd3804" - Symbolics = "0c5d862f-8b57-4792-8d23-62f2024744c7" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" - -[[OptimizationMetaheuristics]] -deps = ["Metaheuristics", "Optimization", "Reexport"] -git-tree-sha1 = "287f529435e4950470857b16e866a682fe6e7893" -uuid = "3aafef2f-86ae-4776-b337-85a36adf0b55" -version = "0.1.3" - -[[OptimizationOptimJL]] -deps = ["Optim", "Optimization", "Reexport", "SparseArrays"] -git-tree-sha1 = "d8a989697ad1037258238004306057ca866bc337" -uuid = "36348300-93cb-4f02-beb5-3c3902f8871e" -version = "0.1.12" - -[[OrderedCollections]] -git-tree-sha1 = "2e73fe17cac3c62ad1aebe70d44c963c3cfdc3e3" -uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d" -version = "1.6.2" - -[[PDMats]] -deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"] -git-tree-sha1 = "66b2fcd977db5329aa35cac121e5b94dd6472198" -uuid = "90014a1f-27ba-587c-ab20-58faa44d9150" -version = "0.11.28" - -[[Parameters]] -deps = ["OrderedCollections", "UnPack"] -git-tree-sha1 = "34c0e9ad262e5f7fc75b10a9952ca7692cfc5fbe" -uuid = "d96e819e-fc66-5662-9728-84c9c7592b0a" -version = "0.12.3" - -[[Parsers]] -deps = ["Dates", "PrecompileTools", "UUIDs"] -git-tree-sha1 = "716e24b21538abc91f6205fd1d8363f39b442851" -uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0" -version = "2.7.2" - -[[Pkg]] -deps = ["Artifacts", "Dates", "Downloads", "FileWatching", "LibGit2", "Libdl", "Logging", "Markdown", "Printf", "REPL", "Random", "SHA", "Serialization", "TOML", "Tar", "UUIDs", "p7zip_jll"] -uuid = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" -version = "1.9.2" - -[[PolyesterWeave]] -deps = ["BitTwiddlingConvenienceFunctions", "CPUSummary", "IfElse", "Static", "ThreadingUtilities"] -git-tree-sha1 = "240d7170f5ffdb285f9427b92333c3463bf65bf6" -uuid = "1d0040c9-8b98-4ee7-8388-3f51789ca0ad" -version = "0.2.1" - -[[PositiveFactorizations]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "17275485f373e6673f7e7f97051f703ed5b15b20" -uuid = "85a6dd25-e78a-55b7-8502-1745935b8125" -version = "0.2.4" - -[[PrecompileTools]] -deps = ["Preferences"] -git-tree-sha1 = "03b4c25b43cb84cee5c90aa9b5ea0a78fd848d2f" -uuid = "aea7be01-6a6a-4083-8856-8a6e6704d82a" -version = "1.2.0" - -[[Preferences]] -deps = ["TOML"] -git-tree-sha1 = "00805cd429dcb4870060ff49ef443486c262e38e" -uuid = "21216c6a-2e73-6563-6e65-726566657250" -version = "1.4.1" - -[[Printf]] -deps = ["Unicode"] -uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" - -[[ProgressLogging]] -deps = ["Logging", "SHA", "UUIDs"] -git-tree-sha1 = "80d919dee55b9c50e8d9e2da5eeafff3fe58b539" -uuid = "33c8b6b6-d38a-422a-b730-caa89a2f386c" -version = "0.1.4" - -[[ProgressMeter]] -deps = ["Distributed", "Printf"] -git-tree-sha1 = "00099623ffee15972c16111bcf84c58a0051257c" -uuid = "92933f4c-e287-5a05-a399-4b506db050ca" -version = "1.9.0" - -[[QuadGK]] -deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "9ebcd48c498668c7fa0e97a9cae873fbee7bfee1" -uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.9.1" - -[[REPL]] -deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] -uuid = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" - -[[Random]] -deps = ["SHA", "Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[RecipesBase]] -deps = ["PrecompileTools"] -git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff" -uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01" -version = "1.3.4" - -[[RecursiveArrayTools]] -deps = ["Adapt", "ArrayInterface", "DocStringExtensions", "GPUArraysCore", "IteratorInterfaceExtensions", "LinearAlgebra", "RecipesBase", "Requires", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "d7087c013e8a496ff396bae843b1e16d9a30ede8" -uuid = "731186ca-8d62-57ce-b412-fbd966d074cd" -version = "2.38.10" - - [RecursiveArrayTools.extensions] - RecursiveArrayToolsMeasurementsExt = "Measurements" - RecursiveArrayToolsMonteCarloMeasurementsExt = "MonteCarloMeasurements" - RecursiveArrayToolsTrackerExt = "Tracker" - RecursiveArrayToolsZygoteExt = "Zygote" - - [RecursiveArrayTools.weakdeps] - Measurements = "eff96d63-e80a-5855-80a2-b1b0885c5ab7" - MonteCarloMeasurements = "0987c9cc-fe09-11e8-30f0-b96dd679fdca" - Tracker = "9f7883ad-71c0-57eb-9f7f-b5c9e6d3789c" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" - -[[Reexport]] -git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b" -uuid = "189a3867-3050-52da-a836-e630ba90ab69" -version = "1.2.2" - -[[RegistryInstances]] -deps = ["LazilyInitializedFields", "Pkg", "TOML", "Tar"] -git-tree-sha1 = "ffd19052caf598b8653b99404058fce14828be51" -uuid = "2792f1a3-b283-48e8-9a74-f99dce5104f3" -version = "0.1.0" - -[[Requires]] -deps = ["UUIDs"] -git-tree-sha1 = "838a3a4188e2ded87a4f9f184b4b0d78a1e91cb7" -uuid = "ae029012-a4dd-5104-9daa-d747884805df" -version = "1.3.0" - -[[Rmath]] -deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" -uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.7.1" - -[[Rmath_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "6ed52fdd3382cf21947b15e8870ac0ddbff736da" -uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.0+0" - -[[Roots]] -deps = ["ChainRulesCore", "CommonSolve", "Printf", "Setfield"] -git-tree-sha1 = "06b5ac80ff1b88bd82df92c1c1875eea3954cd6e" -uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665" -version = "2.0.20" - - [Roots.extensions] - RootsForwardDiffExt = "ForwardDiff" - RootsIntervalRootFindingExt = "IntervalRootFinding" - RootsSymPyExt = "SymPy" - RootsSymPyPythonCallExt = "SymPyPythonCall" - - [Roots.weakdeps] - ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" - IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807" - SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" - SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c" - -[[RuntimeGeneratedFunctions]] -deps = ["ExprTools", "SHA", "Serialization"] -git-tree-sha1 = "6aacc5eefe8415f47b3e34214c1d79d2674a0ba2" -uuid = "7e49a35a-f44a-4d26-94aa-eba1b4ca6b47" -version = "0.5.12" - -[[SHA]] -uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" -version = "0.7.0" - -[[SIMDTypes]] -git-tree-sha1 = "330289636fb8107c5f32088d2741e9fd7a061a5c" -uuid = "94e857df-77ce-4151-89e5-788b33177be4" -version = "0.1.0" - -[[SLEEFPirates]] -deps = ["IfElse", "Static", "VectorizationBase"] -git-tree-sha1 = "4b8586aece42bee682399c4c4aee95446aa5cd19" -uuid = "476501e8-09a2-5ece-8869-fb82de89a1fa" -version = "0.6.39" - -[[SciMLBase]] -deps = ["ADTypes", "ArrayInterface", "ChainRulesCore", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "FillArrays", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables", "TruncatedStacktraces", "ZygoteRules"] -git-tree-sha1 = "1c2a4e245744dd76b2eb677d3535ffad16d8b989" -uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.5.0" - - [SciMLBase.extensions] - SciMLBasePartialFunctionsExt = "PartialFunctions" - SciMLBasePyCallExt = "PyCall" - SciMLBasePythonCallExt = "PythonCall" - SciMLBaseRCallExt = "RCall" - SciMLBaseZygoteExt = "Zygote" - - [SciMLBase.weakdeps] - PartialFunctions = "570af359-4316-4cb7-8c74-252c00c2016b" - PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0" - PythonCall = "6099a3de-0909-46bc-b1f4-468b9a2dfc0d" - RCall = "6f49c342-dc21-5d91-9882-a32aef131414" - Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" - -[[SciMLOperators]] -deps = ["ArrayInterface", "DocStringExtensions", "Lazy", "LinearAlgebra", "Setfield", "SparseArrays", "StaticArraysCore", "Tricks"] -git-tree-sha1 = "65c2e6ced6f62ea796af251eb292a0e131a3613b" -uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "0.3.6" - -[[SearchSpaces]] -deps = ["Combinatorics", "Random"] -git-tree-sha1 = "2662fd537048fb12ff34fabb5249bf50e06f445b" -uuid = "eb7571c6-2196-4f03-99b8-52a5a35b3163" -version = "0.2.0" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[Setfield]] -deps = ["ConstructionBase", "Future", "MacroTools", "StaticArraysCore"] -git-tree-sha1 = "e2cc6d8c88613c05e1defb55170bf5ff211fbeac" -uuid = "efcf1570-3423-57d1-acb7-fd33fddbac46" -version = "1.1.1" - -[[SnoopPrecompile]] -deps = ["Preferences"] -git-tree-sha1 = "e760a70afdcd461cf01a575947738d359234665c" -uuid = "66db9d55-30c0-4569-8b51-7e840670fc0c" -version = "1.0.3" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[SortingAlgorithms]] -deps = ["DataStructures"] -git-tree-sha1 = "5165dfb9fd131cf0c6957a3a7605dede376e7b63" -uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c" -version = "1.2.0" - -[[SparseArrays]] -deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"] -uuid = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" - -[[SpecialFunctions]] -deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"] -git-tree-sha1 = "e2cfc4012a19088254b3950b85c3c1d8882d864d" -uuid = "276daf66-3868-5448-9aa4-cd146d93841b" -version = "2.3.1" -weakdeps = ["ChainRulesCore"] - - [SpecialFunctions.extensions] - SpecialFunctionsChainRulesCoreExt = "ChainRulesCore" - -[[SplittablesBase]] -deps = ["Setfield", "Test"] -git-tree-sha1 = "e08a62abc517eb79667d0a29dc08a3b589516bb5" -uuid = "171d559e-b47b-412a-8079-5efa626c420e" -version = "0.1.15" - -[[Static]] -deps = ["IfElse"] -git-tree-sha1 = "f295e0a1da4ca425659c57441bcb59abb035a4bc" -uuid = "aedffcd0-7271-4cad-89d0-dc628f76c6d3" -version = "0.8.8" - -[[StaticArrayInterface]] -deps = ["ArrayInterface", "Compat", "IfElse", "LinearAlgebra", "PrecompileTools", "Requires", "SparseArrays", "Static", "SuiteSparse"] -git-tree-sha1 = "03fec6800a986d191f64f5c0996b59ed526eda25" -uuid = "0d7ed370-da01-4f52-bd93-41d350b8b718" -version = "1.4.1" -weakdeps = ["OffsetArrays", "StaticArrays"] - - [StaticArrayInterface.extensions] - StaticArrayInterfaceOffsetArraysExt = "OffsetArrays" - StaticArrayInterfaceStaticArraysExt = "StaticArrays" - -[[StaticArrays]] -deps = ["LinearAlgebra", "Random", "StaticArraysCore"] -git-tree-sha1 = "0adf069a2a490c47273727e029371b31d44b72b2" -uuid = "90137ffa-7385-5640-81b9-e52037218182" -version = "1.6.5" -weakdeps = ["Statistics"] - - [StaticArrays.extensions] - StaticArraysStatisticsExt = "Statistics" - -[[StaticArraysCore]] -git-tree-sha1 = "36b3d696ce6366023a0ea192b4cd442268995a0d" -uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c" -version = "1.4.2" - -[[Statistics]] -deps = ["LinearAlgebra", "SparseArrays"] -uuid = "10745b16-79ce-11e8-11f9-7d13ad32a3b2" -version = "1.9.0" - -[[StatsAPI]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1ff449ad350c9c4cbc756624d6f8a8c3ef56d3ed" -uuid = "82ae8749-77ed-4fe6-ae5f-f523153014b0" -version = "1.7.0" - -[[StatsBase]] -deps = ["DataAPI", "DataStructures", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"] -git-tree-sha1 = "1d77abd07f617c4868c33d4f5b9e1dbb2643c9cf" -uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" -version = "0.34.2" - -[[StatsFuns]] -deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "f625d686d5a88bcd2b15cd81f18f98186fdc0c9a" -uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.3.0" -weakdeps = ["ChainRulesCore", "InverseFunctions"] - - [StatsFuns.extensions] - StatsFunsChainRulesCoreExt = "ChainRulesCore" - StatsFunsInverseFunctionsExt = "InverseFunctions" - -[[SuiteSparse]] -deps = ["Libdl", "LinearAlgebra", "Serialization", "SparseArrays"] -uuid = "4607b0f0-06f3-5cda-b6b1-a6196a1729e9" - -[[SuiteSparse_jll]] -deps = ["Artifacts", "Libdl", "Pkg", "libblastrampoline_jll"] -uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c" -version = "5.10.1+6" - -[[SymbolicIndexingInterface]] -deps = ["DocStringExtensions"] -git-tree-sha1 = "f8ab052bfcbdb9b48fad2c80c873aa0d0344dfe5" -uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.2.2" - -[[TOML]] -deps = ["Dates"] -uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76" -version = "1.0.3" - -[[TableTraits]] -deps = ["IteratorInterfaceExtensions"] -git-tree-sha1 = "c06b2f539df1c6efa794486abfb6ed2022561a39" -uuid = "3783bdb8-4a98-5b6b-af9a-565f29a5fe9c" -version = "1.0.1" - -[[Tables]] -deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "LinearAlgebra", "OrderedCollections", "TableTraits"] -git-tree-sha1 = "cb76cf677714c095e535e3501ac7954732aeea2d" -uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" -version = "1.11.1" - -[[Tar]] -deps = ["ArgTools", "SHA"] -uuid = "a4e569a6-e804-4fa4-b0f3-eef7a1d5b13e" -version = "1.10.0" - -[[TensorCore]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "1feb45f88d133a655e001435632f019a9a1bcdb6" -uuid = "62fd8b95-f654-4bbd-a8a5-9c27f68ccd50" -version = "0.1.1" - -[[TerminalLoggers]] -deps = ["LeftChildRightSiblingTrees", "Logging", "Markdown", "Printf", "ProgressLogging", "UUIDs"] -git-tree-sha1 = "f133fab380933d042f6796eda4e130272ba520ca" -uuid = "5d786b92-1e48-4d6f-9151-6b4477ca9bed" -version = "0.1.7" - -[[Test]] -deps = ["InteractiveUtils", "Logging", "Random", "Serialization"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" - -[[ThreadingUtilities]] -deps = ["ManualMemory"] -git-tree-sha1 = "eda08f7e9818eb53661b3deb74e3159460dfbc27" -uuid = "8290d209-cae3-49c0-8002-c8c24d57dab5" -version = "0.5.2" - -[[Transducers]] -deps = ["Adapt", "ArgCheck", "BangBang", "Baselet", "CompositionsBase", "ConstructionBase", "DefineSingletons", "Distributed", "InitialValues", "Logging", "Markdown", "MicroCollections", "Requires", "Setfield", "SplittablesBase", "Tables"] -git-tree-sha1 = "53bd5978b182fa7c57577bdb452c35e5b4fb73a5" -uuid = "28d57a85-8fef-5791-bfe6-a80928e7c999" -version = "0.4.78" - - [Transducers.extensions] - TransducersBlockArraysExt = "BlockArrays" - TransducersDataFramesExt = "DataFrames" - TransducersLazyArraysExt = "LazyArrays" - TransducersOnlineStatsBaseExt = "OnlineStatsBase" - TransducersReferenceablesExt = "Referenceables" - - [Transducers.weakdeps] - BlockArrays = "8e7c35d0-a365-5155-bbbb-fb81a777f24e" - DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0" - LazyArrays = "5078a376-72f3-5289-bfd5-ec5146d43c02" - OnlineStatsBase = "925886fa-5bf2-5e8e-b522-a9147a512338" - Referenceables = "42d2dcc6-99eb-4e98-b66c-637b7d73030e" - -[[Tricks]] -git-tree-sha1 = "eae1bb484cd63b36999ee58be2de6c178105112f" -uuid = "410a4b4d-49e4-4fbc-ab6d-cb71b17b3775" -version = "0.1.8" - -[[TruncatedStacktraces]] -deps = ["InteractiveUtils", "MacroTools", "Preferences"] -git-tree-sha1 = "ea3e54c2bdde39062abf5a9758a23735558705e1" -uuid = "781d530d-4396-4725-bb49-402e4bee1e77" -version = "1.4.0" - -[[UUIDs]] -deps = ["Random", "SHA"] -uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" - -[[UnPack]] -git-tree-sha1 = "387c1f73762231e86e0c9c5443ce3b4a0a9a0c2b" -uuid = "3a884ed6-31ef-47d7-9d2a-63182c4928ed" -version = "1.0.2" - -[[Unicode]] -uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" - -[[UnicodePlots]] -deps = ["ColorSchemes", "ColorTypes", "Contour", "Crayons", "Dates", "LinearAlgebra", "MarchingCubes", "NaNMath", "PrecompileTools", "Printf", "Requires", "SparseArrays", "StaticArrays", "StatsBase"] -git-tree-sha1 = "b96de03092fe4b18ac7e4786bee55578d4b75ae8" -uuid = "b8865327-cd53-5732-bb35-84acbb429228" -version = "3.6.0" - - [UnicodePlots.extensions] - FreeTypeExt = ["FileIO", "FreeType"] - ImageInTerminalExt = "ImageInTerminal" - IntervalSetsExt = "IntervalSets" - TermExt = "Term" - UnitfulExt = "Unitful" - - [UnicodePlots.weakdeps] - FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549" - FreeType = "b38be410-82b0-50bf-ab77-7b57e271db43" - ImageInTerminal = "d8c32880-2388-543b-8c61-d9f865259254" - IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" - Term = "22787eb5-b846-44ae-b979-8e399b8463ab" - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - -[[VectorizationBase]] -deps = ["ArrayInterface", "CPUSummary", "HostCPUFeatures", "IfElse", "LayoutPointers", "Libdl", "LinearAlgebra", "SIMDTypes", "Static", "StaticArrayInterface"] -git-tree-sha1 = "b182207d4af54ac64cbc71797765068fdeff475d" -uuid = "3d5dd08c-fd9d-11e8-17fa-ed2836048c2f" -version = "0.21.64" - -[[Zlib_jll]] -deps = ["Libdl"] -uuid = "83775a58-1f1d-513f-b197-d71354ab007a" -version = "1.2.13+0" - -[[ZygoteRules]] -deps = ["ChainRulesCore", "MacroTools"] -git-tree-sha1 = "9d749cd449fb448aeca4feee9a2f4186dbb5d184" -uuid = "700de1a5-db45-46bc-99cf-38207098b444" -version = "0.2.4" - -[[libblastrampoline_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+0" - -[[nghttp2_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "8e850ede-7688-5339-a07c-302acd2aaf8d" -version = "1.48.0+0" - -[[p7zip_jll]] -deps = ["Artifacts", "Libdl"] -uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" -version = "17.4.0+0" diff --git a/docs/Project.toml b/docs/Project.toml index 2c32161..1a0af8e 100644 --- a/docs/Project.toml +++ b/docs/Project.toml @@ -1,5 +1,7 @@ [deps] ActuaryUtilities = "bdd23359-8b1c-4f88-b89b-d11982a786f4" +CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" DayCounts = "44e31299-2c53-5a9b-9141-82aa45d7972f" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" FinanceCore = "b9b1ffdd-6612-4b69-8227-7663be06e089" diff --git a/docs/make.jl b/docs/make.jl index 7771a4b..d0a405d 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -7,10 +7,14 @@ makedocs(; modules=[ActuaryUtilities, FinanceCore], format=Documenter.HTML(), pages=[ - "Introduction" => "index.md", - "Modules" => [ + "Overview" => "index.md", + "Financial Math" => "financial_math.md", + "Risk Measures" => "risk_measures.md", + "Other Utilities" => "utilities.md", + "API" => [ "ActuaryUtilities" => "API/ActuaryUtilities.md", - "FinanceCore" => "API/FinanceCore.md",], + "FinanceCore (re-exported)" => "API/FinanceCore.md", + ], "Upgrade from Prior Versions" => "upgrade.md", ], repo="https://github.com/JuliaActuary/ActuaryUtilities.jl/blob/{commit}{path}#L{line}", diff --git a/docs/src/financial_math.md b/docs/src/financial_math.md new file mode 100644 index 0000000..8eaccd1 --- /dev/null +++ b/docs/src/financial_math.md @@ -0,0 +1,32 @@ +# Financial Math Submodule + +Provides a set of common routines in financial maths. + +## Quickstart + +```julia +cfs = [5, 5, 105] +times = [1, 2, 3] + +discount_rate = 0.03 + +present_value(discount_rate, cfs, times) # 105.65 +duration(Macaulay(), discount_rate, cfs, times) # 2.86 +duration(discount_rate, cfs, times) # 2.78 +convexity(discount_rate, cfs, times) # 10.62 +``` + + +## API + +### Exported API +```@autodocs +Modules = [ActuaryUtilities.FinancialMath] +Private = false +``` + +### Unexported API +```@autodocs +Modules = [ActuaryUtilities.FinancialMath] +Public = false +``` \ No newline at end of file diff --git a/docs/src/index.md b/docs/src/index.md index 693f3f1..a48c8fe 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -28,14 +28,14 @@ A collection of common functions/manipulations used in Actuarial Calculations. - `accum_offset` to calculate accumulations like survivorship from a mortality vector - `spread` will calculate the spread needed between two yield curves to equate a set of cashflows -### Options Pricing -- `eurocall` and `europut` for Black-Scholes option prices (note: API may change for this in future) - ### Risk Measures - Calculate risk measures for a given vector of risks: - - `CTE` for the Conditional Tail Expectation, or - - `VaR` for the percentile/Value at Risk. + - `CTE` for the Conditional Tail Expectation + - `VaR` for the percentile/Value at Risk + - `WangTransform` for the Wang Transformation + - `ProportionalHazard` for proportional hazards + - `DualPower` for dual power measure ### Insurance mechanics diff --git a/docs/src/risk_measures.md b/docs/src/risk_measures.md new file mode 100644 index 0000000..da7abd6 --- /dev/null +++ b/docs/src/risk_measures.md @@ -0,0 +1,216 @@ +# Risk Measures + +## Quickstart + +```julia +outcomes = rand(100) + +# direct usage +VaR(0.90)(outcomes) # ≈ 0.90 +CTE(0.90)(outcomes) # ≈ 0.95 +WangTransform(0.90)(outcomes) # ≈ 0.81 + +# construct a reusable object (functor) +rm = VaR(0.90) + +rm(outcomes) # ≈ 0.90 +``` + +## Introduction + +Risk measures encompass the set of functions that map a set of outcomes to an output value characterizing the associated riskiness of those outcomes. As is usual when attempting to compress information (e.g. condensing information into a single value), there are multiple ways we can charactize this riskiness. + + +## Coherence & Other Desirable Properties + +Further, it is desireable that a risk measure has certain properties, and risk measures that meet the first four criteria are called "Coherent" in the literature. From "An Introduction to Risk Measures for Actuarial Applications" (Hardy), she describes as follows: + +Using $H$ as a risk measure and $X$ as the associated risk distribution: + +### 1. Translation Invariance + +For any non-random $c$ + +%$H(X + c) = H(X) + c$% +This means that adding a constant amount (positive or negative) to a risk adds the same amount to the risk measure. It also implies that the risk measure for a non-random loss, with known value c, say, is just the amount of the loss c. + +### 2. Positive Homogeneity + +For any non-random $λ > 0$: + +$$H(λX) = λH(X)$$ + +This axiom implies that changing the units of loss does not change the risk measure. + +### 3. Subadditivity + +For any two random losses $X$ and $Y$, + +$$H(X + Y) ≤ H(X) + H(Y)$$ + +It should not be possible to reduce the economic capital required (or the appropriate premium) for a risk by splitting it into constituent parts. Or, in other words, diversification (ie consolidating risks) cannot make the risk greater, but it might make the risk smaller if the risks are less than perfectly correlated. + +### 4. Monotonicity + +If $Pr(X ≤ Y) = 1$ then $H(X) ≤ H(Y)$. + +If one risk is always bigger then another, the risk measures should be similarly ordered. + +### Other Properties + +In "Properties of Distortion Risk Measures" (Balbás, Garrido, Mayoral) also note other properties of interest: + +#### Complete + +Completeness is the property that the distortion function associated with the risk measure produces a unique mapping between the original risk's survial function $S(x)$ and the distorted $S*(x)$ for each $x$. See [Distortion Risk Measures](@ref) for more detail on this. + +In practice, this means that a non-complete risk measure ignores some part of the risk distribution (e.g. CTE and VaR don't use the full distribution and have the same) + +#### Exhaustive + +A risk measure is "exhaustive" if it is coherent and complete. + +#### Adaptable + +A risk measure is "adapted" or "adaptable" if its distortion function (ee [Distortion Risk Measures](@ref)).$g$: + + 1. $g$ is strictly concave, that is $g$ is strictly decreasing. + 2. $lim_{u\to0+} g\prime(u) = \inf and lim_{u\to1-} g\prime(u) = 0. + +Adaptive risk measures are exhaustive but the converse is not true. + +### Summary of Risk Measure Properties + +| Measure | Coherent | Complete | Exhaustive | Adaptable | Condition 2 | +|--------------|----------|----------|------------|-----------|-------------| +| [VaR](@ref) | No | No | No | No | No | +| [CTE](@ref) | Yes | No | No | No | No | +| [DualPower](@ref) $(y > 1)$ | Yes | Yes | Yes | No | Yes | +| [ProportionalHazard](@ref) $(γ > 1)$ | Yes | Yes | Yes | No | Yes | +| [WangTransform](@ref) | Yes | Yes | Yes | Yes | Yes | + +## Distortion Risk Measures + +Distortion Risk Measures ([Wikipedia Link](https://en.wikipedia.org/wiki/Distortion_risk_measure)) are a way of remapping the probabilities of a risk distribution in order to compute a risk measure $H$ on the risk distribution $X$. + +Adapting Wang (2002), there are two key components: + +### Distortion Function $g(u)$ + +This remaps values in the [0,1] range to another value in the [0,1] range, and in $H$ below, operates on the survival function $S$ and $F=1-S$. + +Let $g:[0,1]\to[0,1]$ be an increasing function with $g(0)=0$ and $g(1)=1$. The transform $F^*(x)=g(F(x))$ defines a distorted probability distribution, where "$g$" is called a distortion function. + +Note that $F^*$ and $F$ are equivalent probability measures if and only if $g:[0,1]\to[0,1]$ is continuous and one-to-one. +Definition 4.2. We define a family of distortion risk-measures using the mean-value under the distorted probability $F^*(x)=g(F(x))$: + +### Risk Measure Integration + +To calculate a risk measure $H$, we integrate the distorted $F$ across all possible values in the risk distribution (i.e. $x \in X$): + +$$H(X) = E^*(X) = - \int_{-\infty}^0 g(F(x))dx + \int_0^{+\infty}[1-g(F(x))]dx$$ + +That is, the risk measure ($H$) is equal to the expected value of the distortion of the risk ditribution ($E^*(X)$). + +## Examples + +### Basic Usage + +```julia +outcomes = rand(100) + +# direct usage +VaR(0.90)(outcomes) # ≈ 0.90 +CTE(0.90)(outcomes) # ≈ 0.95 +WangTransform(0.90)(outcomes) # ≈ 0.81 + +# construct a reusable object (functor) +rm = VaR(0.90) + +rm(outcomes) # ≈ 0.90 +``` + +### Comparison + +We will generate a random outcome and show how the risk measures behave: + +```@example +using Distributions +using ActuaryUtilities +using CairoMakie + +outcomes = Weibull(1,5) +# or this could be discrete outcomes as in the next line +#outcomes = rand(LogNormal(2,10)*100,2000) + +αs= range(0.00,0.99;length=100) + +let + f = Figure() + ax = Axis(f[1,1], + xlabel="α", + ylabel="Loss", + title = "Comparison of Risk Measures", + xgridvisible=false, + ygridvisible=false, + ) + + lines!(ax, + αs, + [quantile(outcomes, α) for α in αs], + label = "Quantile α of Outcome", + color = :grey10, + linewidth = 3, + ) + + lines!(ax, + αs, + [VaR(α)(outcomes) for α in αs], + label = "VaR(α)", + linestyle=:dash + ) + lines!(ax, + αs, + [CTE(α)(outcomes) for α in αs], + label = "CTE(α)", + ) + lines!(ax, + αs[2:end], + [WangTransform(α)(outcomes) for α in αs[2:end]], + label = "WangTransform(α)", + ) + lines!(ax, + αs, + [ProportionalHazard(2)(outcomes) for α in αs], + label = "ProportionalHazard(2)", + ) + + lines!(ax, + αs, + [DualPower(2)(outcomes) for α in αs], + label = "DualPower(2)", + ) + lines!(ax, + αs, + [RiskMeasures.Expectation()(outcomes) for α in αs], + label = "Expectation", + ) + axislegend(ax,position=:lt) + + f +end +``` + +## API + +### Exported API +```@autodocs +Modules = [ActuaryUtilities.RiskMeasures] +Private = false +``` + +### Unexported API +```@autodocs +Modules = [ActuaryUtilities.RiskMeasures] +Public = false +``` \ No newline at end of file diff --git a/docs/src/utilities.md b/docs/src/utilities.md new file mode 100644 index 0000000..9affa4a --- /dev/null +++ b/docs/src/utilities.md @@ -0,0 +1,12 @@ +# Utilities submodule + +Provides miscellaneous routines common in actuarial and financial work. + +## API + +### Exported API +```@docs +Utilities.duration +Utilities.years_between +Utilities.accum_offset +``` \ No newline at end of file diff --git a/src/ActuaryUtilities.jl b/src/ActuaryUtilities.jl index 73e0d35..2bf253c 100644 --- a/src/ActuaryUtilities.jl +++ b/src/ActuaryUtilities.jl @@ -1,159 +1,30 @@ module ActuaryUtilities using Reexport -using Dates +import Dates import FinanceCore @reexport using FinanceCore: internal_rate_of_return, irr, present_value, pv -using ForwardDiff -using QuadGK -using MuladdMacro +import ForwardDiff +import QuadGK import FinanceModels import StatsBase using PrecompileTools +import Distributions + +# need to define this here to extend it without conflict inside FinancialMath +function duration() end include("financial_math.jl") include("risk_measures.jl") +include("utilities.jl") -""" - Years_Between(d1::Date, d2::Date) - -Compute the number of integer years between two dates, with the -first date typically before the second. Will return negative number if -first date is after the second. Use third argument to indicate if calendar -anniversary should count as a full year. - -# Examples -```jldoctest -julia> d1 = Date(2018,09,30); - -julia> d2 = Date(2019,09,30); - -julia> d3 = Date(2019,10,01); - -julia> years_between(d1,d3) -1 -julia> years_between(d1,d2,false) # same month/day but `false` overlap -0 -julia> years_between(d1,d2) # same month/day but `true` overlap -1 -julia> years_between(d1,d2) # using default `true` overlap -1 -``` -""" -function years_between(d1::Date, d2::Date, overlap=true) - iy, im, id = Dates.year(d1), Dates.month(d1), Dates.day(d1) - vy, vm, vd = Dates.year(d2), Dates.month(d2), Dates.day(d2) - dur = vy - iy - if vm == im - if overlap - if vd >= id - dur += 1 - end - else - if vd > id - dur += 1 - end - end - elseif vm > im - dur += 1 - end - - return dur - 1 -end - - -""" - duration(d1::Date, d2::Date) - -Compute the duration given two dates, which is the number of years -since the first date. The interval `[0,1)` is defined as having -duration `1`. Can return negative durations if second argument is before the first. - - -```jldoctest -julia> issue_date = Date(2018,9,30); - -julia> duration(issue_date , Date(2019,9,30) ) -2 -julia> duration(issue_date , issue_date) -1 -julia> duration(issue_date , Date(2018,10,1) ) -1 -julia> duration(issue_date , Date(2019,10,1) ) -2 -julia> duration(issue_date , Date(2018,6,30) ) -0 -julia> duration(Date(2018,9,30),Date(2017,6,30)) --1 -``` - -""" -function duration(issue_date::Date, proj_date::Date) - return years_between(issue_date, proj_date, true) + 1 -end - - -""" - accum_offset(x; op=*, init=1.0) - -A shortcut for the common operation wherein a vector is scanned with an operation, but has an initial value and the resulting array is offset from the traditional accumulate. - -This is a common pattern when calculating things like survivorship given a mortality vector and you want the first value of the resulting vector to be `1.0`, and the second value to be `1.0 * x[1]`, etc. - -Two keyword arguments: - -- `op` is the binary (two argument) operator you want to use, such as `*` or `+` -- `init` is the initial value in the returned array - -# Examples - -```julia=repl -julia> accum_offset([0.9, 0.8, 0.7]) -3-element Array{Float64,1}: - 1.0 - 0.9 - 0.7200000000000001 - -julia> accum_offset(1:5) # the product of elements 1:n, with the default `1` as the first value -5-element Array{Int64,1}: - 1 - 1 - 2 - 6 - 24 - -julia> accum_offset(1:5,op=+) -5-element Array{Int64,1}: - 1 - 2 - 4 - 7 - 11 - -``` - -""" -function accum_offset(x; op=*, init=1.0) - xnew = similar(x) - xnew[1] = init - for i in 2:length(x) - xnew[i] = op(xnew[i-1], x[i-1]) - end - return xnew -end - -include("precompile.jl") +# include("precompile.jl") -export years_between, duration, - irr, internal_rate_of_return, spread, - pv, present_value, price, present_values, - breakeven, moic, - accum_offset, - Macaulay, Modified, DV01, KeyRatePar, KeyRateZero, KeyRate, duration, convexity, - VaR, ValueAtRisk, CTE, ConditionalTailExpectation, ExpectedShortfall, - eurocall, europut +@reexport using .FinancialMath +@reexport using .RiskMeasures +@reexport using .Utilities end # module diff --git a/src/financial_math.jl b/src/financial_math.jl index 44b1481..a35c370 100644 --- a/src/financial_math.jl +++ b/src/financial_math.jl @@ -1,3 +1,15 @@ +module FinancialMath + +import ..FinanceCore +import ..FinanceModels +import ..ForwardDiff +import ..ActuaryUtilities: duration + +export irr, internal_rate_of_return, spread, + pv, present_value, price, present_values, + breakeven, moic, + Macaulay, Modified, DV01, KeyRatePar, KeyRateZero, KeyRate, duration, convexity + """ present_values(interest, cashflows, timepoints) @@ -61,7 +73,7 @@ Assumptions: Returns `nothing` if cashflow stream never breaks even. -```jldoctest +```julia julia> breakeven(0.10, [-10,1,2,3,4,8]) 5 @@ -351,9 +363,9 @@ function duration(keyrate::KeyRateDuration, curve, cashflows, timepoints, krd_po shift = keyrate.shift curve_up = _krd_new_curve(keyrate, curve, krd_points) curve_down = _krd_new_curve(opposite(keyrate), curve, krd_points) - price = pv(curve, cashflows, timepoints) - price_up = pv(curve_up, cashflows, timepoints) - price_down = pv(curve_down, cashflows, timepoints) + price = FinanceCore.pv(curve, cashflows, timepoints) + price_up = FinanceCore.pv(curve_up, cashflows, timepoints) + price_down = FinanceCore.pv(curve_down, cashflows, timepoints) return (price_down - price_up) / (2 * shift * price) @@ -424,10 +436,10 @@ Rate{Float64, Periodic}(0.010000000000000009, Periodic(1)) function spread(curve1, curve2, cashflows, times=eachindex(cashflows)) times = FinanceCore.timepoint.(cashflows, times) cashflows = FinanceCore.amount.(cashflows) - pv1 = pv(curve1, cashflows, times) - pv2 = pv(curve2, cashflows, times) - irr1 = irr([-pv1; cashflows], [0.0; times]) - irr2 = irr([-pv2; cashflows], [0.0; times]) + pv1 = FinanceCore.pv(curve1, cashflows, times) + pv2 = FinanceCore.pv(curve2, cashflows, times) + irr1 = FinanceCore.irr([-pv1; cashflows], [0.0; times]) + irr2 = FinanceCore.irr([-pv2; cashflows], [0.0; times]) return irr2 - irr1 @@ -450,4 +462,6 @@ function moic(cfs::T) where {T<:AbstractArray} returned = sum(FinanceCore.amount(cf) for cf in cfs if FinanceCore.amount(cf) > 0) invested = -sum(FinanceCore.amount(cf) for cf in cfs if FinanceCore.amount(cf) < 0) return returned / invested +end + end \ No newline at end of file diff --git a/src/risk_measures.jl b/src/risk_measures.jl index 472b0bb..08322f3 100644 --- a/src/risk_measures.jl +++ b/src/risk_measures.jl @@ -1,49 +1,312 @@ +module RiskMeasures +import ..Distributions +import ..StatsBase +import ..QuadGK + +export VaR, ValueAtRisk, CTE, ConditionalTailExpectation, WangTransform, DualPower, ProportionalHazard + +abstract type RiskMeasure end + +""" + g(rm::RiskMeasure,x) + +The probability distortion function associated with the given risk measure. + +See [Distortion Function g(u)](@ref) """ - VaR(v::AbstractArray,p::Real;rev::Bool=false) +function g(rm::RiskMeasure, x) end + +""" + Expectation()::RiskMeasure + Expectation()(risk)::T (where T is the type of values sampled in `risk`) + +The expected value of the risk. + +`Expectation()` returns a functor which can then be called on a risk distribution. + +## Examples + +```julia-repl +julia> RiskMeasures.Expectation(rand(1000)) +0.4793223308812537 -The `p`th quantile of the vector `v` is the Value at Risk. Assumes more positive values are higher risk measures, so a higher p will return a more positive number, but this can be reversed if `rev` is `true`. +julia> rm = RiskMeasures.Expectation() +ActuaryUtilities.RiskMeasures.Expectation() -Also can be called with `ValueAtRisk(...)`. +julia> rm(rand(1000)) +0.4941708036889741 +``` """ -function VaR(v, p; rev=false) - if rev - return StatsBase.quantile(v, 1 - p) - else - return StatsBase.quantile(v, p) +struct Expectation <: RiskMeasure end +g(rm::Expectation, x) = x + +""" + VaR(α)::RiskMeasure + VaR(α)(risk)::T (where T is the type of values sampled in `risk`) + +The `α`th quantile of the `risk` distribution is the Value at Risk, or αth quantile. `risk` can be a univariate distribution or an array of outcomes. +Assumes more positive values are higher risk measures, so a higher p will return a more positive number. For a discrete risk, the VaR returned is the first value above the αth percentile. + +`VaR(α)` returns a functor which can then be called on a risk distribution. + +## Parameters +- α: [0,1.0) + +## Examples + +```julia-repl +julia> VaR(0.95)(rand(1000)) +0.9561843082268024 + +julia> rm = VaR(0.95) +VaR{Float64}(0.95) + +julia> rm(rand(1000)) +0.9597070153670079 +``` +""" +struct VaR{T<:Real} <: RiskMeasure + α::T + + function VaR(α::T) where {T} + @assert 0 <= α < 1 "α of $α is not 0 ≤ α < 1" + return new{T}(α) end end +g(rm::VaR, x) = x < (1 - rm.α) ? 0 : 1 + """ [`VaR`](@ref) """ ValueAtRisk = VaR """ - CTE(v::AbstractArray,p::Real;rev::Bool=false) + CTE(α)::RiskMeasure + CTE(α)(risk)::T (where T is the type of values sampled in risk) -The average of the values ≥ the `p`th percentile of the vector `v` is the Conditiona Tail Expectation. Assumes more positive values are higher risk measures, so a higher p will return a more positive number, but this can be reversed if `rev` is `true`. +The Conditional Tail Expectation (CTE) at level α is the expected value of the risk distribution above the αth quantile. `risk` can be a univariate distribution or an array of outcomes. +Assumes more positive values are higher risk measures, so a higher p will return a more positive number. -May also be called with `ConditionalTailExpectation(...)`. +CTE(α) returns a functor which can then be called on a risk distribution. -Also known as Tail Value at Risk (TVaR), or Tail Conditional Expectation (TCE) -""" -function CTE(v, p; rev=false) - # filter has the "or approximately equalt to quantile" because - # of floating point path might make the quantile slightly off from the right indexing - # e.g. if values should capture <= q, where q should be 10 but is calculated to be - # 9.99999... - if rev - q = StatsBase.quantile(v, 1 - p) - filter = (v .<= q) .| (v .≈ q) - else - q = StatsBase.quantile(v, p) - filter = (v .>= q) .| (v .≈ q) - end +## Parameters + +- α: [0,1.0) + +## Examples + +```julia-repl +julia> CTE(0.95)(rand(1000)) +0.9766218612020593 - return sum(v[filter]) / sum(filter) +julia> rm = CTE(0.95) +CTE{Float64}(0.95) +julia> rm(rand(1000)) +0.9739835010268733 +``` +""" +struct CTE{T<:Real} <: RiskMeasure + α::T + + function CTE(α::T) where {T} + @assert 0 <= α < 1 "α of $α is not 0 ≤ α < 1" + return new{T}(α) + end end +g(rm::CTE, x) = x < (1 - rm.α) ? x / (1 - rm.α) : 1 """ [`CTE`](@ref) """ ConditionalTailExpectation = CTE + +""" + WangTransform(α)::RiskMeasure + WangTransform(α)(risk)::T (where T is the type of values sampled in risk) + +The Wang Transform is a distortion risk measure that transforms the cumulative distribution function (CDF) of the risk distribution using a normal distribution with mean Φ⁻¹(α) and standard deviation 1. risk can be a univariate distribution or an array of outcomes. + +WangTransform(α) returns a functor which can then be called on a risk distribution. + +## Parameters +- α: [0,1.0] + +In the literature, sometimes λ is used where ``\\lambda = \\Phi^{-1}(\\alpha)``. + + +## Examples + +```julia-repl +julia> WangTransform(0.95)(rand(1000)) +0.8799465543360105 + +julia> rm = WangTransform(0.95) +WangTransform{Float64}(0.95) + +julia> rm(rand(1000)) +0.8892245759705852 +``` + +## References +- "A Risk Measure That Goes Beyond Coherence", Shaun S. Wang, 2002 +""" +struct WangTransform{T} <: RiskMeasure + α::T + function WangTransform(α::T) where {T} + @assert 0 < α < 1 "α of $α is not 0 < α < 1" + return new{T}(α) + end +end +function g(rm::WangTransform, x) + Φ_inv(x) = Distributions.quantile(Distributions.Normal(), x) + Distributions.cdf(Distributions.Normal(), Φ_inv(x) + Φ_inv(rm.α)) +end + +""" + DualPower(v)::RiskMeasure + DualPower(v)(risk)::T (where T is the type of values sampled in risk) + +The Dual Power distortion risk measure is defined as ``1 - (1 - x)^v``, where x is the cumulative distribution function (CDF) of the risk distribution and v is a positive parameter. risk can be a univariate distribution or an array of outcomes. + +DualPower(v) returns a functor which can then be called on a risk distribution. + +""" +struct DualPower{T} <: RiskMeasure + v::T +end +g(rm::DualPower, x) = 1 - (1 - x)^rm.v + +""" + ProportionalHazard(y)::RiskMeasure + ProportionalHazard(y)(risk)::T (where T is the type of values sampled in risk) + +The Proportional Hazard distortion risk measure is defined as ``x^(1/y)``, where x is the cumulative distribution function (CDF) of the risk distribution and y is a positive parameter. risk can be a univariate distribution or an array of outcomes. +ProportionalHazard(y) returns a functor which can then be called on a risk distribution. + +## Examples + +```julia-repl +julia> ProportionalHazard(2)(rand(1000)) +0.6659603556774121 + +julia> rm = ProportionalHazard(2) +ProportionalHazard{Int64}(2) + +julia> rm(rand(1000)) +0.6710587338367799 +``` +""" +struct ProportionalHazard{T} <: RiskMeasure + y::T +end +g(rm::ProportionalHazard, x) = x^(1 / rm.y) + +function (rm::RiskMeasure)(risk) + # Definition 4.2 of "A Risk Measure that Goes Beyond Coherence", Wang 2002 + F(x) = cdf_func(risk)(x) + H(x) = 1 - g(rm, 1 - x) + integral1, _ = QuadGK.quadgk(x -> 1 - H(F(x)), 0, Inf) + integral2, _ = QuadGK.quadgk(x -> H(F(x)), -Inf, 0) + return integral1 - integral2 +end + +""" + cdf_function(risk) + +Returns the appropriate cumulative distribution function depending on the type, specifically: + + cdf_func(S::AbstractArray{<:Real}) = StatsBase.ecdf(S) + cdf_func(S::Distributions.UnivariateDistribution) = x -> Distributions.cdf(S, x) + +""" +cdf_func(S::AbstractArray{<:Real}) = StatsBase.ecdf(S) +cdf_func(S::Distributions.UnivariateDistribution) = x -> Distributions.cdf(S, x) + +###################################################################### +## This section is old, work-in-progress VaR and CTE revamp applicable only for +# AbstractArrays. Keeping this around for now in case perforamnce needs dicatate a specialized +# version of the two, but the above implementation has proved more flexible and general +# than below. + + +# """ +# VaR(v::AbstractArray,p::Real;rev::Bool=false) + +# The `p`th quantile of the vector `v` is the Value at Risk. Assumes more positive values are higher risk measures, so a higher p will return a more positive number., but this can be reversed if `rev` is `true`. + +# Also can be called with `ValueAtRisk(...)`. +# """ +# function VaR_empirical(v::T, p; sorted=false) where {T<:AbstractArray} +# if sorted +# _VaR_sorted(v, p) +# else +# _VaR_sorted(sort(v), p) +# end +# end + +# # Core VaR assumes v is sorted +# function _VaR_sorted(v, p) +# i = 1 +# n = length(v) +# q_prior = 0.0 +# x_prior = first(v) +# for (i, x) in enumerate(v) +# q = i / n +# if q >= p +# # return weighted between two points +# return x * (p - q_prior) / (q - q_prior) + x_prior * (q - p) / (q - q_prior) + +# end +# x_prior = x +# q_prior = q +# end + +# return last(v) +# end + + + + +# """ +# CTE(v::AbstractArray,p::Real;rev::Bool=false) + +# The average of the values ≥ the `p`th percentile of the vector `v` is the Conditiona Tail Expectation. Assumes more positive values are higher risk measures, so a higher p will return a more positive number, but this can be reversed if `rev` is `true`. + +# May also be called with `ConditionalTailExpectation(...)`. + +# Also known as Tail Value at Risk (TVaR), or Tail Conditional Expectation (TCE) +# """ +# function CTE(v::T, p; sorted=false) where {T<:AbstractArray} +# if sorted +# _CTE_sorted(v, p) +# else +# _CTE_sorted(sort(v), p) +# end +# end + +# # Core CTE assumes v is sorted +# function _CTE_sorted(v, p) +# i = 1 +# n = length(v) +# q_prior = 0.0 +# x_prior = first(v) +# sub_total = zero(eltype(v)) +# in_range = false +# for (i, x) in enumerate(v) +# q = i / n +# if in_range || q >= p +# # return weighted between two points +# # return x * (p - q_prior) / (q - q_prior) + x_prior * (q - p) / (q - q_prior) +# in_range = true + +# end +# x_prior = x +# q_prior = q +# end + +# return last(v) +# end + +###################### +end \ No newline at end of file diff --git a/src/utilities.jl b/src/utilities.jl new file mode 100644 index 0000000..a9c6e52 --- /dev/null +++ b/src/utilities.jl @@ -0,0 +1,135 @@ +module Utilities + +import ..Dates +import ..ActuaryUtilities: duration + +export years_between, duration, + accum_offset + +""" + Years_Between(d1::Date, d2::Date) + +Compute the number of integer years between two dates, with the +first date typically before the second. Will return negative number if +first date is after the second. Use third argument to indicate if calendar +anniversary should count as a full year. + +# Examples +```julia +julia> d1 = Date(2018,09,30); + +julia> d2 = Date(2019,09,30); + +julia> d3 = Date(2019,10,01); + +julia> years_between(d1,d3) +1 +julia> years_between(d1,d2,false) # same month/day but `false` overlap +0 +julia> years_between(d1,d2) # same month/day but `true` overlap +1 +julia> years_between(d1,d2) # using default `true` overlap +1 +``` +""" +function years_between(d1::Dates.Date, d2::Dates.Date, overlap=true) + iy, im, id = Dates.year(d1), Dates.month(d1), Dates.day(d1) + vy, vm, vd = Dates.year(d2), Dates.month(d2), Dates.day(d2) + dur = vy - iy + if vm == im + if overlap + if vd >= id + dur += 1 + end + else + if vd > id + dur += 1 + end + end + elseif vm > im + dur += 1 + end + + return dur - 1 +end + +""" + duration(d1::Date, d2::Date) + +Compute the duration given two dates, which is the number of years +since the first date. The interval `[0,1)` is defined as having +duration `1`. Can return negative durations if second argument is before the first. + + +```julia +julia> issue_date = Date(2018,9,30); + +julia> duration(issue_date , Date(2019,9,30) ) +2 +julia> duration(issue_date , issue_date) +1 +julia> duration(issue_date , Date(2018,10,1) ) +1 +julia> duration(issue_date , Date(2019,10,1) ) +2 +julia> duration(issue_date , Date(2018,6,30) ) +0 +julia> duration(Date(2018,9,30),Date(2017,6,30)) +-1 +``` + +""" +function duration(issue_date::Dates.Date, proj_date::Dates.Date) + return years_between(issue_date, proj_date, true) + 1 +end + + +""" + accum_offset(x; op=*, init=1.0) + +A shortcut for the common operation wherein a vector is scanned with an operation, but has an initial value and the resulting array is offset from the traditional accumulate. + +This is a common pattern when calculating things like survivorship given a mortality vector and you want the first value of the resulting vector to be `1.0`, and the second value to be `1.0 * x[1]`, etc. + +Two keyword arguments: + +- `op` is the binary (two argument) operator you want to use, such as `*` or `+` +- `init` is the initial value in the returned array + +# Examples + +```julia=repl +julia> accum_offset([0.9, 0.8, 0.7]) +3-element Array{Float64,1}: + 1.0 + 0.9 + 0.7200000000000001 + +julia> accum_offset(1:5) # the product of elements 1:n, with the default `1` as the first value +5-element Array{Int64,1}: + 1 + 1 + 2 + 6 + 24 + +julia> accum_offset(1:5,op=+) +5-element Array{Int64,1}: + 1 + 2 + 4 + 7 + 11 + +``` + +""" +function accum_offset(x; op=*, init=1.0) + xnew = similar(x) + xnew[1] = init + for i in 2:length(x) + xnew[i] = op(xnew[i-1], x[i-1]) + end + return xnew +end +end \ No newline at end of file diff --git a/test/Project.toml b/test/Project.toml index 8f0f75b..e4a6ceb 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,4 +1,5 @@ [deps] Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" -Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4" +Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" +StatsBase = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/test/risk_measures.jl b/test/risk_measures.jl index afb84be..3d237dc 100644 --- a/test/risk_measures.jl +++ b/test/risk_measures.jl @@ -1,20 +1,105 @@ @testset "Risk Measures" begin - sample = [0:100...] - @testset "VaR" begin - @test VaR(sample,.9) ≈ 90 - @test VaR(sample,.9,rev=true) ≈ 10 - @test VaR(sample,.1) ≈ VaR(sample,1-.9) - @test VaR(sample,.1) == ValueAtRisk(sample,.1) - end - - @testset "CTE" begin - @test CTE(sample,.9) ≈ sum(90:100) / length(90:100) - @test CTE(sample,.1) ≈ sum(10:100) / length(10:100) - @test CTE(sample,.15) >= CTE(sample,.1) # monotonicity - @test CTE(sample,.9,rev=true) ≈ sum(0:10) / length(0:10) - @test CTE(sample,.9) == ConditionalTailExpectation(sample,.9) + @test_throws AssertionError VaR(-0.5) + @test_throws AssertionError VaR(1.0) + @test_throws AssertionError VaR(1.5) + @test_throws AssertionError CTE(-0.5) + @test_throws AssertionError CTE(1.0) + @test_throws AssertionError CTE(1.5) + @test_throws AssertionError WangTransform(0.0) + @test_throws AssertionError WangTransform(1.0) + + # https://utstat.utoronto.ca/sam/coorses/act466/rmn.pdf pg 17 + @test RiskMeasures.g(WangTransform(cdf(Normal(), 1)), 1 - cdf(LogNormal(0, 1), 12)) ≈ 0.06879 atol = 1e-5 + @test RiskMeasures.Expectation()(LogNormal(0, 2 * 1)) ≈ mean(LogNormal(0, 2 * 1)) + + + @test CTE(0.9)(Uniform(-1, 0)) ≈ -0.05 atol = 1e-8 + @test RiskMeasures.Expectation()(Uniform(-1, 0)) ≈ -0.5 atol = 1e-8 + @test CTE(0.0)(Uniform(0, 1) - 0.5) ≈ 0.0 atol = 1e-8 + @test CTE(0.5)(Uniform(0, 1) - 0.5) ≈ 0.25 atol = 1e-8 + + @test CTE(0.0)(Distributions.Normal(0, 1)) ≈ 0 + @test RiskMeasures.Expectation()(Distributions.Normal(3, 1)) ≈ 3 + + # http://actuaries.org/events/congresses/cancun/afir_subject/afir_14_wang.pdf + A = Distributions.DiscreteNonParametric([0.0, 1.0, 5.0], [0.6, 0.375, 0.025]) + B = Distributions.DiscreteNonParametric([0.0, 1.0, 11.0], [0.6, 0.390, 0.01]) + @test WangTransform(0.95)(A) ≈ 2.42 atol = 1e-2 + @test WangTransform(0.95)(B) ≈ 3.40 atol = 1e-2 + @test CTE(0.95)(A) ≈ 3 + @test CTE(0.95)(B) ≈ 3 + + ## example 4.3 + @test WangTransform(0.9)(LogNormal(3, 2)) ≈ exp(3 + quantile(Normal(), 0.9) * 2 + 2^2 / 2) atol = 1e-3 + + ## example 4.4 + C = Distributions.Exponential(1) + α = 0.99 + @test CTE(α)(C) ≈ 5.61 atol = 1e-2 + @test VaR(α)(C) ≈ 4.61 atol = 1e-2 + @test WangTransform(α)(C) ≈ 5.02 atol = 1e-1 + + ## example 4.5 + @test WangTransform(α)(Uniform()) ≈ 0.95 atol = 1e-2 + + # Sepanski & Wang, "New Classes of Distortion Risk Measures and Their Estimation, Table 6 + # note the parameterization of Exp, Lomax (GP), and Weibull is different in Julia + # than in the paper + # TODO: add additional risk measures defined in the paper + dists = [ + Distributions.Uniform(0, 100), + Distributions.Exponential(1 / 0.02), + Distributions.GeneralizedPareto(0, 580.40 / 12.61, 1 / 12.61), + Distributions.Weibull(0.50, 5^(1 / 0.5)), + Distributions.Weibull(1.50, 412.2^(1 / 1.5)) + ] + cte_targets = [ + [62.6, 75.0, 87.5, 97.5, 99.5], + [64.38, 84.66, 119.31, 199.79, 280.26], + [64.54, 85.61, 123.25, 219.04, 327.87], + [66.45, 96.67, 167.36, 424.15, 810.45], + [62.01, 76.23, 97.32, 138.63, 174.22] + ] + var_targets = [ + [25.0, 50.0, 75.0, 95.0, 99.0], + [14.38, 34.66, 69.31, 149.79, 230.26], + [13.39, 32.80, 67.45, 155.64, 255.84], + [2.07, 12.01, 48.05, 224.36, 530.19], + [24.14, 43.38, 68.86, 115.10, 153.31] + ] + alphas = [0.25, 0.5, 0.75, 0.95, 0.99] + @testset "distribution $dist" for (i, dist) in enumerate(dists) + @testset "alpha $α" for (j, α) in enumerate(alphas) + @test CTE(α)(dist) ≈ cte_targets[i][j] rtol = 1e-2 + @test VaR(α)(dist) ≈ var_targets[i][j] rtol = 1e-2 + end end + # Hardy, "An Introduction to Risk Measures for Actuarial Applications + # note the difference for VaR where our VaR is L(Nα+1), as opposed to L(Nα) + # or the smoothed empirical estimate + + # Also, confusingly the examples for VaR don't use the same Table 1 (L) as CTE + L = append!(vec([ + 169.1 170.4 171.3 171.9 172.3 173.3 173.8 174.3 174.9 175.9 + 176.4 177.2 179.1 179.7 180.2 180.5 181.9 182.6 183.0 183.1 + 183.3 184.4 186.9 187.7 188.2 188.5 191.8 191.9 193.1 193.8 + 194.2 196.3 197.6 197.8 199.1 200.5 200.5 200.5 202.8 202.9 + 203.0 203.7 204.4 204.8 205.1 205.8 206.7 207.5 207.9 209.2 + 209.5 210.6 214.7 217.0 218.2 226.2 226.3 226.9 227.5 227.7 + 229.0 231.4 231.6 233.2 237.5 237.9 238.1 240.3 241.0 241.3 + 241.6 243.8 244.0 247.2 247.8 248.8 254.1 255.6 255.9 257.4 + 265.0 265.0 268.9 271.2 271.6 276.5 279.2 284.1 284.3 287.8 + 287.9 298.7 301.6 305.0 313.0 323.8 334.5 343.5 350.3 359.4 + ]), zeros(900)) |> sort + + @test VaR(0.950)(L) ≈ L[951] atol = 1e-2 + @test VaR(0.9505)(L) ≈ L[951] atol = 1e-2 + @test VaR(0.951)(L) ≈ L[952] atol = 1e-2 + @test VaR(0.95)(L) ≈ L[951] atol = 1e-2 + @test CTE(0.95)(L) ≈ 260.68 atol = 1e-1 + @test CTE(0.99)(L) ≈ 321.8 atol = 1e-1 + end diff --git a/test/runtests.jl b/test/runtests.jl index 124fafb..8d73e16 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -2,6 +2,8 @@ using ActuaryUtilities using Dates using Test +using Distributions +using StatsBase const FM = ActuaryUtilities.FinanceModels const FC = ActuaryUtilities.FinanceCore @@ -252,8 +254,8 @@ end c = FM.Yield.Constant(FC.Periodic(0.04, 2)) - cp = ActuaryUtilities._krd_new_curve(KeyRatePar(5), c, 1:10) - cz = ActuaryUtilities._krd_new_curve(KeyRateZero(5), c, 1:10) + cp = FinancialMath._krd_new_curve(KeyRatePar(5), c, 1:10) + cz = FinancialMath._krd_new_curve(KeyRateZero(5), c, 1:10) # test some relationships between par and zero curve @test FM.par(cp, 5) ≈ FM.par(c, 5) + default_shift atol = 0.0002 # 0.001 is the default shift