Skip to main content
Glama
walkingshamrock

Black-Scholes MCP Server

test_black_scholes_vomma.py6.28 kB
#!/usr/bin/env python3 # filepath: /Users/shugo/ghq/github.com/walkingshamrock/black-scholes-mcp/tests/calculators/test_black_scholes_vomma.py import unittest import math from calculators.black_scholes_vomma import calculate_vomma_value from calculators.black_scholes_common import validate_inputs, calculate_d1_d2, norm_pdf class TestBlackScholesVomma(unittest.TestCase): """ Test cases for Black-Scholes Vomma calculation. Vomma (or Volga) measures the rate of change of vega with respect to volatility. It is the second derivative of the option price with respect to volatility. """ def test_calculate_vomma_at_the_money_call(self): # At-the-money option (S = K) S, K, T, r, q, vol = 100, 100, 1, 0.05, 0.02, 0.2 # Calculate expected vomma value based on the formula d1, d2 = calculate_d1_d2(S, K, T, r, q, vol) sqrt_t = math.sqrt(T) expected_vomma = S * math.exp(-q * T) * norm_pdf(d1) * sqrt_t * (d1 * d2) / vol # Get the actual calculation from our implementation vomma = calculate_vomma_value(S, K, T, r, q, vol, "call") # Test that the calculated value matches our expected value self.assertAlmostEqual(vomma, expected_vomma, places=6) def test_calculate_vomma_at_the_money_put(self): # At-the-money option (S = K) S, K, T, r, q, vol = 100, 100, 1, 0.05, 0.02, 0.2 # For puts, the vomma formula is the same as for calls d1, d2 = calculate_d1_d2(S, K, T, r, q, vol) sqrt_t = math.sqrt(T) expected_vomma = S * math.exp(-q * T) * norm_pdf(d1) * sqrt_t * (d1 * d2) / vol # Get the actual calculation from our implementation vomma = calculate_vomma_value(S, K, T, r, q, vol, "put") # Test that the calculated value matches our expected value self.assertAlmostEqual(vomma, expected_vomma, places=6) # Also verify that call and put vomma are the same call_vomma = calculate_vomma_value(S, K, T, r, q, vol, "call") self.assertAlmostEqual(vomma, call_vomma, places=6) def test_calculate_vomma_in_the_money_call(self): # In-the-money call (S > K) S, K, T, r, q, vol = 110, 100, 1, 0.05, 0.02, 0.2 vomma = calculate_vomma_value(S, K, T, r, q, vol, "call") # Calculate expected vomma and verify d1, d2 = calculate_d1_d2(S, K, T, r, q, vol) sqrt_t = math.sqrt(T) expected_vomma = S * math.exp(-q * T) * norm_pdf(d1) * sqrt_t * (d1 * d2) / vol self.assertAlmostEqual(vomma, expected_vomma, places=6) def test_calculate_vomma_out_of_the_money_call(self): # Out-of-the-money call (S < K) S, K, T, r, q, vol = 90, 100, 1, 0.05, 0.02, 0.2 vomma = calculate_vomma_value(S, K, T, r, q, vol, "call") # Calculate expected vomma and verify d1, d2 = calculate_d1_d2(S, K, T, r, q, vol) sqrt_t = math.sqrt(T) expected_vomma = S * math.exp(-q * T) * norm_pdf(d1) * sqrt_t * (d1 * d2) / vol self.assertAlmostEqual(vomma, expected_vomma, places=6) def test_vomma_changes_with_moneyness(self): # Test how vomma changes with the moneyness of the option K, T, r, q, vol = 100, 1, 0.05, 0.02, 0.2 # Calculate vomma for deep ITM, ATM, and deep OTM vomma_deep_itm = calculate_vomma_value(130, K, T, r, q, vol, "call") vomma_atm = calculate_vomma_value(100, K, T, r, q, vol, "call") vomma_deep_otm = calculate_vomma_value(70, K, T, r, q, vol, "call") # The behavior of vomma with moneyness can be complex and depends on # the specific parameters used. Let's verify that vomma calculations # are correct rather than assuming a specific pattern across moneyness. # Verify the ATM calculation against the formula d1, d2 = calculate_d1_d2(100, K, T, r, q, vol) sqrt_t = math.sqrt(T) expected_vomma = 100 * math.exp(-q * T) * norm_pdf(d1) * sqrt_t * (d1 * d2) / vol self.assertAlmostEqual(vomma_atm, expected_vomma, places=6) def test_vomma_changes_with_volatility(self): # Test how vomma changes with different volatilities S, K, T, r, q = 100, 100, 1, 0.05, 0.02 # Calculate vomma at different volatility levels vomma_low_vol = calculate_vomma_value(S, K, T, r, q, 0.1, "call") vomma_mid_vol = calculate_vomma_value(S, K, T, r, q, 0.2, "call") vomma_high_vol = calculate_vomma_value(S, K, T, r, q, 0.3, "call") # For ATM options, vomma typically decreases as volatility increases # This is a common pattern, though the exact behavior can be complex self.assertGreater(vomma_low_vol, vomma_mid_vol) self.assertGreater(vomma_mid_vol, vomma_high_vol) def test_vomma_changes_with_maturity(self): # Test how vomma changes with different times to maturity S, K, r, q, vol = 100, 100, 0.05, 0.02, 0.2 # Calculate vomma at different times to maturity vomma_short = calculate_vomma_value(S, K, 0.25, r, q, vol, "call") vomma_medium = calculate_vomma_value(S, K, 1, r, q, vol, "call") vomma_long = calculate_vomma_value(S, K, 2, r, q, vol, "call") # For ATM options, vomma typically increases with maturity self.assertLess(vomma_short, vomma_medium) self.assertLess(vomma_medium, vomma_long) def test_vomma_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_vomma_value(S, K, T, r, q, 0, "call") def test_vomma_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_vomma_value(S, K, 0, r, q, vol, "call") 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