Skip to main content
Glama

MCP Market Statistics Server

by whdghk1907
test_market_breadth_tools.pyβ€’14 kB
"""μ‹œμž₯ 폭 μ§€ν‘œ 도ꡬ ν…ŒμŠ€νŠΈ""" import pytest from datetime import datetime, timedelta from unittest.mock import AsyncMock from src.tools.market_breadth_tools import MarketBreadthTool from src.exceptions import DataValidationError, DatabaseConnectionError class TestMarketBreadthTool: """μ‹œμž₯ 폭 μ§€ν‘œ 도ꡬ ν…ŒμŠ€νŠΈ""" @pytest.fixture def mock_db_manager(self): """Mock λ°μ΄ν„°λ² μ΄μŠ€ λ§€λ‹ˆμ €""" return AsyncMock() @pytest.fixture def mock_cache_manager(self): """Mock μΊμ‹œ λ§€λ‹ˆμ €""" return AsyncMock() @pytest.fixture def breadth_tool(self, mock_db_manager, mock_cache_manager): """μ‹œμž₯ 폭 μ§€ν‘œ 도ꡬ μΈμŠ€ν„΄μŠ€""" return MarketBreadthTool(mock_db_manager, mock_cache_manager) @pytest.fixture def sample_breadth_data(self): """μƒ˜ν”Œ μ‹œμž₯ 폭 데이터""" return [ { "date": datetime.now().date(), "market": "KOSPI", "advancing": 850, "declining": 680, "unchanged": 120, "total_issues": 1650, "advance_decline_ratio": 1.25, "advance_volume": 2800000000000, "decline_volume": 1900000000000, "timestamp": datetime.now() }, { "date": datetime.now().date() - timedelta(days=1), "market": "KOSPI", "advancing": 720, "declining": 800, "unchanged": 130, "total_issues": 1650, "advance_decline_ratio": 0.90, "advance_volume": 2100000000000, "decline_volume": 2700000000000, "timestamp": datetime.now() - timedelta(days=1) } ] def test_tool_initialization(self, breadth_tool, mock_db_manager, mock_cache_manager): """도ꡬ μ΄ˆκΈ°ν™” ν…ŒμŠ€νŠΈ""" assert breadth_tool.name == "get_market_breadth" assert breadth_tool.description is not None assert "μ‹œμž₯ 폭" in breadth_tool.description assert breadth_tool.db_manager == mock_db_manager assert breadth_tool.cache_manager == mock_cache_manager def test_tool_definition(self, breadth_tool): """도ꡬ μ •μ˜ ν…ŒμŠ€νŠΈ""" definition = breadth_tool.get_tool_definition() assert definition.name == "get_market_breadth" assert definition.description is not None assert definition.inputSchema is not None # μž…λ ₯ μŠ€ν‚€λ§ˆ 검증 schema = definition.inputSchema assert schema["type"] == "object" assert "properties" in schema properties = schema["properties"] assert "market" in properties assert "period" in properties assert "include_volume_analysis" in properties # market νŒŒλΌλ―Έν„° 검증 market_prop = properties["market"] assert market_prop["type"] == "string" assert "KOSPI" in market_prop["enum"] assert "KOSDAQ" in market_prop["enum"] assert "ALL" in market_prop["enum"] # period νŒŒλΌλ―Έν„° 검증 period_prop = properties["period"] assert period_prop["type"] == "string" assert "1d" in period_prop["enum"] assert "1w" in period_prop["enum"] assert "1m" in period_prop["enum"] @pytest.mark.asyncio async def test_execute_daily_breadth(self, breadth_tool, sample_breadth_data): """일일 μ‹œμž₯ 폭 쑰회 ν…ŒμŠ€νŠΈ""" # μΊμ‹œ 미슀 breadth_tool.cache_manager.get.return_value = None # λ°μ΄ν„°λ² μ΄μŠ€ 응닡 μ„€μ • breadth_tool.db_manager.fetch_all.return_value = sample_breadth_data[:1] # μ‹€ν–‰ result = await breadth_tool.execute({ "market": "KOSPI", "period": "1d", "include_volume_analysis": False }) # κ²°κ³Ό 검증 assert len(result) == 1 content = result[0] assert content.type == "text" # JSON νŒŒμ‹±ν•˜μ—¬ λ‚΄μš© 확인 import json data = json.loads(content.text) assert "timestamp" in data assert "period" in data assert "market" in data assert "breadth_data" in data assert "summary" in data # μ‹œμž₯ 폭 데이터 검증 breadth_data = data["breadth_data"] assert len(breadth_data) == 1 today_data = breadth_data[0] assert today_data["advancing"] == 850 assert today_data["declining"] == 680 assert today_data["unchanged"] == 120 assert today_data["advance_decline_ratio"] == 1.25 # μš”μ•½ 정보 검증 summary = data["summary"] assert "avg_advance_decline_ratio" in summary assert "market_sentiment" in summary assert summary["market_sentiment"] == "μƒμŠΉμ„Έ" # ratio > 1.0 @pytest.mark.asyncio async def test_execute_weekly_trend(self, breadth_tool, sample_breadth_data): """μ£Όκ°„ μ‹œμž₯ 폭 νŠΈλ Œλ“œ 뢄석 ν…ŒμŠ€νŠΈ""" # 일주일 κ°„μ˜ 데이터 weekly_data = [] for i in range(7): date = datetime.now().date() - timedelta(days=i) advancing = 800 + (i * 20) # νŠΈλ Œλ“œ 생성 declining = 700 - (i * 10) weekly_data.append({ "date": date, "market": "KOSPI", "advancing": advancing, "declining": declining, "unchanged": 150, "total_issues": 1650, "advance_decline_ratio": advancing / declining, "advance_volume": 2500000000000, "decline_volume": 2000000000000, "timestamp": datetime.now() - timedelta(days=i) }) breadth_tool.cache_manager.get.return_value = None breadth_tool.db_manager.fetch_all.return_value = weekly_data # μ‹€ν–‰ result = await breadth_tool.execute({ "market": "KOSPI", "period": "1w" }) # κ²°κ³Ό 검증 content = result[0] import json data = json.loads(content.text) assert data["period"] == "1w" assert len(data["breadth_data"]) == 7 # νŠΈλ Œλ“œ 뢄석 확인 assert "trend_analysis" in data trend = data["trend_analysis"] assert "direction" in trend assert "strength" in trend @pytest.mark.asyncio async def test_volume_analysis(self, breadth_tool, sample_breadth_data): """κ±°λž˜λŸ‰ 뢄석 포함 ν…ŒμŠ€νŠΈ""" breadth_tool.cache_manager.get.return_value = None breadth_tool.db_manager.fetch_all.return_value = sample_breadth_data # μ‹€ν–‰ result = await breadth_tool.execute({ "market": "KOSPI", "period": "1d", "include_volume_analysis": True }) # κ²°κ³Ό 검증 content = result[0] import json data = json.loads(content.text) assert "volume_analysis" in data volume_analysis = data["volume_analysis"] assert "advance_volume" in volume_analysis assert "decline_volume" in volume_analysis assert "volume_ratio" in volume_analysis assert "volume_trend" in volume_analysis @pytest.mark.asyncio async def test_market_sentiment_calculation(self, breadth_tool): """μ‹œμž₯ 심리 계산 ν…ŒμŠ€νŠΈ""" # κ°•ν•œ μƒμŠΉμ„Έ 데이터 bullish_data = [{ "date": datetime.now().date(), "market": "KOSPI", "advancing": 1200, "declining": 400, "unchanged": 50, "total_issues": 1650, "advance_decline_ratio": 3.0, "advance_volume": 4000000000000, "decline_volume": 1000000000000, "timestamp": datetime.now() }] breadth_tool.cache_manager.get.return_value = None breadth_tool.db_manager.fetch_all.return_value = bullish_data result = await breadth_tool.execute({ "market": "KOSPI", "period": "1d" }) content = result[0] import json data = json.loads(content.text) summary = data["summary"] assert summary["market_sentiment"] == "κ°•ν•œ μƒμŠΉμ„Έ" # ratio >= 2.0 assert summary["avg_advance_decline_ratio"] == 3.0 def test_advance_decline_ratio_calculation(self, breadth_tool): """μƒμŠΉν•˜λ½λΉ„μœ¨ 계산 ν…ŒμŠ€νŠΈ""" # 정상적인 경우 ratio = breadth_tool._calculate_ad_ratio(800, 600) assert abs(ratio - 1.33) < 0.01 # ν•˜λ½ μ’…λͺ©μ΄ 0인 경우 ratio = breadth_tool._calculate_ad_ratio(800, 0) assert ratio == float('inf') # μƒμŠΉ μ’…λͺ©μ΄ 0인 경우 ratio = breadth_tool._calculate_ad_ratio(0, 600) assert ratio == 0.0 def test_market_sentiment_interpretation(self, breadth_tool): """μ‹œμž₯ 심리 해석 ν…ŒμŠ€νŠΈ""" # κ°•ν•œ μƒμŠΉμ„Έ sentiment = breadth_tool._interpret_market_sentiment(2.5) assert sentiment == "κ°•ν•œ μƒμŠΉμ„Έ" # μƒμŠΉμ„Έ sentiment = breadth_tool._interpret_market_sentiment(1.3) assert sentiment == "μƒμŠΉμ„Έ" # 보합 sentiment = breadth_tool._interpret_market_sentiment(0.95) assert sentiment == "보합" # ν•˜λ½μ„Έ sentiment = breadth_tool._interpret_market_sentiment(0.6) assert sentiment == "ν•˜λ½μ„Έ" # κ°•ν•œ ν•˜λ½μ„Έ sentiment = breadth_tool._interpret_market_sentiment(0.3) assert sentiment == "κ°•ν•œ ν•˜λ½μ„Έ" @pytest.mark.asyncio async def test_cache_functionality(self, breadth_tool): """μΊμ‹œ κΈ°λŠ₯ ν…ŒμŠ€νŠΈ""" # μΊμ‹œ 히트 μ‹œλ‚˜λ¦¬μ˜€ cached_data = { "timestamp": datetime.now().isoformat(), "period": "1d", "market": "KOSPI", "breadth_data": [] } breadth_tool.cache_manager.get.return_value = cached_data # μ‹€ν–‰ result = await breadth_tool.execute({ "market": "KOSPI", "period": "1d" }) # μΊμ‹œμ—μ„œ 데이터 λ°˜ν™˜ 확인 content = result[0] import json data = json.loads(content.text) assert data == cached_data # λ°μ΄ν„°λ² μ΄μŠ€ 호좜 μ—†μŒ 확인 breadth_tool.db_manager.fetch_all.assert_not_called() @pytest.mark.asyncio async def test_error_handling(self, breadth_tool): """μ—λŸ¬ 처리 ν…ŒμŠ€νŠΈ""" breadth_tool.cache_manager.get.return_value = None breadth_tool.db_manager.fetch_all.side_effect = DatabaseConnectionError("DB μ—°κ²° μ‹€νŒ¨") with pytest.raises(DatabaseConnectionError): await breadth_tool.execute({ "market": "KOSPI", "period": "1d" }) @pytest.mark.asyncio async def test_invalid_parameters(self, breadth_tool): """잘λͺ»λœ νŒŒλΌλ―Έν„° ν…ŒμŠ€νŠΈ""" # 잘λͺ»λœ μ‹œμž₯ with pytest.raises(ValueError, match="Invalid market"): await breadth_tool.execute({ "market": "INVALID", "period": "1d" }) # 잘λͺ»λœ κΈ°κ°„ with pytest.raises(ValueError, match="Invalid period"): await breadth_tool.execute({ "market": "KOSPI", "period": "invalid" }) @pytest.mark.asyncio async def test_empty_data_handling(self, breadth_tool): """빈 데이터 처리 ν…ŒμŠ€νŠΈ""" breadth_tool.cache_manager.get.return_value = None breadth_tool.db_manager.fetch_all.return_value = [] result = await breadth_tool.execute({ "market": "KOSPI", "period": "1d" }) content = result[0] import json data = json.loads(content.text) assert data["breadth_data"] == [] assert "message" in data assert "데이터가 μ—†μŠ΅λ‹ˆλ‹€" in data["message"] or "no data" in data["message"].lower() @pytest.mark.asyncio async def test_trend_analysis_calculation(self, breadth_tool): """νŠΈλ Œλ“œ 뢄석 계산 ν…ŒμŠ€νŠΈ""" # μƒμŠΉ νŠΈλ Œλ“œ 데이터 trend_data = [] for i in range(5): ratio = 0.8 + (i * 0.1) # 0.8 -> 1.2둜 μƒμŠΉ νŠΈλ Œλ“œ trend_data.append({ "date": datetime.now().date() - timedelta(days=4-i), "market": "KOSPI", "advancing": int(800 * ratio), "declining": 800, "unchanged": 50, "total_issues": 1650, "advance_decline_ratio": ratio, "advance_volume": 2000000000000, "decline_volume": 2000000000000, "timestamp": datetime.now() - timedelta(days=4-i) }) breadth_tool.cache_manager.get.return_value = None breadth_tool.db_manager.fetch_all.return_value = trend_data result = await breadth_tool.execute({ "market": "KOSPI", "period": "1w" }) content = result[0] import json data = json.loads(content.text) assert "trend_analysis" in data trend = data["trend_analysis"] assert trend["direction"] == "μƒμŠΉ" assert "strength" in trend assert trend["days_analyzed"] == 5

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-market-statistics'

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