voly 0.0.234__py3-none-any.whl → 0.0.235__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- voly/formulas.py +39 -54
- {voly-0.0.234.dist-info → voly-0.0.235.dist-info}/METADATA +1 -1
- {voly-0.0.234.dist-info → voly-0.0.235.dist-info}/RECORD +6 -6
- {voly-0.0.234.dist-info → voly-0.0.235.dist-info}/WHEEL +0 -0
- {voly-0.0.234.dist-info → voly-0.0.235.dist-info}/licenses/LICENSE +0 -0
- {voly-0.0.234.dist-info → voly-0.0.235.dist-info}/top_level.txt +0 -0
voly/formulas.py
CHANGED
@@ -8,50 +8,49 @@ from scipy.stats import norm
|
|
8
8
|
from py_vollib.black_scholes.implied_volatility import implied_volatility
|
9
9
|
from typing import Tuple, Dict, Union, List, Optional
|
10
10
|
from voly.utils.logger import catch_exception
|
11
|
-
from
|
11
|
+
from voly.exceptions import VolyError
|
12
12
|
|
13
13
|
|
14
14
|
@catch_exception
|
15
15
|
def vectorize_inputs(func):
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
if
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
return vectorized_func(K, o, t)
|
16
|
+
@wraps(func)
|
17
|
+
def wrapper(s, *args, **kwargs):
|
18
|
+
# s is always scalar
|
19
|
+
all_args = list(args)
|
20
|
+
input_names = func.__code__.co_varnames[1:len(all_args)+1]
|
21
|
+
input_dict = dict(zip(input_names, all_args))
|
22
|
+
input_dict.update(kwargs)
|
23
|
+
|
24
|
+
# Identify vectorized vs scalar inputs
|
25
|
+
vector_lengths = {
|
26
|
+
k: len(v) for k, v in input_dict.items()
|
27
|
+
if isinstance(v, (list, np.ndarray, pd.Series))
|
28
|
+
}
|
29
|
+
|
30
|
+
is_vectorized = len(vector_lengths) > 0
|
31
|
+
|
32
|
+
if is_vectorized:
|
33
|
+
# Check if all are of same length
|
34
|
+
lengths = set(vector_lengths.values())
|
35
|
+
if len(lengths) != 1:
|
36
|
+
raise VolyError("All vectorized inputs must have the same length.")
|
37
|
+
|
38
|
+
if any(not isinstance(v, (list, np.ndarray, pd.Series)) for v in input_dict.values()):
|
39
|
+
raise VolyError("Cannot mix scalar and vector inputs. Pass all as vectors or all as scalars.")
|
40
|
+
|
41
|
+
# Proceed with vectorized call
|
42
|
+
max_len = next(iter(lengths))
|
43
|
+
return [
|
44
|
+
func(
|
45
|
+
s,
|
46
|
+
*(input_dict[name][i] for name in input_names if name in input_dict),
|
47
|
+
**{k: input_dict[k][i] for k in kwargs if k in input_dict}
|
48
|
+
)
|
49
|
+
for i in range(max_len)
|
50
|
+
]
|
51
|
+
else:
|
52
|
+
# All scalar inputs, call directly
|
53
|
+
return func(s, *args, **kwargs)
|
55
54
|
|
56
55
|
return wrapper
|
57
56
|
|
@@ -73,13 +72,6 @@ def d2(s: float, K: float, r: float, o: float, t: float, flag: str = 'call') ->
|
|
73
72
|
@catch_exception
|
74
73
|
@vectorize_inputs
|
75
74
|
def bs(s: float, K: float, r: float, o: float, t: float, flag: str = 'call') -> float:
|
76
|
-
if o <= 0 or t <= 0:
|
77
|
-
# Intrinsic value at expiry
|
78
|
-
if flag.lower() in ["call", "c"]:
|
79
|
-
return max(0, s - K)
|
80
|
-
else:
|
81
|
-
return max(0, K - s)
|
82
|
-
|
83
75
|
d1_val = d1(s, K, r, o, t)
|
84
76
|
d2_val = d2(s, K, r, o, t)
|
85
77
|
|
@@ -92,13 +84,6 @@ def bs(s: float, K: float, r: float, o: float, t: float, flag: str = 'call') ->
|
|
92
84
|
@catch_exception
|
93
85
|
@vectorize_inputs
|
94
86
|
def delta(s: float, K: float, r: float, o: float, t: float, flag: str = 'call') -> float:
|
95
|
-
if o <= 0 or t <= 0:
|
96
|
-
# At expiry, delta is either 0 or 1 for call, 0 or -1 for put
|
97
|
-
if flag.lower() in ["call", "c"]:
|
98
|
-
return 1.0 if s > K else 0.0
|
99
|
-
else:
|
100
|
-
return -1.0 if s < K else 0.0
|
101
|
-
|
102
87
|
d1_val = d1(s, K, r, o, t)
|
103
88
|
|
104
89
|
if flag.lower() in ["call", "c"]:
|
@@ -1,7 +1,7 @@
|
|
1
1
|
voly/__init__.py,sha256=8xyDk7rFCn_MOD5hxuv5cxxKZvBVRiSIM7TgaMPpwpw,211
|
2
2
|
voly/client.py,sha256=H4BY5n1isHOqMYX-Koe8-WKBKE6zxbdDYopDF58BPBI,14533
|
3
3
|
voly/exceptions.py,sha256=PBsbn1vNMvKcCJwwJ4lBO6glD85jo1h2qiEmD7ArAjs,92
|
4
|
-
voly/formulas.py,sha256=
|
4
|
+
voly/formulas.py,sha256=7C7aedAmDIWDO06fHAAjC9V3KDlN_X1Qnyy4tn87-Tc,10289
|
5
5
|
voly/models.py,sha256=CGJQr13Uie7iwtx2hjViN9lMXeRN_uOqzp4u8NPaTlA,9282
|
6
6
|
voly/core/__init__.py,sha256=bu6fS2I1Pj9fPPnl-zY3L7NqrZSY5Zy6NY2uMUvdhKs,183
|
7
7
|
voly/core/charts.py,sha256=6MSU0z01fPOVSssodxdnFqchzDfupSmXq_e71WwDmVQ,12635
|
@@ -13,8 +13,8 @@ voly/core/rnd.py,sha256=wiZ5OIjPDf1Th5_sQ9CZG5JgAo3EL8f63T_Rj1_VP-0,13214
|
|
13
13
|
voly/utils/__init__.py,sha256=E05mWatyC-PDOsCxQV1p5Xi1IgpOomxrNURyCx_gB-w,200
|
14
14
|
voly/utils/density.py,sha256=ONpRli-IaJDgOZ2sb27HHFc9_tkkGSATKl94JODd86A,5879
|
15
15
|
voly/utils/logger.py,sha256=4-_2bVJmq17Q0d7Rd2mPg1AeR8gxv6EPvcmBDMFWcSM,1744
|
16
|
-
voly-0.0.
|
17
|
-
voly-0.0.
|
18
|
-
voly-0.0.
|
19
|
-
voly-0.0.
|
20
|
-
voly-0.0.
|
16
|
+
voly-0.0.235.dist-info/licenses/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
|
17
|
+
voly-0.0.235.dist-info/METADATA,sha256=d35JHNDnrlkN0LVD6bWSqHZyGP6XKzar16GApUw5YJE,4115
|
18
|
+
voly-0.0.235.dist-info/WHEEL,sha256=ck4Vq1_RXyvS4Jt6SI0Vz6fyVs4GWg7AINwpsaGEgPE,91
|
19
|
+
voly-0.0.235.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
|
20
|
+
voly-0.0.235.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|