Skip to main content
Glama

MCP Market Statistics Server

by whdghk1907
test_advanced_pattern_recognition.py24.4 kB
"""고급 패턴 인식 테스트""" import pytest import asyncio import time from datetime import datetime, timedelta from unittest.mock import AsyncMock, MagicMock, patch from typing import Dict, List, Any from src.analytics.advanced_pattern_recognition import AdvancedPatternRecognition from src.exceptions import ModelNotTrainedError, InsufficientDataError, PredictionError class TestAdvancedPatternRecognition: """고급 패턴 인식 테스트""" @pytest.fixture def pattern_config(self): """패턴 인식 설정""" return { "pattern_types": { "chart_patterns": ["head_shoulders", "double_top", "triangle", "flag", "wedge"], "candlestick_patterns": ["doji", "hammer", "engulfing", "harami", "star"], "technical_patterns": ["divergence", "breakout", "support_resistance", "trend_reversal"], "harmonic_patterns": ["gartley", "butterfly", "bat", "crab", "shark"], "elliott_wave": ["impulse", "corrective", "diagonal"] }, "sensitivity_levels": { "high": 0.9, "medium": 0.7, "low": 0.5 }, "lookback_periods": { "short": 20, "medium": 50, "long": 200 }, "confirmation_requirements": { "volume_confirmation": True, "momentum_confirmation": True, "time_confirmation": True }, "pattern_scoring": { "accuracy_weight": 0.4, "profit_potential_weight": 0.3, "risk_reward_weight": 0.3 } } @pytest.fixture def pattern_recognition(self, pattern_config): """패턴 인식 엔진 인스턴스""" return AdvancedPatternRecognition(pattern_config) @pytest.fixture def sample_ohlcv_data(self): """샘플 OHLCV 데이터""" base_price = 50000 data = [] # 헤드앤숄더 패턴 시뮬레이션 pattern_prices = [ 50000, 51000, 52000, 53000, 52000, # 왼쪽 어깨 51000, 54000, 55000, 54000, 51000, # 머리 52000, 53000, 52000, 51000, 50000 # 오른쪽 어깨 ] for i, price in enumerate(pattern_prices): timestamp = datetime.now() - timedelta(days=len(pattern_prices) - i) data.append({ "timestamp": timestamp.isoformat(), "open": price - 100, "high": price + 200, "low": price - 200, "close": price, "volume": 1000000 + i * 10000 }) return data @pytest.fixture def sample_price_series(self): """샘플 가격 시계열 데이터""" prices = [] base = 50000 # 상승 트렌드 -> 하락 트렌드 전환 패턴 for i in range(100): if i < 50: # 상승 트렌드 price = base + i * 100 + (i % 5) * 50 else: # 하락 트렌드 price = base + 5000 - (i - 50) * 80 - ((i - 50) % 5) * 40 prices.append({ "timestamp": (datetime.now() - timedelta(days=100 - i)).isoformat(), "price": price, "volume": 1000000 + (i % 10) * 50000 }) return prices def test_pattern_recognition_initialization(self, pattern_recognition, pattern_config): """패턴 인식 엔진 초기화 테스트""" assert pattern_recognition.pattern_types == pattern_config["pattern_types"] assert pattern_recognition.sensitivity_levels == pattern_config["sensitivity_levels"] assert pattern_recognition.lookback_periods == pattern_config["lookback_periods"] assert pattern_recognition.confirmation_requirements == pattern_config["confirmation_requirements"] assert pattern_recognition.is_trained == False @pytest.mark.asyncio async def test_model_training(self, pattern_recognition, sample_ohlcv_data): """모델 훈련 테스트""" # 훈련 전 상태 assert pattern_recognition.is_trained == False # 훈련 데이터 준비 (더 많은 데이터) extended_data = sample_ohlcv_data * 10 # 150개 데이터포인트 # 모델 훈련 training_result = await pattern_recognition.train(extended_data) # 훈련 후 상태 assert pattern_recognition.is_trained == True assert "patterns_learned" in training_result assert "training_metrics" in training_result assert "model_performance" in training_result @pytest.mark.asyncio async def test_chart_pattern_detection(self, pattern_recognition, sample_ohlcv_data): """차트 패턴 감지 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 차트 패턴 감지 chart_patterns = await pattern_recognition.detect_chart_patterns( sample_ohlcv_data, pattern_types=["head_shoulders", "double_top"] ) # 결과 검증 assert "detected_patterns" in chart_patterns assert "pattern_details" in chart_patterns assert "confidence_scores" in chart_patterns # 각 감지된 패턴에 대한 상세 정보 확인 for pattern in chart_patterns["detected_patterns"]: assert "pattern_type" in pattern assert "start_index" in pattern assert "end_index" in pattern assert "confidence" in pattern assert "key_points" in pattern assert 0 <= pattern["confidence"] <= 1 @pytest.mark.asyncio async def test_candlestick_pattern_detection(self, pattern_recognition, sample_ohlcv_data): """캔들스틱 패턴 감지 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 캔들스틱 패턴 감지 candlestick_patterns = await pattern_recognition.detect_candlestick_patterns( sample_ohlcv_data[-5:], # 최근 5개 캔들 sensitivity="medium" ) # 결과 검증 assert "patterns" in candlestick_patterns assert "interpretations" in candlestick_patterns assert "trading_signals" in candlestick_patterns # 각 패턴에 대한 해석 확인 for pattern in candlestick_patterns["patterns"]: assert "pattern_name" in pattern assert "candle_index" in pattern assert "bullish_bearish" in pattern assert "reliability" in pattern assert pattern["bullish_bearish"] in ["bullish", "bearish", "neutral"] @pytest.mark.asyncio async def test_technical_pattern_detection(self, pattern_recognition, sample_price_series): """기술적 패턴 감지 테스트""" # 모델 훈련 await pattern_recognition.train(sample_price_series) # 기술적 패턴 감지 technical_patterns = await pattern_recognition.detect_technical_patterns( sample_price_series, indicators=["rsi", "macd", "bollinger"] ) # 결과 검증 assert "divergences" in technical_patterns assert "breakouts" in technical_patterns assert "support_resistance_levels" in technical_patterns assert "trend_reversals" in technical_patterns # 지지/저항 레벨 검증 sr_levels = technical_patterns["support_resistance_levels"] assert "support_levels" in sr_levels assert "resistance_levels" in sr_levels assert len(sr_levels["support_levels"]) > 0 assert len(sr_levels["resistance_levels"]) > 0 @pytest.mark.asyncio async def test_harmonic_pattern_detection(self, pattern_recognition, sample_ohlcv_data): """하모닉 패턴 감지 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 하모닉 패턴 감지 harmonic_patterns = await pattern_recognition.detect_harmonic_patterns( sample_ohlcv_data, fibonacci_tolerance=0.05 ) # 결과 검증 assert "detected_patterns" in harmonic_patterns assert "fibonacci_ratios" in harmonic_patterns assert "potential_reversal_zones" in harmonic_patterns # 각 하모닉 패턴의 피보나치 비율 검증 for pattern in harmonic_patterns["detected_patterns"]: assert "pattern_type" in pattern assert "points" in pattern # X, A, B, C, D 포인트 assert "ratios" in pattern assert "completion_zone" in pattern assert "profit_targets" in pattern @pytest.mark.asyncio async def test_elliott_wave_analysis(self, pattern_recognition, sample_price_series): """엘리엇 파동 분석 테스트""" # 모델 훈련 await pattern_recognition.train(sample_price_series) # 엘리엇 파동 분석 elliott_analysis = await pattern_recognition.analyze_elliott_waves( sample_price_series, wave_degree="primary" ) # 결과 검증 assert "wave_count" in elliott_analysis assert "current_wave" in elliott_analysis assert "wave_structure" in elliott_analysis assert "next_wave_projection" in elliott_analysis # 파동 구조 검증 wave_structure = elliott_analysis["wave_structure"] for wave in wave_structure: assert "wave_label" in wave assert "start_point" in wave assert "end_point" in wave assert "wave_type" in wave assert wave["wave_type"] in ["impulse", "corrective", "diagonal"] @pytest.mark.asyncio async def test_pattern_confirmation(self, pattern_recognition, sample_ohlcv_data): """패턴 확인 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 패턴 감지 detected_patterns = await pattern_recognition.detect_all_patterns(sample_ohlcv_data) # 패턴 확인 confirmed_patterns = await pattern_recognition.confirm_patterns( detected_patterns, sample_ohlcv_data, confirmation_criteria=["volume", "momentum", "time"] ) # 결과 검증 assert "confirmed_patterns" in confirmed_patterns assert "confirmation_scores" in confirmed_patterns assert "failed_confirmations" in confirmed_patterns # 확인된 패턴은 더 높은 신뢰도를 가져야 함 for pattern in confirmed_patterns["confirmed_patterns"]: assert "original_confidence" in pattern assert "confirmed_confidence" in pattern assert pattern["confirmed_confidence"] >= pattern["original_confidence"] @pytest.mark.asyncio async def test_pattern_backtesting(self, pattern_recognition, sample_ohlcv_data): """패턴 백테스팅 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 패턴 백테스팅 backtest_results = await pattern_recognition.backtest_patterns( extended_data, entry_rules={"confidence_threshold": 0.7}, exit_rules={"profit_target": 0.05, "stop_loss": 0.02} ) # 결과 검증 assert "total_patterns" in backtest_results assert "successful_patterns" in backtest_results assert "win_rate" in backtest_results assert "average_profit" in backtest_results assert "profit_factor" in backtest_results assert "pattern_performance" in backtest_results # 패턴별 성과 확인 for pattern_type, performance in backtest_results["pattern_performance"].items(): assert "count" in performance assert "win_rate" in performance assert "avg_return" in performance assert "best_return" in performance assert "worst_return" in performance @pytest.mark.asyncio async def test_multi_timeframe_pattern_analysis(self, pattern_recognition, sample_ohlcv_data): """멀티 타임프레임 패턴 분석 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 멀티 타임프레임 분석 mtf_analysis = await pattern_recognition.analyze_multi_timeframe_patterns( sample_ohlcv_data, timeframes=["5m", "15m", "1h", "4h"] ) # 결과 검증 assert "timeframe_patterns" in mtf_analysis assert "confluence_zones" in mtf_analysis assert "dominant_patterns" in mtf_analysis assert "timeframe_alignment" in mtf_analysis # 각 타임프레임별 패턴 확인 for timeframe, patterns in mtf_analysis["timeframe_patterns"].items(): assert isinstance(patterns, list) for pattern in patterns: assert "pattern_type" in pattern assert "strength" in pattern assert "direction" in pattern @pytest.mark.asyncio async def test_pattern_strength_scoring(self, pattern_recognition, sample_ohlcv_data): """패턴 강도 점수 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 패턴 감지 detected_patterns = await pattern_recognition.detect_all_patterns(sample_ohlcv_data) # 패턴 강도 점수 계산 pattern_scores = await pattern_recognition.calculate_pattern_strength( detected_patterns["all_patterns"], market_context={"trend": "bullish", "volatility": "medium"} ) # 결과 검증 assert "scored_patterns" in pattern_scores assert "strength_distribution" in pattern_scores assert "strongest_patterns" in pattern_scores # 각 패턴의 점수 확인 for pattern in pattern_scores["scored_patterns"]: assert "strength_score" in pattern assert "components" in pattern assert 0 <= pattern["strength_score"] <= 1 # 점수 구성 요소 components = pattern["components"] assert "pattern_clarity" in components assert "volume_support" in components assert "market_alignment" in components @pytest.mark.asyncio async def test_pattern_prediction(self, pattern_recognition, sample_ohlcv_data): """패턴 기반 예측 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 현재 패턴 감지 current_patterns = await pattern_recognition.detect_all_patterns(sample_ohlcv_data) # 패턴 기반 예측 predictions = await pattern_recognition.predict_from_patterns( current_patterns["all_patterns"], prediction_horizon=5 ) # 결과 검증 assert "price_predictions" in predictions assert "direction_probability" in predictions assert "target_levels" in predictions assert "confidence_intervals" in predictions # 예측 확률 검증 direction_prob = predictions["direction_probability"] assert "bullish" in direction_prob assert "bearish" in direction_prob assert "neutral" in direction_prob assert abs(sum(direction_prob.values()) - 1.0) < 0.01 # 합이 1 @pytest.mark.asyncio async def test_pattern_alerts(self, pattern_recognition, sample_ohlcv_data): """패턴 알림 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 알림 규칙 설정 alert_rules = { "patterns": ["head_shoulders", "double_top", "breakout"], "min_confidence": 0.8, "min_strength": 0.7 } await pattern_recognition.configure_alerts(alert_rules) # 실시간 패턴 감지 및 알림 alerts = await pattern_recognition.check_pattern_alerts(sample_ohlcv_data) # 결과 검증 assert "triggered_alerts" in alerts assert "alert_summary" in alerts assert "next_check_time" in alerts # 각 알림 확인 for alert in alerts["triggered_alerts"]: assert "pattern_type" in alert assert "confidence" in alert assert "strength" in alert assert "message" in alert assert "severity" in alert assert "timestamp" in alert @pytest.mark.asyncio async def test_pattern_visualization_data(self, pattern_recognition, sample_ohlcv_data): """패턴 시각화 데이터 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 패턴 감지 patterns = await pattern_recognition.detect_chart_patterns(sample_ohlcv_data) # 시각화 데이터 생성 viz_data = await pattern_recognition.generate_visualization_data( patterns["detected_patterns"], sample_ohlcv_data ) # 결과 검증 assert "chart_annotations" in viz_data assert "pattern_overlays" in viz_data assert "key_levels" in viz_data assert "trading_zones" in viz_data # 차트 주석 확인 for annotation in viz_data["chart_annotations"]: assert "x" in annotation assert "y" in annotation assert "text" in annotation assert "type" in annotation @pytest.mark.asyncio async def test_pattern_statistics(self, pattern_recognition, sample_ohlcv_data): """패턴 통계 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 20 # 더 많은 데이터 await pattern_recognition.train(extended_data) # 패턴 통계 수집 statistics = await pattern_recognition.get_pattern_statistics( extended_data, time_period="all" ) # 결과 검증 assert "pattern_frequency" in statistics assert "pattern_success_rates" in statistics assert "average_pattern_duration" in statistics assert "pattern_correlations" in statistics assert "seasonal_patterns" in statistics # 패턴 빈도 확인 pattern_freq = statistics["pattern_frequency"] assert isinstance(pattern_freq, dict) for pattern, freq in pattern_freq.items(): assert freq >= 0 @pytest.mark.asyncio async def test_real_time_pattern_detection(self, pattern_recognition, sample_ohlcv_data): """실시간 패턴 감지 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 실시간 스트리밍 시뮬레이션 streaming_buffer = [] for candle in sample_ohlcv_data: streaming_buffer.append(candle) # 실시간 패턴 감지 real_time_patterns = await pattern_recognition.detect_real_time_patterns( streaming_buffer, min_data_points=5 ) # 결과 검증 assert "active_patterns" in real_time_patterns assert "completed_patterns" in real_time_patterns assert "emerging_patterns" in real_time_patterns assert "pattern_updates" in real_time_patterns @pytest.mark.asyncio async def test_pattern_combination_analysis(self, pattern_recognition, sample_ohlcv_data): """패턴 조합 분석 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 10 await pattern_recognition.train(extended_data) # 모든 패턴 감지 all_patterns = await pattern_recognition.detect_all_patterns(sample_ohlcv_data) # 패턴 조합 분석 combinations = await pattern_recognition.analyze_pattern_combinations( all_patterns["all_patterns"], combination_rules={"max_overlap": 0.5, "min_correlation": 0.3} ) # 결과 검증 assert "pattern_combinations" in combinations assert "synergy_scores" in combinations assert "conflict_analysis" in combinations assert "optimal_combinations" in combinations # 각 조합 확인 for combo in combinations["pattern_combinations"]: assert "patterns" in combo assert "combined_strength" in combo assert "synergy_score" in combo assert "recommendation" in combo @pytest.mark.asyncio async def test_error_handling(self, pattern_recognition): """오류 처리 테스트""" # 훈련되지 않은 모델로 패턴 감지 시도 with pytest.raises(ModelNotTrainedError): await pattern_recognition.detect_chart_patterns([]) # 불충분한 데이터로 훈련 시도 insufficient_data = [{"open": 100, "close": 100}] # 너무 적은 데이터 with pytest.raises(InsufficientDataError): await pattern_recognition.train(insufficient_data) # 잘못된 패턴 타입 await pattern_recognition.train([{"open": 100, "close": 100}] * 100) with pytest.raises(ValueError): await pattern_recognition.detect_chart_patterns([], pattern_types=["invalid_pattern"]) def test_pattern_configuration(self, pattern_recognition): """패턴 설정 테스트""" # 감도 레벨 조정 pattern_recognition.set_sensitivity("high") assert pattern_recognition.current_sensitivity == pattern_recognition.sensitivity_levels["high"] # 패턴 타입 활성화/비활성화 pattern_recognition.enable_pattern_types(["head_shoulders", "double_top"]) assert "head_shoulders" in pattern_recognition.active_pattern_types assert "double_top" in pattern_recognition.active_pattern_types pattern_recognition.disable_pattern_types(["double_top"]) assert "double_top" not in pattern_recognition.active_pattern_types @pytest.mark.asyncio async def test_performance_optimization(self, pattern_recognition, sample_ohlcv_data): """성능 최적화 테스트""" # 모델 훈련 extended_data = sample_ohlcv_data * 50 # 큰 데이터셋 await pattern_recognition.train(extended_data) # 성능 측정 start_time = time.time() # 병렬 패턴 감지 tasks = [ pattern_recognition.detect_chart_patterns(extended_data), pattern_recognition.detect_candlestick_patterns(extended_data[-10:]), pattern_recognition.detect_technical_patterns(extended_data) ] results = await asyncio.gather(*tasks) end_time = time.time() # 성능 확인 processing_time = end_time - start_time assert processing_time < 5.0 # 5초 이내 assert len(results) == 3 # 캐시 활용 확인 metrics = pattern_recognition.get_performance_metrics() assert metrics["cache_hit_rate"] > 0 # 캐시가 활용되었는지 확인

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