Skip to content

Commit

Permalink
add InterestRate Swap and one layer of unwrapping Transducers from Co…
Browse files Browse the repository at this point in the history
…ntracts
  • Loading branch information
alecloudenback committed Nov 3, 2023
1 parent 649ddf5 commit b33d940
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 5 deletions.
17 changes: 16 additions & 1 deletion src/Contract.jl
Original file line number Diff line number Diff line change
Expand Up @@ -424,4 +424,19 @@ end

function cashflows_timepoints(qs::Vector{Q}) where {Q<:Quote}
cashflows_timepoints([q.instrument for q in qs])
end
end

"""
InterestRateSwap(curve, tenor; model_key="OIS")
A convenience method for creating an interest rate swap given a curve and a tenor via a `Composite` contract consisting of receiving a [fixed bond](@ref Bond.Fixed) and paying (i.e. [`Negative`](@ref FinanceCore.Negative)) [floating bond](@ref Bond.Floating). To switch directions of the pay/receive, simply wrap the swap with `Negative(...)`.
The notional is a unit (1.0) amount and assumed to settle four times per period.
"""
function InterestRateSwap(curve, tenor; model_key="OIS")
fixed_rate = par(curve, tenor; frequency=4)
fixed_leg = Bond.Fixed(rate(fixed_rate), Periodic(4), tenor)
float_leg = Bond.Floating(0.0, Periodic(4), tenor, model_key) |> Map(-)
return Composite(fixed_leg, float_leg)

Check warning on line 441 in src/Contract.jl

View check run for this annotation

Codecov / codecov/patch

src/Contract.jl#L437-L441

Added lines #L437 - L441 were not covered by tests
end
2 changes: 1 addition & 1 deletion src/FinanceModels.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ include("model/Model.jl")
include("Projection.jl")
include("fit.jl")

export Cashflow, Quote, Forward, CommonEquity, Option
export Cashflow, Quote, Forward, CommonEquity, Option, InterestRateSwap

using .Bond: ZCBYield, ZCBPrice, ParSwapYield, ParYield, CMTYield, ForwardYields, OISYield
export Bond, ZCBYield, ZCBPrice, ParSwapYield, ParYield, CMTYield, ForwardYields, OISYield
Expand Down
15 changes: 12 additions & 3 deletions src/Projection.jl
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ struct CashflowProjection <: ProjectionKind end
# collecting a Projection gives your the reducible defined below with __foldl__
Base.collect(p::P) where {P<:AbstractProjection} = p |> Map(identity) |> collect
# collecting a contract wraps the contract in with the default Projection, defined next
Base.collect(c::C) where {C<:FinanceCore.AbstractContract} = Projection(c) |> Map(identity) |> collect
Base.collect(c::C) where {C<:FinanceCore.AbstractContract} = Projection(c) |> collect

# Default Projections ##########################

Expand All @@ -73,7 +73,7 @@ Projection(c, m) = Projection(c, m, CashflowProjection())

# Reducibles ###################################

# a more composible, efficient way to create a collection of things that you can apply subsequent transformations to
# a more composable, efficient way to create a collection of things that you can apply subsequent transformations to
# (and those transformations can be Transducers).
# https://juliafolds2.github.io/Transducers.jl/stable/howto/reducibles/
# https://www.youtube.com/watch?v=6mTbuzafcII
Expand All @@ -84,7 +84,7 @@ Projection(c, m) = Projection(c, m, CashflowProjection())
# `__foldl__` where you can define the collection using a `for` loop
# and `foldl__` you can also define state that is used within the loop

# this wraps a contract in a default proejction and makes a contract a reducible collection of cashflows
# this wraps a contract in a default projection and makes a contract a reducible collection of cashflows
function Transducers.asfoldable(c::C) where {C<:FinanceCore.AbstractContract}
Projection(c) |> Map(identity)
end
Expand All @@ -97,6 +97,15 @@ end
return complete(rf, val)
end

# If a Transducer has been combined with a contract into an Eduction
# then unwrap the contract and apply the transducer to the projection
@inline function Transducers.__foldl__(rf, val, p::Projection{C,M,K}) where {C<:Transducers.Eduction,M,K}
rfx = p.contract.rf.xform # get the transducer's "xform" from the projection's contract
rf = Transducers.Reduction(rfx, rf) # compose the xform with any othe existing transducers
p_alt = @set p.contract = p.contract.coll # reset the contract to the underlying contract without transducers
Transducers.__foldl__(rf, val, p_alt) # project with a newly combined reduction

Check warning on line 106 in src/Projection.jl

View check run for this annotation

Codecov / codecov/patch

src/Projection.jl#L102-L106

Added lines #L102 - L106 were not covered by tests
end

#
@inline function Transducers.__foldl__(rf, val, p::Projection{C,M,K}) where {C<:Bond.Fixed,M,K}
b = p.contract
Expand Down

0 comments on commit b33d940

Please sign in to comment.