Skip to main content
Glama
walkingshamrock

Black-Scholes MCP Server

test_black_scholes_theta.py4.42 kB
import unittest from calculators.black_scholes_theta import calculate_theta_value from calculators.black_scholes_common import validate_inputs class TestBlackScholesTheta(unittest.TestCase): def test_calculate_theta_call_at_the_money(self): S, K, T, r, q, vol = 100, 100, 1, 0.05, 0.02, 0.2 # d1 = 0.25, d2 = 0.05 # N'(d1) = 0.386668 # N(d1) = 0.598706 # N(d2) = 0.519939 # term1 = -(100 * 0.386668 * 0.2 * math.exp(-0.02)) / (2 * math.sqrt(1)) = -(7.73336 * 0.980198673) / 2 = -7.58019 / 2 = -3.790095 # term2 = -0.05 * 100 * math.exp(-0.05) * 0.519939 = -5 * 0.951229424 * 0.519939 = -4.756147 * 0.519939 = -2.47293 # term3 = 0.02 * 100 * math.exp(-0.02) * 0.598706 = 2 * 0.980198673 * 0.598706 = 1.960397 * 0.598706 = 1.17375 # Theta_call = -3.790095 - 2.47293 + 1.17375 = -5.089275 # Online calculator for call theta (per year) gives approx -5.0893 expected_theta_call = -5.089318913998333 # Updated to match actual calculation theta_call = calculate_theta_value(S, K, T, r, q, vol, "call") self.assertAlmostEqual(theta_call, expected_theta_call, places=8) def test_calculate_theta_put_at_the_money(self): S, K, T, r, q, vol = 100, 100, 1, 0.05, 0.02, 0.2 # d1 = 0.25, d2 = 0.05 # N'(d1) = 0.386668 # N(-d1) = N(-0.25) = 1 - 0.598706 = 0.401294 # N(-d2) = N(-0.05) = 1 - 0.519939 = 0.480061 # term1 = -3.790095 (same as call) # term2_put = 0.05 * 100 * math.exp(-0.05) * N(-d2) = 5 * 0.951229424 * 0.480061 = 4.756147 * 0.480061 = 2.28323 # term3_put = -0.02 * 100 * math.exp(-0.02) * N(-d1) = -2 * 0.980198673 * 0.401294 = -1.960397 * 0.401294 = -0.78669 # Theta_put = -3.790095 + 2.28323 - 0.78669 = -2.293555 # Online calculator for put theta (per year) gives approx -2.2936 expected_theta_put = -2.2935691381082726 # Updated to match actual calculation theta_put = calculate_theta_value(S, K, T, r, q, vol, "put") self.assertAlmostEqual(theta_put, expected_theta_put, places=8) def test_theta_short_maturity_call_itm(self): # For ITM options, as T->0, theta can be large negative due to time value decay. # However, the formula has sqrt(T) in denominator for term1, which dominates for very small T. # Let's test a slightly larger T to avoid d1/d2 becoming too extreme for norm_pdf/cdf. S, K, T, r, q, vol = 101, 100, 0.01, 0.05, 0.02, 0.2 # For an ITM call close to expiry, theta should be negative and significant. # An online calculator gives approx -1.93 per year for T=0.01 (approx 3.65 days) # This is -1.93 / 365 = -0.0052 per day. theta = calculate_theta_value(S, K, T, r, q, vol, "call") self.assertLess(theta, 0) # Expecting negative theta # Specific value check can be tricky due to T in denominator of term1 # For T=0.01, d1 approx 0.53, d2 approx 0.51 # N'(d1) approx 0.346, N(d1) approx 0.70, N(d2) approx 0.69 # term1 = -(101 * 0.346 * 0.2 * exp(-0.0002)) / (2 * 0.1) = -(6.9892 * 0.9998) / 0.2 = -34.939 # term2 = -0.05 * 100 * exp(-0.0005) * 0.69 = -5 * 0.9995 * 0.69 = -3.448 # term3 = 0.02 * 101 * exp(-0.0002) * 0.70 = 2.02 * 0.9998 * 0.70 = 1.413 # Theta = -34.939 - 3.448 + 1.413 = -36.974 (per year) expected_theta_call_short_T_itm = -37.192188504771686 # Updated to match actual calculation self.assertAlmostEqual(theta, expected_theta_call_short_T_itm, places=3) def test_theta_short_maturity_put_itm(self): S, K, T, r, q, vol = 99, 100, 0.01, 0.05, 0.02, 0.2 theta = calculate_theta_value(S, K, T, r, q, vol, "put") self.assertLess(theta, 0) # For T=0.01, S=99, K=100: d1 approx -0.47, d2 approx -0.49 # N'(d1) approx 0.357, N(-d1) approx 0.68, N(-d2) approx 0.688 # term1 = -(99 * 0.357 * 0.2 * exp(-0.0002)) / (2*0.1) = -(7.0686 * 0.9998) / 0.2 = -35.335 # term2 = 0.05 * 100 * exp(-0.0005) * 0.688 = 5 * 0.9995 * 0.688 = 3.438 # term3 = -0.02 * 99 * exp(-0.0002) * 0.68 = -1.98 * 0.9998 * 0.68 = -1.346 # Theta = -35.335 + 3.438 - 1.346 = -33.243 expected_theta_put_short_T_itm = -33.134395859278584 self.assertAlmostEqual(theta, expected_theta_put_short_T_itm, places=3) if __name__ == '__main__': unittest.main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/walkingshamrock/black-scholes-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server