voly 0.0.95__py3-none-any.whl → 0.0.97__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/client.py CHANGED
@@ -87,231 +87,69 @@ class VolyClient:
87
87
  # -------------------------------------------------------------------------
88
88
 
89
89
  @staticmethod
90
- def svi(log_moneyness_array: float, a: float, b: float, sigma: float, rho: float, m: float) -> float:
91
- return SVIModel.svi(log_moneyness_array, a, b, sigma, rho, m)
92
-
93
- @staticmethod
94
- def svi_d(log_moneyness_array: float, a: float, b: float, sigma: float, rho: float, m: float) -> float:
95
- return SVIModel.svi_d(log_moneyness_array, a, b, sigma, rho, m)
96
-
97
- @staticmethod
98
- def svi_dd(log_moneyness_array: float, a: float, b: float, sigma: float, rho: float, m: float) -> float:
99
- return SVIModel.svi_dd(log_moneyness_array, a, b, sigma, rho, m)
100
-
101
- @staticmethod
102
- def d1(s: float, k: float, r: float, vol: float, t: float,
90
+ def d1(s: float, K: float, r: float, o: float, t: float,
103
91
  option_type: str = 'call') -> float:
104
- return d1(s, k, r, vol, t, option_type)
92
+ return d1(s, K, r, o, t, option_type)
105
93
 
106
94
  @staticmethod
107
- def d2(s: float, k: float, r: float, vol: float, t: float,
95
+ def d2(s: float, K: float, r: float, o: float, t: float,
108
96
  option_type: str = 'call') -> float:
109
- return d2(s, k, r, vol, t, option_type)
97
+ return d2(s, K, r, o, t, option_type)
110
98
 
111
99
  @staticmethod
112
- def bs(s: float, k: float, r: float, vol: float, t: float,
100
+ def bs(s: float, K: float, r: float, o: float, t: float,
113
101
  option_type: str = 'call') -> float:
114
- """
115
- Calculate Black-Scholes option price.
116
-
117
- Parameters:
118
- - s: Underlying price
119
- - k: Strike price
120
- - r: Risk-free rate
121
- - vol: Volatility
122
- - t: Time to expiry in years
123
- - option_type: 'call' or 'put'
124
-
125
- Returns:
126
- - Option price
127
- """
128
- return bs(s, k, r, vol, t, option_type)
102
+ return bs(s, K, r, o, t, option_type)
129
103
 
130
104
  @staticmethod
131
- def delta(s: float, k: float, r: float, vol: float, t: float,
105
+ def delta(s: float, K: float, r: float, o: float, t: float,
132
106
  option_type: str = 'call') -> float:
133
- """
134
- Calculate option delta.
135
-
136
- Parameters:
137
- - s: Underlying price
138
- - k: Strike price
139
- - r: Risk-free rate
140
- - vol: Volatility
141
- - t: Time to expiry in years
142
- - option_type: 'call' or 'put'
143
-
144
- Returns:
145
- - Delta value
146
- """
147
- return delta(s, k, r, vol, t, option_type)
107
+ return delta(s, K, r, o, t, option_type)
148
108
 
149
109
  @staticmethod
150
- def gamma(s: float, k: float, r: float, vol: float, t: float,
110
+ def gamma(s: float, K: float, r: float, o: float, t: float,
151
111
  option_type: str = 'call') -> float:
152
- """
153
- Calculate option gamma.
154
-
155
- Parameters:
156
- - s: Underlying price
157
- - k: Strike price
158
- - r: Risk-free rate
159
- - vol: Volatility
160
- - t: Time to expiry in years
161
-
162
- Returns:
163
- - Gamma value
164
- """
165
- return gamma(s, k, r, vol, t, option_type)
112
+ return gamma(s, K, r, o, t, option_type)
166
113
 
167
114
  @staticmethod
168
- def vega(s: float, k: float, r: float, vol: float, t: float,
115
+ def vega(s: float, K: float, r: float, o: float, t: float,
169
116
  option_type: str = 'call') -> float:
170
- """
171
- Calculate option vega.
172
-
173
- Parameters:
174
- - s: Underlying price
175
- - k: Strike price
176
- - r: Risk-free rate
177
- - vol: Volatility
178
- - t: Time to expiry in years
179
-
180
- Returns:
181
- - Vega value (for 1% change in volatility)
182
- """
183
- return vega(s, k, r, vol, t, option_type)
117
+ return vega(s, K, r, o, t, option_type)
184
118
 
185
119
  @staticmethod
186
- def theta(s: float, k: float, r: float, vol: float, t: float,
120
+ def theta(s: float, K: float, r: float, o: float, t: float,
187
121
  option_type: str = 'call') -> float:
188
- """
189
- Calculate option theta.
190
-
191
- Parameters:
192
- - s: Underlying price
193
- - k: Strike price
194
- - r: Risk-free rate
195
- - vol: Volatility
196
- - t: Time to expiry in years
197
- - option_type: 'call' or 'put'
198
-
199
- Returns:
200
- - Theta value (per day)
201
- """
202
- return theta(s, k, r, vol, t, option_type)
122
+ return theta(s, K, r, o, t, option_type)
203
123
 
204
124
  @staticmethod
205
- def rho(s: float, k: float, r: float, vol: float, t: float,
125
+ def rho(s: float, K: float, r: float, o: float, t: float,
206
126
  option_type: str = 'call') -> float:
207
- """
208
- Calculate option rho.
209
-
210
- Parameters:
211
- - s: Underlying price
212
- - k: Strike price
213
- - r: Risk-free rate
214
- - vol: Volatility
215
- - t: Time to expiry in years
216
- - option_type: 'call' or 'put'
217
-
218
- Returns:
219
- - Rho value (for 1% change in interest rate)
220
- """
221
- return rho(s, k, r, vol, t, option_type)
127
+ return rho(s, K, r, o, t, option_type)
222
128
 
223
129
  @staticmethod
224
- def vanna(s: float, k: float, r: float, vol: float, t: float,
130
+ def vanna(s: float, K: float, r: float, o: float, t: float,
225
131
  option_type: str = 'call') -> float:
226
- """
227
- Calculate option vanna.
228
-
229
- Parameters:
230
- - s: Underlying price
231
- - k: Strike price
232
- - r: Risk-free rate
233
- - vol: Volatility
234
- - t: Time to expiry in years
235
-
236
- Returns:
237
- - Vanna value
238
- """
239
- return vanna(s, k, r, vol, t, option_type)
132
+ return vanna(s, K, r, o, t, option_type)
240
133
 
241
134
  @staticmethod
242
- def volga(s: float, k: float, r: float, vol: float, t: float,
135
+ def volga(s: float, K: float, r: float, o: float, t: float,
243
136
  option_type: str = 'call') -> float:
244
- """
245
- Calculate option volga (vomma).
246
-
247
- Parameters:
248
- - s: Underlying price
249
- - k: Strike price
250
- - r: Risk-free rate
251
- - vol: Volatility
252
- - t: Time to expiry in years
253
-
254
- Returns:
255
- - Volga value
256
- """
257
- return volga(s, k, r, vol, t, option_type)
137
+ return volga(s, K, r, o, t, option_type)
258
138
 
259
139
  @staticmethod
260
- def charm(s: float, k: float, r: float, vol: float, t: float,
140
+ def charm(s: float, K: float, r: float, o: float, t: float,
261
141
  option_type: str = 'call') -> float:
262
- """
263
- Calculate option charm (delta decay).
264
-
265
- Parameters:
266
- - s: Underlying price
267
- - k: Strike price
268
- - r: Risk-free rate
269
- - vol: Volatility
270
- - t: Time to expiry in years
271
- - option_type: 'call' or 'put'
272
-
273
- Returns:
274
- - Charm value (per day)
275
- """
276
- return charm(s, k, r, vol, t, option_type)
142
+ return charm(s, K, r, o, t, option_type)
277
143
 
278
144
  @staticmethod
279
- def greeks(s: float, k: float, r: float, vol: float, t: float,
145
+ def greeks(s: float, K: float, r: float, o: float, t: float,
280
146
  option_type: str = 'call') -> Dict[str, float]:
281
- """
282
- Calculate all option Greeks.
283
-
284
- Parameters:
285
- - s: Underlying price
286
- - k: Strike price
287
- - r: Risk-free rate
288
- - vol: Volatility
289
- - t: Time to expiry in years
290
- - option_type: 'call' or 'put'
291
-
292
- Returns:
293
- - Dictionary with all Greeks (price, delta, gamma, vega, theta, rho, vanna, volga, charm)
294
- """
295
- return greeks(s, k, r, vol, t, option_type)
147
+ return greeks(s, K, r, o, t, option_type)
296
148
 
297
149
  @staticmethod
298
- def iv(option_price: float, s: float, k: float, r: float, t: float,
150
+ def iv(option_price: float, s: float, K: float, r: float, t: float,
299
151
  option_type: str = 'call') -> float:
300
- """
301
- Calculate implied volatility.
302
-
303
- Parameters:
304
- - option_price: Market price of the option
305
- - s: Underlying price
306
- - k: Strike price
307
- - r: Risk-free rate
308
- - t: Time to expiry in years
309
- - option_type: 'call' or 'put'
310
-
311
- Returns:
312
- - Implied volatility
313
- """
314
- return iv(option_price, s, k, r, t, option_type)
152
+ return iv(option_price, s, K, r, t, option_type)
315
153
 
316
154
  # -------------------------------------------------------------------------
317
155
  # Model Fitting
voly/formulas.py CHANGED
@@ -15,72 +15,72 @@ def vectorize_inputs(func):
15
15
  """
16
16
  Decorator to vectorize Black-Scholes functions to handle both scalar and array inputs.
17
17
  """
18
- def wrapper(s, k, r, vol, t, option_type='call'):
18
+ def wrapper(s, K, r, o, t, option_type='call'):
19
19
  # Check if inputs are scalar
20
- k_scalar = np.isscalar(k)
21
- vol_scalar = np.isscalar(vol)
20
+ K_scalar = np.isscalar(K)
21
+ o_scalar = np.isscalar(o)
22
22
 
23
23
  # If both inputs are scalar, use the original function directly
24
- if k_scalar and vol_scalar:
25
- return func(s, k, r, vol, t, option_type)
24
+ if K_scalar and o_scalar:
25
+ return func(s, K, r, o, t, option_type)
26
26
 
27
27
  # Use NumPy's vectorize to handle array inputs
28
- vectorized_func = np.vectorize(lambda k_val, vol_val:
29
- func(s, k_val, r, vol_val, t, option_type))
28
+ vectorized_func = np.vectorize(lambda K_val, o_val:
29
+ func(s, K_val, r, o_val, t, option_type))
30
30
 
31
31
  # Call the vectorized function with the inputs
32
- return vectorized_func(k, vol)
32
+ return vectorized_func(K, o)
33
33
 
34
34
  return wrapper
35
35
 
36
36
 
37
37
  @catch_exception
38
38
  @vectorize_inputs
39
- def d1(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
39
+ def d1(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
40
40
  # option_type is ignored in this function but included for compatibility
41
- if vol <= 0 or t <= 0:
41
+ if o <= 0 or t <= 0:
42
42
  return np.nan
43
- return (np.log(s / k) + (r + vol ** 2 / 2) * t) / (vol * np.sqrt(t))
43
+ return (np.log(s / K) + (r + o ** 2 / 2) * t) / (o * np.sqrt(t))
44
44
 
45
45
  @catch_exception
46
46
  @vectorize_inputs
47
- def d2(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
47
+ def d2(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
48
48
  # option_type is ignored in this function but included for compatibility
49
- if vol <= 0 or t <= 0:
49
+ if o <= 0 or t <= 0:
50
50
  return np.nan
51
- return d1(s, k, r, vol, t, option_type) - vol * np.sqrt(t)
51
+ return d1(s, K, r, o, t, option_type) - o * np.sqrt(t)
52
52
 
53
53
 
54
54
  @catch_exception
55
55
  @vectorize_inputs
56
- def bs(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
57
- if vol <= 0 or t <= 0:
56
+ def bs(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
57
+ if o <= 0 or t <= 0:
58
58
  # Intrinsic value at expiry
59
59
  if option_type.lower() in ["call", "c"]:
60
- return max(0, s - k)
60
+ return max(0, s - K)
61
61
  else:
62
- return max(0, k - s)
62
+ return max(0, K - s)
63
63
 
64
- d1_val = d1(s, k, r, vol, t)
65
- d2_val = d2(s, k, r, vol, t)
64
+ d1_val = d1(s, K, r, o, t)
65
+ d2_val = d2(s, K, r, o, t)
66
66
 
67
67
  if option_type.lower() in ["call", "c"]:
68
- return s * norm.cdf(d1_val) - k * np.exp(-r * t) * norm.cdf(d2_val)
68
+ return s * norm.cdf(d1_val) - K * np.exp(-r * t) * norm.cdf(d2_val)
69
69
  else: # put
70
- return k * np.exp(-r * t) * norm.cdf(-d2_val) - s * norm.cdf(-d1_val)
70
+ return K * np.exp(-r * t) * norm.cdf(-d2_val) - s * norm.cdf(-d1_val)
71
71
 
72
72
 
73
73
  @catch_exception
74
74
  @vectorize_inputs
75
- def delta(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
76
- if vol <= 0 or t <= 0:
75
+ def delta(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
76
+ if o <= 0 or t <= 0:
77
77
  # At expiry, delta is either 0 or 1 for call, 0 or -1 for put
78
78
  if option_type.lower() in ["call", "c"]:
79
- return 1.0 if s > k else 0.0
79
+ return 1.0 if s > K else 0.0
80
80
  else:
81
- return -1.0 if s < k else 0.0
81
+ return -1.0 if s < K else 0.0
82
82
 
83
- d1_val = d1(s, k, r, vol, t)
83
+ d1_val = d1(s, K, r, o, t)
84
84
 
85
85
  if option_type.lower() in ["call", "c"]:
86
86
  return norm.cdf(d1_val)
@@ -90,41 +90,41 @@ def delta(s: float, k: float, r: float, vol: float, t: float, option_type: str =
90
90
 
91
91
  @catch_exception
92
92
  @vectorize_inputs
93
- def gamma(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
94
- if vol <= 0 or t <= 0:
93
+ def gamma(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
94
+ if o <= 0 or t <= 0:
95
95
  return 0.0
96
96
 
97
- d1_val = d1(s, k, r, vol, t, option_type)
98
- return norm.pdf(d1_val) / (s * vol * np.sqrt(t))
97
+ d1_val = d1(s, K, r, o, t, option_type)
98
+ return norm.pdf(d1_val) / (s * o * np.sqrt(t))
99
99
 
100
100
 
101
101
  @catch_exception
102
102
  @vectorize_inputs
103
- def vega(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
104
- if vol <= 0 or t <= 0:
103
+ def vega(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
104
+ if o <= 0 or t <= 0:
105
105
  return 0.0
106
106
 
107
- d1_val = d1(s, k, r, vol, t, option_type)
107
+ d1_val = d1(s, K, r, o, t, option_type)
108
108
  return s * norm.pdf(d1_val) * np.sqrt(t) / 100 # Divided by 100 for 1% change
109
109
 
110
110
 
111
111
  @catch_exception
112
112
  @vectorize_inputs
113
- def theta(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
114
- if vol <= 0 or t <= 0:
113
+ def theta(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
114
+ if o <= 0 or t <= 0:
115
115
  return 0.0
116
116
 
117
- d1_val = d1(s, k, r, vol, t, option_type)
118
- d2_val = d2(s, k, r, vol, t, option_type)
117
+ d1_val = d1(s, K, r, o, t, option_type)
118
+ d2_val = d2(s, K, r, o, t, option_type)
119
119
 
120
120
  # First part of theta (same for both call and put)
121
- theta_part1 = -s * norm.pdf(d1_val) * vol / (2 * np.sqrt(t))
121
+ theta_part1 = -s * norm.pdf(d1_val) * o / (2 * np.sqrt(t))
122
122
 
123
123
  # Second part depends on option type
124
124
  if option_type.lower() in ["call", "c"]:
125
- theta_part2 = -r * k * np.exp(-r * t) * norm.cdf(d2_val)
125
+ theta_part2 = -r * K * np.exp(-r * t) * norm.cdf(d2_val)
126
126
  else: # put
127
- theta_part2 = r * k * np.exp(-r * t) * norm.cdf(-d2_val)
127
+ theta_part2 = r * K * np.exp(-r * t) * norm.cdf(-d2_val)
128
128
 
129
129
  # Return theta per day (t is in years)
130
130
  return (theta_part1 + theta_part2) / 365.0
@@ -132,50 +132,50 @@ def theta(s: float, k: float, r: float, vol: float, t: float, option_type: str =
132
132
 
133
133
  @catch_exception
134
134
  @vectorize_inputs
135
- def rho(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
136
- if vol <= 0 or t <= 0:
135
+ def rho(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
136
+ if o <= 0 or t <= 0:
137
137
  return 0.0
138
138
 
139
- d2_val = d2(s, k, r, vol, t, option_type)
139
+ d2_val = d2(s, K, r, o, t, option_type)
140
140
 
141
141
  if option_type.lower() in ["call", "c"]:
142
- return k * t * np.exp(-r * t) * norm.cdf(d2_val) / 100
142
+ return K * t * np.exp(-r * t) * norm.cdf(d2_val) / 100
143
143
  else: # put
144
- return -k * t * np.exp(-r * t) * norm.cdf(-d2_val) / 100
144
+ return -K * t * np.exp(-r * t) * norm.cdf(-d2_val) / 100
145
145
 
146
146
 
147
147
  @catch_exception
148
148
  @vectorize_inputs
149
- def vanna(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
150
- if vol <= 0 or t <= 0:
149
+ def vanna(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
150
+ if o <= 0 or t <= 0:
151
151
  return 0.0
152
152
 
153
- d1_val = d1(s, k, r, vol, t, option_type)
154
- d2_val = d2(s, k, r, vol, t, option_type)
153
+ d1_val = d1(s, K, r, o, t, option_type)
154
+ d2_val = d2(s, K, r, o, t, option_type)
155
155
 
156
- return -norm.pdf(d1_val) * d2_val / vol
156
+ return -norm.pdf(d1_val) * d2_val / o
157
157
 
158
158
 
159
159
  @catch_exception
160
160
  @vectorize_inputs
161
- def volga(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
162
- if vol <= 0 or t <= 0:
161
+ def volga(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
162
+ if o <= 0 or t <= 0:
163
163
  return 0.0
164
164
 
165
- d1_val = d1(s, k, r, vol, t, option_type)
166
- d2_val = d2(s, k, r, vol, t, option_type)
165
+ d1_val = d1(s, K, r, o, t, option_type)
166
+ d2_val = d2(s, K, r, o, t, option_type)
167
167
 
168
- return s * norm.pdf(d1_val) * np.sqrt(t) * d1_val * d2_val / vol
168
+ return s * norm.pdf(d1_val) * np.sqrt(t) * d1_val * d2_val / o
169
169
 
170
170
 
171
171
  @catch_exception
172
172
  @vectorize_inputs
173
- def charm(s: float, k: float, r: float, vol: float, t: float, option_type: str = 'call') -> float:
174
- if vol <= 0 or t <= 0:
173
+ def charm(s: float, K: float, r: float, o: float, t: float, option_type: str = 'call') -> float:
174
+ if o <= 0 or t <= 0:
175
175
  return 0.0
176
176
 
177
- d1_val = d1(s, k, r, vol, t, option_type)
178
- d2_val = d2(s, k, r, vol, t, option_type)
177
+ d1_val = d1(s, K, r, o, t, option_type)
178
+ d2_val = d2(s, K, r, o, t, option_type)
179
179
 
180
180
  # First term is the same for calls and puts
181
181
  term1 = -norm.pdf(d1_val) * d1_val / (2 * t)
@@ -192,34 +192,34 @@ def charm(s: float, k: float, r: float, vol: float, t: float, option_type: str =
192
192
 
193
193
  @catch_exception
194
194
  @vectorize_inputs
195
- def greeks(s: float, k: float, r: float, vol: float, t: float,
195
+ def greeks(s: float, K: float, r: float, o: float, t: float,
196
196
  option_type: str = 'call') -> Dict[str, float]:
197
197
  return {
198
- 'price': bs(s, k, r, vol, t, option_type),
199
- 'delta': delta(s, k, r, vol, t, option_type),
200
- 'gamma': gamma(s, k, r, vol, t, option_type),
201
- 'vega': vega(s, k, r, vol, t, option_type),
202
- 'theta': theta(s, k, r, vol, t, option_type),
203
- 'rho': rho(s, k, r, vol, t, option_type),
204
- 'vanna': vanna(s, k, r, vol, t, option_type),
205
- 'volga': volga(s, k, r, vol, t, option_type),
206
- 'charm': charm(s, k, r, vol, t, option_type)
198
+ 'price': bs(s, K, r, o, t, option_type),
199
+ 'delta': delta(s, K, r, o, t, option_type),
200
+ 'gamma': gamma(s, K, r, o, t, option_type),
201
+ 'vega': vega(s, K, r, o, t, option_type),
202
+ 'theta': theta(s, K, r, o, t, option_type),
203
+ 'rho': rho(s, K, r, o, t, option_type),
204
+ 'vanna': vanna(s, K, r, o, t, option_type),
205
+ 'volga': volga(s, K, r, o, t, option_type),
206
+ 'charm': charm(s, K, r, o, t, option_type)
207
207
  }
208
208
 
209
209
 
210
210
  @catch_exception
211
211
  @vectorize_inputs
212
- def iv(option_price: float, s: float, k: float, r: float, t: float,
212
+ def iv(option_price: float, s: float, K: float, r: float, t: float,
213
213
  option_type: str = 'call', precision: float = 1e-8,
214
214
  max_iterations: int = 100) -> float:
215
215
  """
216
216
  Calculate implied volatility using Newton-Raphson method.
217
217
 
218
218
  Parameters:
219
- - option_price: Market price of the option
219
+ - option_price: MarKet price of the option
220
220
  - s: Underlying price
221
- - k: Strike price
222
- - r: Risk-free rate
221
+ - K: Strike price
222
+ - r: RisK-free rate
223
223
  - t: Time to expiry in years
224
224
  - option_type: 'call' or 'put'
225
225
  - precision: Desired precision
@@ -233,46 +233,46 @@ def iv(option_price: float, s: float, k: float, r: float, t: float,
233
233
 
234
234
  # Check if option price is within theoretical bounds
235
235
  if option_type.lower() in ["call", "c"]:
236
- intrinsic = max(0, s - k * np.exp(-r * t))
236
+ intrinsic = max(0, s - K * np.exp(-r * t))
237
237
  if option_price < intrinsic:
238
238
  return np.nan # Price below intrinsic value
239
239
  if option_price >= s:
240
240
  return np.inf # Price exceeds underlying
241
241
  else: # put
242
- intrinsic = max(0, k * np.exp(-r * t) - s)
242
+ intrinsic = max(0, K * np.exp(-r * t) - s)
243
243
  if option_price < intrinsic:
244
244
  return np.nan # Price below intrinsic value
245
- if option_price >= k:
245
+ if option_price >= K:
246
246
  return np.inf # Price exceeds strike
247
247
 
248
248
  # Initial guess - Manaster and Koehler (1982) method
249
- vol = np.sqrt(2 * np.pi / t) * option_price / s
249
+ o = np.sqrt(2 * np.pi / t) * option_price / s
250
250
 
251
251
  # Ensure initial guess is reasonable
252
- vol = max(0.001, min(vol, 5.0))
252
+ o = max(0.001, min(o, 5.0))
253
253
 
254
254
  for _ in range(max_iterations):
255
255
  # Calculate option price and vega with current volatility
256
- price = bs(s, k, r, vol, t, option_type)
257
- v = vega(s, k, r, vol, t, option_type)
256
+ price = bs(s, K, r, o, t, option_type)
257
+ v = vega(s, K, r, o, t, option_type)
258
258
 
259
259
  # Calculate price difference
260
260
  price_diff = price - option_price
261
261
 
262
262
  # Check if precision reached
263
263
  if abs(price_diff) < precision:
264
- return vol
264
+ return o
265
265
 
266
266
  # Avoid division by zero
267
267
  if abs(v) < 1e-10:
268
268
  # Change direction based on whether price is too high or too low
269
- vol = vol * 1.5 if price_diff < 0 else vol * 0.5
269
+ o = o * 1.5 if price_diff < 0 else o * 0.5
270
270
  else:
271
271
  # Newton-Raphson update
272
- vol = vol - price_diff / (v * 100) # Vega is for 1% change
272
+ o = o - price_diff / (v * 100) # Vega is for 1% change
273
273
 
274
274
  # Ensure volatility stays in reasonable bounds
275
- vol = max(0.001, min(vol, 5.0))
275
+ o = max(0.001, min(o, 5.0))
276
276
 
277
277
  # If we reach here, we didn't converge
278
278
  return np.nan
@@ -286,7 +286,7 @@ def get_domain(domain_params: Tuple[float, float, int] = (-1.5, 1.5, 1000),
286
286
  t: float = None,
287
287
  return_domain: str = 'log_moneyness') -> np.ndarray:
288
288
  """
289
- Compute the x-domain for a given return type (log-moneyness, moneyness, strikes, or delta).
289
+ Compute the x-domain for a given return type (log-moneyness, moneyness, returns, strikes, or delta).
290
290
 
291
291
  Parameters:
292
292
  -----------
@@ -336,7 +336,7 @@ def get_domain(domain_params: Tuple[float, float, int] = (-1.5, 1.5, 1000),
336
336
 
337
337
  elif return_domain == 'delta':
338
338
  # Check for required parameters
339
- required_params = {'s': s, 'o': o, 'r': r, 't': t}
339
+ required_params = {'s': s, 'r': r, 'o': o, 't': t}
340
340
  missing_params = [param for param, value in required_params.items() if value is None]
341
341
  if missing_params:
342
342
  raise ValueError(f"The following parameters are required for return_domain='delta': {missing_params}")
@@ -355,4 +355,4 @@ def get_domain(domain_params: Tuple[float, float, int] = (-1.5, 1.5, 1000),
355
355
 
356
356
  else:
357
357
  raise ValueError(
358
- f"Invalid return_domain: {return_domain}. Must be one of ['log_moneyness', 'moneyness', 'returns', 'strikes', 'delta'].")
358
+ f"Invalid return_domain: {return_domain}. Must be one of ['log_moneyness', 'moneyness', 'returns', 'striKes', 'delta'].")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: voly
3
- Version: 0.0.95
3
+ Version: 0.0.97
4
4
  Summary: Options & volatility research package
5
5
  Author-email: Manu de Cara <manu.de.cara@gmail.com>
6
6
  License: MIT
@@ -1,7 +1,7 @@
1
1
  voly/__init__.py,sha256=8xyDk7rFCn_MOD5hxuv5cxxKZvBVRiSIM7TgaMPpwpw,211
2
- voly/client.py,sha256=M_XmGQAheVSPOBJPXVYJzm1s8ZOcBZ6keeZhb9Yu0R4,15367
2
+ voly/client.py,sha256=kHb357sFOlJ_x17vc0UqIXeJ43SRTcNP-7pIuZ01jkI,11314
3
3
  voly/exceptions.py,sha256=PBsbn1vNMvKcCJwwJ4lBO6glD85jo1h2qiEmD7ArAjs,92
4
- voly/formulas.py,sha256=YsEnX8RECZyInHHM5Suis-APtYAa5HM5sUR8o17uRcc,11716
4
+ voly/formulas.py,sha256=6yuu0-vO6TkV7p94W8d_akuC_byySs02-yhy62W8eA4,11575
5
5
  voly/models.py,sha256=Vs69QZYQ_Tt6hkaZ6Mfnq3II1dHDqQrZTzBNiaOIbwo,3516
6
6
  voly/core/__init__.py,sha256=bu6fS2I1Pj9fPPnl-zY3L7NqrZSY5Zy6NY2uMUvdhKs,183
7
7
  voly/core/charts.py,sha256=E21OZB5lTY4YL2flgaFJ6s5g3_ExtAQT2zryZZxLPyM,12735
@@ -11,8 +11,8 @@ voly/core/interpolate.py,sha256=JkK172-FXyhesW3hY4pEeuJWG3Bugq7QZXbeKoRpLuo,5305
11
11
  voly/core/rnd.py,sha256=yNkQuiiw--exiJLHa9Wd9zy5sZN5_QJ3itKmr04zg-Q,10047
12
12
  voly/utils/__init__.py,sha256=E05mWatyC-PDOsCxQV1p5Xi1IgpOomxrNURyCx_gB-w,200
13
13
  voly/utils/logger.py,sha256=4-_2bVJmq17Q0d7Rd2mPg1AeR8gxv6EPvcmBDMFWcSM,1744
14
- voly-0.0.95.dist-info/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
15
- voly-0.0.95.dist-info/METADATA,sha256=-SqneUSjwQfKII7TKtRq1cF_9_Dr1msCAu_BsZo_6cA,4092
16
- voly-0.0.95.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
17
- voly-0.0.95.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
18
- voly-0.0.95.dist-info/RECORD,,
14
+ voly-0.0.97.dist-info/LICENSE,sha256=wcHIVbE12jfcBOai_wqBKY6xvNQU5E909xL1zZNq_2Q,1065
15
+ voly-0.0.97.dist-info/METADATA,sha256=6IuTDv_DuHFZqsjTHbUSKv8ZEB8hW8cqqWtZNhE5ovg,4092
16
+ voly-0.0.97.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
17
+ voly-0.0.97.dist-info/top_level.txt,sha256=ZfLw2sSxF-LrKAkgGjOmeTcw6_gD-30zvtdEY5W4B7c,5
18
+ voly-0.0.97.dist-info/RECORD,,
File without changes
File without changes