adding varcovar var, adding notebooks, adding npm publish

This commit is contained in:
Andy Pack 2025-02-14 23:24:45 +00:00
parent 335f5dbc82
commit 43450bfbcb
Signed by: sarsoo
GPG Key ID: A55BA3536A5E0ED7
21 changed files with 6514 additions and 42 deletions

@ -29,3 +29,43 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
publishNPM:
name: Publish NPM
runs-on: ubuntu-latest
needs: [ build ] # for ignoring bad builds
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
steps:
- name: Checkout
uses: actions/checkout@v4
with:
github-server-url: https://gitea.sheep-ghoul.ts.net
- name: Install Rust
uses: actions-rs/toolchain@v1
with:
toolchain: stable
- name: Cargo Build
uses: actions-rs/cargo@v1
with:
command: build
- name: Install wasm-pack
run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
- name: Build Rust for WASM
working-directory: ./finlib-wasm
run: wasm-pack build --release
- name: Install Node
uses: actions/setup-node@v2
with:
node-version: 22
registry-url: 'https://gitea.sheep-ghoul.ts.net/api/packages/sarsoo/npm/'
- name: Publish
working-directory: ./finlib-wasm/pkg
run: npm publish --provenance --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

348
Cargo.lock generated

@ -61,6 +61,21 @@ dependencies = [
"windows-sys",
]
[[package]]
name = "approx"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cab112f0a86d568ea0e627cc1d6be74a1e9cd55214684db5561995f6dad897c6"
dependencies = [
"num-traits",
]
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "autocfg"
version = "1.4.0"
@ -79,6 +94,18 @@ version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "bytemuck"
version = "1.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef657dfab802224e671f5818e9a4935f9b1957ed18e58292690cc39e7a4092a3"
[[package]]
name = "byteorder"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]]
name = "cbindgen"
version = "0.28.0"
@ -223,8 +250,13 @@ checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
name = "finlib"
version = "0.0.1"
dependencies = [
"log",
"nalgebra",
"ndarray",
"ndarray-stats",
"pyo3",
"rayon",
"statrs",
]
[[package]]
@ -246,6 +278,17 @@ dependencies = [
"wasm-bindgen-test",
]
[[package]]
name = "getrandom"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.3.1"
@ -254,7 +297,7 @@ checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
dependencies = [
"cfg-if",
"libc",
"wasi",
"wasi 0.13.3+wasi-0.2.2",
"windows-targets",
]
@ -298,6 +341,15 @@ version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itertools"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
dependencies = [
"either",
]
[[package]]
name = "itoa"
version = "1.0.14"
@ -320,6 +372,12 @@ version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "libm"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
@ -332,6 +390,16 @@ version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
[[package]]
name = "matrixmultiply"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9380b911e3e96d10c1f415da0876389aaf1b56759054eeb0de7df940c456ba1a"
dependencies = [
"autocfg",
"rawpointer",
]
[[package]]
name = "memchr"
version = "2.7.4"
@ -357,18 +425,159 @@ dependencies = [
"walkdir",
]
[[package]]
name = "nalgebra"
version = "0.33.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26aecdf64b707efd1310e3544d709c5c0ac61c13756046aaaba41be5c4f66a3b"
dependencies = [
"approx",
"matrixmultiply",
"nalgebra-macros",
"num-complex",
"num-rational",
"num-traits",
"rand",
"rand_distr",
"simba",
"typenum",
]
[[package]]
name = "nalgebra-macros"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "254a5372af8fc138e36684761d3c0cdb758a4410e938babcff1c860ce14ddbfc"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "ndarray"
version = "0.16.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "882ed72dce9365842bf196bdeedf5055305f11fc8c03dee7bb0194a6cad34841"
dependencies = [
"matrixmultiply",
"num-complex",
"num-integer",
"num-traits",
"portable-atomic",
"portable-atomic-util",
"rawpointer",
]
[[package]]
name = "ndarray-stats"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17ebbe97acce52d06aebed4cd4a87c0941f4b2519b59b82b4feb5bd0ce003dfd"
dependencies = [
"indexmap",
"itertools",
"ndarray",
"noisy_float",
"num-integer",
"num-traits",
"rand",
]
[[package]]
name = "noisy_float"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "978fe6e6ebc0bf53de533cd456ca2d9de13de13856eda1518a285d7705a213af"
dependencies = [
"num-traits",
]
[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
]
[[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-bigint",
"num-integer",
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
"libm",
]
[[package]]
name = "once_cell"
version = "1.20.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
[[package]]
name = "paste"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
[[package]]
name = "portable-atomic"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
[[package]]
name = "portable-atomic-util"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507"
dependencies = [
"portable-atomic",
]
[[package]]
name = "ppv-lite86"
version = "0.2.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro2"
version = "1.0.93"
@ -384,6 +593,7 @@ version = "0.0.1"
dependencies = [
"finlib",
"pyo3",
"pyo3-log",
]
[[package]]
@ -424,6 +634,17 @@ dependencies = [
"pyo3-build-config",
]
[[package]]
name = "pyo3-log"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be5bb22b77965a7b5394e9aae9897a0607b51df5167561ffc3b02643b4200bc7"
dependencies = [
"arc-swap",
"log",
"pyo3",
]
[[package]]
name = "pyo3-macros"
version = "0.23.4"
@ -458,6 +679,52 @@ dependencies = [
"proc-macro2",
]
[[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 0.2.15",
]
[[package]]
name = "rand_distr"
version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
dependencies = [
"num-traits",
"rand",
]
[[package]]
name = "rawpointer"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60a357793950651c4ed0f3f52338f53b2f809f32d83a07f72909fa13e4c6c1e3"
[[package]]
name = "rayon"
version = "1.10.0"
@ -532,6 +799,15 @@ version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
[[package]]
name = "safe_arch"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96b02de82ddbe1b636e6170c21be622223aea188ef2e139be0a5b219ec215323"
dependencies = [
"bytemuck",
]
[[package]]
name = "same-file"
version = "1.0.6"
@ -588,6 +864,31 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "simba"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3a386a501cd104797982c15ae17aafe8b9261315b5d07e3ec803f2ea26be0fa"
dependencies = [
"approx",
"num-complex",
"num-traits",
"paste",
"wide",
]
[[package]]
name = "statrs"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a3fe7c28c6512e766b0874335db33c94ad7b8f9054228ae1c2abd47ce7d335e"
dependencies = [
"approx",
"nalgebra",
"num-traits",
"rand",
]
[[package]]
name = "strsim"
version = "0.11.1"
@ -619,7 +920,7 @@ checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91"
dependencies = [
"cfg-if",
"fastrand",
"getrandom",
"getrandom 0.3.1",
"once_cell",
"rustix",
"windows-sys",
@ -659,6 +960,12 @@ dependencies = [
"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.16"
@ -687,6 +994,12 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.13.3+wasi-0.2.2"
@ -801,6 +1114,16 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "wide"
version = "0.7.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41b5576b9a81633f3e8df296ce0063042a73507636cbe956c61133dd7034ab22"
dependencies = [
"bytemuck",
"safe_arch",
]
[[package]]
name = "winapi-util"
version = "0.1.9"
@ -900,3 +1223,24 @@ checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
dependencies = [
"bitflags",
]
[[package]]
name = "zerocopy"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
dependencies = [
"byteorder",
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

@ -20,11 +20,13 @@ edition = "2021"
[workspace.dependencies]
rayon = "1.10.0"
[workspace.dependencies.pyo3]
version = "0.23.4"
# "abi3-py38" tells pyo3 (and maturin) to build using the stable ABI with minimum Python version 3.8
features = ["extension-module", "abi3-py38"]
ndarray = "0.16.1"
ndarray-stats = "0.6.0"
nalgebra = "0.33.2"
statrs = "0.18.0"
log = "0.4.25"
pyo3 = { version = "0.23.4", features = ["extension-module", "abi3-py38"] }
pyo3-log = "0.12.1"
[profile.release]
# Tell `rustc` to optimize for small code size.

@ -12,7 +12,19 @@ public static class ValueAtRisk
unsafe {
var valueArr = values.ToArray();
fixed (double* ptrOne = valueArr) {
var ret = NativeMethods.value_at_risk(ptrOne, (UIntPtr)valueArr.Length, confidence);
var ret = NativeMethods.historical_value_at_risk(ptrOne, (UIntPtr)valueArr.Length, confidence);
return *ret;
}
}
}
public static double VarCovar(IEnumerable<double> values, double confidence)
{
unsafe {
var valueArr = values.ToArray();
fixed (double* ptrOne = valueArr) {
var ret = NativeMethods.varcovar_value_at_risk(ptrOne, (UIntPtr)valueArr.Length, confidence);
return *ret;
}

@ -22,8 +22,11 @@ namespace FinLib
[DllImport(__DllName, EntryPoint = "covariance", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern double* covariance(double* arr, nuint len, double* arr_two, nuint len_two);
[DllImport(__DllName, EntryPoint = "value_at_risk", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern double* value_at_risk(double* arr, nuint len, double confidence);
[DllImport(__DllName, EntryPoint = "historical_value_at_risk", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern double* historical_value_at_risk(double* arr, nuint len, double confidence);
[DllImport(__DllName, EntryPoint = "varcovar_value_at_risk", CallingConvention = CallingConvention.Cdecl, ExactSpelling = true)]
internal static extern double* varcovar_value_at_risk(double* arr, nuint len, double confidence);
}

@ -19,9 +19,11 @@ extern "C" {
const double *covariance(const double *arr, size_t len, const double *arr_two, size_t len_two);
const double *historical_value_at_risk(const double *arr, size_t len, double confidence);
double interest_compound(double principal, double rate, double time, double n);
const double *value_at_risk(const double *arr, size_t len, double confidence);
const double *varcovar_value_at_risk(const double *arr, size_t len, double confidence);
} // extern "C"

@ -26,11 +26,21 @@ pub unsafe extern "C" fn covariance(arr: *const f64, len: usize, arr_two: *const
}
#[no_mangle]
pub unsafe extern "C" fn value_at_risk(arr: *const f64, len: usize, confidence: f64) -> *const f64 {
pub unsafe extern "C" fn historical_value_at_risk(arr: *const f64, len: usize, confidence: f64) -> *const f64 {
let input_array = unsafe {
assert!(!arr.is_null());
slice::from_raw_parts(arr, len)
};
Box::into_raw(Box::new(finlib::risk::var::historical::value_at_risk(input_array, confidence)))
}
}
#[no_mangle]
pub unsafe extern "C" fn varcovar_value_at_risk(arr: *const f64, len: usize, confidence: f64) -> *const f64 {
let input_array = unsafe {
assert!(!arr.is_null());
slice::from_raw_parts(arr, len)
};
Box::into_raw(Box::new(finlib::risk::var::varcovar::value_at_risk(input_array, confidence)))
}

@ -7,7 +7,12 @@ edition.workspace = true
[dependencies]
pyo3 = { workspace = true, optional = true }
rayon = { workspace = true, optional = true }
ndarray = { workspace = true }
ndarray-stats = { workspace = true }
nalgebra = { workspace = true }
statrs = { workspace = true }
log = { workspace = true }
[features]
py = ["dep:pyo3"]
parallel = ["dep::rayon"]
parallel = ["dep:rayon"]

@ -7,6 +7,7 @@ use rayon::prelude::*;
pub fn value_at_risk(values: &[f64], confidence: f64) -> f64 {
let mut roc = rates_of_change(values).collect::<Vec<_>>();
// roc.par_sort_by(|x, y| x.partial_cmp(y).unwrap());
roc.sort_by(|x, y| x.partial_cmp(y).unwrap());

@ -1 +1,2 @@
pub mod historical;
pub mod historical;
pub mod varcovar;

@ -0,0 +1,19 @@
use crate::util::roc::rates_of_change;
use crate::stats;
#[cfg(feature = "parallel")]
use rayon::prelude::*;
use statrs::distribution::{ContinuousCDF, Normal};
// https://medium.com/@serdarilarslan/value-at-risk-var-and-its-implementation-in-python-5c9150f73b0e
pub fn value_at_risk(values: &[f64], confidence: f64) -> f64 {
let roc = rates_of_change(values).collect::<Vec<_>>();
let mean = stats::mean(&roc);
let std_dev = stats::sample_std_dev(&roc);
let n = Normal::new(0.0, 1.0).unwrap();
mean + std_dev * n.inverse_cdf(confidence)
}

@ -18,7 +18,8 @@ pub fn covariance(slice: &[f64], slice_two: &[f64]) -> Option<f64>
)
.map(|(x, y)| (x - mean_1) * (y - mean_2))
.sum::<f64>()
/ ((slice.len() - 1) as f64))
/ ((slice.len() - 1) as f64)
)
}
_ => None
}

@ -1 +1,2 @@
pub mod roc;
pub mod roc;
pub mod vector;

17
finlib/src/util/vector.rs Normal file

@ -0,0 +1,17 @@
pub fn dot_product(a: &[f64], b: &[f64]) -> f64 {
assert_eq!(a.len(), b.len());
a.iter()
.zip(b.iter())
.map(|(x, y)| x * y)
.sum()
}
pub fn mag(a: &[f64]) -> f64 {
f64::sqrt(
a.iter()
.map(|x| f64::powi(*x, 2))
.sum()
)
}

File diff suppressed because one or more lines are too long

5102
notebooks/poetry.lock generated Normal file

File diff suppressed because it is too large Load Diff

22
notebooks/pyproject.toml Normal file

@ -0,0 +1,22 @@
[project]
name = "notebooks"
version = "0.1.0"
requires-python = ">=3.12,<3.13"
dependencies = [
"jupyterlab (>=4.3.5,<5.0.0)",
"matplotlib (>=3.10.0,<4.0.0)",
"seaborn (>=0.13.2,<0.14.0)",
"openbb (>=4.4.0,<5.0.0)",
"yfinance (>=0.2.52,<0.3.0)",
"pandas (>=2.2.3,<3.0.0)",
"numpy (>=2.2.3,<3.0.0)",
"maturin (>=1.8.2,<2.0.0)"
]
[tool.poetry]
package-mode = false
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"

File diff suppressed because one or more lines are too long

@ -18,4 +18,5 @@ crate-type = ["cdylib"]
[dependencies]
finlib = { path = "../finlib", features = ["py"] }
pyo3 = { workspace = true }
pyo3 = { workspace = true }
pyo3-log = { workspace = true }

@ -1,30 +1,63 @@
use pyo3::prelude::*;
#[pyfunction]
pub fn compound(principal: f64, rate: f64, time: f64, n: f64) -> PyResult<f64> {
Ok(finlib::interest::compound(principal, rate, time, n))
}
#[pyfunction]
pub fn covariance(slice: Vec<f64>, slice_two: Vec<f64>) -> PyResult<Option<f64>> {
Ok(finlib::stats::covariance(&slice, &slice_two))
}
#[pymodule]
fn pyfinlib(m: &Bound<'_, PyModule>) -> PyResult<()> {
register_interest_module(m);
register_stats_module(m);
Ok(())
}
mod pyfinlib {
use super::*;
fn register_interest_module(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
let child_module = PyModule::new(parent_module.py(), "interest")?;
child_module.add_function(wrap_pyfunction!(compound, &child_module)?)?;
parent_module.add_submodule(&child_module)
}
#[pymodule_init]
fn init(m: &Bound<'_, PyModule>) -> PyResult<()> {
pyo3_log::init();
fn register_stats_module(parent_module: &Bound<'_, PyModule>) -> PyResult<()> {
let child_module = PyModule::new(parent_module.py(), "stats")?;
child_module.add_function(wrap_pyfunction!(covariance, &child_module)?)?;
parent_module.add_submodule(&child_module)
Ok(())
}
#[pymodule]
mod interest {
use super::*;
#[pyfunction]
pub fn compound(principal: f64, rate: f64, time: f64, n: f64) -> PyResult<f64> {
Ok(finlib::interest::compound(principal, rate, time, n))
}
}
#[pymodule]
mod risk {
use super::*;
#[pymodule]
mod var {
use super::*;
#[pyfunction]
fn historical(values: Vec<f64>, confidence: f64) -> PyResult<f64> {
Ok(finlib::risk::var::historical::value_at_risk(&values, confidence))
}
#[pyfunction]
fn varcovar(values: Vec<f64>, confidence: f64) -> PyResult<f64> {
Ok(finlib::risk::var::varcovar::value_at_risk(&values, confidence))
}
}
}
#[pymodule]
mod stats {
use super::*;
#[pyfunction]
pub fn covariance(slice: Vec<f64>, slice_two: Vec<f64>) -> PyResult<Option<f64>> {
Ok(finlib::stats::covariance(&slice, &slice_two))
}
}
#[pymodule]
mod util {
use super::*;
#[pyfunction]
pub fn rates_of_change(slice: Vec<f64>) -> PyResult<Vec<f64>> {
Ok(finlib::util::roc::rates_of_change(&slice).collect::<Vec<_>>())
}
}
}