diff --git a/Cargo.lock b/Cargo.lock index 44b16bc..86421cd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,17 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "ahash" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" +dependencies = [ + "getrandom", + "once_cell", + "version_check", +] + [[package]] name = "android-tzdata" version = "0.1.1" @@ -17,18 +28,103 @@ dependencies = [ "libc", ] +[[package]] +name = "approx" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + [[package]] name = "autocfg" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "borsh" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6362ed55def622cddc70a4746a68554d7b687713770de539e59a739b249f8ed" +dependencies = [ + "borsh-derive", + "cfg_aliases", +] + +[[package]] +name = "borsh-derive" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ef8005764f53cd4dca619f5bf64cafd4664dada50ece25e4d81de54c80cc0b" +dependencies = [ + "once_cell", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.60", + "syn_derive", +] + [[package]] name = "bumpalo" version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" +[[package]] +name = "bytecheck" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" +dependencies = [ + "bytecheck_derive", + "ptr_meta", + "simdutf8", +] + +[[package]] +name = "bytecheck_derive" +version = "0.6.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "bytemuck" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78834c15cb5d5efe3452d58b1e8ba890dd62d21907f867f383358198e56ebca5" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + [[package]] name = "calendar" version = "0.1.0" @@ -48,6 +144,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + [[package]] name = "chrono" version = "0.4.38" @@ -68,6 +170,44 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash", +] + +[[package]] +name = "hashbrown" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" + [[package]] name = "iana-time-zone" version = "0.1.60" @@ -91,6 +231,22 @@ dependencies = [ "cc", ] +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.5", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + [[package]] name = "js-sys" version = "0.3.69" @@ -112,6 +268,77 @@ version = "0.4.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" +[[package]] +name = "matrixmultiply" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7574c1cf36da4798ab73da5b215bbf444f50718207754cb522201d78d1cd0ff2" +dependencies = [ + "autocfg", + "rawpointer", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "nalgebra" +version = "0.32.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ea4908d4f23254adda3daa60ffef0f1ac7b8c3e9a864cf3cc154b251908a2ef" +dependencies = [ + "approx", + "matrixmultiply", + "nalgebra-macros", + "num-complex", + "num-rational", + "num-traits", + "simba", + "typenum", +] + +[[package]] +name = "nalgebra-macros" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91761aed67d03ad966ef783ae962ef9bbaca728d2dd7ceb7939ec110fffad998" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -127,6 +354,50 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.81" @@ -136,6 +407,26 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "ptr_meta" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0738ccf7ea06b608c10564b31debd4f5bc5e197fc8bfe088f68ae5ce81e7a4f1" +dependencies = [ + "ptr_meta_derive", +] + +[[package]] +name = "ptr_meta_derive" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16b845dbfca988fa33db069c0e230574d15a3088f147a87b64c7589eb662c9ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "qlab" version = "0.1.0" @@ -172,6 +463,7 @@ version = "0.1.0" dependencies = [ "num-traits", "qlab-error", + "spline-interpolation", ] [[package]] @@ -203,6 +495,194 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rawpointer" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3" + +[[package]] +name = "rend" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" +dependencies = [ + "bytecheck", +] + +[[package]] +name = "rkyv" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" +dependencies = [ + "bitvec", + "bytecheck", + "bytes", + "hashbrown 0.12.3", + "ptr_meta", + "rend", + "rkyv_derive", + "seahash", + "tinyvec", + "uuid", +] + +[[package]] +name = "rkyv_derive" +version = "0.7.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "rust_decimal" +version = "1.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1790d1c4c0ca81211399e0e0af16333276f375209e71a37b67698a373db5b47a" +dependencies = [ + "arrayvec", + "borsh", + "bytes", + "num-traits", + "rand", + "rkyv", + "serde", + "serde_json", +] + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "safe_arch" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f398075ce1e6a179b46f51bd88d0598b92b00d3551f1a2d4ac49e771b56ac354" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "seahash" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" + +[[package]] +name = "serde" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.203" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "serde_json" +version = "1.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "simba" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "061507c94fc6ab4ba1c9a0305018408e312e17c041eb63bef8aa726fa33aceae" +dependencies = [ + "approx", + "num-complex", + "num-traits", + "paste", + "wide", +] + +[[package]] +name = "simdutf8" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f27f6278552951f1f2b8cf9da965d10969b2efdea95a6ec47987ab46edfe263a" + +[[package]] +name = "spline-interpolation" +version = "0.1.0" +dependencies = [ + "nalgebra", + "num-traits", + "rust_decimal", + "thiserror", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.60" @@ -214,32 +694,106 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "syn_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1329189c02ff984e9736652b1631330da25eaa6bc639089ed4915d25446cbe7b" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "thiserror" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +checksum = "c546c80d6be4bc6a00c0f01730c08df82eaa7a7a61f11d656526506112cc1709" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.59" +version = "1.0.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", ] +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "toml_datetime" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4badfd56924ae69bcc9039335b2e017639ce3f9b001c393c1b2d1ef846ce2cbf" + +[[package]] +name = "toml_edit" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + [[package]] name = "unicode-ident" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + [[package]] name = "wasm-bindgen" version = "0.2.92" @@ -261,7 +815,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -283,7 +837,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -294,6 +848,16 @@ version = "0.2.92" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" +[[package]] +name = "wide" +version = "0.7.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a040b111774ab63a19ef46bbc149398ab372b4ccdcfd719e9814dbd7dfd76c8" +dependencies = [ + "bytemuck", + "safe_arch", +] + [[package]] name = "windows-core" version = "0.52.0" @@ -366,3 +930,21 @@ name = "windows_x86_64_msvc" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] diff --git a/crates/qlab-instrument/src/bond.rs b/crates/qlab-instrument/src/bond.rs index 93903e3..ff9282f 100644 --- a/crates/qlab-instrument/src/bond.rs +++ b/crates/qlab-instrument/src/bond.rs @@ -1,4 +1,5 @@ -use num_traits::{Float, FromPrimitive}; +use num_traits::real::Real; +use num_traits::FromPrimitive; use qlab_error::QLabResult; use qlab_math::interpolation::Method; use qlab_termstructure::yield_curve::YieldCurve; @@ -30,7 +31,7 @@ pub struct Bond { bond_cash_flows: Vec>, } -impl + AddAssign> Bond { +impl + AddAssign> Bond { /// Creates a new bond with the given parameters. /// /// This function calculates the cash flows for the bond based on the provided parameters. @@ -112,15 +113,15 @@ impl + AddAssign> Bond { let first_prior = first_coupon_date.checked_sub_months(months_in_regular_coupon_period)?; match first_prior.cmp(&issue_date) { Ordering::Less => { - let coupon_fraction = V::from_i32(first_coupon_date - issue_date)? - / V::from_i32(first_coupon_date - first_prior)?; + let coupon_fraction = V::from_i64(first_coupon_date - issue_date)? + / V::from_i64(first_coupon_date - first_prior)?; bond_cash_flows[0].payment_amount *= coupon_fraction; } Ordering::Greater => { let second_prior = first_prior.checked_sub_months(months_in_regular_coupon_period)?; - let coupon_fraction = V::from_i32(first_prior - issue_date)? - / V::from_i32(first_prior - second_prior)?; + let coupon_fraction = V::from_i64(first_prior - issue_date)? + / V::from_i64(first_prior - second_prior)?; bond_cash_flows[0].payment_amount += coupon_fraction * regular_coupon_payment; } Ordering::Equal => {} @@ -140,15 +141,15 @@ impl + AddAssign> Bond { penultimate_coupon_date.checked_add_months(months_in_regular_coupon_period)?; match maturity_date.cmp(&maturity_regular_date) { Ordering::Less => { - let coupon_fraction = V::from_i32(maturity_date - penultimate_coupon_date)? - / V::from_i32(maturity_regular_date - penultimate_coupon_date)?; + let coupon_fraction = V::from_i64(maturity_date - penultimate_coupon_date)? + / V::from_i64(maturity_regular_date - penultimate_coupon_date)?; final_coupon *= coupon_fraction; } Ordering::Greater => { let next_regular_date = maturity_regular_date.checked_add_months(months_in_regular_coupon_period)?; - let extra_coupon_fraction = V::from_i32(maturity_date - maturity_regular_date)? - / V::from_i32(next_regular_date - maturity_regular_date)?; + let extra_coupon_fraction = V::from_i64(maturity_date - maturity_regular_date)? + / V::from_i64(next_regular_date - maturity_regular_date)?; final_coupon += extra_coupon_fraction * regular_coupon_payment; } Ordering::Equal => {} diff --git a/crates/qlab-math/Cargo.toml b/crates/qlab-math/Cargo.toml index 43f3007..9c1c39a 100644 --- a/crates/qlab-math/Cargo.toml +++ b/crates/qlab-math/Cargo.toml @@ -13,6 +13,7 @@ description = "Mathematics related code for the qlab" [dependencies] num-traits = { workspace = true } qlab-error = { workspace = true } +spline-interpolation = { version = "0.1.0", path = "src/interpolation/spline-interpolation", default-features = false } [lints] workspace = true diff --git a/crates/qlab-math/src/interpolation.rs b/crates/qlab-math/src/interpolation.rs index a4f553e..d321849 100644 --- a/crates/qlab-math/src/interpolation.rs +++ b/crates/qlab-math/src/interpolation.rs @@ -1,16 +1,15 @@ -use num_traits::Float; +use num_traits::real::Real; use qlab_error::QLabResult; pub mod linear; #[derive(Copy, Clone, Debug)] -pub(crate) struct Point { +pub(crate) struct Point { x: V, y: V, } -#[allow(private_bounds)] -pub trait Method { +pub trait Method { /// Fits the model to the given data points. /// /// This function adjusts the parameters of the model to minimize the difference diff --git a/crates/qlab-math/src/interpolation/linear.rs b/crates/qlab-math/src/interpolation/linear.rs index 3b08c2f..49775f7 100644 --- a/crates/qlab-math/src/interpolation/linear.rs +++ b/crates/qlab-math/src/interpolation/linear.rs @@ -1,5 +1,5 @@ use crate::interpolation::{Method, Point}; -use num_traits::Float; +use num_traits::real::Real; use qlab_error::ComputeError::InvalidInput; use qlab_error::QLabResult; use std::fmt::Debug; @@ -13,7 +13,7 @@ use std::fmt::Debug; /// # Examples /// /// ``` -/// use num_traits::Float; +/// use num_traits::real::Real; /// use qlab_math::interpolation::linear::Linear; /// use qlab_math::interpolation::Method; /// @@ -26,11 +26,11 @@ use std::fmt::Debug; /// /// ``` #[derive(Default)] -pub struct Linear { +pub struct Linear { points: Vec>, } -impl Linear { +impl Linear { /// Creates a new instance of the `QLab` struct. /// /// # Arguments @@ -50,7 +50,7 @@ impl Linear { } } -impl Method for Linear { +impl Method for Linear { fn fit(&mut self, xs_and_ys: &[(V, V)]) -> QLabResult<()> { let mut points = Vec::with_capacity(xs_and_ys.len()); for &(x, y) in xs_and_ys { diff --git a/crates/qlab-termstructure/src/yield_curve.rs b/crates/qlab-termstructure/src/yield_curve.rs index 25978a8..ce6dfe3 100644 --- a/crates/qlab-termstructure/src/yield_curve.rs +++ b/crates/qlab-termstructure/src/yield_curve.rs @@ -1,4 +1,5 @@ -use num_traits::{Float, FromPrimitive}; +use num_traits::real::Real; +use num_traits::FromPrimitive; use qlab_error::ComputeError::InvalidInput; use qlab_error::QLabResult; use qlab_math::interpolation::Method; @@ -8,15 +9,15 @@ use std::marker::PhantomData; /// A trait representing a yield curve with discount factor calculations. /// -/// The trait is generic over the type of Floating point values (`V`) and the day count convention (`D`). -pub struct YieldCurve> { +/// The trait is generic over the type of Realing point values (`V`) and the day count convention (`D`). +pub struct YieldCurve> { settlement_date: Date, interpolator: I, _phantom: PhantomData, _day_count: PhantomData, } -impl> YieldCurve { +impl> YieldCurve { /// Creates a new instance of the `QLab` struct. /// /// # Arguments diff --git a/crates/qlab-time/src/date.rs b/crates/qlab-time/src/date.rs index 38ef516..ff108dd 100644 --- a/crates/qlab-time/src/date.rs +++ b/crates/qlab-time/src/date.rs @@ -1,7 +1,7 @@ use crate::business_day_convention::DateRolling; use crate::calendar::Calendar; use crate::period::Period; -use chrono::{Datelike, NaiveDate}; +use chrono::{Datelike, NaiveDate, TimeDelta}; use std::fmt; use std::fmt::{Debug, Formatter}; use std::ops::Sub; @@ -238,10 +238,10 @@ impl From for Date { } impl Sub for Date { - type Output = i32; + type Output = i64; fn sub(self, rhs: Self) -> Self::Output { - self.0.num_days_from_ce() - rhs.0.num_days_from_ce() + (self.0 - rhs.0).num_days() } } diff --git a/crates/qlab-time/src/day_count.rs b/crates/qlab-time/src/day_count.rs index aac684c..92bf3fb 100644 --- a/crates/qlab-time/src/day_count.rs +++ b/crates/qlab-time/src/day_count.rs @@ -3,14 +3,14 @@ pub mod act_365; pub mod thirty_360; use crate::date::Date; -use num_traits::{Float, FromPrimitive}; +use num_traits::{real::Real, FromPrimitive}; use qlab_error::QLabResult; pub trait DayCount { /// Calculates the day count fraction between two dates. /// /// This function calculates the day count fraction between `date1` and `date2` - /// using a generic type `V`, which must implement the `Float` and `FromPrimitive` + /// using a generic type `V`, which must implement the `Real` and `FromPrimitive` /// traits. The day count fraction represents the portion of a year between the two /// dates, expressed as a fraction. /// @@ -26,7 +26,7 @@ pub trait DayCount { /// /// # Errors /// An error occurs if a cast from `V` to a primitive type fails. - fn calculate_day_count_fraction( + fn calculate_day_count_fraction( date1: Date, date2: Date, ) -> QLabResult; diff --git a/crates/qlab-time/src/day_count/act_360.rs b/crates/qlab-time/src/day_count/act_360.rs index 012617b..90cb63c 100644 --- a/crates/qlab-time/src/day_count/act_360.rs +++ b/crates/qlab-time/src/day_count/act_360.rs @@ -1,20 +1,19 @@ use crate::date::Date; use crate::day_count::DayCount; -use num_traits::{Float, FromPrimitive}; +use num_traits::{real::Real, FromPrimitive}; use qlab_error::{ComputeError, QLabResult}; #[derive(Debug)] pub struct Act360; impl DayCount for Act360 { - fn calculate_day_count_fraction( + fn calculate_day_count_fraction( date1: Date, date2: Date, ) -> QLabResult { - let date_diff = V::from_i32(date2 - date1) + let date_diff = V::from_i64(date2 - date1) .ok_or_else(|| ComputeError::CastNumberError(format!("{}", date2 - date1).into()))?; - let denomination = V::from_i32(360) - .ok_or_else(|| ComputeError::CastNumberError(format!("{}", 360).into()))?; + let denomination = V::from_i32(360).unwrap(); Ok(date_diff.div(denomination)) } diff --git a/crates/qlab-time/src/day_count/act_365.rs b/crates/qlab-time/src/day_count/act_365.rs index 3574e4b..a82b9d2 100644 --- a/crates/qlab-time/src/day_count/act_365.rs +++ b/crates/qlab-time/src/day_count/act_365.rs @@ -1,6 +1,6 @@ use crate::date::Date; use crate::day_count::DayCount; -use num_traits::Float; +use num_traits::real::Real; use num_traits::FromPrimitive; use qlab_error::{ComputeError, QLabResult}; @@ -8,14 +8,13 @@ use qlab_error::{ComputeError, QLabResult}; pub struct Act365; impl DayCount for Act365 { - fn calculate_day_count_fraction( + fn calculate_day_count_fraction( date1: Date, date2: Date, ) -> QLabResult { - let date_diff = V::from_i32(date2 - date1) + let date_diff = V::from_i64(date2 - date1) .ok_or_else(|| ComputeError::CastNumberError(format!("{}", date2 - date1).into()))?; - let denomination = V::from_i32(365) - .ok_or_else(|| ComputeError::CastNumberError(format!("{}", 365).into()))?; + let denomination = V::from_i32(365).unwrap(); Ok(date_diff.div(denomination)) } diff --git a/crates/qlab-time/src/day_count/thirty_360.rs b/crates/qlab-time/src/day_count/thirty_360.rs index 96a0576..af680f4 100644 --- a/crates/qlab-time/src/day_count/thirty_360.rs +++ b/crates/qlab-time/src/day_count/thirty_360.rs @@ -1,6 +1,6 @@ use crate::date::Date; use crate::day_count::DayCount; -use num_traits::{Float, FromPrimitive}; +use num_traits::{real::Real, FromPrimitive}; use qlab_error::ComputeError::InvalidInput; use qlab_error::{ComputeError, QLabResult}; @@ -25,7 +25,7 @@ impl Thirty360 { } impl DayCount for Thirty360 { - fn calculate_day_count_fraction( + fn calculate_day_count_fraction( date1: Date, date2: Date, ) -> QLabResult {