nautilus_model/python/data/
greeks.rs

1// -------------------------------------------------------------------------------------------------
2//  Copyright (C) 2015-2025 Posei Systems Pty Ltd. All rights reserved.
3//  https://poseitrader.io
4//
5//  Licensed under the GNU Lesser General Public License Version 3.0 (the "License");
6//  You may not use this file except in compliance with the License.
7//  You may obtain a copy of the License at https://www.gnu.org/licenses/lgpl-3.0.en.html
8//
9//  Unless required by applicable law or agreed to in writing, software
10//  distributed under the License is distributed on an "AS IS" BASIS,
11//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//  See the License for the specific language governing permissions and
13//  limitations under the License.
14// -------------------------------------------------------------------------------------------------
15
16use pyo3::prelude::*;
17
18use crate::data::greeks::{
19    BlackScholesGreeksResult, ImplyVolAndGreeksResult, black_scholes_greeks, imply_vol,
20    imply_vol_and_greeks,
21};
22
23#[pymethods]
24impl ImplyVolAndGreeksResult {
25    /// Creates a new [`ImplyVolAndGreeksResult`] instance.
26    #[new]
27    fn py_new(vol: f64, price: f64, delta: f64, gamma: f64, theta: f64, vega: f64) -> Self {
28        Self {
29            vol,
30            price,
31            delta,
32            gamma,
33            theta,
34            vega,
35        }
36    }
37
38    #[getter]
39    #[pyo3(name = "vol")]
40    fn py_vol(&self) -> f64 {
41        self.vol
42    }
43
44    #[getter]
45    #[pyo3(name = "price")]
46    fn py_price(&self) -> f64 {
47        self.price
48    }
49
50    #[getter]
51    #[pyo3(name = "delta")]
52    fn py_delta(&self) -> f64 {
53        self.delta
54    }
55
56    #[getter]
57    #[pyo3(name = "gamma")]
58    fn py_gamma(&self) -> f64 {
59        self.gamma
60    }
61
62    #[getter]
63    #[pyo3(name = "vega")]
64    fn py_vega(&self) -> f64 {
65        self.vega
66    }
67
68    #[getter]
69    #[pyo3(name = "theta")]
70    fn py_theta(&self) -> f64 {
71        self.theta
72    }
73
74    fn __repr__(&self) -> String {
75        format!("{self:?}")
76    }
77}
78
79#[pymethods]
80impl BlackScholesGreeksResult {
81    /// Creates a new [`BlackScholesGreeksResult`] instance.
82    #[new]
83    fn py_new(price: f64, delta: f64, gamma: f64, theta: f64, vega: f64) -> Self {
84        Self {
85            price,
86            delta,
87            gamma,
88            theta,
89            vega,
90        }
91    }
92
93    #[getter]
94    #[pyo3(name = "price")]
95    fn py_price(&self) -> f64 {
96        self.price
97    }
98
99    #[getter]
100    #[pyo3(name = "delta")]
101    fn py_delta(&self) -> f64 {
102        self.delta
103    }
104
105    #[getter]
106    #[pyo3(name = "gamma")]
107    fn py_gamma(&self) -> f64 {
108        self.gamma
109    }
110
111    #[getter]
112    #[pyo3(name = "vega")]
113    fn py_vega(&self) -> f64 {
114        self.vega
115    }
116
117    #[getter]
118    #[pyo3(name = "theta")]
119    fn py_theta(&self) -> f64 {
120        self.theta
121    }
122
123    fn __repr__(&self) -> String {
124        format!("{self:?}")
125    }
126}
127
128/// Computes Black-Scholes greeks for given parameters.
129///
130/// # Errors
131///
132/// Returns a `PyErr` if the greeks calculation fails.
133#[pyfunction]
134#[pyo3(name = "black_scholes_greeks")]
135#[allow(clippy::too_many_arguments)]
136pub fn py_black_scholes_greeks(
137    s: f64,
138    r: f64,
139    b: f64,
140    sigma: f64,
141    is_call: bool,
142    k: f64,
143    t: f64,
144    multiplier: f64,
145) -> PyResult<BlackScholesGreeksResult> {
146    let result = black_scholes_greeks(s, r, b, sigma, is_call, k, t, multiplier);
147    Ok(result)
148}
149
150/// Computes the implied volatility for an option given its parameters and market price.
151///
152/// # Errors
153///
154/// Returns a `PyErr` if implied volatility calculation fails.
155#[pyfunction]
156#[pyo3(name = "imply_vol")]
157pub fn py_imply_vol(
158    s: f64,
159    r: f64,
160    b: f64,
161    is_call: bool,
162    k: f64,
163    t: f64,
164    price: f64,
165) -> PyResult<f64> {
166    let vol = imply_vol(s, r, b, is_call, k, t, price);
167    Ok(vol)
168}
169
170/// Computes implied volatility and option greeks for given parameters and market price.
171///
172/// # Errors
173///
174/// Returns a `PyErr` if calculation fails.
175#[pyfunction]
176#[pyo3(name = "imply_vol_and_greeks")]
177#[allow(clippy::too_many_arguments)]
178pub fn py_imply_vol_and_greeks(
179    s: f64,
180    r: f64,
181    b: f64,
182    is_call: bool,
183    k: f64,
184    t: f64,
185    price: f64,
186    multiplier: f64,
187) -> PyResult<ImplyVolAndGreeksResult> {
188    let result = imply_vol_and_greeks(s, r, b, is_call, k, t, price, multiplier);
189    Ok(result)
190}