diff --git a/FinLib.NET/FinLib.Bench/Benchmarks/HistoricalVAR.cs b/FinLib.NET/FinLib.Bench/Benchmarks/HistoricalVAR.cs
new file mode 100644
index 0000000..186943f
--- /dev/null
+++ b/FinLib.NET/FinLib.Bench/Benchmarks/HistoricalVAR.cs
@@ -0,0 +1,34 @@
+using System.Security.Cryptography;
+using BenchmarkDotNet.Attributes;
+using FinLib.Bench.Comparisons;
+
+namespace FinLib.Bench.Benchmarks;
+
+public class HistoricalVar
+{
+    private const int N = 10000;
+
+    // [Params(0.05d, 0.1d)]
+    public double confidence = 0.05;
+    [Params(10, 1000, 10000)]
+    public int length;
+    private double[] data;
+
+    [GlobalSetup]
+    public void Setup()
+    {
+        data = new double[length];
+        var random = new Random(42);
+
+        for (int i = 0; i < length; i++)
+        {
+            data[i] = random.NextDouble();
+        }
+    }
+
+    [Benchmark]
+    public double FinLibDotnet() => HistoricalVARDotnet.ValueAtRisk(data.ToList(), confidence);
+
+    [Benchmark]
+    public double FinLibRust() => FinLib.Risk.ValueAtRisk.Historical(data, confidence);
+}
\ No newline at end of file
diff --git a/FinLib.NET/FinLib.Bench/Comparisons/HistoricalVARDotnet.cs b/FinLib.NET/FinLib.Bench/Comparisons/HistoricalVARDotnet.cs
new file mode 100644
index 0000000..2abf9a3
--- /dev/null
+++ b/FinLib.NET/FinLib.Bench/Comparisons/HistoricalVARDotnet.cs
@@ -0,0 +1,37 @@
+namespace FinLib.Bench.Comparisons;
+
+public static class HistoricalVARDotnet
+{
+    public static IEnumerable<(T, T)> Pairwise<T>(this IEnumerable<T> enumerable)
+    {
+        var previous = default(T);
+
+        using (var e = enumerable.GetEnumerator())
+        {
+            if (e.MoveNext())
+                previous = e.Current;
+
+            while (e.MoveNext())
+            {
+                previous = e.Current;
+                yield return (previous, e.Current);
+            }
+        }
+    }
+
+    public static IEnumerable<double> RatesOfChange(this IEnumerable<double> values)
+    {
+        foreach (var value in values.Pairwise())
+        {
+            yield return (value.Item2 - value.Item1) / value.Item1;
+        }
+    }
+
+    public static double ValueAtRisk(List<double> values, double confidence)
+    {
+        var roc = values.RatesOfChange().Order().ToArray();
+        var threshold = (int) Math.Floor(confidence * roc.Length);
+
+        return roc[threshold];
+    }
+}
\ No newline at end of file
diff --git a/FinLib.NET/FinLib.Bench/FinLib.Bench.csproj b/FinLib.NET/FinLib.Bench/FinLib.Bench.csproj
new file mode 100644
index 0000000..2c65660
--- /dev/null
+++ b/FinLib.NET/FinLib.Bench/FinLib.Bench.csproj
@@ -0,0 +1,18 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <OutputType>Exe</OutputType>
+        <TargetFramework>net9.0</TargetFramework>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <Nullable>enable</Nullable>
+    </PropertyGroup>
+
+    <ItemGroup>
+      <PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <ProjectReference Include="..\FinLib\FinLib.csproj" />
+    </ItemGroup>
+
+</Project>
diff --git a/FinLib.NET/FinLib.Bench/Program.cs b/FinLib.NET/FinLib.Bench/Program.cs
new file mode 100644
index 0000000..6a48140
--- /dev/null
+++ b/FinLib.NET/FinLib.Bench/Program.cs
@@ -0,0 +1,13 @@
+using BenchmarkDotNet.Running;
+using FinLib.Bench.Benchmarks;
+
+namespace FinLib.Bench
+{
+    public class Program
+    {
+        public static void Main(string[] args)
+        {
+            var summary = BenchmarkRunner.Run<HistoricalVar>();
+        }
+    }
+}
\ No newline at end of file
diff --git a/FinLib.NET/FinLib.Test/Basic.cs b/FinLib.NET/FinLib.Test/Basic.cs
index b1e46a7..4c38a95 100644
--- a/FinLib.NET/FinLib.Test/Basic.cs
+++ b/FinLib.NET/FinLib.Test/Basic.cs
@@ -11,24 +11,24 @@ public class Tests
     [Test]
     public void TestCompoundInterest()
     {
-        FinLib.CompoundInterest(100, 0.05, 1, 1).Should().Be(105);
+        Interest.Interest.Compound(100, 0.05, 1, 1).Should().Be(105);
     }
 
     [Test]
     public void TestCompoundInterestMonthly()
     {
-        Math.Round(FinLib.CompoundInterest(100, 0.05, 1, 12), 2).Should().Be(105.12);
+        Math.Round(Interest.Interest.Compound(100, 0.05, 1, 12), 2).Should().Be(105.12);
     }
 
     [Test]
     public void Covariance()
     {
-        FinLib.Covariance([1d, 2d, 3d, 4], [1d, 2, 3, 4]).Should().Be(1.6666666666666667);
+        Stats.Stats.Covariance([1d, 2d, 3d, 4], [1d, 2, 3, 4]).Should().Be(1.6666666666666667);
     }
 
     [Test]
     public void CovarianceBreaking()
     {
-        FinLib.Covariance([1d, 2d, 3d, 4], [1d]).Should().BeNull();
+        Stats.Stats.Covariance([1d, 2d, 3d, 4], [1d]).Should().BeNull();
     }
 }
