Skip to main content
Glama

MCP Stock Details Server

by whdghk1907
test_risk_analysis.pyβ€’11.8 kB
""" Unit tests for Risk Analysis functionality TDD Red Phase: Write failing tests for comprehensive risk assessment """ import pytest import asyncio from unittest.mock import Mock, AsyncMock, patch from datetime import datetime, date, timedelta from typing import Any, Dict, List, Optional # Test imports - initially will fail (TDD Red phase) from src.server import MCPStockDetailsServer from src.tools.risk_tools import RiskAnalyzer from src.exceptions import MCPStockDetailsError, InsufficientDataError class TestRiskAnalysis: """Test cases for risk analysis functionality""" @pytest.fixture def server_with_risk(self): """Create server instance with risk analyzer""" server = MCPStockDetailsServer() # This will fail initially - Red phase server.risk_analyzer = RiskAnalyzer() return server @pytest.fixture def sample_risk_data(self): """Sample risk data for testing""" return { "005930": { # Samsung Electronics "market_risk": { "beta": 1.25, "volatility": 0.28, "var_95": 0.048, "var_99": 0.072, "correlation_market": 0.85, "sharpe_ratio": 1.35 }, "credit_risk": { "credit_rating": "AA", "probability_default": 0.003, "debt_to_equity": 0.45, "interest_coverage": 12.5, "current_ratio": 2.1 }, "liquidity_risk": { "trading_volume": 15000000, "bid_ask_spread": 0.002, "market_impact": 0.015, "liquidity_score": 85.3 }, "operational_risk": { "business_risk_score": 72.5, "regulatory_risk": 65.0, "technology_risk": 58.3, "management_risk": 78.9 }, "concentration_risk": { "geographic_concentration": 0.45, "product_concentration": 0.38, "customer_concentration": 0.22 } } } @pytest.mark.asyncio async def test_get_risk_analysis_tool_registration(self, server_with_risk): """Test that get_risk_analysis tool is properly registered""" tools = await server_with_risk.list_tools() tool_names = [tool.name for tool in tools] assert "get_risk_analysis" in tool_names # Check tool description and parameters risk_tool = next(tool for tool in tools if tool.name == "get_risk_analysis") assert "risk" in risk_tool.description.lower() assert "analysis" in risk_tool.description.lower() assert "company_code" in risk_tool.inputSchema["properties"] @pytest.mark.asyncio async def test_market_risk_assessment(self, server_with_risk, sample_risk_data): """Test market risk assessment""" company_code = "005930" with patch.object(server_with_risk.risk_analyzer, 'get_risk_data') as mock_risk: mock_risk.return_value = sample_risk_data[company_code] result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "include_market_risk": True }) assert result is not None assert len(result) > 0 content = result[0].text # Should include market risk metrics assert "MARKET RISK" in content assert "Beta" in content assert "Volatility" in content assert "VaR" in content or "Value at Risk" in content assert "1.25" in content # Beta value @pytest.mark.asyncio async def test_credit_risk_assessment(self, server_with_risk, sample_risk_data): """Test credit risk assessment""" company_code = "005930" with patch.object(server_with_risk.risk_analyzer, 'get_risk_data') as mock_risk: mock_risk.return_value = sample_risk_data[company_code] result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "include_credit_risk": True }) assert result is not None content = result[0].text # Should include credit risk metrics assert "CREDIT RISK" in content assert "Credit Rating" in content assert "AA" in content assert "Debt-to-Equity" in content assert "Interest Coverage" in content @pytest.mark.asyncio async def test_liquidity_risk_assessment(self, server_with_risk): """Test liquidity risk assessment""" company_code = "005930" result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "include_liquidity_risk": True }) assert result is not None content = result[0].text # Should include liquidity risk metrics assert "LIQUIDITY RISK" in content assert "Trading Volume" in content assert "Bid-Ask Spread" in content assert "Market Impact" in content assert "Liquidity Score" in content @pytest.mark.asyncio async def test_operational_risk_assessment(self, server_with_risk): """Test operational risk assessment""" company_code = "005930" result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "include_operational_risk": True }) assert result is not None content = result[0].text # Should include operational risk metrics assert "OPERATIONAL RISK" in content assert "Business Risk" in content assert "Regulatory Risk" in content assert "Technology Risk" in content assert "Management Risk" in content @pytest.mark.asyncio async def test_concentration_risk_assessment(self, server_with_risk, sample_risk_data): """Test concentration risk assessment""" company_code = "005930" with patch.object(server_with_risk.risk_analyzer, 'get_risk_data') as mock_risk: mock_risk.return_value = sample_risk_data[company_code] result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "include_concentration_risk": True }) assert result is not None content = result[0].text # Should include concentration risk metrics assert "CONCENTRATION RISK" in content assert "Geographic" in content assert "Product" in content assert "Customer" in content @pytest.mark.asyncio async def test_integrated_risk_score(self, server_with_risk, sample_risk_data): """Test integrated risk score calculation""" company_code = "005930" with patch.object(server_with_risk.risk_analyzer, 'get_risk_data') as mock_risk: mock_risk.return_value = sample_risk_data[company_code] result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "include_integrated_score": True }) assert result is not None content = result[0].text # Should include integrated risk score assert "INTEGRATED RISK SCORE" in content assert "Overall Risk Rating" in content assert "Risk Level" in content assert "Score" in content @pytest.mark.asyncio async def test_risk_adjusted_returns(self, server_with_risk): """Test risk-adjusted returns calculation""" company_code = "005930" result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "include_risk_adjusted_returns": True }) assert result is not None content = result[0].text # Should include risk-adjusted metrics assert "RISK-ADJUSTED RETURNS" in content assert "Sharpe Ratio" in content assert "Treynor Ratio" in content or "Alpha" in content assert "Information Ratio" in content or "Jensen's Alpha" in content @pytest.mark.asyncio async def test_scenario_analysis(self, server_with_risk): """Test scenario analysis and stress testing""" company_code = "005930" result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "include_scenario_analysis": True }) assert result is not None content = result[0].text # Should include scenario analysis assert "SCENARIO ANALYSIS" in content assert "Bull Case" in content or "Optimistic" in content assert "Bear Case" in content or "Pessimistic" in content assert "Base Case" in content or "Expected" in content assert "Stress Test" in content @pytest.mark.asyncio async def test_portfolio_risk_metrics(self, server_with_risk): """Test portfolio risk metrics""" company_code = "005930" result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "include_portfolio_metrics": True }) assert result is not None content = result[0].text # Should include portfolio risk metrics assert "PORTFOLIO RISK" in content or "RISK METRICS" in content assert "Correlation" in content assert "Diversification" in content or "Portfolio Impact" in content @pytest.mark.asyncio async def test_comprehensive_risk_report(self, server_with_risk, sample_risk_data): """Test comprehensive risk report generation""" company_code = "005930" with patch.object(server_with_risk.risk_analyzer, 'get_risk_data') as mock_risk: mock_risk.return_value = sample_risk_data[company_code] result = await server_with_risk._handle_get_risk_analysis({ "company_code": company_code, "analysis_type": "comprehensive" }) assert result is not None content = result[0].text # Should include comprehensive analysis assert "COMPREHENSIVE RISK ANALYSIS" in content assert "Risk Summary" in content assert "Key Risk Factors" in content assert "Risk Recommendations" in content @pytest.mark.asyncio async def test_risk_analysis_error_handling(self, server_with_risk): """Test error handling for risk analysis""" # Test invalid company code with pytest.raises(MCPStockDetailsError): await server_with_risk._handle_get_risk_analysis({ "company_code": "", "include_market_risk": True }) # Test insufficient risk data with pytest.raises(InsufficientDataError): await server_with_risk._handle_get_risk_analysis({ "company_code": "999999", # Non-existent company "include_market_risk": True })

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/whdghk1907/mcp-stock-details'

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