Skip to content

Commit

Permalink
intermediate progress
Browse files Browse the repository at this point in the history
  • Loading branch information
alecloudenback committed Jun 24, 2024
1 parent d21bdeb commit 7b3017c
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 54 deletions.
5 changes: 3 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Optimization = "7f7a1694-90dd-40f0-9382-eb1efda571ba"
OptimizationMetaheuristics = "3aafef2f-86ae-4776-b337-85a36adf0b55"
PrecompileTools = "aea7be01-6a6a-4083-8856-8a6e6704d82a"
QuadGK = "1fd47b50-473d-5c70-9696-f719f8f3bcdc"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
Expand All @@ -30,17 +31,17 @@ FinanceModelsMakieCoreExt = "MakieCore"
AccessibleOptimization = "^0.1.1"
Accessors = "^0.1"
BSplineKit = "^0.16"
Dates = "^1.6"
FinanceCore = "^2.1"
IntervalSets = "^0.7"
LinearAlgebra = "^1.6"
Dates = "^1.6"
MakieCore = "0.6"
Optimization = "^3.15"
OptimizationMetaheuristics = "^0.1.2"
PrecompileTools = "^1.1"
Reexport = "^1.2"
StaticArrays = "^1.6"
SpecialFunctions = "2"
StaticArrays = "^1.6"
Transducers = "^0.4"
UnicodePlots = "^3.6"
julia = "1.9"
Expand Down
1 change: 1 addition & 0 deletions src/FinanceModels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import BSplineKit
import UnicodePlots
using Transducers: @next, complete, __foldl__, asfoldable
import SpecialFunctions
import QuadGK



Expand Down
90 changes: 38 additions & 52 deletions src/model/Yield/MonotoneConvex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -44,52 +44,51 @@ function __issector2(g0, g1)
a || b
end


# Hagan West - WILMOTT magazine pgs 75-81
function g(x, f⁻, f, fᵈ)
g0 = f⁻ - fᵈ
g1 = f - fᵈ
A = -2 * g0
B = -2 * g1
function g(f⁻, f, fᵈ)
@show f⁻, f, fᵈ
@show g0 = f⁻ - fᵈ
@show g1 = f - fᵈ
if sign(g0) == sign(g1)
# sector (iv)
η = g1 / (g1 + g0)
α = -g0 * g1 / (g1 + g0)

if x < η
return α + (g0 - α) * ((η - x) / η)^2
return x -> α + (g0 - α) * ((η - x) / η)^2
else
return α + (g1 - α) * ((x - η) / (1 - η))^2
return x -> α + (g1 - α) * ((x - η) / (1 - η))^2
end


elseif __issector1(g0, g1)
# sector (i)
g0 * (1 - 4 * x + 3 * x^2) + g1 * (-2 * x + 3 * x^2)
x -> g0 * (1 - 4 * x + 3 * x^2) + g1 * (-2 * x + 3 * x^2)
elseif __issector2(g0, g1)
# sector (ii)
η = (g1 + 2 * g0) / (g1 - g0)
if x < η
return g0
return x -> g0
else
return g0 + (g1 - g0) * ((x - η) / (1 - η))^2
return x -> g0 + (g1 - g0) * ((x - η) / (1 - η))^2
end
else
# sector (iii)
η = 3 * g1 / (g1 - g0)
if x > η
return g1
return x -> g1
else
return g1 + (g0 - g1) * ((η - x) / η)^2
return x -> g1 + (g0 - g1) * ((η - x) / η)^2
end

end
end

function g_rate(x, f⁻, f, fᵈ)
g0 = f⁻ - fᵈ
g1 = f - fᵈ
A = -2 * g0
B = -2 * g1
@show x, f⁻, f, fᵈ
@show g0 = f⁻ - fᵈ
@show g1 = f - fᵈ
if sign(g0) == sign(g1)
# sector (iv)
η = g1 / (g1 + g0)
Expand All @@ -104,6 +103,7 @@ function g_rate(x, f⁻, f, fᵈ)

elseif __issector1(g0, g1)
# sector (i)
@show "(i)"
g0 * (x - 2 * x^2 + x^3) + g1 * (-x^2 + x^3)
elseif __issector2(g0, g1)
# sector (ii)
Expand Down Expand Up @@ -137,22 +137,12 @@ end
"""
returns the index associated with the time t, an initial rate vector, and a time vector
"""
function __monotone_convex_init(t, rates, times)
# the array indexing in the paper and psuedo-VBA is messy
t = min(t, last(times))
# times = collect(times)
# rates = collect(rates)
function __i_time(t, times)
i_time = findfirst(x -> x > t, times)
if i_time == nothing
i_time = lastindex(times)
end
# if !iszero(first(times))
# pushfirst!(times, zero(eltype(times)))
# pushfirst!(rates, first(rates))

# end

return t, i_time, rates, times
return i_time
end