\ No newline at end of file
diff --git a/FinLib.NET/FinLib.sln b/FinLib.NET/FinLib.sln
index 524b55e..2c8fb4a 100644
--- a/FinLib.NET/FinLib.sln
+++ b/FinLib.NET/FinLib.sln
@@ -4,6 +4,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FinLib", "FinLib\FinLib.csp
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FinLib.Test", "FinLib.Test\FinLib.Test.csproj", "{148E024C-07D0-4DC0-A3E2-A146E709897B}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FinLib.Bench", "FinLib.Bench\FinLib.Bench.csproj", "{F4171146-0A63-4611-972B-BAFB9A090D2B}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -18,5 +20,9 @@ Global
 		{148E024C-07D0-4DC0-A3E2-A146E709897B}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{148E024C-07D0-4DC0-A3E2-A146E709897B}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{148E024C-07D0-4DC0-A3E2-A146E709897B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F4171146-0A63-4611-972B-BAFB9A090D2B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F4171146-0A63-4611-972B-BAFB9A090D2B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F4171146-0A63-4611-972B-BAFB9A090D2B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F4171146-0A63-4611-972B-BAFB9A090D2B}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 EndGlobal
diff --git a/FinLib.NET/FinLib/FinLib.Interest.cs b/FinLib.NET/FinLib/FinLib.Interest.cs
new file mode 100644
index 0000000..a6bba3f
--- /dev/null
+++ b/FinLib.NET/FinLib/FinLib.Interest.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace FinLib.Interest;
+
+public static class Interest
+{
+    public static double Compound(double principal, double rate, double time, double n)
+    {
+        return NativeMethods.interest_compound(principal, rate, time, n);
+    }
+}
\ No newline at end of file
diff --git a/FinLib.NET/FinLib/FinLib.Risk.cs b/FinLib.NET/FinLib/FinLib.Risk.cs
new file mode 100644
index 0000000..347955a
--- /dev/null
+++ b/FinLib.NET/FinLib/FinLib.Risk.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace FinLib.Risk;
+
+public static class ValueAtRisk
+{
+    public static double Historical(IEnumerable<double> values, double confidence)
+    {
+        unsafe {
+            var valueArr = values.ToArray();
+            fixed (double* ptrOne = valueArr) {
+                var ret = NativeMethods.value_at_risk(ptrOne, (UIntPtr)valueArr.Length, confidence);
+
+                return *ret;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/FinLib.NET/FinLib/FinLib.cs b/FinLib.NET/FinLib/FinLib.cs
index 00d5183..1483ee4 100644
--- a/FinLib.NET/FinLib/FinLib.cs
+++ b/FinLib.NET/FinLib/FinLib.cs
@@ -3,15 +3,10 @@ using System.Collections;
 using System.Collections.Generic;
 using System.Linq;
 
-namespace FinLib;
+namespace FinLib.Stats;
 
-public static class FinLib
+public static class Stats
 {
-    public static double CompoundInterest(double principal, double rate, double time, double n)
-    {
-        return NativeMethods.interest_compound(principal, rate, time, n);
-    }
-
     public static double? Covariance(IEnumerable<double> valuesOne, IEnumerable<double> valuesTwo)
     {
         unsafe {
diff --git a/FinLib.NET/FinLib/NativeMethods.g.cs b/FinLib.NET/FinLib/NativeMethods.g.cs
index 8544bd6..195eca3 100644
--- a/FinLib.NET/FinLib/NativeMethods.g.cs
+++ b/FinLib.NET/FinLib/NativeMethods.g.cs
@@ -22,6 +22,9 @@ 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);
+
 
     }
 
diff --git a/finlib-cpp/finlib-native.h b/finlib-cpp/include/finlib-native.h
similarity index 86%
rename from finlib-cpp/finlib-native.h
rename to finlib-cpp/include/finlib-native.h
index efcf02a..a0f37af 100644
--- a/finlib-cpp/finlib-native.h
+++ b/finlib-cpp/include/finlib-native.h
@@ -21,6 +21,8 @@ const double *covariance(const double *arr, size_t len, const double *arr_two, s
 
 double interest_compound(double principal, double rate, double time, double n);
 
+const double *value_at_risk(const double *arr, size_t len, double confidence);
+
 }  // extern "C"
 
 }  // namespace finlib
diff --git a/finlib-ffi/build.rs b/finlib-ffi/build.rs
index 949bf2d..4f30ff9 100644
--- a/finlib-ffi/build.rs
+++ b/finlib-ffi/build.rs
@@ -14,7 +14,7 @@ fn main() {
         .with_config(config)
         .generate()
         .expect("Unable to generate bindings")
-        .write_to_file("../finlib-cpp/finlib-native.h");
+        .write_to_file("../finlib-cpp/include/finlib-native.h");
 
     csbindgen::Builder::default()
         .input_extern_file("src/lib.rs")
diff --git a/finlib-ffi/src/lib.rs b/finlib-ffi/src/lib.rs
index 5c79ccb..8865bfe 100644
--- a/finlib-ffi/src/lib.rs
+++ b/finlib-ffi/src/lib.rs
@@ -23,4 +23,14 @@ pub unsafe extern "C" fn covariance(arr: *const f64, len: usize, arr_two: *const
         Some(v) => Box::into_raw(Box::new(v))
     }
 
+}
+
+#[no_mangle]
+pub unsafe extern "C" fn 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 newline at end of file
diff --git a/finlib/Cargo.toml b/finlib/Cargo.toml
index f1d735c..f080a0e 100644
--- a/finlib/Cargo.toml
+++ b/finlib/Cargo.toml
@@ -6,7 +6,8 @@ edition.workspace = true
 
 [dependencies]
 pyo3 = { workspace = true, optional = true }
-rayon = { workspace = true }
+rayon = { workspace = true, optional = true }
 
 [features]
-py = ["dep:pyo3"]
\ No newline at end of file
+py = ["dep:pyo3"]
+parallel = ["dep::rayon"]
\ No newline at end of file
diff --git a/finlib/src/lib.rs b/finlib/src/lib.rs
index 40ee7ce..71f9f98 100644
--- a/finlib/src/lib.rs
+++ b/finlib/src/lib.rs
@@ -1,2 +1,4 @@
 pub mod interest;
-pub mod stats;
\ No newline at end of file
+pub mod stats;
+pub mod util;
+pub mod risk;
\ No newline at end of file
diff --git a/finlib/src/risk/mod.rs b/finlib/src/risk/mod.rs
new file mode 100644
index 0000000..cd03cb3
--- /dev/null
+++ b/finlib/src/risk/mod.rs
@@ -0,0 +1 @@
+pub mod var;
\ No newline at end of file
diff --git a/finlib/src/risk/var/historical.rs b/finlib/src/risk/var/historical.rs
new file mode 100644
index 0000000..62bb273
--- /dev/null
+++ b/finlib/src/risk/var/historical.rs
@@ -0,0 +1,27 @@
+use crate::util::roc::rates_of_change;
+
+#[cfg(feature = "parallel")]
+use rayon::prelude::*;
+
+// https://www.simtrade.fr/blog_simtrade/historical-method-var-calculation/
+
+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());
+
+    let threshold = (confidence * roc.len() as f64).floor() as usize;
+
+    roc[threshold]
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn var_test() {
+        let result = value_at_risk(&[1f64, 2f64, 4f64, 5f64], 0.01f64);
+        assert_eq!(result, 0.25f64);
+    }
+}
\ No newline at end of file
diff --git a/finlib/src/risk/var/mod.rs b/finlib/src/risk/var/mod.rs
new file mode 100644
index 0000000..1fd4453
--- /dev/null
+++ b/finlib/src/risk/var/mod.rs
@@ -0,0 +1 @@
+pub mod historical;
\ No newline at end of file
diff --git a/finlib/src/stats/covariance.rs b/finlib/src/stats/covariance.rs
index 70a3735..9f1c86c 100644
--- a/finlib/src/stats/covariance.rs
+++ b/finlib/src/stats/covariance.rs
@@ -1,3 +1,4 @@
+#[cfg(feature = "parallel")]
 use rayon::prelude::*;
 use super::mean;
 
@@ -8,7 +9,13 @@ pub fn covariance(slice: &[f64], slice_two: &[f64]) -> Option<f64>
             let mean_1 = mean(slice);
             let mean_2 = mean(slice_two);
 
-            Some(slice.par_iter().zip(slice_two.par_iter())
+            Some(slice
+                // .par_iter()
+                .iter()
+                .zip(slice_two
+                    // .par_iter()
+                    .iter()
+                )
                 .map(|(x, y)| (x - mean_1) * (y - mean_2))
                 .sum::<f64>()
                 / ((slice.len() - 1) as f64))
diff --git a/finlib/src/stats/mod.rs b/finlib/src/stats/mod.rs
index 090f32e..c2bb3ac 100644
--- a/finlib/src/stats/mod.rs
+++ b/finlib/src/stats/mod.rs
@@ -1,29 +1,37 @@
 mod covariance;
 pub use covariance::*;
 
+#[cfg(feature = "parallel")]
 use rayon::prelude::*;
 
 pub fn mean(slice: &[f64]) -> f64
 {
-    slice.par_iter().sum::<f64>() / slice.len() as f64
+    slice
+        // .par_iter()
+        .iter()
+        .sum::<f64>() / slice.len() as f64
 }
 
 pub fn population_variance(slice: &[f64]) -> f64
 {
     let mean = mean(slice);
-    slice.par_iter()
+    slice
+        // .par_iter()
+        .iter()
         .map(|x| f64::powi(x - mean, 2))
         .sum::<f64>()
-        / slice.len() as f64
+    / slice.len() as f64
 }
 
 pub fn sample_variance(slice: &[f64]) -> f64
 {
     let mean = mean(slice);
-    slice.par_iter()
+    slice
+        // .par_iter()
+        .iter()
         .map(|x| f64::powi(x - mean, 2))
         .sum::<f64>()
-        / ((slice.len() - 1) as f64)
+    / ((slice.len() - 1) as f64)
 }
 
 pub fn population_std_dev(slice: &[f64]) -> f64
diff --git a/finlib/src/util/mod.rs b/finlib/src/util/mod.rs
new file mode 100644
index 0000000..e313a5b
--- /dev/null
+++ b/finlib/src/util/mod.rs
@@ -0,0 +1 @@
+pub mod roc;
\ No newline at end of file
diff --git a/finlib/src/util/roc.rs b/finlib/src/util/roc.rs
new file mode 100644
index 0000000..f9920c4
--- /dev/null
+++ b/finlib/src/util/roc.rs
@@ -0,0 +1,33 @@
+#[cfg(feature = "parallel")]
+use rayon::prelude::*;
+
+pub fn changes(values: &[f64]) -> impl Iterator<Item = f64> + use<'_> {
+    values
+        .windows(2)
+        // .par_windows(2)
+        .map(|x| x[1] - x[0])
+}
+
+pub fn rates_of_change(values: &[f64]) -> impl Iterator<Item = f64> + use<'_> {
+    values
+        .windows(2)
+        // .par_windows(2)
+        .map(|x| (x[1] - x[0])/x[0])
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    #[test]
+    fn change_test() {
+        let result = changes(&[1f64, 2f64, 4f64, 5f64]).collect::<Vec<_>>();
+        assert_eq!(result, vec![1f64, 2f64, 1f64]);
+    }
+
+    #[test]
+    fn roc_test() {
+        let result = rates_of_change(&[1f64, 2f64, 4f64, 5f64]).collect::<Vec<_>>();
+        assert_eq!(result, vec![1f64, 1f64, 0.25f64]);
+    }
+}
\ No newline at end of file
diff --git a/pyfinlib/src/lib.rs b/pyfinlib/src/lib.rs
index e0c923b..312bb5a 100644
--- a/pyfinlib/src/lib.rs
+++ b/pyfinlib/src/lib.rs
@@ -12,7 +12,19 @@ pub fn covariance(slice: Vec<f64>, slice_two: Vec<f64>) -> PyResult<Option<f64>>
 
 #[pymodule]
 fn pyfinlib(m: &Bound<'_, PyModule>) -> PyResult<()> {
-    m.add_function(wrap_pyfunction!(compound, m)?)?;
-    m.add_function(wrap_pyfunction!(covariance, m)?)?;
+    register_interest_module(m);
+    register_stats_module(m);
     Ok(())
+}
+
+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)
+}
+
+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)
 }
\ No newline at end of file