From 57c35252989364a45b02609bf3731c05948932af Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Wed, 30 Jan 2019 23:27:39 -0600 Subject: [PATCH 01/11] work through build errors 1 --- src/FinancialMarkets.jl | 5 --- src/businessdayconventions.jl | 14 ++++---- src/calendars.jl | 8 ++--- src/calendars/calendars_au.jl | 2 +- src/calendars/calendars_aume.jl | 2 +- src/calendars/calendars_ausy.jl | 2 +- src/calendars/calendars_euta.jl | 6 ++-- src/calendars/calendars_gb.jl | 4 +-- src/calendars/calendars_jp.jl | 4 +-- src/calendars/calendars_nz.jl | 2 +- src/calendars/calendars_nzau.jl | 2 +- src/calendars/calendars_nzwe.jl | 2 +- src/calendars/calendars_us.jl | 6 ++-- src/cashflow.jl | 5 ++- src/constants.jl | 4 ++- src/currencies.jl | 17 +++++----- src/indices.jl | 32 +++++++++--------- src/instruments.jl | 2 +- src/instruments/cash.jl | 2 +- src/instruments/deposit.jl | 2 +- src/instruments/fra.jl | 2 +- src/instruments/futures.jl | 4 +-- src/interestrates.jl | 13 ++++---- src/schedule.jl | 18 +++++----- src/shifters.jl | 3 +- src/times.jl | 14 ++++---- test/runtests.jl | 2 +- test/test_times.jl | 58 ++++++++++++++++----------------- 28 files changed, 115 insertions(+), 122 deletions(-) diff --git a/src/FinancialMarkets.jl b/src/FinancialMarkets.jl index 844beb6..bd79779 100644 --- a/src/FinancialMarkets.jl +++ b/src/FinancialMarkets.jl @@ -1,10 +1,5 @@ module FinancialMarkets -if VERSION < v"0.4-" - using Dates -else - using Base.Dates -end import DataFrames.DataFrame export diff --git a/src/businessdayconventions.jl b/src/businessdayconventions.jl index 3f09edf..1aa4dc0 100644 --- a/src/businessdayconventions.jl +++ b/src/businessdayconventions.jl @@ -3,18 +3,18 @@ ##### -abstract BusinessDayConvention +abstract type BusinessDayConvention end # Sources: # 1. ISDA 2006 definitions # 2. Opengamma: Interest rate instruments and market conventions guide -immutable Unadjusted <: BusinessDayConvention end -immutable Preceding <: BusinessDayConvention end -immutable ModifiedPreceding <: BusinessDayConvention end -immutable Following <: BusinessDayConvention end -immutable ModifiedFollowing <: BusinessDayConvention end -immutable Succeeding <: BusinessDayConvention end +struct Unadjusted <: BusinessDayConvention end +struct Preceding <: BusinessDayConvention end +struct ModifiedPreceding <: BusinessDayConvention end +struct Following <: BusinessDayConvention end +struct ModifiedFollowing <: BusinessDayConvention end +struct Succeeding <: BusinessDayConvention end ##### # Methods diff --git a/src/calendars.jl b/src/calendars.jl index 50c5a08..414718d 100644 --- a/src/calendars.jl +++ b/src/calendars.jl @@ -2,13 +2,13 @@ # Type declarations ##### -abstract FinCalendar -abstract SingleFCalendar <: FinCalendar -immutable JointFCalendar <: FinCalendar +abstract type FinCalendar end +abstract type SingleFCalendar <: FinCalendar end +struct JointFCalendar <: FinCalendar calendars::Vector{SingleFCalendar} onbad::Bool end -immutable NoFCalendar <: SingleFCalendar end +struct NoFCalendar <: SingleFCalendar end ##### diff --git a/src/calendars/calendars_au.jl b/src/calendars/calendars_au.jl index abfcd52..7e40a86 100644 --- a/src/calendars/calendars_au.jl +++ b/src/calendars/calendars_au.jl @@ -2,7 +2,7 @@ # Type declarations ##### -abstract AUFCalendar <: SingleFCalendar +abstract type AUFCalendar <: SingleFCalendar end ##### # Methods diff --git a/src/calendars/calendars_aume.jl b/src/calendars/calendars_aume.jl index db2d1fa..4e6c893 100644 --- a/src/calendars/calendars_aume.jl +++ b/src/calendars/calendars_aume.jl @@ -2,7 +2,7 @@ # Type declarations ##### -immutable AUMEFCalendar <: AUFCalendar end +struct AUMEFCalendar <: AUFCalendar end ##### # Methods diff --git a/src/calendars/calendars_ausy.jl b/src/calendars/calendars_ausy.jl index 9248cc6..378607e 100644 --- a/src/calendars/calendars_ausy.jl +++ b/src/calendars/calendars_ausy.jl @@ -2,7 +2,7 @@ # Type declarations ##### -immutable AUSYFCalendar <: AUFCalendar end +struct AUSYFCalendar <: AUFCalendar end ##### # Methods diff --git a/src/calendars/calendars_euta.jl b/src/calendars/calendars_euta.jl index 4871b02..b54c858 100644 --- a/src/calendars/calendars_euta.jl +++ b/src/calendars/calendars_euta.jl @@ -2,9 +2,9 @@ # Type declarations ##### -abstract EUFCalendar <: SingleFCalendar -immutable EUTAFCalendar <: EUFCalendar end -immutable EULIBORFCalendar <: EUFCalendar end +abstract type EUFCalendar <: SingleFCalendar end +struct EUTAFCalendar <: EUFCalendar end +struct EULIBORFCalendar <: EUFCalendar end ##### # Methods diff --git a/src/calendars/calendars_gb.jl b/src/calendars/calendars_gb.jl index 5582f5a..be9d1bb 100644 --- a/src/calendars/calendars_gb.jl +++ b/src/calendars/calendars_gb.jl @@ -2,8 +2,8 @@ # Type declarations ##### -abstract GBFCalendar <: SingleFCalendar -immutable GBLOFCalendar <: GBFCalendar end +abstract type GBFCalendar <: SingleFCalendar end +struct GBLOFCalendar <: GBFCalendar end ##### # Methods diff --git a/src/calendars/calendars_jp.jl b/src/calendars/calendars_jp.jl index 40002f3..81b6506 100644 --- a/src/calendars/calendars_jp.jl +++ b/src/calendars/calendars_jp.jl @@ -3,8 +3,8 @@ ##### -abstract JPFCalendar <: SingleFCalendar -immutable JPTOFCalendar <: JPFCalendar end +abstract type JPFCalendar <: SingleFCalendar end +struct JPTOFCalendar <: JPFCalendar end ##### # Methods diff --git a/src/calendars/calendars_nz.jl b/src/calendars/calendars_nz.jl index 01a9759..54e6317 100644 --- a/src/calendars/calendars_nz.jl +++ b/src/calendars/calendars_nz.jl @@ -2,7 +2,7 @@ # Type declarations ##### -abstract NZFCalendar <: SingleFCalendar +abstract type NZFCalendar <: SingleFCalendar end ##### # Methods diff --git a/src/calendars/calendars_nzau.jl b/src/calendars/calendars_nzau.jl index c840700..cdeeb6c 100644 --- a/src/calendars/calendars_nzau.jl +++ b/src/calendars/calendars_nzau.jl @@ -2,7 +2,7 @@ # Type declarations ##### -immutable NZAUFCalendar <: NZFCalendar end +struct NZAUFCalendar <: NZFCalendar end ##### # Methods diff --git a/src/calendars/calendars_nzwe.jl b/src/calendars/calendars_nzwe.jl index 36d45a7..b321a64 100644 --- a/src/calendars/calendars_nzwe.jl +++ b/src/calendars/calendars_nzwe.jl @@ -2,7 +2,7 @@ # Type declarations ##### -immutable NZWEFCalendar <: NZFCalendar end +struct NZWEFCalendar <: NZFCalendar end ##### # Methods diff --git a/src/calendars/calendars_us.jl b/src/calendars/calendars_us.jl index 1960cd5..e28ae90 100644 --- a/src/calendars/calendars_us.jl +++ b/src/calendars/calendars_us.jl @@ -2,9 +2,9 @@ # Type declarations ##### -abstract USFCalendar <: SingleFCalendar -immutable USNYFCalendar <: USFCalendar end -immutable USLIBORFCalendar <: USFCalendar end +abstract type USFCalendar <: SingleFCalendar end +struct USNYFCalendar <: USFCalendar end +struct USLIBORFCalendar <: USFCalendar end ##### # Methods diff --git a/src/cashflow.jl b/src/cashflow.jl index 1760618..26d2a79 100644 --- a/src/cashflow.jl +++ b/src/cashflow.jl @@ -2,7 +2,7 @@ # Types #### -type CashFlow +struct CashFlow currency::Vector{Currency} date::Vector{TimeType} amount::Vector{Real} @@ -17,8 +17,7 @@ end CashFlow(currency::Currency, date::TimeType, amount::Real) = ( CashFlow([currency], [date], [amount])) -function CashFlow{C<:Currency, T<:TimeType, R<:Real}(currency::Vector{C}, - date::Vector{T}, amount::Vector{R}) +function CashFlow(currency::Vector{C}, date::Vector{T}, amount::Vector{R}) where {C<:Currency, T<:TimeType, R<:Real} currency = Currency[ccy for ccy in currency] date = TimeType[dt for dt in date] amount = Real[amt for amt in amount] diff --git a/src/constants.jl b/src/constants.jl index 6886f3a..a7c2cd8 100644 --- a/src/constants.jl +++ b/src/constants.jl @@ -1,5 +1,7 @@ +using Dates + # Session variables -const EVAL_DATE = today() +const EVAL_DATE = Dates.today() # Seasonal constants to determine start of seasons (more precisely, equinoxes # ands solstices) diff --git a/src/currencies.jl b/src/currencies.jl index bb7d602..ed7faea 100644 --- a/src/currencies.jl +++ b/src/currencies.jl @@ -2,37 +2,37 @@ # Types #### -abstract Currency +abstract type Currency end # Sources: # 1. ISDA 2006 definitions # 2. Opengamma: Interest rate instruments and market conventions guide -immutable AUD <: Currency +struct AUD <: Currency calendar::JointFCalendar AUD(calendar::AUSYFCalendar) = new(calendar) end AUD() = AUD(AUSYFCalendar()) -immutable EUR <: Currency +struct EUR <: Currency calendar::JointFCalendar EUR(calendar::EUTAFCalendar) = new(calendar) end EUR() = EUR(EUTAFCalendar()) -immutable GBP <: Currency +struct GBP <: Currency calendar::JointFCalendar GBP(calendar::GBLOFCalendar) = new(calendar) end GBP() = GBP(GBLOFCalendar()) -immutable JPY <: Currency +struct JPY <: Currency calendar::JointFCalendar JPY(calendar::JPTOFCalendar) = new(calendar) end JPY() = JPY(JPTOFCalendar()) -immutable NZD <: Currency +struct NZD <: Currency calendar::JointFCalendar function NZD(calendar::JointFCalendar) cals = [NZAUFCalendar(), NZWEFCalendar()] @@ -43,7 +43,7 @@ immutable NZD <: Currency end NZD() = NZD(+(NZAUFCalendar(), NZWEFCalendar())) -immutable USD <: Currency +struct USD <: Currency calendar::JointFCalendar USD(calendar::USNYFCalendar) = new(calendar) end @@ -58,8 +58,7 @@ const CCY_STRENGTH = [EUR => 1, GBP => 2, AUD => 3, NZD => 4, USD => 5, Base.isless(x::Currency, y::Currency) = (CCY_STRENGTH[typeof(x)] > CCY_STRENGTH[typeof(y)]) -=={T<:Currency}(ccy1::T, ccy2::T) = true +==(ccy1::T, ccy2::T) where {T<:Currency} = true ==(ccy1::Currency, ccy2::Currency) = false Base.string(ccy::Currency) = string(typeof(ccy)) Base.show(io::IO, ccy::Currency) = print(io, string(ccy)) -@vectorize_1arg Currency Base.string diff --git a/src/indices.jl b/src/indices.jl index 1e9c179..824cbb9 100644 --- a/src/indices.jl +++ b/src/indices.jl @@ -2,14 +2,14 @@ # Types #### -abstract Index -abstract InterestRateIndex <: Index +abstract type Index end +abstract type InterestRateIndex <: Index end ############################################################################## ### Cash ############################################################################## -immutable ONIA{CCY<:Currency} <: InterestRateIndex +struct ONIA{CCY<:Currency} <: InterestRateIndex currency::CCY calendar::JointFCalendar bdc::BusinessDayConvention @@ -26,12 +26,12 @@ ONIA(::NZD) = ONIA{NZD}(NZD(), +(NZAUFCalendar(), NZWEFCalendar()), Following(), A365()) ONIA(::USD) = ONIA{USD}(USD(), USNYFCalendar(), Following(), A360()) -typealias AONIA ONIA{AUD} -typealias EONIA ONIA{EUR} -typealias SONIA ONIA{GBP} -typealias TONAR ONIA{JPY} -typealias NZIONA ONIA{NZD} -typealias FedFund ONIA{USD} +const AONIA = ONIA{AUD} +const EONIA = ONIA{EUR} +const SONIA = ONIA{GBP} +const TONAR = ONIA{JPY} +const NZIONA = ONIA{NZD} +const FedFund = ONIA{USD} AONIA() = ONIA(AUD()) EONIA() = ONIA(EUR()) @@ -44,7 +44,7 @@ FedFund() = ONIA(USD()) ### LIBOR ############################################################################## -immutable IBOR{CCY<:Currency} <: InterestRateIndex +struct IBOR{CCY<:Currency} <: InterestRateIndex currency::CCY spotlag::Period tenor::Period @@ -146,12 +146,12 @@ function IBOR(::USD, tenor::Period) IBOR{USD}(USD(), spotlag, tenor, calendar, bdc, true, A360()) end -typealias AUDBBSW IBOR{AUD} -typealias EURIBOR IBOR{EUR} -typealias GBPLIBOR IBOR{GBP} -typealias JPYLIBOR IBOR{JPY} -typealias NZDBKBM IBOR{NZD} -typealias USDLIBOR IBOR{USD} +const AUDBBSW = IBOR{AUD} +const EURIBOR = IBOR{EUR} +const GBPLIBOR = IBOR{GBP} +const JPYLIBOR = IBOR{JPY} +const NZDBKBM = IBOR{NZD} +const USDLIBOR = IBOR{USD} AUDBBSW(tenor) = IBOR(AUD(), tenor) EURIBOR(tenor) = IBOR(EUR(), tenor) diff --git a/src/instruments.jl b/src/instruments.jl index cf84cce..c64e1c0 100644 --- a/src/instruments.jl +++ b/src/instruments.jl @@ -2,7 +2,7 @@ # Types #### -abstract Instrument +abstract type Instrument end include("instruments/cash.jl") include("instruments/deposit.jl") diff --git a/src/instruments/cash.jl b/src/instruments/cash.jl index 6858e2d..46c325f 100644 --- a/src/instruments/cash.jl +++ b/src/instruments/cash.jl @@ -2,7 +2,7 @@ # Types #### -type Cash <: Instrument +struct Cash <: Instrument amount::Real rate::Real tradedate::TimeType diff --git a/src/instruments/deposit.jl b/src/instruments/deposit.jl index ae49d37..bf1eb4e 100644 --- a/src/instruments/deposit.jl +++ b/src/instruments/deposit.jl @@ -2,7 +2,7 @@ # Types #### -type Deposit <: Instrument +struct Deposit <: Instrument amount::Real rate::Real tradedate::TimeType diff --git a/src/instruments/fra.jl b/src/instruments/fra.jl index 1f525ce..ad7b94c 100644 --- a/src/instruments/fra.jl +++ b/src/instruments/fra.jl @@ -2,7 +2,7 @@ # Types #### -type FRA <: Instrument +struct FRA <: Instrument amount::Real rate::Real tradedate::TimeType diff --git a/src/instruments/futures.jl b/src/instruments/futures.jl index c36ab4b..2a1fcc5 100644 --- a/src/instruments/futures.jl +++ b/src/instruments/futures.jl @@ -2,8 +2,8 @@ # Types #### -abstract Future <: Instrument -type STIRFuture <: Future +abstract type Future <: Instrument end +struct STIRFuture <: Future amount::Real price::Real tradedate::TimeType diff --git a/src/interestrates.jl b/src/interestrates.jl index d252d40..4481a95 100644 --- a/src/interestrates.jl +++ b/src/interestrates.jl @@ -1,8 +1,9 @@ +using Printf #### # Types #### -type InterestRate +struct InterestRate rate::Real compounding::Int daycount::DayCountFraction @@ -14,7 +15,7 @@ type InterestRate end -type DiscountFactor +struct DiscountFactor discountfactor::Real startdate::TimeType enddate::TimeType @@ -36,15 +37,13 @@ value(df::DiscountFactor) = df.discountfactor # IO function Base.string(r::InterestRate) - (@sprintf("%05f", 100 * value(r)) * "%," * - uppercase(COMPOUNDINGS[r.compounding]) * "," * - uppercase(string(r.daycount))) + s = @sprintf "%05f" 100 * value(r) + "$(s)%, $(uppercase(COMPOUNDINGS[r.compounding])), $(uppercase(string(r.daycount))))" end Base.show(io::IO, r::InterestRate) = print(io, string(r)) function Base.string(df::DiscountFactor) - ("DF: " * @sprintf("%06f", value(df)) * ", " * string(df.startdate) * - "--" * string(df.enddate)) + "DF: $(@sprintf("%06f", value(df))), $(df.startdate)--$(string(df.enddate))" end Base.show(io::IO, df::DiscountFactor) = print(io, string(df)) diff --git a/src/schedule.jl b/src/schedule.jl index 439183b..28a6b09 100644 --- a/src/schedule.jl +++ b/src/schedule.jl @@ -2,22 +2,22 @@ # Types #### # Stub types -abstract Stub -abstract FrontStub <: Stub -abstract BackStub <: Stub -immutable ShortFrontStub <: FrontStub end -immutable LongFrontStub <: FrontStub end -immutable ShortBackStub <: BackStub end -immutable LongBackStub <: BackStub end +abstract type Stub end +abstract type FrontStub <: Stub end +abstract type BackStub <: Stub end +struct ShortFrontStub <: FrontStub end +struct LongFrontStub <: FrontStub end +struct ShortBackStub <: BackStub end +struct LongBackStub <: BackStub end # Schedules -abstract DateSchedule +abstract type DateSchedule end # Sources: # 1. Opengamma: Interest rate instruments and market conventions guide # 2. Quantlib.org -immutable SwapDateSchedule <: DateSchedule +struct SwapDateSchedule <: DateSchedule dates::Array{TimeType, 1} tenor::Period calendar::FinCalendar diff --git a/src/shifters.jl b/src/shifters.jl index dc12674..c17da6e 100644 --- a/src/shifters.jl +++ b/src/shifters.jl @@ -2,8 +2,7 @@ # 1. Opengamma: Interest rate instruments and market conventions guide # 2. Quantlib.org -function shift(dt::TimeType, p::Period, bdc = Unadjusted(), c = NoFCalendar(), - eom = true) +function shift(dt::TimeType, p::Period, bdc = Unadjusted(), c = NoFCalendar(), eom = true) result = dt # Extract period details n = p.value diff --git a/src/times.jl b/src/times.jl index b0391df..5608bed 100644 --- a/src/times.jl +++ b/src/times.jl @@ -2,18 +2,18 @@ # Type declarations ##### -abstract DayCountFraction +abstract type DayCountFraction end # Sources: # 1. ISDA 2006 definitions # 2. Opengamma: Interest rate instruments and market conventions guide -immutable A365 <: DayCountFraction end -immutable A360 <: DayCountFraction end -immutable ActActISDA <: DayCountFraction end -immutable Thirty360 <: DayCountFraction end -immutable ThirtyE360 <: DayCountFraction end -immutable ThirtyEP360 <: DayCountFraction end +struct A365 <: DayCountFraction end +struct A360 <: DayCountFraction end +struct ActActISDA <: DayCountFraction end +struct Thirty360 <: DayCountFraction end +struct ThirtyE360 <: DayCountFraction end +struct ThirtyEP360 <: DayCountFraction end #### # Day count basis methods diff --git a/test/runtests.jl b/test/runtests.jl index ad4828e..4cd5e37 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,6 @@ using Dates using FinancialMarkets -using Base.Test +using Test include("test_times.jl") include("test_calendars.jl") diff --git a/test/test_times.jl b/test/test_times.jl index 96b959a..86718e4 100644 --- a/test/test_times.jl +++ b/test/test_times.jl @@ -7,47 +7,47 @@ d6 = Date(2014, 3, 31) # A/365 a365 = A365() -@test_approx_eq years(d1, d2, a365) 1.0 -@test_approx_eq years(d2, d1, a365) -1.0 -@test_approx_eq years(d1, d3, a365) 31 / 365 +@test years(d1, d2, a365) ≈ 1.0 +@test years(d2, d1, a365) ≈ -1.0 +@test years(d1, d3, a365) ≈ 31 / 365 # A/360 a360 = A360() -@test_approx_eq years(d1, d2, a360) 365 / 360 -@test_approx_eq years(d2, d1, a360) -365 / 360 -@test_approx_eq years(d1, d3, a360) 31 / 360 +@test years(d1, d2, a360) ≈ 365 / 360 +@test years(d2, d1, a360) ≈ -365 / 360 +@test years(d1, d3, a360) ≈ 31 / 360 # Act/Act actact = ActActISDA() -@test_approx_eq years(d1, d2, actact) 1.0 -@test_approx_eq years(d2, d1, actact) -1.0 -@test_approx_eq years(d4, d1, actact) 31 / 366 + 1 +@test years(d1, d2, actact) ≈ 1.0 +@test years(d2, d1, actact) ≈ -1.0 +@test years(d4, d1, actact) ≈ 31 / 366 + 1 # Thirty360 thirty360 = Thirty360() -@test_approx_eq years(d1, d2, thirty360) 1.0 -@test_approx_eq years(d2, d1, thirty360) -1.0 -@test_approx_eq years(d1, d3, thirty360) 1 / 12 -@test_approx_eq years(d4, d1, thirty360) (2 * 360 - 11 * 30) / 360 -@test_approx_eq years(d1, d5, thirty360) 1 / 12 -@test_approx_eq years(d5, d6, thirty360) 1 / 6 -@test_approx_eq years(d1, d6, thirty360) (2 * 30 + 30) / 360 +@test years(d1, d2, thirty360) ≈ 1.0 +@test years(d2, d1, thirty360) ≈ -1.0 +@test years(d1, d3, thirty360) ≈ 1 / 12 +@test years(d4, d1, thirty360) (2 * 360 - 11 * 30) ≈ / 360 +@test years(d1, d5, thirty360) ≈ 1 / 12 +@test years(d5, d6, thirty360) ≈ 1 / 6 +@test years(d1, d6, thirty360) (2 * 30 + 30) ≈ / 360 # ThirtyE360 thirtyE360 = ThirtyE360() -@test_approx_eq years(d1, d2, thirtyE360) years(d1, d2, thirty360) -@test_approx_eq years(d2, d1, thirtyE360) years(d2, d1, thirty360) -@test_approx_eq years(d1, d3, thirtyE360) years(d1, d3, thirty360) -@test_approx_eq years(d4, d1, thirtyE360) years(d4, d1, thirty360) -@test_approx_eq years(d1, d5, thirtyE360) 29 / 360 -@test_approx_eq years(d5, d6, thirtyE360) years(d5, d6, thirty360) -@test_approx_eq years(d1, d6, thirtyE360) (2 * 30 + 29) / 360 +@test years(d1, d2, thirtyE360) ≈ years(d1, d2, thirty360) +@test years(d2, d1, thirtyE360) ≈ years(d2, d1, thirty360) +@test years(d1, d3, thirtyE360) ≈ years(d1, d3, thirty360) +@test years(d4, d1, thirtyE360) ≈ years(d4, d1, thirty360) +@test years(d1, d5, thirtyE360) ≈ 29 / 360 +@test years(d5, d6, thirtyE360) ≈ years(d5, d6, thirty360) +@test years(d1, d6, thirtyE360) (2 * 30 + 29) ≈ / 360 # ThirtyEP360 thirtyEP360 = ThirtyEP360() -@test_approx_eq years(d1, d2, thirtyEP360) years(d1, d2, thirty360) -@test_approx_eq years(d2, d1, thirtyEP360) years(d2, d1, thirty360) -@test_approx_eq years(d1, d3, thirtyEP360) years(d1, d3, thirty360) -@test_approx_eq years(d1, d5, thirtyEP360) 1 / 12 -@test_approx_eq years(d5, d6, thirtyEP360) (-29 + 3 * 30) / 360 -@test_approx_eq years(d1, d6, thirtyEP360) 3 * 30 / 360 +@test years(d1, d2, thirtyEP360) ≈ years(d1, d2, thirty360) +@test years(d2, d1, thirtyEP360) ≈ years(d2, d1, thirty360) +@test years(d1, d3, thirtyEP360) ≈ years(d1, d3, thirty360) +@test years(d1, d5, thirtyEP360) ≈ 1 / 12 +@test years(d5, d6, thirtyEP360) (-29 + 3 * 30) ≈ / 360 +@test years(d1, d6, thirtyEP360) ≈ 3 * 30 / 360 From 6025a5a2d1970a2b1bf26a24c662f47e3e273517 Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Thu, 31 Jan 2019 23:23:12 -0600 Subject: [PATCH 02/11] continue 1.0 update progress --- src/calendars.jl | 6 +-- src/calendars/epochs.jl | 4 +- src/constants.jl | 4 +- src/interestrates.jl | 85 +++++++++++++++++++++++++------------ src/times.jl | 3 ++ test/test_calendars_ausy.jl | 10 +++-- test/test_times.jl | 8 ++-- 7 files changed, 79 insertions(+), 41 deletions(-) diff --git a/src/calendars.jl b/src/calendars.jl index 414718d..00662b6 100644 --- a/src/calendars.jl +++ b/src/calendars.jl @@ -16,9 +16,9 @@ struct NoFCalendar <: SingleFCalendar end ##### JointFCalendar(c::SingleFCalendar...) = JointFCalendar([ ci for ci in c ], true) -+(c1::SingleFCalendar, c2::SingleFCalendar) = JointFCalendar([c1, c2], true) -*(c1::SingleFCalendar, c2::SingleFCalendar) = JointFCalendar([c1, c2], false) -+(jc::JointFCalendar, c::SingleFCalendar) = JointFCalendar([jc.calendars, c], +Base.:+(c1::SingleFCalendar, c2::SingleFCalendar) = JointFCalendar([c1, c2], true) +Base.:*(c1::SingleFCalendar, c2::SingleFCalendar) = JointFCalendar([c1, c2], false) +Base.:+(jc::JointFCalendar, c::SingleFCalendar) = JointFCalendar([jc.calendars, c], jc.onbad) Base.convert(::Type{JointFCalendar}, c::SingleFCalendar) = JointFCalendar(c) diff --git a/src/calendars/epochs.jl b/src/calendars/epochs.jl index 5dbe8ba..b0de2ef 100644 --- a/src/calendars/epochs.jl +++ b/src/calendars/epochs.jl @@ -51,7 +51,9 @@ function seasonstart(y::Integer, m::Integer) y = (y - 2000) / 1000 k = SEASON[m] jde0 = 0 - for i in 1:length(k) jde0 += y ^ (i - 1) * k[i] end + for i in 1:length(k) + jde0 += (y ^ (i - 1) * k[i])[1] + end # Calculate corrections tt = (jde0 - 2451545) / 36525 w = 35999.373tt - 2.47 diff --git a/src/constants.jl b/src/constants.jl index a7c2cd8..3df2472 100644 --- a/src/constants.jl +++ b/src/constants.jl @@ -10,8 +10,8 @@ const SEASON_MAR = [2451623.80984, 365242.37404, 0.05169, -0.00411, -0.00057] const SEASON_JUN = [2451716.56767, 365241.62603, 0.00325, 0.00888, -0.00030] const SEASON_SEP = [2451810.21715, 365242.01767, -0.11575, 0.00337, 0.00078] const SEASON_DEC = [2451900.05952, 365242.74049, 0.06223, 0.00823, 0.00032] -const SEASON = [Mar => SEASON_MAR, Jun => SEASON_JUN, Sep => SEASON_SEP, - Dec => SEASON_DEC] +const SEASON = Dict(Mar => SEASON_MAR, Jun => SEASON_JUN, Sep => SEASON_SEP, + Dec => SEASON_DEC) const SEASON_A = [485, 203, 199, 182, 156, 136, 77, 74, 70, 58, 52, 50, 45, 44, 29, 18, 17, 16, 14, 12, 12, 12, 9, 8] const SEASON_B = [324.96, 337.23, 342.08, 27.85, 73.14, 171.52, 222.54, 296.72, diff --git a/src/interestrates.jl b/src/interestrates.jl index 4481a95..4821da3 100644 --- a/src/interestrates.jl +++ b/src/interestrates.jl @@ -1,4 +1,5 @@ using Printf + #### # Types #### @@ -114,33 +115,63 @@ function equivalent(to::InterestRate, x::InterestRate) end # arithmetic operations -for op in (:+, :*, :-, :/) - @eval begin - function ($op)(x::InterestRate, y::Real) - InterestRate(($op)(value(x), y), x.compounding, x.daycount) - end - end - @eval begin - function ($op)(x::InterestRate, y::InterestRate) - InterestRate(($op)(value(x), value(equivalent(x, y))), - x.compounding, x.daycount) - end - end +# for op in (Base.:+, Base.:*, Base.:-, Base.:/) +# @eval begin +# function $op(x::InterestRate, y::Real) +# InterestRate($op(value(x), y), x.compounding, x.daycount) +# end +# end +# @eval begin +# function $op(x::InterestRate, y::InterestRate) +# InterestRate($op(value(x), value(equivalent(x, y))), +# x.compounding, x.daycount) +# end +# end +# end +function Base.:+(x::InterestRate, y::Real) + InterestRate(Base.:+(value(x), y), x.compounding, x.daycount) +end +function Base.:+(x::InterestRate, y::InterestRate) + InterestRate(Base.:+(value(x), value(equivalent(x, y))), + x.compounding, x.daycount) +end +function Base.:-(x::InterestRate, y::Real) + InterestRate(Base.:-(value(x), y), x.compounding, x.daycount) +end +function Base.:-(x::InterestRate, y::InterestRate) + InterestRate(Base.:-(value(x), value(equivalent(x, y))), + x.compounding, x.daycount) +end +function Base.:*(x::InterestRate, y::Real) + InterestRate(Base.:*(value(x), y), x.compounding, x.daycount) end -(+)(x::Real, y::InterestRate) = y + x -(*)(x::Real, y::InterestRate) = y * x -(-)(x::Real, y::InterestRate) = -1(y - x) -(/)(x::Real, y::InterestRate) = InterestRate(x / value(y), y.compounding, +function Base.:*(x::InterestRate, y::InterestRate) + InterestRate(Base.:*(value(x), value(equivalent(x, y))), + x.compounding, x.daycount) +end +function Base.:/(x::InterestRate, y::Real) + InterestRate(Base.:/(value(x), y), x.compounding, x.daycount) +end +function Base.:/(x::InterestRate, y::InterestRate) + InterestRate(Base.:/(value(x), value(equivalent(x, y))), + x.compounding, x.daycount) +end + + +Base.:+(x::Real, y::InterestRate) = y + x +Base.:*(x::Real, y::InterestRate) = y * x +Base.:-(x::Real, y::InterestRate) = -1(y - x) +Base.:/(x::Real, y::InterestRate) = InterestRate(x / value(y), y.compounding, y.daycount) -function (*)(x::DiscountFactor, y::DiscountFactor) +function Base.:*(x::DiscountFactor, y::DiscountFactor) msg = "The discount factors must represent two cotinguous spans of time." (x.enddate == y.enddate || y.startdate == x.enddate) || throw( ArgumentError(msg)) DiscountFactor(value(x) * value(y), min(x.startdate, y.startdate), max(x.enddate, y.enddate)) end -function (/)(x::DiscountFactor, y::DiscountFactor) +function Base.:/(x::DiscountFactor, y::DiscountFactor) msg = "The discount factors must start at the same instant." (x.startdate == y.startdate) || throw(ArgumentError(msg)) DiscountFactor(value(x) / value(y), min(x.enddate, y.enddate), @@ -148,12 +179,12 @@ function (/)(x::DiscountFactor, y::DiscountFactor) end # comparison operations -for op in (:(==), :!=, :<, :<=, :>, :>=) - @eval begin - function ($op)(x::InterestRate, y::InterestRate) - return ($op)(value(x), value(equivalent(x, y))) - end - (($op)(x::DiscountFactor, y::DiscountFactor) = - ($op)(value(x), value(y))) - end -end +# for op in (:(==), :!=, :<, :<=, :>, :>=) +# @eval begin +# function $op(x::InterestRate, y::InterestRate) +# return $op(value(x), value(equivalent(x, y))) +# end +# $op(x::DiscountFactor, y::DiscountFactor) = +# $op(value(x), value(y)) +# end +# end diff --git a/src/times.jl b/src/times.jl index 5608bed..c3497b8 100644 --- a/src/times.jl +++ b/src/times.jl @@ -1,3 +1,5 @@ +using Dates +import Base: (==), +, - ##### # Type declarations ##### @@ -35,6 +37,7 @@ end function years(date1::TimeType, date2::TimeType, dc::ActActISDA) date1 == date2 && return 0 y1 = year(date1); y2 = year(date2) + @show diy1 = daysinyear(year(date1)); diy2 = daysinyear(year(date2)) bony1 = Date(y1 + 1, 1, 1) boy2 = Date(y2, 1, 1) diff --git a/test/test_calendars_ausy.jl b/test/test_calendars_ausy.jl index 4fd32f5..1607903 100644 --- a/test/test_calendars_ausy.jl +++ b/test/test_calendars_ausy.jl @@ -8,14 +8,16 @@ Date(2014, 12, 26), Date(2016, 1, 1), Date(2016, 1, 26), Date(2016, 3, 25), Date(2016, 3, 26), Date(2016, 3, 27), Date(2016, 3, 28), Date(2016, 4, 25), Date(2016, 6, 13), Date(2016, 8, 1), Date(2016, 10, 3), Date(2016, 12, 25), Date(2016, 12, 27), Date(2016, 12, 26)] -dt = Date(2014) -while year(dt) == 2014 + +for day in 0:364 + dt = Date(2014,1,1) + Dates.Day(day) @test !((dt in ausyholidays || isweekend(dt)) $ !isgood(dt, AUSYFCalendar())) dt += Day(1) end -dt = Date(2016) -while year(dt) == 2016 + +for day in 0:364 + dt = Date(2016,1,1) + day @test !((dt in ausyholidays || isweekend(dt)) $ !isgood(dt, AUSYFCalendar())) dt += Day(1) diff --git a/test/test_times.jl b/test/test_times.jl index 86718e4..71ccf19 100644 --- a/test/test_times.jl +++ b/test/test_times.jl @@ -28,10 +28,10 @@ thirty360 = Thirty360() @test years(d1, d2, thirty360) ≈ 1.0 @test years(d2, d1, thirty360) ≈ -1.0 @test years(d1, d3, thirty360) ≈ 1 / 12 -@test years(d4, d1, thirty360) (2 * 360 - 11 * 30) ≈ / 360 +@test years(d4, d1, thirty360) ≈ (2 * 360 - 11 * 30) / 360 @test years(d1, d5, thirty360) ≈ 1 / 12 @test years(d5, d6, thirty360) ≈ 1 / 6 -@test years(d1, d6, thirty360) (2 * 30 + 30) ≈ / 360 +@test years(d1, d6, thirty360) ≈ (2 * 30 + 30) / 360 # ThirtyE360 thirtyE360 = ThirtyE360() @@ -41,7 +41,7 @@ thirtyE360 = ThirtyE360() @test years(d4, d1, thirtyE360) ≈ years(d4, d1, thirty360) @test years(d1, d5, thirtyE360) ≈ 29 / 360 @test years(d5, d6, thirtyE360) ≈ years(d5, d6, thirty360) -@test years(d1, d6, thirtyE360) (2 * 30 + 29) ≈ / 360 +@test years(d1, d6, thirtyE360) ≈ (2 * 30 + 29) / 360 # ThirtyEP360 thirtyEP360 = ThirtyEP360() @@ -49,5 +49,5 @@ thirtyEP360 = ThirtyEP360() @test years(d2, d1, thirtyEP360) ≈ years(d2, d1, thirty360) @test years(d1, d3, thirtyEP360) ≈ years(d1, d3, thirty360) @test years(d1, d5, thirtyEP360) ≈ 1 / 12 -@test years(d5, d6, thirtyEP360) (-29 + 3 * 30) ≈ / 360 +@test years(d5, d6, thirtyEP360) ≈ (-29 + 3 * 30) / 360 @test years(d1, d6, thirtyEP360) ≈ 3 * 30 / 360 From 49d6b847f38be59a9e201f929d9d40aefb5f259b Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 2 Feb 2019 10:29:11 -0600 Subject: [PATCH 03/11] update calendar tests for 1.0 --- test/test_calendars_aume.jl | 10 ++++------ test/test_calendars_ausy.jl | 17 +++++------------ test/test_calendars_euta.jl | 10 ++++------ test/test_calendars_gb.jl | 10 ++++------ test/test_calendars_jp.jl | 10 ++++------ test/test_calendars_nzau.jl | 10 ++++------ test/test_calendars_us.jl | 8 +++----- 7 files changed, 28 insertions(+), 47 deletions(-) diff --git a/test/test_calendars_aume.jl b/test/test_calendars_aume.jl index a078ee4..7aebb23 100644 --- a/test/test_calendars_aume.jl +++ b/test/test_calendars_aume.jl @@ -7,9 +7,7 @@ Date(2014, 6, 9), Date(2014, 11, 4), Date(2014, 12, 25), Date(2014, 12, 26), Date(2015, 1, 1), Date(2015, 1, 26), Date(2015, 3, 9), Date(2015, 4, 3), Date(2015, 4, 4), Date(2015, 4, 6), Date(2015, 4, 25), Date(2015, 6, 8), Date(2015, 11, 3), Date(2015, 12, 25), Date(2015, 12, 26), Date(2015, 12, 28)] -dt = Date(2014) -while year(dt) <= 2015 - @test !((dt in aumeholidays || isweekend(dt)) $ - !isgood(dt, AUMEFCalendar())) - dt += Day(1) -end + +for dt in Date(2015,1,1):Dates.Day(1):Date(2015,12,31) + @test !((dt in aumeholidays || isweekend(dt)) ⊻ !isgood(dt, AUMEFCalendar())) +end \ No newline at end of file diff --git a/test/test_calendars_ausy.jl b/test/test_calendars_ausy.jl index 1607903..6eead84 100644 --- a/test/test_calendars_ausy.jl +++ b/test/test_calendars_ausy.jl @@ -9,17 +9,10 @@ Date(2016, 3, 26), Date(2016, 3, 27), Date(2016, 3, 28), Date(2016, 4, 25), Date(2016, 6, 13), Date(2016, 8, 1), Date(2016, 10, 3), Date(2016, 12, 25), Date(2016, 12, 27), Date(2016, 12, 26)] -for day in 0:364 - dt = Date(2014,1,1) + Dates.Day(day) - @test !((dt in ausyholidays || isweekend(dt)) $ - !isgood(dt, AUSYFCalendar())) - dt += Day(1) -end - -for day in 0:364 - dt = Date(2016,1,1) + day - @test !((dt in ausyholidays || isweekend(dt)) $ - !isgood(dt, AUSYFCalendar())) - dt += Day(1) +for dt in Date(2014,1,1):Dates.Day(1):Date(2014,12,31) + @test !((dt in ausyholidays || isweekend(dt)) ⊻ !isgood(dt, AUSYFCalendar())) end +for dt in Date(2016,1,1):Dates.Day(1):Date(2016,12,31) + @test !((dt in ausyholidays || isweekend(dt)) ⊻ !isgood(dt, AUSYFCalendar())) +end \ No newline at end of file diff --git a/test/test_calendars_euta.jl b/test/test_calendars_euta.jl index c7c167d..60c788f 100644 --- a/test/test_calendars_euta.jl +++ b/test/test_calendars_euta.jl @@ -4,9 +4,7 @@ # https://web.archive.org/web/20130511041319/http://www.bundesbank.de/Redaktion/EN/Downloads/Press/Publications/ecb_holidays_2013.pdf?__blob=publicationFile targetholidays = [Date(2013, 1, 1), Date(2013, 3, 29), Date(2013, 4, 1), Date(2013, 5, 1), Date(2013, 12, 25), Date(2013, 12, 26)] - dt = Date(2013) - while year(dt) <= 2013 - @test !((dt in targetholidays || isweekend(dt)) $ - !isgood(dt, EUTAFCalendar())) - dt += Day(1) -end + +for dt in Date(2013,1,1):Dates.Day(1):Date(2013,12,31) + @test !((dt in targetholidays || isweekend(dt)) ⊻ !isgood(dt, EUTAFCalendar())) +end \ No newline at end of file diff --git a/test/test_calendars_gb.jl b/test/test_calendars_gb.jl index 5c1fa86..2c7d77d 100644 --- a/test/test_calendars_gb.jl +++ b/test/test_calendars_gb.jl @@ -8,9 +8,7 @@ gbholidays = [Date(2012, 1, 1), Date(2012, 1, 2), Date(2012, 4, 6), Date(2013, 1, 1), Date(2013, 3, 29), Date(2013, 4, 1), Date(2013, 5, 6), Date(2013, 5, 27), Date(2013, 8, 26), Date(2013, 12, 25), Date(2013, 12, 26)] - dt = Date(2012) - while year(dt) <= 2013 - @test !((dt in gbholidays || isweekend(dt)) $ - !isgood(dt, GBLOFCalendar())) - dt += Day(1) -end + +for dt in Date(2012,1,1):Dates.Day(1):Date(2013,12,31) + @test !((dt in gbholidays || isweekend(dt)) ⊻ !isgood(dt, GBLOFCalendar())) +end \ No newline at end of file diff --git a/test/test_calendars_jp.jl b/test/test_calendars_jp.jl index c43fff3..5e5536d 100644 --- a/test/test_calendars_jp.jl +++ b/test/test_calendars_jp.jl @@ -15,9 +15,7 @@ jpholidays = [Date(2014, 1, 1), Date(2014, 1, 2), Date(2014, 1, 3), Date(2013, 9, 16), Date(2013, 9, 23), Date(2013, 10, 14), Date(2013, 11, 3), Date(2013, 11, 4), Date(2013, 11, 23), Date(2013, 12, 23), Date(2013, 12, 31)] -dt = Date(2013) -while year(dt) <= 2014 - @test !((dt in jpholidays || isweekend(dt)) $ - !isgood(dt, JPTOFCalendar())) - dt += Day(1) -end + +for dt in Date(2013,1,1):Dates.Day(1):Date(2014,12,31) + @test !((dt in jpholidays || isweekend(dt)) ⊻ !isgood(dt, JPTOFCalendar())) +end \ No newline at end of file diff --git a/test/test_calendars_nzau.jl b/test/test_calendars_nzau.jl index f75b1f8..0dda310 100644 --- a/test/test_calendars_nzau.jl +++ b/test/test_calendars_nzau.jl @@ -6,9 +6,7 @@ nzauholidays = [Date(2014, 1, 1), Date(2014, 1, 2), Date(2014, 1, 27), Date(2015, 1, 1), Date(2015, 1, 2), Date(2015, 1, 26), Date(2015, 2, 6), Date(2015, 4, 3), Date(2015, 4, 6), Date(2015, 4, 27), Date(2015, 6, 1), Date(2015, 10, 26), Date(2015, 12, 25), Date(2015, 12, 28)] -dt = Date(2014) -while year(dt) <= 2015 - !((dt in nzauholidays || isweekend(dt)) $ - !isgood(dt, NZAUFCalendar())) - dt += Day(1) -end + +for dt in Date(2014,1,1):Dates.Day(1):Date(2015,12,31) + @test !((dt in nzauholidays || isweekend(dt)) ⊻ !isgood(dt, NZAUFCalendar())) +end \ No newline at end of file diff --git a/test/test_calendars_us.jl b/test/test_calendars_us.jl index bdb92e6..8477203 100644 --- a/test/test_calendars_us.jl +++ b/test/test_calendars_us.jl @@ -9,9 +9,7 @@ usholidays = [Date(2012, 1, 1), Date(2012, 1, 2), Date(2012, 1, 16), Date(2013, 5, 27), Date(2013, 7, 4), Date(2013, 9, 2), Date(2013, 10, 14), Date(2013, 11, 11), Date(2013, 11, 28), Date(2013, 12, 25)] -dt = Date(2012) -while year(dt) <= 2013 - @test !((dt in usholidays || isweekend(dt)) $ - !isgood(dt, USNYFCalendar())) - dt += Day(1) + + for dt in Date(2012,1,1):Dates.Day(1):Date(2013,12,31) + @test !((dt in usholidays || isweekend(dt)) ⊻ !isgood(dt, USNYFCalendar())) end From 9e7ad516966f16066d0f32062414d5967b149394 Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 2 Feb 2019 10:54:01 -0600 Subject: [PATCH 04/11] update interest rate tests for 1.0 --- src/constants.jl | 4 ++-- test/test_interestrates.jl | 28 +++++++++++++++------------- 2 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/constants.jl b/src/constants.jl index 3df2472..8a8bcb3 100644 --- a/src/constants.jl +++ b/src/constants.jl @@ -26,7 +26,7 @@ const SEASON_C = [1934.136, 32964.467, 20.186, 445267.112, 45036.886, 22518.443, (const Simply, Annually, SemiAnnually, TriAnnually, Quarterly, BiMonthly, Monthly, Fortnightly, Weekly, Daily, Continuously = 0, 1, 2, 3, 4, 6, 12, 24, 52, 365, 1000) -const COMPOUNDINGS = [0 => "simply", 1 => "annually", 2 => "semi-annually", +const COMPOUNDINGS = Dict(0 => "simply", 1 => "annually", 2 => "semi-annually", 3 => "tri-annually", 4 => "quarterly", 6 => "bi-monthly", 12 => "monthly", - 24 => "fornightly", 52 => "weekly", 365 => "daily", 1000 => "continuously"] + 24 => "fornightly", 52 => "weekly", 365 => "daily", 1000 => "continuously") diff --git a/test/test_interestrates.jl b/test/test_interestrates.jl index 5470c3b..7b5e9c2 100644 --- a/test/test_interestrates.jl +++ b/test/test_interestrates.jl @@ -6,16 +6,18 @@ r = InterestRate(0.04, Simply, a365) df = DiscountFactor(1 / (1 + 0.04 * years(d1, d2, a365)), d1, d2) # Test conversion between DF & IR & vice-versa -@test_approx_eq convert(DiscountFactor, r, d1, d2).discountfactor df.discountfactor -@test_approx_eq convert(InterestRate, df, Simply, a365).rate r.rate -r.compounding = Quarterly -df.discountfactor = (1 + 0.04 / 4) ^ (-4 * years(d1, d2, a365)) -@test_approx_eq convert(DiscountFactor, r, d1, d2).discountfactor df.discountfactor -@test_approx_eq convert(InterestRate, df, Quarterly, a365).rate r.rate -r.compounding = Continuously -df.discountfactor = exp(-0.04years(d1, d2, a365)) -@test_approx_eq convert(DiscountFactor, r, d1, d2).discountfactor df.discountfactor -@test_approx_eq convert(InterestRate, df, Continuously, a365).rate r.rate +@test convert(DiscountFactor, r, d1, d2).discountfactor ≈ df.discountfactor +@test convert(InterestRate, df, Simply, a365).rate ≈ r.rate + +r = InterestRate(0.04, Quarterly, a365) +df = DiscountFactor((1 + 0.04 / 4) ^ (-4 * years(d1, d2, a365)), d1, d2) +@test convert(DiscountFactor, r, d1, d2).discountfactor ≈ df.discountfactor +@test convert(InterestRate, df, Quarterly, a365).rate ≈ r.rate + +r = InterestRate(0.04, Continuously, a365) +df = DiscountFactor(exp(-0.04years(d1, d2, a365)), d1, d2) +@test convert(DiscountFactor, r, d1, d2).discountfactor ≈ df.discountfactor +@test convert(InterestRate, df, Continuously, a365).rate ≈ r.rate # Test conversion between rates d1 = Date(2013,1,1) @@ -26,6 +28,6 @@ r2 = convert(InterestRate, convert(DiscountFactor, r, d1, d2), SemiAnnually, r.daycount) r3 = convert(InterestRate, convert(DiscountFactor, r, d1, d2), SemiAnnually, thirty360) -@test_approx_eq convert(InterestRate, r, thirty360).rate r1.rate -@test_approx_eq convert(InterestRate, r, SemiAnnually).rate r2.rate -@test_approx_eq convert(InterestRate, r, SemiAnnually, thirty360).rate r3.rate +@test convert(InterestRate, r, thirty360).rate ≈ r1.rate +@test convert(InterestRate, r, SemiAnnually).rate ≈ r2.rate +@test convert(InterestRate, r, SemiAnnually, thirty360).rate ≈ r3.rate From 6508775b784bb30f0bc52df8f08f255c63f1706b Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 2 Feb 2019 10:54:10 -0600 Subject: [PATCH 05/11] update business day conventions for 1.0 --- src/businessdayconventions.jl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/businessdayconventions.jl b/src/businessdayconventions.jl index 1aa4dc0..2fce34f 100644 --- a/src/businessdayconventions.jl +++ b/src/businessdayconventions.jl @@ -1,3 +1,4 @@ +import Dates: adjust ##### # Types ##### @@ -20,30 +21,30 @@ struct Succeeding <: BusinessDayConvention end # Methods ##### -adjust(dt::TimeType, bdc::Unadjusted, c::FinCalendar = NoFCalendar()) = dt -function adjust(dt::TimeType, bdc::Preceding, c::FinCalendar = NoFCalendar()) +Dates.adjust(dt::TimeType, bdc::Unadjusted, c::FinCalendar = NoFCalendar()) = dt +function Dates.adjust(dt::TimeType, bdc::Preceding, c::FinCalendar = NoFCalendar()) while !isgood(dt, c) dt -= Day(1) end return dt end -function adjust(dt::TimeType, bdc::Following, c::FinCalendar = NoFCalendar()) +function Dates.adjust(dt::TimeType, bdc::Following, c::FinCalendar = NoFCalendar()) while !isgood(dt, c) dt += Day(1) end return dt end -function adjust(dt::TimeType, bdc::ModifiedPreceding, +function Dates.adjust(dt::TimeType, bdc::ModifiedPreceding, c::FinCalendar = NoFCalendar()) pre_dt = adjust(dt, Preceding(), c) month(dt) != month(pre_dt) ? adjust(dt, Following(), c) : pre_dt end -function adjust(dt::TimeType, bdc::ModifiedFollowing, +function Dates.adjust(dt::TimeType, bdc::ModifiedFollowing, c::FinCalendar = NoFCalendar()) follow_dt = adjust(dt, Following(), c) month(dt) != month(follow_dt) ? adjust(dt, Preceding(), c) : follow_dt end -function adjust(dt::TimeType, bdc::Succeeding, c::FinCalendar = NoFCalendar()) +function Dates.adjust(dt::TimeType, bdc::Succeeding, c::FinCalendar = NoFCalendar()) follow_dt = adjust(dt, Following(), c) is_barrier_crossed = (month(follow_dt) != month(dt) || day(dt) ≤ 15 && day(follow_dt) > 15) From 783049fa4d57f42cd524daf86334c5ea301aca61 Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 2 Feb 2019 10:57:34 -0600 Subject: [PATCH 06/11] update currencies for 1.0 --- src/currencies.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/currencies.jl b/src/currencies.jl index ed7faea..adb8451 100644 --- a/src/currencies.jl +++ b/src/currencies.jl @@ -52,8 +52,8 @@ USD() = USD(USNYFCalendar()) # Source: # 2. Opengamma: Interest rate instruments and market conventions guide -const CCY_STRENGTH = [EUR => 1, GBP => 2, AUD => 3, NZD => 4, USD => 5, - JPY => 6] +const CCY_STRENGTH = Dict(EUR => 1, GBP => 2, AUD => 3, NZD => 4, USD => 5, + JPY => 6) Base.isless(x::Currency, y::Currency) = (CCY_STRENGTH[typeof(x)] > CCY_STRENGTH[typeof(y)]) From 3f0cdfb241b07f8025999c7cde91f7e374f52d78 Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 2 Feb 2019 10:58:17 -0600 Subject: [PATCH 07/11] update cash for 1.0 --- test/test_cash.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_cash.jl b/test/test_cash.jl index e1be7f2..66f28f2 100644 --- a/test/test_cash.jl +++ b/test/test_cash.jl @@ -6,4 +6,4 @@ cfs = CashFlow(audcash) @test price(audcash) == 1e6 @test cfs.currency == [AUD(), AUD()] @test cfs.date == [Date(2014, 9, 26), Date(2014, 9, 29)] -@test_approx_eq cfs.amount 1e6 * [-1.0, 1.0 + 0.04 * 3.0 / 365.0] +@test cfs.amount ≈ 1e6 * [-1.0, 1.0 + 0.04 * 3.0 / 365.0] From 377da9783f90d1326d8659259d63ed0bdd4120df Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 2 Feb 2019 10:58:56 -0600 Subject: [PATCH 08/11] update deposit for 1.0 --- test/test_deposit.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_deposit.jl b/test/test_deposit.jl index 845cf74..da1d9bc 100644 --- a/test/test_deposit.jl +++ b/test/test_deposit.jl @@ -7,4 +7,4 @@ tau = years(depo.startdate, depo.enddate, depo.index.daycount) @test price(depo) == 1e6 / (1 + 0.04 * tau) @test cfs.currency == [USD(), USD()] @test cfs.date == [Date(2014, 9, 30), Date(2014, 12, 31)] -@test_approx_eq cfs.amount [-price(depo), 1] +@test cfs.amount ≈ [-price(depo), 1] From c518bdd82ac520aaac175f2756429ff08e073ef2 Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 2 Feb 2019 11:00:57 -0600 Subject: [PATCH 09/11] update futures for 1.0 --- src/instruments/futures.jl | 12 ++++++------ test/test_futures.jl | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/instruments/futures.jl b/src/instruments/futures.jl index 2a1fcc5..fc5dab7 100644 --- a/src/instruments/futures.jl +++ b/src/instruments/futures.jl @@ -14,12 +14,12 @@ end # Methods #### -stirsettlementparameters(ccy::AUD) = ["nth" => 2, "day" => Fri, "off" => Day(0)] -stirsettlementparameters(ccy::EUR) = ["nth" => 3, "day" => Wed, "off" => Day(0)] -stirsettlementparameters(ccy::GBP) = ["nth" => 3, "day" => Wed, "off" => Day(0)] -stirsettlementparameters(ccy::JPY) = ["nth" => 3, "day" => Wed, "off" => Day(0)] -stirsettlementparameters(ccy::NZD) = ["nth" => 1, "day" => Wed, "off" => Day(8)] -stirsettlementparameters(ccy::USD) = ["nth" => 3, "day" => Wed, "off" => Day(0)] +stirsettlementparameters(ccy::AUD) = Dict("nth" => 2, "day" => Fri, "off" => Day(0)) +stirsettlementparameters(ccy::EUR) = Dict("nth" => 3, "day" => Wed, "off" => Day(0)) +stirsettlementparameters(ccy::GBP) = Dict("nth" => 3, "day" => Wed, "off" => Day(0)) +stirsettlementparameters(ccy::JPY) = Dict("nth" => 3, "day" => Wed, "off" => Day(0)) +stirsettlementparameters(ccy::NZD) = Dict("nth" => 1, "day" => Wed, "off" => Day(8)) +stirsettlementparameters(ccy::USD) = Dict("nth" => 3, "day" => Wed, "off" => Day(0)) function to_nth_dayofweek(dt::TimeType, n::Integer, dow::Integer) dt + Day(7 * (n - 1) + mod(dow - dayofweek(dt), 7)) diff --git a/test/test_futures.jl b/test/test_futures.jl index 1024890..b30b5db 100644 --- a/test/test_futures.jl +++ b/test/test_futures.jl @@ -14,4 +14,4 @@ tau = years(stir.underlying.startdate, stir.underlying.enddate, @test price(stir) == 1e6 / (1 + 0.04 * tau) @test cfs.currency == [EUR(), EUR()] @test cfs.date == [Date(2014, 12, 17), Date(2015, 3, 17)] -@test_approx_eq cfs.amount 1 * [-price(stir), 1e6] +@test cfs.amount ≈ 1 * [-price(stir), 1e6] From 132fa3f4e2ad6126a9bcdb950c2f7945b38dd884 Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 2 Feb 2019 11:54:02 -0600 Subject: [PATCH 10/11] update interest rate operator definitions --- src/interestrates.jl | 69 +++++++++++--------------------------- test/test_interestrates.jl | 7 ++++ 2 files changed, 26 insertions(+), 50 deletions(-) diff --git a/src/interestrates.jl b/src/interestrates.jl index 4821da3..5be09cf 100644 --- a/src/interestrates.jl +++ b/src/interestrates.jl @@ -115,49 +115,19 @@ function equivalent(to::InterestRate, x::InterestRate) end # arithmetic operations -# for op in (Base.:+, Base.:*, Base.:-, Base.:/) -# @eval begin -# function $op(x::InterestRate, y::Real) -# InterestRate($op(value(x), y), x.compounding, x.daycount) -# end -# end -# @eval begin -# function $op(x::InterestRate, y::InterestRate) -# InterestRate($op(value(x), value(equivalent(x, y))), -# x.compounding, x.daycount) -# end -# end -# end -function Base.:+(x::InterestRate, y::Real) - InterestRate(Base.:+(value(x), y), x.compounding, x.daycount) -end -function Base.:+(x::InterestRate, y::InterestRate) - InterestRate(Base.:+(value(x), value(equivalent(x, y))), - x.compounding, x.daycount) -end -function Base.:-(x::InterestRate, y::Real) - InterestRate(Base.:-(value(x), y), x.compounding, x.daycount) -end -function Base.:-(x::InterestRate, y::InterestRate) - InterestRate(Base.:-(value(x), value(equivalent(x, y))), - x.compounding, x.daycount) -end -function Base.:*(x::InterestRate, y::Real) - InterestRate(Base.:*(value(x), y), x.compounding, x.daycount) -end -function Base.:*(x::InterestRate, y::InterestRate) - InterestRate(Base.:*(value(x), value(equivalent(x, y))), - x.compounding, x.daycount) -end -function Base.:/(x::InterestRate, y::Real) - InterestRate(Base.:/(value(x), y), x.compounding, x.daycount) -end -function Base.:/(x::InterestRate, y::InterestRate) - InterestRate(Base.:/(value(x), value(equivalent(x, y))), - x.compounding, x.daycount) +for op in (:+, :*, :-, :/) + @eval begin + function Base.$op(x::InterestRate, y::Real) + InterestRate(Base.$op(value(x), y), x.compounding, x.daycount) + end + end + @eval begin + function Base.$op(x::InterestRate, y::InterestRate) + InterestRate(Base.$op(value(x), value(equivalent(x, y))), x.compounding, x.daycount) + end + end end - Base.:+(x::Real, y::InterestRate) = y + x Base.:*(x::Real, y::InterestRate) = y * x Base.:-(x::Real, y::InterestRate) = -1(y - x) @@ -179,12 +149,11 @@ function Base.:/(x::DiscountFactor, y::DiscountFactor) end # comparison operations -# for op in (:(==), :!=, :<, :<=, :>, :>=) -# @eval begin -# function $op(x::InterestRate, y::InterestRate) -# return $op(value(x), value(equivalent(x, y))) -# end -# $op(x::DiscountFactor, y::DiscountFactor) = -# $op(value(x), value(y)) -# end -# end +for op in (:(==), :!=, :<, :<=, :>, :>=) + @eval begin + function Base.$op(x::InterestRate, y::InterestRate) + return Base.$op(value(x), value(equivalent(x, y))) + end + Base.$op(x::DiscountFactor, y::DiscountFactor) = Base.$op(value(x), value(y)) + end +end diff --git a/test/test_interestrates.jl b/test/test_interestrates.jl index 7b5e9c2..8ad5175 100644 --- a/test/test_interestrates.jl +++ b/test/test_interestrates.jl @@ -31,3 +31,10 @@ r3 = convert(InterestRate, convert(DiscountFactor, r, d1, d2), SemiAnnually, @test convert(InterestRate, r, thirty360).rate ≈ r1.rate @test convert(InterestRate, r, SemiAnnually).rate ≈ r2.rate @test convert(InterestRate, r, SemiAnnually, thirty360).rate ≈ r3.rate + + +@test InterestRate(0.04, Simply, a365) < InterestRate(0.05, Simply, a365) +@test InterestRate(0.05, Simply, a365) > InterestRate(0.04, Simply, a365) +@test InterestRate(0.05, Simply, a365) == InterestRate(0.05, Simply, a365) +@test InterestRate(0.05, Simply, a365) >= InterestRate(0.05, Simply, a365) +@test InterestRate(0.05, Simply, a365) <= InterestRate(0.05, Simply, a365) \ No newline at end of file From 7ea9948d592c79ae41058f2846d5f24cf7032a1d Mon Sep 17 00:00:00 2001 From: Alec Loudenback Date: Sat, 2 Feb 2019 12:11:05 -0600 Subject: [PATCH 11/11] update readme --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index e021c3f..77408be 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,13 @@ For example: ```julia # Load packages -using Dates, FinancialMarkets -# Create US Dollar object -USD = USD() + using Dates, FinancialMarkets + # Create 3m USD LIBOR -depo = Deposit(USD, Month(3), 0.05) -# Price depo at trade date -price(depo) +depo = Deposit(USD(), Month(3), 0.05) + +# Price depo at trade date with default par of 1e6 +price(depo) # returns 987518.8588670965 ``` ## Features