diff --git a/Cargo.lock b/Cargo.lock index 9f80713..676577c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -183,6 +183,17 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "console_log" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be8aed40e4edbf4d3b4431ab260b63fdc40f5780a4766824329ea0f1eefe3c0f" +dependencies = [ + "log", + "wasm-bindgen", + "web-sys", +] + [[package]] name = "crossbeam-deque" version = "0.8.6" @@ -258,6 +269,7 @@ dependencies = [ "pyo3", "rayon", "statrs", + "wasm-bindgen", ] [[package]] @@ -274,7 +286,9 @@ name = "finlib-wasm" version = "0.0.1" dependencies = [ "console_error_panic_hook", + "console_log", "finlib", + "log", "wasm-bindgen", "wasm-bindgen-test", ] diff --git a/Cargo.toml b/Cargo.toml index 162eedf..0867f5b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ ndarray-stats = "0.6.0" nalgebra = "0.33.2" statrs = "0.18.0" log = "0.4.25" +wasm-bindgen = "0.2.100" pyo3 = { version = "0.23.4", features = ["extension-module", "abi3-py38"] } pyo3-log = "0.12.1" diff --git a/finlib-ffi/Cargo.toml b/finlib-ffi/Cargo.toml index a371f5c..46c3636 100644 --- a/finlib-ffi/Cargo.toml +++ b/finlib-ffi/Cargo.toml @@ -13,7 +13,7 @@ readme.workspace = true crate-type = ["cdylib"] [dependencies] -finlib = { path = "../finlib" } +finlib = { path = "../finlib", features = ["ffi"] } [build-dependencies] cbindgen = "0.28.0" diff --git a/finlib-wasm/Cargo.toml b/finlib-wasm/Cargo.toml index b368953..e9f9e90 100644 --- a/finlib-wasm/Cargo.toml +++ b/finlib-wasm/Cargo.toml @@ -16,8 +16,10 @@ crate-type = ["cdylib", "rlib"] default = ["console_error_panic_hook"] [dependencies] -wasm-bindgen = "0.2.100" +wasm-bindgen = { workspace = true } finlib = { path = "../finlib", features = ["wasm"] } +log = { workspace = true } +console_log = { version = "1.0.0", features = ["color"] } # The `console_error_panic_hook` crate provides better debugging of panics by # logging them with `console.error`. This is great for development, but requires diff --git a/finlib-wasm/src/lib.rs b/finlib-wasm/src/lib.rs index e7f8af4..d6489d8 100644 --- a/finlib-wasm/src/lib.rs +++ b/finlib-wasm/src/lib.rs @@ -1,4 +1,13 @@ use wasm_bindgen::prelude::wasm_bindgen; +use console_log; +use log::Level; + +#[wasm_bindgen(start)] +fn start() { + if let Err(_) = console_log::init_with_level(Level::Debug) { + + } +} #[wasm_bindgen] pub struct Interest { } diff --git a/finlib/Cargo.toml b/finlib/Cargo.toml index cf65cbd..3fc91b6 100644 --- a/finlib/Cargo.toml +++ b/finlib/Cargo.toml @@ -11,6 +11,7 @@ documentation.workspace = true readme.workspace = true [dependencies] +wasm-bindgen = { workspace = true, optional = true } pyo3 = { workspace = true, optional = true } rayon = { workspace = true, optional = true } ndarray = { workspace = true } @@ -22,5 +23,6 @@ getrandom = "*" [features] py = ["dep:pyo3"] -wasm = ["getrandom/js"] -parallel = ["dep:rayon"] \ No newline at end of file +wasm = ["getrandom/js", "dep:wasm-bindgen"] +parallel = ["dep:rayon"] +ffi = [] \ No newline at end of file diff --git a/finlib/src/lib.rs b/finlib/src/lib.rs index 71f9f98..29a08cf 100644 --- a/finlib/src/lib.rs +++ b/finlib/src/lib.rs @@ -1,4 +1,6 @@ pub mod interest; pub mod stats; pub mod util; -pub mod risk; \ No newline at end of file +pub mod risk; +#[cfg(feature = "py")] +pub mod py; \ No newline at end of file diff --git a/finlib/src/py/mod.rs b/finlib/src/py/mod.rs new file mode 100644 index 0000000..3d5ddb6 --- /dev/null +++ b/finlib/src/py/mod.rs @@ -0,0 +1,30 @@ +use pyo3::prelude::*; +use crate::risk::portfolio::{Portfolio, PortfolioAsset}; + +#[pymethods] +impl Portfolio { + + #[new] + pub fn init(assets: Vec<PortfolioAsset>) -> Self { + Portfolio::from(assets) + } + + #[pyo3(name = "is_valid")] + pub fn is_valid_py(&self) -> bool { + self.is_valid() + } + + #[pyo3(name = "value_at_risk")] + pub fn value_at_risk_py(&mut self, confidence: f64) -> PyResult<Option<f64>> { + Ok(self.value_at_risk(confidence)) + } +} + +#[pymethods] +impl PortfolioAsset { + + #[new] + pub fn init(portfolio_weight: f64, name: String, values: Vec<f64>) -> Self { + PortfolioAsset::new(portfolio_weight, name, values) + } +} \ No newline at end of file diff --git a/finlib/src/risk/mod.rs b/finlib/src/risk/mod.rs index cd03cb3..bc8efc9 100644 --- a/finlib/src/risk/mod.rs +++ b/finlib/src/risk/mod.rs @@ -1 +1,2 @@ -pub mod var; \ No newline at end of file +pub mod var; +pub mod portfolio; diff --git a/finlib/src/risk/portfolio.rs b/finlib/src/risk/portfolio.rs new file mode 100644 index 0000000..0340a39 --- /dev/null +++ b/finlib/src/risk/portfolio.rs @@ -0,0 +1,201 @@ +use ndarray::prelude::*; +use ndarray_stats::CorrelationExt; +#[cfg(feature = "wasm")] +use wasm_bindgen::prelude::*; +#[cfg(feature = "py")] +use pyo3::prelude::*; +use crate::risk::var::varcovar::portfolio_value_at_risk; +use crate::stats; +use crate::util::roc::rates_of_change; + +#[cfg_attr(feature = "wasm", wasm_bindgen)] +#[cfg_attr(feature = "py", pyclass)] +#[cfg_attr(feature = "ffi", repr(C))] +#[derive(Clone)] +pub struct Portfolio { + assets: Vec<PortfolioAsset> +} + +#[cfg_attr(feature = "wasm", wasm_bindgen)] +#[cfg_attr(feature = "py", pyclass)] +#[repr(u8)] +#[derive(Clone, Copy, Debug, Eq, PartialEq, Ord, PartialOrd)] +pub enum ValueType { + Absolute, + RateOfChange +} + +#[cfg_attr(feature = "wasm", wasm_bindgen)] +#[cfg_attr(feature = "py", pyclass)] +#[cfg_attr(feature = "ffi", repr(C))] +#[derive(Clone)] +pub struct PortfolioAsset { + portfolio_weight: f64, + name: String, + values: Vec<f64>, + value_type: ValueType +} + +impl PortfolioAsset { + pub fn new(portfolio_weight: f64, name: String, values: Vec<f64>) -> PortfolioAsset { + PortfolioAsset { + portfolio_weight, name, values, value_type: ValueType::Absolute + } + } + + pub fn apply_rates_of_change(&mut self) { + match self.value_type { + ValueType::Absolute => { + self.values = rates_of_change(&self.values).collect(); + self.value_type = ValueType::RateOfChange; + } + _ => {} + } + } + + pub fn get_mean_and_std(&self) -> Option<(f64, f64)> { + match self.value_type { + ValueType::Absolute => { + let roc = rates_of_change(&self.values).collect::<Vec<f64>>(); + Some((stats::mean(&roc), stats::sample_std_dev(&roc))) + } + ValueType::RateOfChange => { + Some((stats::mean(&self.values), stats::sample_std_dev(&self.values))) + } + } + } +} + +impl Portfolio { + pub fn from(assets: Vec<PortfolioAsset>) -> Portfolio { + Portfolio { + assets + } + } + + pub fn get_asset_weight(&self) -> impl Iterator<Item=f64> + use<'_> { + self.assets + .iter() + .map(|x| x.portfolio_weight) + } + + pub fn apply_rates_of_change(&mut self) { + for asset in self.assets.iter_mut() { + asset.apply_rates_of_change(); + } + } + + pub fn valid_sizes(&self) -> bool { + let mut last_value_length: Option<usize> = None; + + for asset in &self.assets { + match last_value_length { + None => { + last_value_length = Some(asset.values.len()); + } + Some(l) => { + if l != asset.values.len() { + return false; + } + last_value_length = Some(asset.values.len()); + } + } + } + + true + } + + pub fn valid_weights(&self) -> bool { + let mut weight = 1 as f64; + + for asset in &self.assets { + weight -= asset.portfolio_weight; + } + + f64::abs(weight) < 0.01 + } + + pub fn is_valid(&self) -> bool { + self.valid_sizes() && self.valid_weights() + } + + pub fn get_matrix(&self) -> Option<Array2<f64>> { + if self.assets.is_empty() || !self.valid_sizes() { + return None; + } + + let column_count = self.assets.len(); + let row_count = self.assets[0].values.len(); + + let matrix = Array2::from_shape_vec((column_count, row_count), + self.assets + .iter() + .map(|a| a.values.clone()) + .flatten() + .collect::<Vec<f64>>() + ).unwrap(); + + Some(matrix.into_owned()) + } + + pub fn get_mean_and_std(&mut self) -> Option<(f64, f64)> { + if !self.valid_sizes() { + return None; + } + + self.apply_rates_of_change(); + let m = self.get_matrix(); + if m.is_none() { + return None; + } + let m = m.unwrap(); + + let cov = m.cov(1.); + if cov.is_err() { + return None; + } + let cov = cov.unwrap(); + let mean_return = m.mean_axis(Axis(1)); + if mean_return.is_none() { + return None; + } + let mean_return = mean_return.unwrap(); + let asset_weights = Array::from_vec( + self.get_asset_weight().collect::<Vec<f64>>() + ).to_owned(); + + let porfolio_mean_return = mean_return.dot(&asset_weights); + let portfolio_stddev = f64::sqrt(asset_weights.t().dot(&cov).dot(&asset_weights)); + + Some((porfolio_mean_return, portfolio_stddev)) + } + + pub fn value_at_risk(&mut self, confidence: f64) -> Option<f64> { + portfolio_value_at_risk(self, confidence) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn var_test() { + let assets = vec![ + PortfolioAsset::new(0.3, "awdad".to_string(), vec![2f64, 3f64, 4f64]), + PortfolioAsset::new(0.7, "awdad".to_string(), vec![1f64, 6f64, 8f64]), + ]; + + let m = Portfolio::from(assets).get_matrix().unwrap(); + println!("matrix 0; {:?}", m); + + let col = m.row(0); + println!("column 0; {:?}", col); + let cov = m.cov(1.); + + println!("cov 0; {:?}", cov); + + + col.len(); + } +} \ No newline at end of file diff --git a/finlib/src/risk/var/mod.rs b/finlib/src/risk/var/mod.rs index 6c298bf..36a75d8 100644 --- a/finlib/src/risk/var/mod.rs +++ b/finlib/src/risk/var/mod.rs @@ -1,2 +1,2 @@ pub mod historical; -pub mod varcovar; \ No newline at end of file +pub mod varcovar; diff --git a/finlib/src/risk/var/varcovar.rs b/finlib/src/risk/var/varcovar.rs index 870811c..06b0f08 100644 --- a/finlib/src/risk/var/varcovar.rs +++ b/finlib/src/risk/var/varcovar.rs @@ -1,10 +1,11 @@ -use crate::util::roc::rates_of_change; use crate::stats; +use crate::util::roc::rates_of_change; +use ndarray_stats::CorrelationExt; +use crate::risk::portfolio::Portfolio; #[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 { @@ -16,4 +17,44 @@ pub fn value_at_risk(values: &[f64], confidence: f64) -> f64 { let n = Normal::new(0.0, 1.0).unwrap(); mean + std_dev * n.inverse_cdf(confidence) +} + +pub fn portfolio_value_at_risk(portfolio: &mut Portfolio, confidence: f64) -> Option<f64> { + match portfolio.get_mean_and_std() { + None => None, + Some((mean, std_dev)) => { + let n = Normal::new(0.0, 1.0).unwrap(); + Some(mean + std_dev * n.inverse_cdf(confidence)) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::risk::portfolio::PortfolioAsset; + + #[test] + fn var_test() { + let assets = vec![ + PortfolioAsset::new(0.3, "awdad".to_string(), vec![2f64, 3f64, 4f64]), + PortfolioAsset::new(0.7, "awdad".to_string(), vec![1f64, 6f64, 8f64]), + ]; + + let mut portfolio = Portfolio::from(assets); + + portfolio_value_at_risk(&mut portfolio, 0.1); + + } + + #[test] + fn var_test_one_asset() { + let assets = vec![ + PortfolioAsset::new(0.3, "awdad".to_string(), vec![2f64, 3f64, 4f64]) + ]; + + let mut portfolio = Portfolio::from(assets); + + portfolio_value_at_risk(&mut portfolio, 0.1); + } } \ No newline at end of file diff --git a/notebooks/varcovar_var_portfolio.ipynb b/notebooks/varcovar_var_portfolio.ipynb new file mode 100644 index 0000000..425bf13 --- /dev/null +++ b/notebooks/varcovar_var_portfolio.ipynb @@ -0,0 +1,417 @@ +{ + "cells": [ + { + "cell_type": "code", + "id": "initial_id", + "metadata": { + "collapsed": true, + "ExecuteTime": { + "end_time": "2025-02-15T20:07:39.398175Z", + "start_time": "2025-02-15T20:07:34.126281Z" + } + }, + "source": [ + "import matplotlib.pyplot as plt\n", + "from openbb import obb\n", + "import pyfinlib\n" + ], + "outputs": [], + "execution_count": 1 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-02-15T20:07:39.862808Z", + "start_time": "2025-02-15T20:07:39.401473Z" + } + }, + "cell_type": "code", + "source": "aapl = obb.equity.price.historical(symbol='AAPL', provider='yfinance')", + "id": "e5573366e39b2962", + "outputs": [], + "execution_count": 2 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-02-15T20:07:39.992579Z", + "start_time": "2025-02-15T20:07:39.984673Z" + } + }, + "cell_type": "code", + "source": "aapl.results", + "id": "ba361e8697a2e425", + "outputs": [ + { + "data": { + "text/plain": [ + "[YFinanceEquityHistoricalData(date=2024-02-15, open=183.5500030517578, high=184.49000549316406, low=181.35000610351562, close=183.86000061035156, volume=65434500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-02-16, open=183.4199981689453, high=184.85000610351562, low=181.6699981689453, close=182.30999755859375, volume=49701400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-02-20, open=181.7899932861328, high=182.42999267578125, low=180.0, close=181.55999755859375, volume=53665600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-02-21, open=181.94000244140625, high=182.88999938964844, low=180.66000366210938, close=182.32000732421875, volume=41529700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-02-22, open=183.47999572753906, high=184.9600067138672, low=182.4600067138672, close=184.3699951171875, volume=52292200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-02-23, open=185.00999450683594, high=185.0399932861328, low=182.22999572753906, close=182.52000427246094, volume=45119700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-02-26, open=182.24000549316406, high=182.75999450683594, low=180.64999389648438, close=181.16000366210938, volume=40867400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-02-27, open=181.10000610351562, high=183.9199981689453, low=179.55999755859375, close=182.6300048828125, volume=54318900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-02-28, open=182.50999450683594, high=183.1199951171875, low=180.1300048828125, close=181.4199981689453, volume=48953900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-02-29, open=181.27000427246094, high=182.57000732421875, low=179.52999877929688, close=180.75, volume=136682600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-01, open=179.5500030517578, high=180.52999877929688, low=177.3800048828125, close=179.66000366210938, volume=73488000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-04, open=176.14999389648438, high=176.89999389648438, low=173.7899932861328, close=175.10000610351562, volume=81510100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-05, open=170.75999450683594, high=172.0399932861328, low=169.6199951171875, close=170.1199951171875, volume=95132400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-06, open=171.05999755859375, high=171.24000549316406, low=168.67999267578125, close=169.1199951171875, volume=68587700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-07, open=169.14999389648438, high=170.72999572753906, low=168.49000549316406, close=169.0, volume=71765100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-08, open=169.0, high=173.6999969482422, low=168.94000244140625, close=170.72999572753906, volume=76114600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-11, open=172.94000244140625, high=174.3800048828125, low=172.0500030517578, close=172.75, volume=60139500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-12, open=173.14999389648438, high=174.02999877929688, low=171.00999450683594, close=173.22999572753906, volume=59825400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-13, open=172.77000427246094, high=173.19000244140625, low=170.75999450683594, close=171.1300048828125, volume=52488700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-14, open=172.91000366210938, high=174.30999755859375, low=172.0500030517578, close=173.0, volume=72913500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-15, open=171.1699981689453, high=172.6199951171875, low=170.2899932861328, close=172.6199951171875, volume=121664700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-18, open=175.57000732421875, high=177.7100067138672, low=173.52000427246094, close=173.72000122070312, volume=75604200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-19, open=174.33999633789062, high=176.61000061035156, low=173.02999877929688, close=176.0800018310547, volume=55215200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-20, open=175.72000122070312, high=178.6699981689453, low=175.08999633789062, close=178.6699981689453, volume=53423100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-21, open=177.0500030517578, high=177.49000549316406, low=170.83999633789062, close=171.3699951171875, volume=106181300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-22, open=171.75999450683594, high=173.0500030517578, low=170.05999755859375, close=172.27999877929688, volume=71106600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-25, open=170.57000732421875, high=171.94000244140625, low=169.4499969482422, close=170.85000610351562, volume=54288300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-26, open=170.0, high=171.4199981689453, low=169.5800018310547, close=169.7100067138672, volume=57388400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-27, open=170.41000366210938, high=173.60000610351562, low=170.11000061035156, close=173.30999755859375, volume=60273300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-03-28, open=171.75, high=172.22999572753906, low=170.50999450683594, close=171.47999572753906, volume=65672700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-01, open=171.19000244140625, high=171.25, low=169.47999572753906, close=170.02999877929688, volume=46240500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-02, open=169.0800018310547, high=169.33999633789062, low=168.22999572753906, close=168.83999633789062, volume=49329500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-03, open=168.7899932861328, high=170.67999267578125, low=168.5800018310547, close=169.64999389648438, volume=47691700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-04, open=170.2899932861328, high=171.9199981689453, low=168.82000732421875, close=168.82000732421875, volume=53704400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-05, open=169.58999633789062, high=170.38999938964844, low=168.9499969482422, close=169.5800018310547, volume=42055200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-08, open=169.02999877929688, high=169.1999969482422, low=168.24000549316406, close=168.4499969482422, volume=37425500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-09, open=168.6999969482422, high=170.0800018310547, low=168.35000610351562, close=169.6699981689453, volume=42451200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-10, open=168.8000030517578, high=169.08999633789062, low=167.11000061035156, close=167.77999877929688, volume=49709300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-11, open=168.33999633789062, high=175.4600067138672, low=168.16000366210938, close=175.0399932861328, volume=91070300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-12, open=174.25999450683594, high=178.36000061035156, low=174.2100067138672, close=176.5500030517578, volume=101593300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-15, open=175.36000061035156, high=176.6300048828125, low=172.5, close=172.69000244140625, volume=73531800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-16, open=171.75, high=173.75999450683594, low=168.27000427246094, close=169.3800048828125, volume=73711200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-17, open=169.61000061035156, high=170.64999389648438, low=168.0, close=168.0, volume=50901200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-18, open=168.02999877929688, high=168.63999938964844, low=166.5500030517578, close=167.0399932861328, volume=43122900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-19, open=166.2100067138672, high=166.39999389648438, low=164.0800018310547, close=165.0, volume=67772100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-22, open=165.52000427246094, high=167.25999450683594, low=164.77000427246094, close=165.83999633789062, volume=48116400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-23, open=165.35000610351562, high=167.0500030517578, low=164.9199981689453, close=166.89999389648438, volume=49537800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-24, open=166.5399932861328, high=169.3000030517578, low=166.2100067138672, close=169.02000427246094, volume=48251800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-25, open=169.52999877929688, high=170.61000061035156, low=168.14999389648438, close=169.88999938964844, volume=50558300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-26, open=169.8800048828125, high=171.33999633789062, low=169.17999267578125, close=169.3000030517578, volume=44838400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-29, open=173.3699951171875, high=176.02999877929688, low=173.10000610351562, close=173.5, volume=68169400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-04-30, open=173.3300018310547, high=174.99000549316406, low=170.0, close=170.3300018310547, volume=65934800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-01, open=169.5800018310547, high=172.7100067138672, low=169.11000061035156, close=169.3000030517578, volume=50383100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-02, open=172.50999450683594, high=173.4199981689453, low=170.88999938964844, close=173.02999877929688, volume=94214900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-03, open=186.64999389648438, high=187.0, low=182.66000366210938, close=183.3800048828125, volume=163224100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-06, open=182.35000610351562, high=184.1999969482422, low=180.4199981689453, close=181.7100067138672, volume=78569700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-07, open=183.4499969482422, high=184.89999389648438, low=181.32000732421875, close=182.39999389648438, volume=77305800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-08, open=182.85000610351562, high=183.07000732421875, low=181.4499969482422, close=182.74000549316406, volume=45057100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-09, open=182.55999755859375, high=184.66000366210938, low=182.11000061035156, close=184.57000732421875, volume=48983000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-10, open=184.89999389648438, high=185.08999633789062, low=182.1300048828125, close=183.0500030517578, volume=50759500, vwap=None, split_ratio=None, dividend=0.25),\n", + " YFinanceEquityHistoricalData(date=2024-05-13, open=185.44000244140625, high=187.10000610351562, low=184.6199951171875, close=186.27999877929688, volume=72044800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-14, open=187.50999450683594, high=188.3000030517578, low=186.2899932861328, close=187.42999267578125, volume=52393600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-15, open=187.91000366210938, high=190.64999389648438, low=187.3699951171875, close=189.72000122070312, volume=70400000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-16, open=190.47000122070312, high=191.10000610351562, low=189.66000366210938, close=189.83999633789062, volume=52845200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-17, open=189.50999450683594, high=190.80999755859375, low=189.17999267578125, close=189.8699951171875, volume=41282900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-20, open=189.3300018310547, high=191.9199981689453, low=189.00999450683594, close=191.0399932861328, volume=44361300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-21, open=191.08999633789062, high=192.72999572753906, low=190.9199981689453, close=192.35000610351562, volume=42309400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-22, open=192.27000427246094, high=192.82000732421875, low=190.27000427246094, close=190.89999389648438, volume=34648500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-23, open=190.97999572753906, high=191.0, low=186.6300048828125, close=186.8800048828125, volume=51005900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-24, open=188.82000732421875, high=190.5800018310547, low=188.0399932861328, close=189.97999572753906, volume=36294600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-28, open=191.50999450683594, high=193.0, low=189.10000610351562, close=189.99000549316406, volume=52280100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-29, open=189.61000061035156, high=192.25, low=189.50999450683594, close=190.2899932861328, volume=53068000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-30, open=190.75999450683594, high=192.17999267578125, low=190.6300048828125, close=191.2899932861328, volume=49947900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-05-31, open=191.44000244140625, high=192.57000732421875, low=189.91000366210938, close=192.25, volume=75158300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-03, open=192.89999389648438, high=194.99000549316406, low=192.52000427246094, close=194.02999877929688, volume=50080500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-04, open=194.63999938964844, high=195.32000732421875, low=193.02999877929688, close=194.35000610351562, volume=47471400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-05, open=195.39999389648438, high=196.89999389648438, low=194.8699951171875, close=195.8699951171875, volume=54156800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-06, open=195.69000244140625, high=196.5, low=194.1699981689453, close=194.47999572753906, volume=41181800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-07, open=194.64999389648438, high=196.94000244140625, low=194.13999938964844, close=196.88999938964844, volume=53103900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-10, open=196.89999389648438, high=197.3000030517578, low=192.14999389648438, close=193.1199951171875, volume=97262100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-11, open=193.64999389648438, high=207.16000366210938, low=193.6300048828125, close=207.14999389648438, volume=172373300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-12, open=207.3699951171875, high=220.1999969482422, low=206.89999389648438, close=213.07000732421875, volume=198134300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-13, open=214.74000549316406, high=216.75, low=211.60000610351562, close=214.24000549316406, volume=97862700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-14, open=213.85000610351562, high=215.1699981689453, low=211.3000030517578, close=212.49000549316406, volume=70122700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-17, open=213.3699951171875, high=218.9499969482422, low=212.72000122070312, close=216.6699981689453, volume=93728300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-18, open=217.58999633789062, high=218.6300048828125, low=213.0, close=214.2899932861328, volume=79943300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-20, open=213.92999267578125, high=214.24000549316406, low=208.85000610351562, close=209.67999267578125, volume=86172500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-21, open=210.38999938964844, high=211.88999938964844, low=207.11000061035156, close=207.49000549316406, volume=246421400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-24, open=207.72000122070312, high=212.6999969482422, low=206.58999633789062, close=208.13999938964844, volume=80727000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-25, open=209.14999389648438, high=211.3800048828125, low=208.61000061035156, close=209.07000732421875, volume=56713900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-26, open=211.5, high=214.86000061035156, low=210.63999938964844, close=213.25, volume=66213200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-27, open=214.69000244140625, high=215.74000549316406, low=212.35000610351562, close=214.10000610351562, volume=49772700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-06-28, open=215.77000427246094, high=216.07000732421875, low=210.3000030517578, close=210.6199951171875, volume=82542700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-01, open=212.08999633789062, high=217.50999450683594, low=211.9199981689453, close=216.75, volume=60402900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-02, open=216.14999389648438, high=220.3800048828125, low=215.10000610351562, close=220.27000427246094, volume=58046200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-03, open=220.0, high=221.5500030517578, low=219.02999877929688, close=221.5500030517578, volume=37369800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-05, open=221.64999389648438, high=226.4499969482422, low=221.64999389648438, close=226.33999633789062, volume=60412400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-08, open=227.08999633789062, high=227.85000610351562, low=223.25, close=227.82000732421875, volume=59085900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-09, open=227.92999267578125, high=229.39999389648438, low=226.3699951171875, close=228.67999267578125, volume=48076100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-10, open=229.3000030517578, high=233.0800018310547, low=229.25, close=232.97999572753906, volume=62627700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-11, open=231.38999938964844, high=232.38999938964844, low=225.77000427246094, close=227.57000732421875, volume=64710600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-12, open=228.9199981689453, high=232.63999938964844, low=228.67999267578125, close=230.5399932861328, volume=53046500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-15, open=236.47999572753906, high=237.22999572753906, low=233.08999633789062, close=234.39999389648438, volume=62631300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-16, open=235.0, high=236.27000427246094, low=232.3300018310547, close=234.82000732421875, volume=43234300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-17, open=229.4499969482422, high=231.4600067138672, low=226.63999938964844, close=228.8800048828125, volume=57345900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-18, open=230.27999877929688, high=230.44000244140625, low=222.27000427246094, close=224.17999267578125, volume=66034600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-19, open=224.82000732421875, high=226.8000030517578, low=223.27999877929688, close=224.30999755859375, volume=49151500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-22, open=227.00999450683594, high=227.77999877929688, low=223.08999633789062, close=223.9600067138672, volume=48201800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-23, open=224.3699951171875, high=226.94000244140625, low=222.67999267578125, close=225.00999450683594, volume=39960300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-24, open=224.0, high=224.8000030517578, low=217.1300048828125, close=218.5399932861328, volume=61777600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-25, open=218.92999267578125, high=220.85000610351562, low=214.6199951171875, close=217.49000549316406, volume=51391200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-26, open=218.6999969482422, high=219.49000549316406, low=216.00999450683594, close=217.9600067138672, volume=41601300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-29, open=216.9600067138672, high=219.3000030517578, low=215.75, close=218.24000549316406, volume=36311800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-30, open=219.19000244140625, high=220.3300018310547, low=216.1199951171875, close=218.8000030517578, volume=41643800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-07-31, open=221.44000244140625, high=223.82000732421875, low=220.6300048828125, close=222.0800018310547, volume=50036300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-01, open=224.3699951171875, high=224.47999572753906, low=217.02000427246094, close=218.36000061035156, volume=62501000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-02, open=219.14999389648438, high=225.60000610351562, low=217.7100067138672, close=219.86000061035156, volume=105568600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-05, open=199.08999633789062, high=213.5, low=196.0, close=209.27000427246094, volume=119548600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-06, open=205.3000030517578, high=209.99000549316406, low=201.07000732421875, close=207.22999572753906, volume=69660500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-07, open=206.89999389648438, high=213.63999938964844, low=206.38999938964844, close=209.82000732421875, volume=63516400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-08, open=213.11000061035156, high=214.1999969482422, low=208.8300018310547, close=213.30999755859375, volume=47161100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-09, open=212.10000610351562, high=216.77999877929688, low=211.97000122070312, close=216.24000549316406, volume=42201600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-12, open=216.07000732421875, high=219.50999450683594, low=215.60000610351562, close=217.52999877929688, volume=38028100, vwap=None, split_ratio=None, dividend=0.25),\n", + " YFinanceEquityHistoricalData(date=2024-08-13, open=219.00999450683594, high=221.88999938964844, low=219.00999450683594, close=221.27000427246094, volume=44155300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-14, open=220.57000732421875, high=223.02999877929688, low=219.6999969482422, close=221.72000122070312, volume=41960600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-15, open=224.60000610351562, high=225.35000610351562, low=222.75999450683594, close=224.72000122070312, volume=46414000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-16, open=223.9199981689453, high=226.8300018310547, low=223.64999389648438, close=226.0500030517578, volume=44340200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-19, open=225.72000122070312, high=225.99000549316406, low=223.0399932861328, close=225.88999938964844, volume=40687800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-20, open=225.77000427246094, high=227.1699981689453, low=225.4499969482422, close=226.50999450683594, volume=30299000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-21, open=226.52000427246094, high=227.97999572753906, low=225.0500030517578, close=226.39999389648438, volume=34765500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-22, open=227.7899932861328, high=228.33999633789062, low=223.89999389648438, close=224.52999877929688, volume=43695300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-23, open=225.66000366210938, high=228.22000122070312, low=224.3300018310547, close=226.83999633789062, volume=38677300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-26, open=226.75999450683594, high=227.27999877929688, low=223.88999938964844, close=227.17999267578125, volume=30602200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-27, open=226.0, high=228.85000610351562, low=224.88999938964844, close=228.02999877929688, volume=35934600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-28, open=227.9199981689453, high=229.86000061035156, low=225.67999267578125, close=226.49000549316406, volume=38052200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-29, open=230.10000610351562, high=232.9199981689453, low=228.8800048828125, close=229.7899932861328, volume=51906300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-08-30, open=230.19000244140625, high=230.39999389648438, low=227.47999572753906, close=229.0, volume=52990800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-03, open=228.5500030517578, high=229.0, low=221.1699981689453, close=222.77000427246094, volume=50190600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-04, open=221.66000366210938, high=221.77999877929688, low=217.47999572753906, close=220.85000610351562, volume=43840200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-05, open=221.6300048828125, high=225.47999572753906, low=221.52000427246094, close=222.3800048828125, volume=36615400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-06, open=223.9499969482422, high=225.24000549316406, low=219.77000427246094, close=220.82000732421875, volume=48423000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-09, open=220.82000732421875, high=221.27000427246094, low=216.7100067138672, close=220.91000366210938, volume=67180000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-10, open=218.9199981689453, high=221.47999572753906, low=216.72999572753906, close=220.11000061035156, volume=51591000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-11, open=221.4600067138672, high=223.08999633789062, low=217.88999938964844, close=222.66000366210938, volume=44587100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-12, open=222.5, high=223.5500030517578, low=219.82000732421875, close=222.77000427246094, volume=37498200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-13, open=223.5800018310547, high=224.0399932861328, low=221.91000366210938, close=222.5, volume=36766600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-16, open=216.5399932861328, high=217.22000122070312, low=213.9199981689453, close=216.32000732421875, volume=59357400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-17, open=215.75, high=216.89999389648438, low=214.5, close=216.7899932861328, volume=45519300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-18, open=217.5500030517578, high=222.7100067138672, low=217.5399932861328, close=220.69000244140625, volume=59894900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-19, open=224.99000549316406, high=229.82000732421875, low=224.6300048828125, close=228.8699951171875, volume=66781300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-20, open=229.97000122070312, high=233.08999633789062, low=227.6199951171875, close=228.1999969482422, volume=318679900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-23, open=227.33999633789062, high=229.4499969482422, low=225.80999755859375, close=226.47000122070312, volume=54146000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-24, open=228.64999389648438, high=229.35000610351562, low=225.72999572753906, close=227.3699951171875, volume=43556100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-25, open=224.92999267578125, high=227.2899932861328, low=224.02000427246094, close=226.3699951171875, volume=42308700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-26, open=227.3000030517578, high=228.5, low=225.41000366210938, close=227.52000427246094, volume=36636700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-27, open=228.4600067138672, high=229.52000427246094, low=227.3000030517578, close=227.7899932861328, volume=34026000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-09-30, open=230.0399932861328, high=233.0, low=229.64999389648438, close=233.0, volume=54541900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-01, open=229.52000427246094, high=229.64999389648438, low=223.74000549316406, close=226.2100067138672, volume=63285000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-02, open=225.88999938964844, high=227.3699951171875, low=223.02000427246094, close=226.77999877929688, volume=32880600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-03, open=225.13999938964844, high=226.80999755859375, low=223.32000732421875, close=225.6699981689453, volume=34044200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-04, open=227.89999389648438, high=228.0, low=224.1300048828125, close=226.8000030517578, volume=37245100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-07, open=224.5, high=225.69000244140625, low=221.3300018310547, close=221.69000244140625, volume=39505400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-08, open=224.3000030517578, high=225.97999572753906, low=223.25, close=225.77000427246094, volume=31855700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-09, open=225.22999572753906, high=229.75, low=224.8300018310547, close=229.5399932861328, volume=33591100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-10, open=227.77999877929688, high=229.5, low=227.1699981689453, close=229.0399932861328, volume=28183500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-11, open=229.3000030517578, high=229.41000366210938, low=227.33999633789062, close=227.5500030517578, volume=31759200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-14, open=228.6999969482422, high=231.72999572753906, low=228.60000610351562, close=231.3000030517578, volume=39882100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-15, open=233.61000061035156, high=237.49000549316406, low=232.3699951171875, close=233.85000610351562, volume=64751400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-16, open=231.60000610351562, high=232.1199951171875, low=229.83999633789062, close=231.77999877929688, volume=34082200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-17, open=233.42999267578125, high=233.85000610351562, low=230.52000427246094, close=232.14999389648438, volume=32993800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-18, open=236.17999267578125, high=236.17999267578125, low=234.00999450683594, close=235.0, volume=46431500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-21, open=234.4499969482422, high=236.85000610351562, low=234.4499969482422, close=236.47999572753906, volume=36254500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-22, open=233.88999938964844, high=236.22000122070312, low=232.60000610351562, close=235.86000061035156, volume=38846600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-23, open=234.0800018310547, high=235.13999938964844, low=227.75999450683594, close=230.75999450683594, volume=52287000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-24, open=229.97999572753906, high=230.82000732421875, low=228.41000366210938, close=230.57000732421875, volume=31109500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-25, open=229.74000549316406, high=233.22000122070312, low=229.57000732421875, close=231.41000366210938, volume=38802300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-28, open=233.32000732421875, high=234.72999572753906, low=232.5500030517578, close=233.39999389648438, volume=36087100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-29, open=233.10000610351562, high=234.3300018310547, low=232.32000732421875, close=233.6699981689453, volume=35417200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-30, open=232.61000061035156, high=233.47000122070312, low=229.5500030517578, close=230.10000610351562, volume=47070900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-10-31, open=229.33999633789062, high=229.8300018310547, low=225.3699951171875, close=225.91000366210938, volume=64370100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-01, open=220.97000122070312, high=225.35000610351562, low=220.27000427246094, close=222.91000366210938, volume=65276700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-04, open=220.99000549316406, high=222.7899932861328, low=219.7100067138672, close=222.00999450683594, volume=44944500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-05, open=221.8000030517578, high=223.9499969482422, low=221.13999938964844, close=223.4499969482422, volume=28111300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-06, open=222.61000061035156, high=226.07000732421875, low=221.19000244140625, close=222.72000122070312, volume=54561100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-07, open=224.6300048828125, high=227.8800048828125, low=224.57000732421875, close=227.47999572753906, volume=42137700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-08, open=227.1699981689453, high=228.66000366210938, low=226.41000366210938, close=226.9600067138672, volume=38328800, vwap=None, split_ratio=None, dividend=0.25),\n", + " YFinanceEquityHistoricalData(date=2024-11-11, open=225.0, high=225.6999969482422, low=221.5, close=224.22999572753906, volume=42005600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-12, open=224.5500030517578, high=225.58999633789062, low=223.36000061035156, close=224.22999572753906, volume=40398300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-13, open=224.00999450683594, high=226.64999389648438, low=222.75999450683594, close=225.1199951171875, volume=48566200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-14, open=225.02000427246094, high=228.8699951171875, low=225.0, close=228.22000122070312, volume=44923900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-15, open=226.39999389648438, high=226.9199981689453, low=224.27000427246094, close=225.0, volume=47923700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-18, open=225.25, high=229.74000549316406, low=225.1699981689453, close=228.02000427246094, volume=44686000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-19, open=226.97999572753906, high=230.16000366210938, low=226.66000366210938, close=228.27999877929688, volume=36211800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-20, open=228.05999755859375, high=229.92999267578125, low=225.88999938964844, close=229.0, volume=35169600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-21, open=228.8800048828125, high=230.16000366210938, low=225.7100067138672, close=228.52000427246094, volume=42108300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-22, open=228.05999755859375, high=230.72000122070312, low=228.05999755859375, close=229.8699951171875, volume=38168300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-25, open=231.4600067138672, high=233.25, low=229.74000549316406, close=232.8699951171875, volume=90152800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-26, open=233.3300018310547, high=235.57000732421875, low=233.3300018310547, close=235.05999755859375, volume=45986200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-27, open=234.47000122070312, high=235.69000244140625, low=233.80999755859375, close=234.92999267578125, volume=33498400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-11-29, open=234.80999755859375, high=237.80999755859375, low=233.97000122070312, close=237.3300018310547, volume=28481400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-02, open=237.27000427246094, high=240.7899932861328, low=237.16000366210938, close=239.58999633789062, volume=48137100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-03, open=239.80999755859375, high=242.75999450683594, low=238.89999389648438, close=242.64999389648438, volume=38861000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-04, open=242.8699951171875, high=244.11000061035156, low=241.25, close=243.00999450683594, volume=44383900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-05, open=243.99000549316406, high=244.5399932861328, low=242.1300048828125, close=243.0399932861328, volume=40033900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-06, open=242.91000366210938, high=244.6300048828125, low=242.0800018310547, close=242.83999633789062, volume=36870600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-09, open=241.8300018310547, high=247.24000549316406, low=241.75, close=246.75, volume=44649200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-10, open=246.88999938964844, high=248.2100067138672, low=245.33999633789062, close=247.77000427246094, volume=36914800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-11, open=247.9600067138672, high=250.8000030517578, low=246.25999450683594, close=246.49000549316406, volume=45205800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-12, open=246.88999938964844, high=248.74000549316406, low=245.67999267578125, close=247.9600067138672, volume=32777500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-13, open=247.82000732421875, high=249.2899932861328, low=246.24000549316406, close=248.1300048828125, volume=33155300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-16, open=247.99000549316406, high=251.3800048828125, low=247.64999389648438, close=251.0399932861328, volume=51694800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-17, open=250.0800018310547, high=253.8300018310547, low=249.77999877929688, close=253.47999572753906, volume=51356400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-18, open=252.16000366210938, high=254.27999877929688, low=247.74000549316406, close=248.0500030517578, volume=56774100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-19, open=247.5, high=252.0, low=247.08999633789062, close=249.7899932861328, volume=60882300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-20, open=248.0399932861328, high=255.0, low=245.69000244140625, close=254.49000549316406, volume=147495300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-23, open=254.77000427246094, high=255.64999389648438, low=253.4499969482422, close=255.27000427246094, volume=40858800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-24, open=255.49000549316406, high=258.2099914550781, low=255.2899932861328, close=258.20001220703125, volume=23234700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-26, open=258.19000244140625, high=260.1000061035156, low=257.6300048828125, close=259.0199890136719, volume=27237100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-27, open=257.8299865722656, high=258.70001220703125, low=253.05999755859375, close=255.58999633789062, volume=42355300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-30, open=252.22999572753906, high=253.5, low=250.75, close=252.1999969482422, volume=35557500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2024-12-31, open=252.44000244140625, high=253.27999877929688, low=249.42999267578125, close=250.4199981689453, volume=39480700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-02, open=248.92999267578125, high=249.10000610351562, low=241.82000732421875, close=243.85000610351562, volume=55740700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-03, open=243.36000061035156, high=244.17999267578125, low=241.88999938964844, close=243.36000061035156, volume=40244100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-06, open=244.30999755859375, high=247.3300018310547, low=243.1999969482422, close=245.0, volume=45045600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-07, open=242.97999572753906, high=245.5500030517578, low=241.35000610351562, close=242.2100067138672, volume=40856000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-08, open=241.9199981689453, high=243.7100067138672, low=240.0500030517578, close=242.6999969482422, volume=37628900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-10, open=240.00999450683594, high=240.16000366210938, low=233.0, close=236.85000610351562, volume=61710900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-13, open=233.52999877929688, high=234.6699981689453, low=229.72000122070312, close=234.39999389648438, volume=49630700, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-14, open=234.75, high=236.1199951171875, low=232.47000122070312, close=233.27999877929688, volume=39435300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-15, open=234.63999938964844, high=238.9600067138672, low=234.42999267578125, close=237.8699951171875, volume=39832000, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-16, open=237.35000610351562, high=238.00999450683594, low=228.02999877929688, close=228.25999450683594, volume=71759100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-17, open=232.1199951171875, high=232.2899932861328, low=228.47999572753906, close=229.97999572753906, volume=68488300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-21, open=224.0, high=224.4199981689453, low=219.3800048828125, close=222.63999938964844, volume=98070400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-22, open=219.7899932861328, high=224.1199951171875, low=219.7899932861328, close=223.8300018310547, volume=64126500, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-23, open=224.74000549316406, high=227.02999877929688, low=222.3000030517578, close=223.66000366210938, volume=60234800, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-24, open=224.77999877929688, high=225.6300048828125, low=221.41000366210938, close=222.77999877929688, volume=54697900, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-27, open=224.02000427246094, high=232.14999389648438, low=223.97999572753906, close=229.86000061035156, volume=94863400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-28, open=230.85000610351562, high=240.19000244140625, low=230.80999755859375, close=238.25999450683594, volume=75707600, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-29, open=234.1199951171875, high=239.86000061035156, low=234.00999450683594, close=239.36000061035156, volume=45486100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-30, open=238.6699981689453, high=240.7899932861328, low=237.2100067138672, close=237.58999633789062, volume=55658300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-01-31, open=247.19000244140625, high=247.19000244140625, low=233.44000244140625, close=236.0, volume=101075100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-02-03, open=229.99000549316406, high=231.8300018310547, low=225.6999969482422, close=228.00999450683594, volume=73063300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-02-04, open=227.25, high=233.1300048828125, low=226.64999389648438, close=232.8000030517578, volume=45067300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-02-05, open=228.52999877929688, high=232.6699981689453, low=228.27000427246094, close=232.47000122070312, volume=39620300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-02-06, open=231.2899932861328, high=233.8000030517578, low=230.42999267578125, close=233.22000122070312, volume=29925300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-02-07, open=232.60000610351562, high=234.0, low=227.25999450683594, close=227.6300048828125, volume=39707200, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-02-10, open=229.57000732421875, high=230.58999633789062, low=227.1999969482422, close=227.64999389648438, volume=33115600, vwap=None, split_ratio=None, dividend=0.25),\n", + " YFinanceEquityHistoricalData(date=2025-02-11, open=228.1999969482422, high=235.22999572753906, low=228.1300048828125, close=232.6199951171875, volume=53718400, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-02-12, open=231.1999969482422, high=236.9600067138672, low=230.67999267578125, close=236.8699951171875, volume=45243300, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-02-13, open=236.91000366210938, high=242.33999633789062, low=235.57000732421875, close=241.52999877929688, volume=53614100, vwap=None, split_ratio=None, dividend=0.0),\n", + " YFinanceEquityHistoricalData(date=2025-02-14, open=241.25, high=245.5500030517578, low=240.99000549316406, close=244.60000610351562, volume=40838100, vwap=None, split_ratio=None, dividend=0.0)]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 3 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-02-15T20:07:40.016044Z", + "start_time": "2025-02-15T20:07:40.014035Z" + } + }, + "cell_type": "code", + "source": "data = [i.open for i in aapl.results]", + "id": "481bc5b5742518f7", + "outputs": [], + "execution_count": 4 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-02-15T20:07:40.041952Z", + "start_time": "2025-02-15T20:07:40.038215Z" + } + }, + "cell_type": "code", + "source": [ + "returns = pyfinlib.util.rates_of_change(data)\n", + "portfolio = pyfinlib.Portfolio([pyfinlib.PortfolioAsset(1, \"AAPL\", data)])\n", + "\n", + "VaR_historical = portfolio.value_at_risk(0.05)\n", + "VaR_historical_10 = portfolio.value_at_risk(0.1)\n", + "VaR_historical, VaR_historical_10" + ], + "id": "28a68dea99911874", + "outputs": [ + { + "data": { + "text/plain": [ + "(-0.026022532720986438, -0.020002956044025813)" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 5 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-02-15T20:07:40.167970Z", + "start_time": "2025-02-15T20:07:40.061711Z" + } + }, + "cell_type": "code", + "source": [ + "# Plot the historical returns and VaR threshold\n", + "plt.figure(figsize=(10, 6))\n", + "plt.hist(returns, bins=50, alpha=0.75, color='blue', edgecolor='black')\n", + "plt.axvline(VaR_historical, color='red', linestyle='--', label=f'VaR (95%): {VaR_historical:.2%}')\n", + "plt.axvline(VaR_historical_10, color='orange', linestyle='--', label=f'VaR (90%): {VaR_historical_10:.2%}')\n", + "plt.title('Historical Returns of AAPL')\n", + "plt.xlabel('Returns')\n", + "plt.ylabel('Frequency')\n", + "plt.legend()\n", + "plt.show()" + ], + "id": "5ab5e055a23f28ed", + "outputs": [ + { + "data": { + "text/plain": [ + "<Figure size 1000x600 with 1 Axes>" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAA0kAAAIjCAYAAADWYVDIAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAYqZJREFUeJzt3Qd4FOX2+PGTtmlAAOnSBZEiSLGgoDRBsCCgiA1Q/yIX9KqIKFYUEcVru1cE/SkgdlFRrl1RUAELWBDwIiBBkQ4SSELaZv7PeZdNZtNIwk4ym/1+nmfg3d2ZfWd3ssmcPe97JsKyLEsAAAAAAEak7z8AAAAAgCJIAgAAAAAbgiQAAAAAsCFIAgAAAAAbgiQAAAAAsCFIAgAAAAAbgiQAAAAAsCFIAgAAAAAbgiQAAAAAsCFIAoAK1rx5cxk9erS4SUREhEyZMsWR505OTjbPP2/ePEeeHz45OTkyadIkadKkiURGRsqFF15Y2bsEACGLIAkAjoKe+GsAsHLlyiIf79Wrl3To0OGo+/nggw8cC2LcYsmSJea99C9RUVFSr149ueiii+TXX38t13Nu27bNvG8//fSTVHVz5syRRx55xLxfL7zwgtx8882l2u6UU04x7/esWbOOuK7X65VGjRqZ9T/88MMi19H3234cExISpF27dnLXXXfJgQMHSv3ZAYDKFF2pvQNAGFq/fr35pr+sQdLMmTMdC5QOHTok0dHu+JPwz3/+U04++WTJzs6W1atXy+zZs00AtWbNGmnQoEGZg6T77rvPZO9OOukkqco+//xzOfbYY+Xxxx8v9TYbNmyQ77//3rw/L7/8svzjH/84Yh/bt2/PW3/gwIHFrqtBV7Vq1SQ1NVU++eQTmTZtmtl+2bJlJjgCADdzx19EAAgjsbGx4ga5ubmSlZUlcXFxZnGLnj17mmyIX5s2bczJ+/z5881wMjfIyMgQj8dT5mDXSbt27ZKaNWuWaZuXXnrJZOseffRR857r0EgNgEpav0uXLjJq1Ci54447JC0tTRITE4tcV5+vTp06pj127FgZNmyYvP322/LNN99I9+7dy/jqAKBiuee3OwCE6ZwkzZhotqN169YmWDnmmGOkR48e8umnn5rHdV3NIin7MCY/PVG95ZZbzFwUDcA0qPjXv/4llmUF9KvbXH/99SYD0L59e7PuRx99lPdYwSzVX3/9Jddcc40ZXqXrtmjRwgQrGlipffv2ycSJE+XEE080GYMaNWqYzMLPP/8c9KBJbdq0qdD+XX311VK/fn2zf/qadMiZn2afNCOlrrrqqrz3zT83qri5YTpEUhf78+h2r732mhkyptkaHUKmQ8d0e33tui86B0jbdevWNe+LDk2z0+27du0q1atXN++Vvm9PPvnkEV//kY6vf87XF198IWvXrs17nbrfR/LKK6+YYOa8886TpKQkc7ukbOPChQtlxIgRMnz4cHP73XffldLq06eP+X/z5s2l3gYAKguZJAAIgpSUFNmzZ0+h+zUAOhINTqZPny7/7//9PzM/RE++dZ7GDz/8IGeffbZcd911ZtiYBk0vvvhiwLZ6onzBBReYE2QNaHRI2ccffyy33nqrOXEvOPRKhzu98cYbJljSb/mLyxpof7ov+/fvlzFjxsgJJ5xgnu/NN9+U9PR0k0X5/fff5Z133pGLL77YBFA7d+6UZ555Rs466yxZt26dCa6CQYMAVatWrbz7tK/TTjstL/DTwETnyOh7oO/fTTfdJG3btpX7779f7rnnHvMa/MHW6aefXq79mDp1qnndGgBlZmaattJgaMCAAXLqqaea4OWzzz4zmZnjjjsub/iaHrtLL71U+vbtKw8//LC5T+dZ6dCzG2+8sdg+S3N89bXrz4UOZ9OhbfqzpPT1l+Tbb7+VjRs3yty5c81rGTp0qAmgNUNUlEWLFpnn1yBJhz1qIKnrX3bZZaV6//xBrn4JAACuZwEAym3u3Ln6dX6JS/v27QO2adasmTVq1Ki82506dbLOPffcEvsZP368ea6C3nnnHXP/Aw88EHD/RRddZEVERFgbN27Mu0/Xi4yMtNauXVvoefSxe++9N+/2yJEjzbrff/99oXVzc3PN/xkZGZbX6w14bPPmzVZsbKx1//33B9ynz6/vVUm++OILs96cOXOs3bt3W9u2bbM++ugjq1WrVua1fPfdd3nrXnPNNVbDhg2tPXv2BDzHiBEjrKSkJCs9Pd3c1v0vru+Cx8HvrLPOMkvB/WrZsmXe8/rp9vqY/fWqzp07W127ds27feONN1o1atSwcnJyrLIoy/HVfS74s1aS66+/3mrSpEne8fzkk09MXz/++GOR65933nnWGWeckXf72WeftaKjo61du3YFrKc/R/o869evN8dRj/8zzzxjfi7q169v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5njCmWPy888/y6WXXmp+J8XHx0vbtm3lySefDHgOPiuBZs6cKc2bNze/y0899VT57rvvSlx/wYIFcsIJJ5j1TzzxRPnggw8CHtcaSFqFtWHDhuYY9OvXTzZs2HDUxz7cBPO4ZGdny2233WbuT0xMlEaNGsnIkSNl27ZtAc+h/RX8XDz00EOOvcZw/6yMHj260Pt9zjnnBKzDZ6Xij0tx51uPPPJI+H5WrBB0zjnnWJ06dbK++eYb66uvvrJatWplXXrppSVu8/jjj1vTp083i77sv//+u8zPm5KSYtWvX9+6/PLLrTVr1livvvqqFR8fbz3zzDNWuCvPMRk7dqzVpEkTa/HixdbKlSut0047zTr99NPzHk9PT7e2b98esAwYMMA666yz8tb54osvzPFcv359wHper9fR1xsqnDguSt/zuXPnBrznhw4dynv8999/txISEqwJEyZY69ats/7zn/9YUVFR1kcffWSFOyeOyfPPP2/985//tJYsWWJt2rTJevHFF83vJn3f/fis5Hvttdcsj8djzZkzx1q7dq117bXXWjVr1rR27txZ5PrLli0zP78zZswwP8933XWXFRMTY/3yyy956zz00ENWUlKS9c4771g///yzdcEFF1gtWrQI+FyU59iHk2Afl/3791v9+vWzXn/9det///uftWLFCuuUU06xunbtGvA8zZo1s+6///6Az0VqamqFvOZw/KyMGjXKfBbs7/e+ffsCnofPSsUfl4LnW3PmzLEiIiLM35Rw/ayEXJCkB1f/0H///fd593344YfmQP71119H3N5/olAwSCrN8z799NNWrVq1rMzMzLx1brvtNqtNmzZWOCvPMdE/XvoBXbBgQd59v/76q3ke/UNWlF27dplt5s+ff8TjCWePi95euHBhsX1PmjTJat++fcB9l1xyiQlyw1lFfVbUuHHjrN69e+fd5rOST0+Ux48fn3dbA8VGjRqZL9GKMnz4cOvcc88NuO/UU0+1rrvuOtPOzc21GjRoYD3yyCMBxy02NtZ8mRaMv13hINjHpSjfffedOQ5btmwJOPHTL1JRMcdEg6TBgwcX2yefFXd8VgYPHmz16dMn4L5w+6yE3HC7FStWmNRrt27d8u7TYQ2RkZHy7bffOvq8us6ZZ54pHo8nb50BAwbI+vXr5e+//5ZwVZ5jsmrVKjMUQtfz0zRw06ZNzfMVZf78+ZKQkCAXXXRRocf0IsM6zOXss8+WZcuWBeV1hTqnj4sO/6pTp46ccsopMmfOHDPcyN63/Tn8n5Xijm24qKjPikpJSZHatWsXuj/cPytZWVnmPbW/n/r+6+3i3s8j/Txv3rzZDFu0r5OUlGSGwPjXcepvV1XhxHEp7nOhQ4T0WNjpkCEdztq5c2czvCgnJ0fCnZPHRIf/1qtXT9q0aSP/+Mc/ZO/evQHPwWelcj8rOpz7/fffN8McCwqnz0q0hBj9Q6QfLLvo6GhzMnA0Y+tL87z6f4sWLQLWqV+/ft5jtWrVknBUnmOi92uwWfAPlb6fxW3z/PPPy2WXXWbG+/vpyd7s2bPNL9PMzEx57rnnzNwz/UWq82HCmZPH5f7775c+ffqYoPWTTz6RcePGmfHi//znP/Oex//ZsD/HgQMH5NChQwHHMJxU1Gdl+fLl8vrrr5s/cn58Vnz27NkjXq+3yJ/P//3vf0VuU9zPs/1vg/++ktZx4m9XVeHEcSlqbp/OUdL5ezrXxU9/b+lnQI+FfnYmT54s27dvl8cee0zCmVPHROcfDR061JxPbdq0Se644w4ZOHCgOWGPioris+KCz8oLL7wg1atXN8fJLtw+K64Jkm6//XZ5+OGHS1zn119/rbD9gbuOif7y1L5efPHFgPv1Wyhd/E4//XTzS/fxxx8vtG5V4Ybjcvfdd+e19duktLQ0842SP0gKN244Jn5r1qyRwYMHy7333iv9+/cP688K4KfZ2OHDh5uM96xZswIemzBhQl67Y8eO5kuJ6667TqZPn24KzyC4RowYkdfWAgL6nh933HEmu9S3b99K3Tf46OiQyy+/3BR5COfPimuCpFtuucVUPClJy5YtpUGDBnmVzfw01aeVUPSx8irN8+r/Bat8+W8fTd9u5eQx0fs1ZaxVBu3fkOv7WdQ2+q23DhPq2rXrEfdbh399/fXXUlW56bj46bCiqVOnmgyF/qIs7rOi395WxSySW47JunXrzEnGmDFj5K677pJw/6wURYeI6rfVRf18lnQMSlrf/7/epxk7+zr6e8u/jhN/u6oKJ45LwQBpy5Yt8vnnnwdkkYr7fabHJjk5OeCLhXDj5DEp+LtR+9q4caP5/cVnpXKPy1dffWWmkbz++utH3Jcq/1mxQox/Qp9WePL7+OOPg1a4oaTn9RduyMrKyltn8uTJFG4oxzHxT0Z/88038+7T6kNFTUY/ePCgVa1atYBKXSXRakZDhgyxwp3Tx8XugQceMJ8Ne+GGDh06BKyjlYko3ODcMdGKm/Xq1bNuvfXWUu9PuH5WdNLz9ddfHzDp+dhjjy1x0vN5550XcF/37t0LFW7417/+FVANtajCDeX92xUOgn1clP69vvDCC00hGS3+UxovvfSSFRkZWajiWjhy4pgU9Oeff5rPwbvvvmtu81mp3OOihTUKVoAM189KyAVJ/tKQnTt3tr799lvr66+/tlq3bh1QGnLr1q0mcNHH/bRM4Y8//mj93//9n/nwffnll+b23r17S/28erKiJcCvvPJKc0KiJRi1zDElwMt3TLSscdOmTa3PP//c/DLUD6wuBT333HNWXFxckVW5tMqKltzdsGGDKWV54403mg/sZ5995uCrDe/jsmjRIvM50vdb33f98kA/B/fcc0+hEuB6wq6V2GbOnEkJcAePiR6LunXrWldccUVAaVb7SSGflXz6u1sDmHnz5pkTsjFjxpjyuTt27DCP6+/422+/PaB8bnR0tAmC9Of53nvvLbIEuD6HnuitXr3aVIYqqgR4Scc+3AX7uGiApKXYGzdubP30008Bnw1/ldrly5ebz4Y+rqWO9aRPP0sjR46spHehah8T/dJz4sSJ5guezZs3m98/Xbp0MZ+FjIyMvOfhs1Lxv8P8X+7o3+5Zs2YV6jMcPyshGSRpYKMfFs0u1KhRw7rqqqvMB89PP3gaCGnWyE9/IPS+gote66W0z6v0+hc9evQwP5watesfRpTvmOjJg5Yp1gyEfij1G23941WQngxedtllRfb78MMPW8cdd5wJomrXrm316tXLnEjCueOipVhPOukk85yJiYnmWhazZ88udL0dfU5dT6/l0LJly4DPWjhz4pgU9/tNy7X68VkJpJlpDTz151O/ldXrsfjptdj021S7N954wzr++OPN+pqVeP/99wMe12zS3Xffbb5I078Pffv2NdeksivN35hwF8zj4v8sFbX4P1+rVq0ypZD1Glf62Wjbtq314IMPBpywh7tgHhO9/mH//v3NybWepOvvKL3Gj//k3o/PSsX/DlP6pb9eY0+TAgWF42clQv+p7CF/AAAAAOAWIXedJAAAAABwEkESAAAAANgQJAEAAACADUESAAAAANgQJAEAAACADUESAAAAANgQJAEAAACADUESAAAAANgQJAEAAACADUESAKDSjR49WiIiIswSExMjLVq0kEmTJklGRkaptl+yZInZdv/+/Y7vKwCg6ouu7B0AAECdc845MnfuXMnOzpZVq1bJqFGjTODz8MMPV+h+aP8aqAEAwheZJACAK8TGxkqDBg2kSZMmcuGFF0q/fv3k008/NY/l5ubK9OnTTYYpPj5eOnXqJG+++aZ5LDk5WXr37m3atWrVMoGVZqZU8+bN5Yknngjo56STTpIpU6bk3db1Z82aJRdccIEkJibKtGnTzOO63osvvmieIykpSUaMGCEHDx7M2077P/HEE83+HHPMMWZ/09LSKuS9AgA4iyAJAOA6a9askeXLl4vH4zG3NUCaP3++zJ49W9auXSs333yzXHHFFbJ06VITVL311ltmvfXr18v27dvlySefLFN/GhQNGTJEfvnlF7n66qvNfZs2bZJ33nlH3nvvPbNoXw899JB5TPu49NJLzbq//vqrGe43dOhQsSwr6O8FAKDiMdwOAOAKGohUq1ZNcnJyJDMzUyIjI+Wpp54y7QcffFA+++wz6d69u1m3ZcuW8vXXX8szzzwjZ511ltSuXdvcX69ePalZs2aZ+77sssvkqquuCrhPs1fz5s2T6tWrm9tXXnmlLF682GSaNEjS/dTAqFmzZuZxzSoBAKoGgiQAgCvokDkd9qZD1h5//HGJjo6WYcOGmcxRenq6nH322QHrZ2VlSefOnYPSd7du3Qrdp8Ps/AGSatiwoezatcu0dbhf3759TWA0YMAA6d+/v1x00UVmuB8AIPQRJAEAXEHnA7Vq1cq058yZYwKR559/Xjp06GDue//99+XYY48tNI+pJJqNKjgETgszFNV3QQWLN+jcJc0uqaioKDNfSocEfvLJJ/Kf//xH7rzzTvn222/NvCkAQGhjThIAwHU0uLnjjjvkrrvuknbt2plg6I8//jBBlH3R+UjKP3fJ6/UGPE/dunXN0Di/AwcOyObNm4Oyjxo0nXHGGXLffffJjz/+aPZh4cKFQXluAEDlIpMEAHCliy++WG699VYz72jixImmWINmcnr06CEpKSmybNkyqVGjhikVrvOCNGjReU2DBg0yFed0flOfPn3MvKLzzz/fzFW65557TBboaGnGSOcn6TA7nQelt3fv3i1t27YNymsHAFQugiQAgCvpnKTrr79eZsyYYbI/mhXSKne///67CXi6dOlisk1Kh+FpRuf22283BRhGjhxpgqPJkyebbc877zxTxnvq1KlBySRpcPbll1+a8uKandIg7dFHH5WBAwcG4ZUDACpbhEW9UgAAAADIw5wkAAAAALAhSAIAAAAAG4IkAAAAALAhSAIAAAAAG4IkAAAAALAhSAIAAAAAG4IkAAAAALAhSAIAAAAAG4IkAAAAALAhSAIAAAAAG4IkAAAAAJB8/x+C8nKvBR5fygAAAABJRU5ErkJggg==" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 6 + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": "", + "id": "ddeb6ada3ab526b5" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyfinlib/src/lib.rs b/pyfinlib/src/lib.rs index 17ccebb..9f9f586 100644 --- a/pyfinlib/src/lib.rs +++ b/pyfinlib/src/lib.rs @@ -4,6 +4,11 @@ use pyo3::prelude::*; mod pyfinlib { use super::*; + #[pymodule_export] + use finlib::risk::portfolio::Portfolio; + #[pymodule_export] + use finlib::risk::portfolio::PortfolioAsset; + #[pymodule_init] fn init(m: &Bound<'_, PyModule>) -> PyResult<()> { pyo3_log::init();