Skip to main content
Glama
walkingshamrock

Black-Scholes MCP Server

test_black_scholes_vera.py5.76 kB
#!/usr/bin/env python3 # filepath: /Users/shugo/ghq/github.com/walkingshamrock/black-scholes-mcp/tests/calculators/test_black_scholes_vera.py import unittest import math from calculators.black_scholes_vera import calculate_vera_value from calculators.black_scholes_common import validate_inputs, calculate_d1_d2, norm_pdf class TestBlackScholesVera(unittest.TestCase): """ Test cases for Black-Scholes Vera calculation. Vera (or DrhoDvol) measures the rate of change of rho with respect to volatility. """ def test_calculate_vera_at_the_money(self): # At-the-money option (S = K) S, K, T, r, q, vol = 100, 100, 1, 0.05, 0.02, 0.2 # Calculate expected vera value based on the formula for a call d1, d2 = calculate_d1_d2(S, K, T, r, q, vol) expected_vera = -K * T * math.exp(-r * T) * norm_pdf(d2) * d1 / (vol * math.sqrt(T)) # Get the actual calculation from our implementation vera = calculate_vera_value(S, K, T, r, q, vol) # Test that the calculated value matches our expected value self.assertAlmostEqual(vera, expected_vera, places=6) def test_calculate_vera_in_the_money(self): # In-the-money call (S > K) S, K, T, r, q, vol = 110, 100, 1, 0.05, 0.02, 0.2 # Calculate expected vera value d1, d2 = calculate_d1_d2(S, K, T, r, q, vol) expected_vera = -K * T * math.exp(-r * T) * norm_pdf(d2) * d1 / (vol * math.sqrt(T)) # Get the actual calculation vera = calculate_vera_value(S, K, T, r, q, vol) # Test that the calculated value matches our expected value self.assertAlmostEqual(vera, expected_vera, places=6) def test_calculate_vera_out_of_the_money(self): # Out-of-the-money call (S < K) S, K, T, r, q, vol = 90, 100, 1, 0.05, 0.02, 0.2 # Calculate expected vera value d1, d2 = calculate_d1_d2(S, K, T, r, q, vol) expected_vera = -K * T * math.exp(-r * T) * norm_pdf(d2) * d1 / (vol * math.sqrt(T)) # Get the actual calculation vera = calculate_vera_value(S, K, T, r, q, vol) # Test that the calculated value matches our expected value self.assertAlmostEqual(vera, expected_vera, places=6) def test_vera_sign_for_call(self): # Test the sign of vera for different moneyness levels for a call option K, T, r, q, vol = 100, 1, 0.05, 0.02, 0.2 # For deep ITM call (S >> K) vera_itm = calculate_vera_value(130, K, T, r, q, vol) # For ATM call vera_atm = calculate_vera_value(100, K, T, r, q, vol) # For deep OTM call (S << K) vera_otm = calculate_vera_value(70, K, T, r, q, vol) # For calls, vera should be negative for deep ITM options due to positive d1 self.assertLess(vera_itm, 0) # For ATM options, vera should be close to zero and may be positive or negative # depending on exact parameters, but typically negative self.assertLess(vera_atm, 0) # For OTM options, vera can be positive when d1 is negative enough # Let's verify the sign based on d1 d1, _ = calculate_d1_d2(70, K, T, r, q, vol) if d1 < 0: self.assertGreater(vera_otm, 0) else: self.assertLess(vera_otm, 0) def test_vera_changes_with_maturity(self): # Test how vera changes with different times to maturity S, K, r, q, vol = 100, 100, 0.05, 0.02, 0.2 # Calculate vera at different times to maturity vera_short = calculate_vera_value(S, K, 0.25, r, q, vol) vera_medium = calculate_vera_value(S, K, 1, r, q, vol) vera_long = calculate_vera_value(S, K, 2, r, q, vol) # The magnitude of vera increases with time to maturity # since vera includes a factor of T self.assertTrue(abs(vera_short) < abs(vera_medium)) self.assertTrue(abs(vera_medium) < abs(vera_long)) # For ATM options, vera should be negative across different maturities # with standard parameters self.assertLess(vera_short, 0) self.assertLess(vera_medium, 0) self.assertLess(vera_long, 0) def test_vera_changes_with_vol(self): # Test how vera changes with different volatilities S, K, T, r, q = 100, 100, 1, 0.05, 0.02 # Calculate vera at different volatility levels vera_low_vol = calculate_vera_value(S, K, T, r, q, 0.1) vera_mid_vol = calculate_vera_value(S, K, T, r, q, 0.2) vera_high_vol = calculate_vera_value(S, K, T, r, q, 0.3) # The magnitude of vera typically decreases as volatility increases # for ATM options with standard parameters # Note: This depends on how the factor d1/(vol*sqrt(T)) changes # with volatility, which can be complex self.assertTrue(abs(vera_low_vol) > abs(vera_mid_vol)) self.assertTrue(abs(vera_mid_vol) > abs(vera_high_vol)) def test_vera_with_zero_vol(self): # Test case for very low volatility S, K, T, r, q = 100, 100, 1, 0.05, 0.02 # Extremely low volatility should be caught by validation with self.assertRaises(ValueError): calculate_vera_value(S, K, T, r, q, 0) def test_vera_with_zero_time(self): # Test case for very short time to maturity S, K, r, q, vol = 100, 100, 0.05, 0.02, 0.2 # Extremely short time should be caught by validation with self.assertRaises(ValueError): calculate_vera_value(S, K, 0, r, q, vol) 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