"""
Expand Down Expand Up @@ -193,37 +183,33 @@ function __monotone_convex_fs(rates, times)
return f, fᵈ
end

function myzero(t, rates, times, f, fᵈ)
lt = last(times)
# if the time is greater than the last input time then extrapolate using the forwards
if t > lt
r = myzero(lt, rates, times)
return r * lt / t + forward(lt, rates, times) * (1 - lt / t)
end

t, i_time, rates, times = __monotone_convex_init(t, rates, times)
x = (t - times[i_time]) / (times[i_time+1] - times[i_time])
G = g_rate(x, f[i_time], f[i_time+1], fᵈ[i_time+1])
return 1 / t * (times[i_time] * rates[i_time] + (t - times[i_time]) * fᵈ[i_time+1] + (times[i_time+1] - times[i_time]) * G)




end

function Base.zero(mc::MonotoneConvex, t)
lt = last(mc.times)
f, fᵈ = mc.f, mc.fᵈ
t, i_time, rates, times = __monotone_convex_init(t, mc.rates, mc.times)
# if the time is greater than the last input time then extrapolate using the forwards
if t > lt
r = myzero(lt, rates, times, f, fᵈ)
return r * lt / t + forward(lt, rates, times) * (1 - lt / t)
r = Base.zero(mc, lt)
i_time = __i_time(t, mc.times)
return r * lt / t + forward(lt, mc.rates, mc.times) * (1 - lt / t)
end
@show i_time = __i_time(t, mc.times)
# if the time is greater than the last input time then extrapolate using the forwards

x = (t - times[i_time]) / (times[i_time+1] - times[i_time])
G = g_rate(x, f[i_time], f[i_time+1], fᵈ[i_time+1])
return Continuous(1 / t * (times[i_time] * rates[i_time] + (t - times[i_time]) * fᵈ[i_time+1] + (times[i_time+1] - times[i_time]) * G))
x = if i_time == 1
x = t / times[i_time]
else
x = (t - times[i_time-1]) / (times[i_time] - times[i_time-1])
end
G = g(f[i_time], f[i_time+1], fᵈ[i_time])
return Continuous(1 / t * (times[i_time] * rates[i_time] + (t - times[i_time]) * fᵈ[i_time] + (times[i_time] - times[i_time-1]) * G))

# STATUS:
# intermediate G/other results OK
# need to get the right rate. Instead of last formula, trying the approach on pg 39 of
# http://uu.diva-portal.org/smash/get/diva2:1477828/FULLTEXT01.pdf
# and have added QuadGK and converted the G function to return a function of x instead of a calculated value
# (also need to change the signature of associated test cases)
# QuadGK.quadgk(G,t)

end

Expand Down
12 changes: 12 additions & 0 deletions test/MonotoneConvex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

f, fᵈ = Yield.__monotone_convex_fs(rates, times)

@test all(f .== c.f)
@test all(fᵈ .== c.fᵈ)

@test fᵈ[1] 0.0202 atol = 0.0001
@test fᵈ[2] 0.0258 atol = 0.0001
@test fᵈ[3] 0.0373 atol = 0.0001
Expand All @@ -25,6 +28,14 @@
@test f[5] 0.0515 atol = 0.0001
@test f[6] 0.0620 atol = 0.0001

@test FinanceModels.Yield.g(0.5, 0.018793076350927487, 0.023021969250703423, 0.020202707317519466) 0.0042 * (0.5)^2 - 0.0014 atol = 0.0001
@test FinanceModels.Yield.g(0, 0.023021969250703423, 0.03158945081076577, 0.02584123118388738) -0.0028 atol = 0.0001
@test FinanceModels.Yield.g(0.5, 0.023021969250703423, 0.03158945081076577, 0.02584123118388738) 0.0087 * (0.5)^2 0.0002 * 0.5 - 0.0028 atol = 0.0001
@test FinanceModels.Yield.g(0.5, 0.03158945081076577, 0.04089471650423902, 0.03733767043764417) -0.0063 * (0.5)^2 + 0.0156 * 0.5 - 0.0057 atol = 0.0001
@test FinanceModels.Yield.g(0.5, 0.04089471650423902, 0.051473984626221235, 0.04445176257083387) 0.0102 * (0.5)^2 + 0.0004 * 0.5 - 0.0036 atol = 0.0001
@test FinanceModels.Yield.g(0.5, 0.04089471650423902, 0.051473984626221235, 0.044451762570833877) -0.0105 * (0.5)^2 + 0.021 * 0.5 - 0.007 atol = 0.0001


function r(t)
if 0 <= t <= 1
return 0.0014t^2 + 0.0188
Expand All @@ -49,5 +60,6 @@
end


# TODO: More tests from
# https://repository.up.ac.za/bitstream/handle/2263/25882/dissertation.pdf?sequence=1&isAllowed=y
end

0 comments on commit 7b3017c

Please sign in to comment.