diff --git a/Project.toml b/Project.toml index 3c8c9a47..654745b8 100644 --- a/Project.toml +++ b/Project.toml @@ -8,15 +8,14 @@ AccessibleOptimization = "d88a00a0-4a21-4fe4-a515-e2123c37b885" Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" BSplineKit = "093aae92-e908-43d7-9660-e50ee39d5a0a" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" -Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f" FinanceCore = "b9b1ffdd-6612-4b69-8227-7663be06e089" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba" OptimizationMetaheuristics = "3aafef2f-86ae-4776-b337-85a36adf0b55" -OptimizationOptimJL = "36348300-93cb-4f02-beb5-3c3902f8871e" PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a" Reexport = "189a3867-3050-52da-a836-e630ba90ab69" +SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" Transducers = "28d57a85-8fef-5791-bfe6-a80928e7c999" UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" @@ -25,30 +24,23 @@ UnicodePlots = "b8865327-cd53-5732-bb35-84acbb429228" MakieCore = "20f20a25-4f0e-4fdf-b5d1-57303727442b" [extensions] -# name of extension to the left -# extension dependencies required to load the extension to the right -# use a list for multiple extension dependencies FinanceModelsMakieCoreExt = "MakieCore" [compat] -julia = "1.9" #Bsplinekit 0.16 is 1.8 or above and AccessibleOptimization's deps is 1.9 -FinanceCore = "^2" +AccessibleOptimization = "^0.1.1" +Accessors = "^0.1" BSplineKit = "^0.16" +FinanceCore = "^2" IntervalSets = "^0.7" -Transducers = "^0.4" MakieCore = "0.6" Optimization = "^3.15" OptimizationMetaheuristics = "^0.1.2" -OptimizationOptimJL = "^0.1.9" -Distributions = "^0.25" -AccessibleOptimization = "^0.1.1" -Accessors = "^0.1" PrecompileTools = "^1.1" Reexport = "^1.2" StaticArrays = "^1.6" +Transducers = "^0.4" UnicodePlots = "^3.6" - - +julia = "1.9" [extras] ActuaryUtilities = "bdd23359-8b1c-4f88-b89b-d11982a786f4" diff --git a/src/FinanceModels.jl b/src/FinanceModels.jl index 22932f71..56f509f0 100644 --- a/src/FinanceModels.jl +++ b/src/FinanceModels.jl @@ -4,7 +4,6 @@ import Dates using Reexport @reexport using FinanceCore using FinanceCore: present_value, discount, accumulation -using OptimizationOptimJL using OptimizationMetaheuristics using StaticArrays using IntervalSets @@ -15,7 +14,7 @@ using Transducers import BSplineKit import UnicodePlots using Transducers: @next, complete, __foldl__, asfoldable -import Distributions +import SpecialFunctions diff --git a/src/model/Yield.jl b/src/model/Yield.jl index 3370dd1b..89477892 100644 --- a/src/model/Yield.jl +++ b/src/model/Yield.jl @@ -6,7 +6,7 @@ import ..BSplineKit import UnicodePlots import ..Bond: coupon_times -using FinanceCore: Continuous, Periodic, discount, accumulation, AbstractContract +using ..FinanceCore: Continuous, Periodic, discount, accumulation, AbstractContract export discount, zero, forward, par, pv diff --git a/src/utils.jl b/src/utils.jl index 8768a8a2..4b812dc3 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -1,4 +1,11 @@ -N(x) = Distributions.cdf(Distributions.Normal(), x) +# all we need is cumulative normal, so avoid Distributions.jl dependency +# https://www.johndcook.com/blog/cpp_phi/ + +function ϕ(x) + return 0.5 * SpecialFunctions.erfc(-x * √(0.5)) +end + +N(x) = ϕ(x) function d1(S, K, τ, r, σ, q) return (log(S / K) + (r - q + σ^2 / 2) * τ) / (σ * √(τ)) diff --git a/test/misc.jl b/test/misc.jl index 4b136fe5..6c99023e 100644 --- a/test/misc.jl +++ b/test/misc.jl @@ -7,4 +7,27 @@ rates = convert.(DecFP.Dec64, [0.01, 0.01, 0.03, 0.05, 0.07, 0.16, 0.35, 0.92, 1.40, 1.74, 2.31, 2.41] ./ 100) y = fit(Spline.Linear(), CMTYield.(rates, mats), Fit.Bootstrap()) @test y isa FinanceModels.Yield.AbstractYieldModel +end + +@testset "Normal CDF" begin + # https://www.johndcook.com/blog/cpp_phi/ + + x = [ + -3, + -1, + 0.0, + 0.5, + 2.1 + ] + target = [ + 0.00134989803163, + 0.158655253931, + 0.5, + 0.691462461274, + 0.982135579437 + ] + @testset "confirm accuracy" for i in 1:5 + @test isapprox(FinanceModels.ϕ(x[i]), target[i], atol=1e-12) + end + end \ No newline at end of file