EDIT
based on the answer provided, I have followed, but still I cant match the bbg data with my calculations, could some advise how to match the bloomberg Price given the data?

import numpy as np
import scipy.stats as ss
def BlackScholes(payoff, S0, K, T, r, sigma, q):
d1 = (np.log(S0 / K) + (r - q + sigma**2 / 2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
if payoff == "call":
return S0 * np.exp(-q * T) * ss.norm.cdf(d1) - K * np.exp(-r * T) * ss.norm.cdf(d2)
elif payoff == "put":
return K * np.exp(-r * T) * ss.norm.cdf(-d2) - S0 * np.exp(-q * T) * ss.norm.cdf(-d1)
d = 92
h = 5
m = 10
y = 365
T = d/y + h/24/y + m/60/24/y
rr = 0.05277
q =0
S0 = 4739.21
K = 4740
sigma = 0.12954
print(BlackScholes(payoff='call', S0=S0, K=K, T=T, r=rr, sigma=sigma, q=q))
155.7605850060304
I am trying to reconcile SPY Bloomberg Terminal option data, but for some reason, it doesn't match. I would expect this to match the Mid for the 475 strike, but it doesn't
T = 30/365
q = 0
r = 0.0548
S0 = 474.93
payoff = 'call'
K = 475
F = 477.1
print(BlackScholesWithForwards(payoff='call', F=F, K=K, T=T, r=r, sigma=11.84289027/100, q=q))
8.771200411422967
Option monitor bloomberg data, as of 17 Jan 24:
| Expiry | Days to Expiry | Contract Size | Risk-Free Rate | Forward Price |
|---|---|---|---|---|
| 16-Feb-24 (30d) | 30 | 100 | 5.480000 | 477.100000 |
| Strike | Ticker | Bid | Ask | Last | IVM | Volm |
|---|---|---|---|---|---|---|
| 470 | SPY 2/16/24 C470 | 11.279999 | 11.329999 | 11.109999 | 12.769134 | 1322 |
| 471 | SPY 2/16/24 C471 | 10.550000 | 10.600000 | 10.020000 | 12.529111 | 1048 |
| 472 | SPY 2/16/24 C472 | 9.840000 | 9.880000 | 9.859999 | 12.406106 | 1355 |
| 473 | SPY 2/16/24 C473 | 9.159999 | 9.189999 | 9.140000 | 12.176440 | 1285 |
| 474 | SPY 2/16/24 C474 | 8.489999 | 8.520000 | 8.510000 | 12.000890 | 3941 |
| 475 | SPY 2/16/24 C475 | 7.849999 | 7.880000 | 7.880000 | 11.842890 | 10970 |
| 476 | SPY 2/16/24 C476 | 7.239999 | 7.260000 | 7.230000 | 11.700001 | 6087 |
| 477 | SPY 2/16/24 C477 | 6.650000 | 6.670000 | 6.670000 | 11.542202 | 4000 |
import numpy as np
import scipy.stats as ss
def BlackScholesWithForwards(payoff='call', F=1000, K=100, T=None, r=None, sigma=0.35, q=0):
# Check if T and r are provided; if not, use default values or raise an exception
if T is None or r is None:
raise ValueError("Please provide values for T and r")
d1 = (np.log(F / K) + (r - q + sigma**2 / 2) * T) / (sigma * np.sqrt(T))
d2 = d1 - sigma * np.sqrt(T)
if payoff == "call":
return np.exp(-q * T) * (F * ss.norm.cdf(d1) - K * np.exp(-r * T) * ss.norm.cdf(d2))
elif payoff == "put":
return np.exp(-r * T) * (K * ss.norm.cdf(-d2) - F * np.exp(-q * T) * ss.norm.cdf(-d1))
else:
raise ValueError("Invalid value for payoff. Use 'call' or 'put'.")

