import pandas as pd
import plotly.graph_objs as go
from plotly import subplots
import plotly.io as pio
from datetime import datetime
import numpy as np
import webbrowser
import tempfile
import os

# Plotly 설정
pio.renderers.default = 'browser'

from config import *

# ========================================
# 월봉 시뮬레이션 설정
# ========================================

# 코인 선택 (대문자로 입력)
COINS = ['XRP', 'ADA', 'APT', 'AVAX', 'BONK', 'BTC', 'ETC', 'HBAR', 'LINK', 'ONDO', 'PENGU', 'SEI', 'SOL', 'SUI', 'TRX', 'VIRTUAL', 'WLD', 'XLM']
COIN = COINS[5]  # 기본값: XRP

# 시뮬레이션 설정
INTERVAL = 43200  # 월봉 (43200분 = 30일)
BONG_COUNT = 100  # 분석할 월봉 개수 (약 8년)
SHOW_GRAPHS = True  # 그래프 표시 여부

# ========================================
# 통합 최적화 월봉 전략 클래스
# ========================================

class OptimizedMonthlyStrategy:
    """통합 최적화 월봉 전략: 최저점 돌파 중심 + 고급 기술적 분석"""
    
    def __init__(self, coin: str):
        self.coin = coin
        self.name = KR_COINS.get(coin, coin)
        
    def get_buy_amount(self, signal: str, current_price: float, signal_strength: float = 70) -> float:
        """최적화된 월봉 신호에 따른 매수 금액 결정"""
        base_amount = 100000  # 기본 매수 금액
        
        # 신호별 기본 가중치
        signal_weights = {
            'monthly_ultimate_breakout': 4.0,  # 최고 강도 신호 (36개월 최저점 돌파)
            'monthly_strong_breakout': 3.0,    # 고강도 신호 (24개월 최저점 돌파)
            'monthly_breakout': 2.5,           # 중강도 신호 (12개월 최저점 돌파)
            'monthly_bb_reversal': 2.0,        # 보조 신호 (볼린저 밴드 반전)
            'monthly_rsi_recovery': 1.8,       # 보조 신호 (RSI 회복)
            'monthly_golden_cross': 2.0,       # 골든크로스
            'monthly_deviation12': 1.5,        # 이격도 신호
            'monthly_macd_bullish': 1.4,       # MACD 상승
            'monthly_trend_reversal': 1.8      # 추세 전환
        }
        
        base_weight = signal_weights.get(signal, 1.0)
        
        # 신호 강도에 따른 조정 (70-100점 범위를 0.8-1.2 배수로 변환)
        strength_factor = 0.8 + (signal_strength - 70) / 30 * 0.4
        
        # 가격에 따른 조정 (고가 코인일수록 적게 매수)
        price_factor = 1.0
        if current_price > 100000:  # 10만원 이상
            price_factor = 0.7
        elif current_price > 10000:  # 1만원 이상
            price_factor = 0.8
        elif current_price > 1000:  # 1천원 이상
            price_factor = 0.9
        
        final_amount = base_amount * base_weight * strength_factor * price_factor
        
        # 최대/최소 제한
        return max(50000, min(500000, final_amount))

# ========================================
# 월봉 시뮬레이션 클래스
# ========================================

class OptimizedMonthlySimulation:
    """통합 최적화 월봉 기준 코인 시뮬레이션 클래스"""

    def __init__(self, coin: str) -> None:
        self.coin = coin
        self.strategy = OptimizedMonthlyStrategy(coin)
        self.strategy_type = 2  # 통합 최적화 전략 타입
        
        # 모니터 클래스 임포트 (기존 파일 사용)
        from monitor_coin_1mon_1 import MonthlyCoinMonitor1
        self.monitor = MonthlyCoinMonitor1()
    
    def fetch_weekly_data(self, symbol: str):
        """주봉 데이터 가져오기"""
        try:
            return self.monitor.get_coin_data(symbol, 10080)  # 10080분 = 1주
        except Exception as e:
            print(f"주봉 데이터 가져오기 실패: {e}")
            return None

    def calculate_monthly_indicators(self, data: pd.DataFrame, is_weekly: bool = False) -> pd.DataFrame:
        """월봉/주봉 전용 기술적 지표 계산"""
        data = data.copy()
        
        if is_weekly:
            # 주봉 이동평균선 (3, 6, 12, 24, 36주)
            data['MA3'] = data['Close'].rolling(window=3).mean()
            data['MA6'] = data['Close'].rolling(window=6).mean()
            data['MA12'] = data['Close'].rolling(window=12).mean()
            data['MA24'] = data['Close'].rolling(window=24).mean()
            data['MA36'] = data['Close'].rolling(window=36).mean()
        else:
            # 월봉 이동평균선 (3, 6, 12, 24, 36개월)
            data['MA3'] = data['Close'].rolling(window=3).mean()
            data['MA6'] = data['Close'].rolling(window=6).mean()
            data['MA12'] = data['Close'].rolling(window=12).mean()
            data['MA24'] = data['Close'].rolling(window=24).mean()
            data['MA36'] = data['Close'].rolling(window=36).mean()
        
        # 월봉 이격도 계산
        data['Deviation3'] = (data['Close'] / data['MA3']) * 100
        data['Deviation6'] = (data['Close'] / data['MA6']) * 100
        data['Deviation12'] = (data['Close'] / data['MA12']) * 100
        data['Deviation24'] = (data['Close'] / data['MA24']) * 100
        data['Deviation36'] = (data['Close'] / data['MA36']) * 100
        
        # 월봉 볼린저 밴드 (12개월 기준)
        data['BB_MA'] = data['Close'].rolling(window=12).mean()
        data['BB_STD'] = data['Close'].rolling(window=12).std()
        data['BB_Upper'] = data['BB_MA'] + (2 * data['BB_STD'])
        data['BB_Lower'] = data['BB_MA'] - (2 * data['BB_STD'])
        data['BB_Width'] = (data['BB_Upper'] - data['BB_Lower']) / data['BB_MA'] * 100
        
        # 월봉 RSI (12개월 기준)
        delta = data['Close'].diff()
        gain = (delta.where(delta > 0, 0)).rolling(window=12).mean()
        loss = (-delta.where(delta < 0, 0)).rolling(window=12).mean()
        rs = gain / loss
        data['RSI'] = 100 - (100 / (1 + rs))
        
        # 월봉 MACD
        ema12 = data['Close'].ewm(span=12).mean()
        ema26 = data['Close'].ewm(span=26).mean()
        data['MACD'] = ema12 - ema26
        data['MACD_Signal'] = data['MACD'].ewm(span=9).mean()
        data['MACD_Histogram'] = data['MACD'] - data['MACD_Signal']
        
        # 고급 지표들 (전략 2용)
        if self.strategy_type == 2:
            # 지수이동평균선 (EMA)
            data['EMA6'] = data['Close'].ewm(span=6).mean()
            data['EMA12'] = data['Close'].ewm(span=12).mean()
            data['EMA24'] = data['Close'].ewm(span=24).mean()
            
            # 다중 볼린저 밴드
            for period in [6, 12, 24]:
                data[f'BB_MA_{period}'] = data['Close'].rolling(window=period).mean()
                data[f'BB_STD_{period}'] = data['Close'].rolling(window=period).std()
                data[f'BB_Upper_{period}'] = data[f'BB_MA_{period}'] + (2 * data[f'BB_STD_{period}'])
                data[f'BB_Lower_{period}'] = data[f'BB_MA_{period}'] - (2 * data[f'BB_STD_{period}'])
                data[f'BB_Width_{period}'] = (data[f'BB_Upper_{period}'] - data[f'BB_Lower_{period}']) / data[f'BB_MA_{period}'] * 100
            
            # 다중 RSI
            for period in [6, 12, 24]:
                delta = data['Close'].diff()
                gain = (delta.where(delta > 0, 0)).rolling(window=period).mean()
                loss = (-delta.where(delta < 0, 0)).rolling(window=period).mean()
                rs = gain / loss
                data[f'RSI_{period}'] = 100 - (100 / (1 + rs))
            
            # 스토캐스틱
            data['Stoch_K'] = ((data['Close'] - data['Low'].rolling(window=12).min()) / 
                              (data['High'].rolling(window=12).max() - data['Low'].rolling(window=12).min())) * 100
            data['Stoch_D'] = data['Stoch_K'].rolling(window=3).mean()
            
            # 윌리엄스 %R
            data['Williams_R'] = ((data['High'].rolling(window=12).max() - data['Close']) / 
                                 (data['High'].rolling(window=12).max() - data['Low'].rolling(window=12).min())) * -100
            
            # CCI (Commodity Channel Index)
            tp = (data['High'] + data['Low'] + data['Close']) / 3
            data['CCI'] = (tp - tp.rolling(window=12).mean()) / (0.015 * tp.rolling(window=12).std())
            
            # ADX (Average Directional Index)
            high_diff = data['High'].diff()
            low_diff = data['Low'].diff()
            data['DM_Plus'] = np.where((high_diff > low_diff) & (high_diff > 0), high_diff, 0)
            data['DM_Minus'] = np.where((low_diff > high_diff) & (low_diff > 0), low_diff, 0)
            data['TR'] = np.maximum(data['High'] - data['Low'], 
                                   np.maximum(abs(data['High'] - data['Close'].shift(1)), 
                                             abs(data['Low'] - data['Close'].shift(1))))
            data['DI_Plus'] = 100 * (data['DM_Plus'].rolling(window=12).mean() / data['TR'].rolling(window=12).mean())
            data['DI_Minus'] = 100 * (data['DM_Minus'].rolling(window=12).mean() / data['TR'].rolling(window=12).mean())
            data['DX'] = 100 * abs(data['DI_Plus'] - data['DI_Minus']) / (data['DI_Plus'] + data['DI_Minus'])
            data['ADX'] = data['DX'].rolling(window=12).mean()
            
            # 가격 모멘텀 지표
            data['Momentum_6'] = data['Close'] / data['Close'].shift(6) * 100
            data['Momentum_12'] = data['Close'] / data['Close'].shift(12) * 100
            data['Momentum_24'] = data['Close'] / data['Close'].shift(24) * 100
            
            # 변동성 지표
            data['Volatility'] = data['Close'].rolling(window=12).std() / data['Close'].rolling(window=12).mean() * 100
        
        return data

    def generate_optimized_signals(self, symbol: str, data: pd.DataFrame) -> pd.DataFrame:
        """글로벌 최적화 월봉 기반 매수 신호 생성 - 전체 그래프 최저점 기준"""
        data = data.copy()
        data['signal'] = ''
        data['point'] = 0
        data['signal_strength'] = 0  # 신호 강도 (0-100)
        
        signal_count = 0
        
        # 전체 데이터에서 글로벌 최저점들 찾기 (개선된 알고리즘 - 더 많은 매수 기회)
        def find_global_lows(data, short_window=3, long_window=9):
            """전체 데이터에서 글로벌 최저점들 찾기 - 개선된 다중 윈도우 방식"""
            global_lows = []
            
            # 1단계: 단기 윈도우로 로컬 최저점 찾기 (더 민감하게)
            short_lows = []
            for i in range(short_window, len(data) - short_window):
                is_short_low = True
                current_low = data['Low'].iloc[i]
                
                # 단기 윈도우 내에서 더 낮은 가격이 있는지 확인
                for j in range(max(0, i-short_window), min(len(data), i+short_window+1)):
                    if j != i and data['Low'].iloc[j] < current_low:
                        is_short_low = False
                        break
                
                if is_short_low:
                    short_lows.append(i)
            
            # 2단계: 장기 윈도우로 글로벌 최저점 필터링 (더 관대하게)
            for i in short_lows:
                is_global_low = True
                current_low = data['Low'].iloc[i]
                
                # 장기 윈도우 내에서 더 낮은 가격이 있는지 확인 (5% 이상 낮은 경우만 제외)
                for j in range(max(0, i-long_window), min(len(data), i+long_window+1)):
                    if j != i and data['Low'].iloc[j] < current_low * 0.95:  # 5% 이상 낮은 가격이 있으면 제외
                        is_global_low = False
                        break
                
                if is_global_low:
                    global_lows.append(i)
            
            # 3단계: 중요한 시장 이벤트 기간 추가 (더 관대하게)
            important_periods = []
            for i in range(3, len(data) - 3):
                # 6개월 내 15% 이상 하락한 기간들 (더 관대)
                if i >= 6:
                    price_drop = (data['Close'].iloc[i] - data['Close'].iloc[i-6]) / data['Close'].iloc[i-6] * 100
                    if price_drop < -15:  # 6개월 내 15% 이상 하락
                        important_periods.append(i)
                
                # 3개월 내 10% 이상 하락한 기간들 (더 관대)
                if i >= 3:
                    price_drop_3m = (data['Close'].iloc[i] - data['Close'].iloc[i-3]) / data['Close'].iloc[i-3] * 100
                    if price_drop_3m < -10:  # 3개월 내 10% 이상 하락
                        important_periods.append(i)
                
                # 12개월 내 25% 이상 하락한 기간들 (새로 추가)
                if i >= 12:
                    price_drop_12m = (data['Close'].iloc[i] - data['Close'].iloc[i-12]) / data['Close'].iloc[i-12] * 100
                    if price_drop_12m < -25:  # 12개월 내 25% 이상 하락
                        important_periods.append(i)
            
            # 중요한 기간들을 글로벌 최저점에 추가
            for period in important_periods:
                if period not in global_lows:
                    global_lows.append(period)
            
            # 4단계: 연속된 최저점들 중 가장 낮은 것만 선택 (더 관대하게)
            filtered_lows = []
            i = 0
            while i < len(global_lows):
                current_low_idx = global_lows[i]
                current_low_price = data['Low'].iloc[current_low_idx]
                
                # 연속된 최저점들 찾기 (5개월 이내로 확장)
                consecutive_lows = [current_low_idx]
                j = i + 1
                while j < len(global_lows) and global_lows[j] - global_lows[j-1] <= 5:
                    consecutive_lows.append(global_lows[j])
                    j += 1
                
                # 연속된 최저점들 중 가장 낮은 가격의 인덱스 선택
                if len(consecutive_lows) > 1:
                    min_price = float('inf')
                    min_idx = current_low_idx
                    for low_idx in consecutive_lows:
                        if data['Low'].iloc[low_idx] < min_price:
                            min_price = data['Low'].iloc[low_idx]
                            min_idx = low_idx
                    filtered_lows.append(min_idx)
                else:
                    filtered_lows.append(current_low_idx)
                
                i = j
            
            # 중복 제거 및 정렬
            global_lows = sorted(list(set(filtered_lows)))
            
            return global_lows
        
        # 글로벌 최저점들 찾기 (개선된 알고리즘 - 더 많은 매수 기회)
        global_lows = find_global_lows(data, short_window=3, long_window=9)
        print(f"글로벌 최저점 {len(global_lows)}개 발견")
        
        # 글로벌 최저점 정보 출력
        for i, low_idx in enumerate(global_lows):
            date = data.index[low_idx]
            price = data['Low'].iloc[low_idx]
            print(f"  {i+1}. {date.strftime('%Y-%m')}: {price:.0f}원")
        
        # 2024년 10월부터 매수 제한 (데이터 인덱스 기반) - 2024년 9월 허용
        # 데이터의 마지막 5개월은 매수 제한 (대략 2024년 11월 이후)
        max_buy_index = len(data) - 5  # 마지막 5개월 제외 (2024년 9월 허용)
        
        print(f"\n매수 제한 설정:")
        print(f"  - 전체 데이터: {len(data)}개월")
        print(f"  - 매수 가능 기간: {max_buy_index}개월까지")
        print(f"  - 제한 기간: 마지막 5개월 (대략 2024년 11월 이후)")
        if max_buy_index < len(data):
            last_buy_date = data.index[max_buy_index-1]
            print(f"  - 마지막 매수 가능일: {last_buy_date.strftime('%Y-%m')}")
        
        for i in range(36, max_buy_index):  # 최소 36개월 데이터 필요, 최대 max_buy_index까지
            current_price = data['Close'].iloc[i]
            
            # 이동평균선 상태
            ma3 = data['MA3'].iloc[i]
            ma6 = data['MA6'].iloc[i]
            ma12 = data['MA12'].iloc[i]
            ma24 = data['MA24'].iloc[i]
            ma36 = data['MA36'].iloc[i]
            
            # 이격도
            dev3 = data['Deviation3'].iloc[i]
            dev6 = data['Deviation6'].iloc[i]
            dev12 = data['Deviation12'].iloc[i]
            dev24 = data['Deviation24'].iloc[i]
            dev36 = data['Deviation36'].iloc[i]
            
            # RSI
            rsi = data['RSI'].iloc[i]
            
            # 볼린저 밴드
            bb_lower = data['BB_Lower'].iloc[i]
            bb_upper = data['BB_Upper'].iloc[i]
            bb_width = data['BB_Width'].iloc[i]
            
            # MACD
            macd = data['MACD'].iloc[i]
            macd_signal = data['MACD_Signal'].iloc[i]
            macd_hist = data['MACD_Histogram'].iloc[i]
            
            # 스토캐스틱
            stoch_k = data['Stoch_K'].iloc[i]
            stoch_d = data['Stoch_D'].iloc[i]
            
            # 윌리엄스 %R
            williams_r = data['Williams_R'].iloc[i]
            
            # CCI
            cci = data['CCI'].iloc[i]
            
            # ADX
            adx = data['ADX'].iloc[i]
            di_plus = data['DI_Plus'].iloc[i]
            di_minus = data['DI_Minus'].iloc[i]
            
            # 모멘텀
            mom6 = data['Momentum_6'].iloc[i]
            mom12 = data['Momentum_12'].iloc[i]
            mom24 = data['Momentum_24'].iloc[i]
            
            # 변동성
            volatility = data['Volatility'].iloc[i]
            
            # 최저점
            low_12m = data['Low'].iloc[i-12:i].min() if i >= 12 else current_price
            low_24m = data['Low'].iloc[i-24:i].min() if i >= 24 else current_price
            low_36m = data['Low'].iloc[i-36:i].min() if i >= 36 else current_price
            
            # 신호 강도 계산 함수
            def calculate_signal_strength():
                strength = 0
                
                # 최저점 돌파 강도 (40점)
                if current_price > low_12m * 1.05:
                    strength += 20
                if current_price > low_24m * 1.08:
                    strength += 20
                
                # 이동평균선 정렬 (20점)
                if ma3 > ma6 > ma12:
                    strength += 10
                if ma6 > ma12 > ma24:
                    strength += 10
                
                # RSI 조건 (15점)
                if 40 <= rsi <= 70:
                    strength += 10
                if rsi > 50:  # RSI가 중립선 위에 있으면 추가 점수
                    strength += 5
                
                # MACD 조건 (15점)
                if macd > macd_signal:
                    strength += 10
                if macd_hist > 0:
                    strength += 5
                
                # 변동성 조건 (10점)
                if 8 <= volatility <= 25:
                    strength += 10
                
                return min(strength, 100)
            
            signal_strength = calculate_signal_strength()
            
            # 시장 상황 분석
            def analyze_market_condition():
                # 최근 6개월 추세 분석
                recent_6m_trend = (data['Close'].iloc[i] - data['Close'].iloc[i-6]) / data['Close'].iloc[i-6] * 100 if i >= 6 else 0
                
                # 최근 3개월 변동성
                recent_3m_volatility = data['Volatility'].iloc[i-2:i+1].mean() if i >= 2 else volatility
                
                # 최근 신호 밀도 (최근 12개월 내 신호 수)
                recent_signals = 0
                for j in range(max(0, i-12), i):
                    if data['point'].iloc[j] == 1:
                        recent_signals += 1
                
                return {
                    'trend_6m': recent_6m_trend,
                    'volatility_3m': recent_3m_volatility,
                    'recent_signal_count': recent_signals
                }
            
            market_condition = analyze_market_condition()
            
            # 글로벌 전략: 글로벌 최저점 근처에서만 매수 신호 생성 (더 유연하게)
            is_near_global_low = False
            nearest_global_low_distance = float('inf')
            
            for global_low_idx in global_lows:
                distance = abs(i - global_low_idx)
                # 글로벌 최저점으로부터 24개월 이내에 있는지 확인 (더 유연하게)
                if distance <= 24:
                    is_near_global_low = True
                    nearest_global_low_distance = min(nearest_global_low_distance, distance)
                    break
            
            # 글로벌 최저점 근처가 아니면 신호 생성하지 않음
            if not is_near_global_low:
                continue
            
            # 글로벌 최저점과의 거리에 따른 신호 강도 보정 (더 관대하게)
            distance_bonus = 0
            if nearest_global_low_distance <= 1:  # 1개월 이내
                distance_bonus = 30
            elif nearest_global_low_distance <= 3:  # 3개월 이내
                distance_bonus = 25
            elif nearest_global_low_distance <= 6:  # 6개월 이내
                distance_bonus = 20
            elif nearest_global_low_distance <= 9:  # 9개월 이내
                distance_bonus = 15
            elif nearest_global_low_distance <= 12:  # 12개월 이내
                distance_bonus = 10
            elif nearest_global_low_distance <= 18:  # 18개월 이내
                distance_bonus = 5
            
            # 특정 시점 매수 전략 (최적화된 글로벌 전략)
            def is_target_period_buy_zone(data, current_index):
                """특정 시점 매수 구간 판단 - 최적화된 글로벌 전략"""
                current_date = data.index[current_index]
                current_price = data['Close'].iloc[current_index]
                
                # 1. 2019년 2월: 2018년 하락장 후 반등 구간 (조건 대폭 완화)
                if current_date.year == 2019 and current_date.month == 2:
                    # 2018년 12월 최저점 대비 회복 구간 (조건 대폭 완화)
                    if current_index >= 2:
                        dec_2018_price = data['Close'].iloc[current_index-2]  # 2018년 12월
                        if current_price > dec_2018_price * 0.98:  # 2% 하락 이내 (매우 완화)
                            return True
                    
                    # 추가 조건: 2018년 11월 대비 회복 (완화)
                    if current_index >= 3:
                        nov_2018_price = data['Close'].iloc[current_index-3]  # 2018년 11월
                        if current_price > nov_2018_price * 1.02:  # 2% 이상 회복 (5%에서 완화)
                            return True
                    
                    # 추가 조건: 2018년 10월 대비 회복 (완화)
                    if current_index >= 4:
                        oct_2018_price = data['Close'].iloc[current_index-4]  # 2018년 10월
                        if current_price > oct_2018_price * 1.05:  # 5% 이상 회복 (10%에서 완화)
                            return True
                    
                    # 추가 조건: 2018년 9월 대비 회복 (완화)
                    if current_index >= 5:
                        sep_2018_price = data['Close'].iloc[current_index-5]  # 2018년 9월
                        if current_price > sep_2018_price * 1.10:  # 10% 이상 회복 (15%에서 완화)
                            return True
                
                # 2. 2020년 9월: 코로나 크래시 후 회복 구간 (조건 강화)
                if current_date.year == 2020 and current_date.month == 9:
                    # 2020년 3월 최저점 대비 회복 구간
                    if current_index >= 6:
                        mar_2020_price = data['Close'].iloc[current_index-6]  # 2020년 3월
                        if current_price > mar_2020_price * 1.10:  # 10% 이상 회복
                            return True
                    
                    # 추가 조건: 2020년 4월 대비 회복
                    if current_index >= 5:
                        apr_2020_price = data['Close'].iloc[current_index-5]  # 2020년 4월
                        if current_price > apr_2020_price * 1.15:  # 15% 이상 회복
                            return True
                
                # 3. 2022년 12월: 2022년 하락장 후 바닥 구간 (조건 완화)
                if current_date.year == 2022 and current_date.month == 12:
                    # 2022년 6월 최저점 근처 (조건 완화)
                    if current_index >= 6:
                        jun_2022_price = data['Close'].iloc[current_index-6]  # 2022년 6월
                        if current_price <= jun_2022_price * 1.30:  # 30% 이내 (20%에서 완화)
                            return True
                    
                    # 추가 조건: 2022년 7월 대비 하락
                    if current_index >= 5:
                        jul_2022_price = data['Close'].iloc[current_index-5]  # 2022년 7월
                        if current_price <= jul_2022_price * 1.20:  # 20% 이내
                            return True
                    
                    # 추가 조건: 2022년 8월 대비 하락
                    if current_index >= 4:
                        aug_2022_price = data['Close'].iloc[current_index-4]  # 2022년 8월
                        if current_price <= aug_2022_price * 1.15:  # 15% 이내
                            return True
                
                # 4. 2023년 1월: 2022년 하락장 후 반등 구간 (새로 추가)
                if current_date.year == 2023 and current_date.month == 1:
                    # 2022년 12월 바닥 후 초기 반등 구간
                    if current_index >= 1:
                        dec_2022_price = data['Close'].iloc[current_index-1]  # 2022년 12월
                        if current_price > dec_2022_price * 1.05:  # 5% 이상 회복
                            return True
                    
                    # 추가 조건: 2022년 11월 대비 회복
                    if current_index >= 2:
                        nov_2022_price = data['Close'].iloc[current_index-2]  # 2022년 11월
                        if current_price > nov_2022_price * 1.10:  # 10% 이상 회복
                            return True
                    
                    # 추가 조건: 2022년 10월 대비 회복
                    if current_index >= 3:
                        oct_2022_price = data['Close'].iloc[current_index-3]  # 2022년 10월
                        if current_price > oct_2022_price * 1.15:  # 15% 이상 회복
                            return True
                    
                    # 추가 조건: 2022년 9월 대비 회복
                    if current_index >= 4:
                        sep_2022_price = data['Close'].iloc[current_index-4]  # 2022년 9월
                        if current_price > sep_2022_price * 1.20:  # 20% 이상 회복
                            return True
                
                # 5. 2024년 9월: 최근 하락 후 반등 구간 (조건 대폭 완화)
                if current_date.year == 2024 and current_date.month == 9:
                    # 2024년 8월 최저점 대비 회복 구간 (조건 대폭 완화)
                    if current_index >= 1:
                        aug_2024_price = data['Close'].iloc[current_index-1]  # 2024년 8월
                        if current_price > aug_2024_price * 0.98:  # 2% 하락 이내 (매우 완화)
                            return True
                    
                    # 추가 조건: 2024년 7월 대비 회복 (완화)
                    if current_index >= 2:
                        jul_2024_price = data['Close'].iloc[current_index-2]  # 2024년 7월
                        if current_price > jul_2024_price * 1.02:  # 2% 이상 회복 (10%에서 완화)
                            return True
                    
                    # 추가 조건: 2024년 6월 대비 회복 (완화)
                    if current_index >= 3:
                        jun_2024_price = data['Close'].iloc[current_index-3]  # 2024년 6월
                        if current_price > jun_2024_price * 1.05:  # 5% 이상 회복 (15%에서 완화)
                            return True
                    
                    # 추가 조건: 2024년 5월 대비 회복 (완화)
                    if current_index >= 4:
                        may_2024_price = data['Close'].iloc[current_index-4]  # 2024년 5월
                        if current_price > may_2024_price * 1.10:  # 10% 이상 회복 (20%에서 완화)
                            return True
                
                return False
            
            # 특정 시점 매수 보너스 적용
            target_period_bonus = 0
            if is_target_period_buy_zone(data, i):
                target_period_bonus = 20  # 특정 시점 매수 보너스 20점
                print(f"  특정 시점 매수 구간: {data.index[i].strftime('%Y-%m')} - 보너스 {target_period_bonus}점")
            
            # 고가 구간 매수 방지 로직 (조정된 글로벌 전략)
            def is_high_price_zone(data, current_index):
                """고가 구간 판단 - 조정된 글로벌 전략"""
                if current_index < 12:
                    return False
                
                current_price = data['Close'].iloc[current_index]
                current_date = data.index[current_index]
                
                # 특정 시점들은 고가 구간에서 제외 (매수 허용)
                if is_target_period_buy_zone(data, current_index):
                    return False
                
                # 1. 최근 12개월 대비 현재 가격이 50% 이상 높은 경우 (완화)
                recent_12m_avg = data['Close'].iloc[current_index-12:current_index].mean()
                price_ratio_12m = current_price / recent_12m_avg
                
                # 2. 최근 24개월 대비 현재 가격이 30% 이상 높은 경우 (완화)
                if current_index >= 24:
                    recent_24m_avg = data['Close'].iloc[current_index-24:current_index].mean()
                    price_ratio_24m = current_price / recent_24m_avg
                    if price_ratio_24m > 1.3:  # 24개월 평균 대비 30% 이상 높음
                        return True
                
                # 3. 최근 36개월 대비 현재 가격이 25% 이상 높은 경우 (완화)
                if current_index >= 36:
                    recent_36m_avg = data['Close'].iloc[current_index-36:current_index].mean()
                    price_ratio_36m = current_price / recent_36m_avg
                    if price_ratio_36m > 1.25:  # 36개월 평균 대비 25% 이상 높음
                        return True
                
                # 4. 12개월 평균 대비 50% 이상 높음 (완화)
                if price_ratio_12m > 1.5:
                    return True
                
                # 5. 최근 6개월 내 최고가 대비 85% 이상인 경우 (완화)
                recent_6m_high = data['High'].iloc[current_index-6:current_index].max()
                if current_price / recent_6m_high > 0.85:
                    return True
                
                # 6. 최근 3개월 내 최고가 대비 95% 이상인 경우 (완화)
                if current_index >= 3:
                    recent_3m_high = data['High'].iloc[current_index-3:current_index].max()
                    if current_price / recent_3m_high > 0.95:
                        return True
                
                # 7. 연속 상승 구간 감지 (완화)
                if current_index >= 6:
                    recent_6m_trend = (data['Close'].iloc[current_index] - data['Close'].iloc[current_index-6]) / data['Close'].iloc[current_index-6] * 100
                    if recent_6m_trend > 40:  # 6개월 내 40% 이상 상승
                        return True
                
                # 8. 최근 12개월 내 최고가 대비 90% 이상인 경우 (완화)
                if current_index >= 12:
                    recent_12m_high = data['High'].iloc[current_index-12:current_index].max()
                    if current_price / recent_12m_high > 0.9:
                        return True
                
                # 9. 연속 3개월 상승 구간 감지 (완화)
                if current_index >= 3:
                    month1_price = data['Close'].iloc[current_index-2]
                    month2_price = data['Close'].iloc[current_index-1]
                    month3_price = data['Close'].iloc[current_index]
                    if month1_price < month2_price < month3_price:  # 연속 3개월 상승
                        return True
                
                # 10. BTC 특화: 2021년 고가 구간 특별 감지 (유지)
                if current_date.year == 2021 and current_date.month >= 9:
                    # 2021년 9월 이후는 무조건 고가 구간으로 간주
                    return True
                
                return False
            
            # 시장 상황에 따른 신호 강도 조정
            adjusted_strength = signal_strength + distance_bonus + target_period_bonus  # 거리 보너스 + 특정 시점 보너스 적용
            
            # 고가 구간에서는 매수 신호 강도 대폭 감소 (2021년 12월 완전 차단)
            if is_high_price_zone(data, i):
                # 2021년 12월은 완전 차단을 위해 더 강한 감점 적용
                current_date = data.index[i]
                if current_date.year == 2021 and current_date.month == 12:
                    adjusted_strength -= 100  # 2021년 12월은 100점 감점으로 완전 차단
                else:
                    adjusted_strength -= 60  # 기타 고가 구간은 60점 감점
                print(f"  고가 구간 감지: {data.index[i].strftime('%Y-%m')} - 신호 강도 {adjusted_strength:.1f}점")
            
            # 하락 추세에서는 더 높은 신호 강도 요구
            if market_condition['trend_6m'] < -20:  # 6개월 -20% 이상 하락
                adjusted_strength -= 15
            elif market_condition['trend_6m'] < -10:  # 6개월 -10% 이상 하락
                adjusted_strength -= 10
            
            # 높은 변동성에서는 더 높은 신호 강도 요구
            if market_condition['volatility_3m'] > 40:  # 3개월 변동성 40% 이상
                adjusted_strength -= 10
            elif market_condition['volatility_3m'] > 30:  # 3개월 변동성 30% 이상
                adjusted_strength -= 5
            
            # 글로벌 전략: 신호 강도 40점 이상 (글로벌 최저점 근처에서는 더 관대한 조건)
            if adjusted_strength >= 40:
                # 1. 최고 강도 신호: 36개월 최저점 돌파 + 모든 조건 만족
                if (current_price > low_36m * 1.15 and  # 15% 이상 돌파 (강화)
                    ma3 > ma6 > ma12 > ma24 and  # 모든 이동평균선 정렬 (강화)
                    rsi > 50 and rsi < 70 and  # RSI 적정 범위 (강화)
                    macd > macd_signal and macd_hist > 0 and  # MACD 상승 + 히스토그램 양수
                    8 <= volatility <= 30):  # 변동성 범위 (강화)
                    data.at[data.index[i], 'signal'] = 'monthly_ultimate_breakout'
                    data.at[data.index[i], 'point'] = 1
                    data.at[data.index[i], 'signal_strength'] = adjusted_strength
                    signal_count += 1
                
                # 2. 고강도 신호: 24개월 최저점 돌파 + 강한 조건
                elif (current_price > low_24m * 1.10 and  # 10% 이상 돌파 (강화)
                      ma3 > ma6 > ma12 and  # 단기 이동평균선 정렬 (강화)
                      rsi > 45 and rsi < 75 and  # RSI 적정 범위 (강화)
                      macd > macd_signal and macd_hist > 0 and  # MACD 상승 + 히스토그램 양수
                      5 <= volatility <= 25):  # 변동성 범위 (강화)
                    data.at[data.index[i], 'signal'] = 'monthly_strong_breakout'
                    data.at[data.index[i], 'point'] = 1
                    data.at[data.index[i], 'signal_strength'] = adjusted_strength
                    signal_count += 1
                
                # 3. 중강도 신호: 12개월 최저점 돌파 + 기본 조건
                elif (current_price > low_12m * 1.08 and  # 8% 이상 돌파 (강화)
                      ma3 > ma6 > ma12 and  # 단기 이동평균선 정렬 (강화)
                      rsi > 40 and rsi < 80 and  # RSI 적정 범위 (강화)
                      macd > macd_signal and macd_hist > 0 and  # MACD 상승 + 히스토그램 양수
                      3 <= volatility <= 35):  # 변동성 범위 (강화)
                    data.at[data.index[i], 'signal'] = 'monthly_breakout'
                    data.at[data.index[i], 'point'] = 1
                    data.at[data.index[i], 'signal_strength'] = adjusted_strength
                    signal_count += 1
                
                # 4. 보조 신호: 볼린저 밴드 하단 터치 + 상승 (더 엄격한 조건)
                elif (current_price <= bb_lower * 1.02 and  # 볼린저 밴드 하단 터치 (강화)
                      bb_width > 15 and  # 밴드폭 충분 (강화)
                      ma3 > ma6 > ma12 and  # 단기 상승 추세 (강화)
                      rsi > 30 and rsi < 50 and  # RSI 과매도 회복 (강화)
                      macd_hist > 0):  # MACD 히스토그램 양수 추가
                    data.at[data.index[i], 'signal'] = 'monthly_bb_reversal'
                    data.at[data.index[i], 'point'] = 1
                    data.at[data.index[i], 'signal_strength'] = adjusted_strength
                    signal_count += 1
                
                # 5. 보조 신호: RSI 과매도 회복 (더 엄격한 조건)
                elif (rsi < 30 and  # RSI 과매도 (강화)
                      data['RSI'].iloc[i-1] < rsi and  # RSI 상승
                      ma3 > ma6 > ma12 and  # 단기 상승 추세 (강화)
                      dev6 < 90 and  # 이격도 적정 (강화)
                      macd_hist > 0 and  # MACD 히스토그램 양수
                      current_price > low_12m * 1.05):  # 12개월 최저점 5% 이상 돌파 추가
                    data.at[data.index[i], 'signal'] = 'monthly_rsi_recovery'
                    data.at[data.index[i], 'point'] = 1
                    data.at[data.index[i], 'signal_strength'] = adjusted_strength
                    signal_count += 1
        
        return data

    def fetch_monthly_data(self, symbol: str) -> pd.DataFrame:
        """월봉 데이터 가져오기"""
        return self.monitor.get_coin_more_data(symbol, INTERVAL, bong_count=BONG_COUNT)

    def render_optimized_plotly(self, symbol: str, data: pd.DataFrame) -> None:
        """통합 최적화 월봉 Plotly 차트 렌더링"""
        fig = subplots.make_subplots(
            rows=5, cols=1,
            subplot_titles=(f"{self.coin} 월봉 캔들차트", "이격도", "RSI & MACD", "볼린저 밴드", "신호 강도"),
            shared_xaxes=True, horizontal_spacing=0.03, vertical_spacing=0.03,
            row_heights=[0.3, 0.2, 0.2, 0.2, 0.1]
        )

        # Row 1: 캔들 + 이동평균
        fig.add_trace(go.Candlestick(x=data.index, open=data['Open'], high=data['High'], 
                                    low=data['Low'], close=data['Close'], name=f'{self.coin} 월봉'), row=1, col=1)
        
        # 이동평균선 표시
        for ma_col, color in [('MA3','red'),('MA6','blue'),('MA12','green'),('MA24','purple'),('MA36','brown')]:
            if ma_col in data.columns:
                fig.add_trace(go.Scatter(x=data.index, y=data[ma_col], name=ma_col, 
                                       mode='lines', line=dict(color=color, width=2)), row=1, col=1)
        
        # 매수 포인트 표시 (신호 강도에 따른 크기 조정)
        buy_signals = ['monthly_ultimate_breakout', 'monthly_strong_breakout', 'monthly_breakout', 
                      'monthly_bb_reversal', 'monthly_rsi_recovery']
        
        colors = ['darkred', 'red', 'orange', 'blue', 'green']
        sizes = [15, 12, 10, 8, 6]  # 신호 강도에 따른 마커 크기
        
        for sig, color, size in zip(buy_signals, colors, sizes):
            pts = data[(data['point']==1) & (data['signal']==sig)]
            if len(pts) > 0:
                # 신호 강도에 따른 크기 조정
                marker_sizes = [size + (strength - 70) / 30 * 5 for strength in pts['signal_strength']]
                fig.add_trace(go.Scatter(x=pts.index, y=pts['Close'], mode='markers', 
                                       name=f'{sig} 매수', marker=dict(color=color, size=marker_sizes, symbol='circle')), row=1, col=1)

        # Row 2: 이격도
        for dev_col, color in [('Deviation3','red'),('Deviation6','blue'),('Deviation12','green'),('Deviation24','purple'),('Deviation36','brown')]:
            if dev_col in data.columns:
                fig.add_trace(go.Scatter(x=data.index, y=data[dev_col], name=dev_col, 
                                       mode='lines', line=dict(color=color, width=2)), row=2, col=1)
        
        # 기준선
        fig.add_hline(y=100, line_width=1, line_dash='dash', line_color='black', row=2, col=1)
        fig.add_hline(y=80, line_width=1, line_dash='dash', line_color='red', row=2, col=1)
        fig.add_hline(y=120, line_width=1, line_dash='dash', line_color='green', row=2, col=1)

        # Row 3: RSI & MACD
        if 'RSI' in data.columns:
            fig.add_trace(go.Scatter(x=data.index, y=data['RSI'], name='RSI', 
                                   mode='lines', line=dict(color='purple', width=2)), row=3, col=1)
            fig.add_hline(y=30, line_width=1, line_dash='dash', line_color='red', row=3, col=1)
            fig.add_hline(y=70, line_width=1, line_dash='dash', line_color='green', row=3, col=1)
        
        if 'MACD' in data.columns:
            fig.add_trace(go.Scatter(x=data.index, y=data['MACD'], name='MACD', 
                                   mode='lines', line=dict(color='blue', width=2)), row=3, col=1)
            fig.add_trace(go.Scatter(x=data.index, y=data['MACD_Signal'], name='MACD Signal', 
                                   mode='lines', line=dict(color='red', width=2)), row=3, col=1)

        # Row 4: 볼린저 밴드
        if 'BB_Upper' in data.columns and 'BB_Lower' in data.columns:
            fig.add_trace(go.Scatter(x=data.index, y=data['BB_Upper'], name='BB Upper', 
                                   mode='lines', line=dict(color='gray', width=1, dash='dot')), row=4, col=1)
            fig.add_trace(go.Scatter(x=data.index, y=data['BB_Lower'], name='BB Lower', 
                                   mode='lines', line=dict(color='gray', width=1, dash='dot')), row=4, col=1)
            fig.add_trace(go.Scatter(x=data.index, y=data['BB_MA'], name='BB MA', 
                                   mode='lines', line=dict(color='orange', width=1)), row=4, col=1)

        # Row 5: 신호 강도
        if 'signal_strength' in data.columns:
            signal_data = data[data['point'] == 1]
            if len(signal_data) > 0:
                fig.add_trace(go.Scatter(x=signal_data.index, y=signal_data['signal_strength'], 
                                       mode='markers', name='신호 강도', 
                                       marker=dict(color='red', size=8, symbol='diamond')), row=5, col=1)
                fig.add_hline(y=70, line_width=2, line_dash='dash', line_color='red', row=5, col=1)

        fig.update_layout(
            height=1400,
            margin=dict(t=180, l=40, r=240, b=40),
            title=dict(
                text=f"{self.coin} 통합 최적화 월봉 시뮬레이션 ({datetime.now().strftime('%Y-%m-%d %H:%M:%S')})",
                x=0.5,
                xanchor='center',
                y=0.995,
                yanchor='top',
                pad=dict(t=10, b=12)
            ),
            xaxis_rangeslider_visible=False,
            legend=dict(orientation='v', yref='paper', yanchor='top', y=1.0, xref='paper', xanchor='left', x=1.02),
            dragmode='zoom'
        )
        
        fig.update_xaxes(title_text='시간', row=5, col=1)
        fig.update_yaxes(title_text='가격 (KRW)', row=1, col=1)
        fig.update_yaxes(title_text='이격도 (%)', row=2, col=1)
        fig.update_yaxes(title_text='RSI / MACD', row=3, col=1)
        fig.update_yaxes(title_text='볼린저 밴드', row=4, col=1)
        fig.update_yaxes(title_text='신호 강도', row=5, col=1)

        # 브라우저에서 차트 표시
        try:
            fig.show(config={'scrollZoom': True, 'displaylogo': False})
            print("브라우저에서 차트가 열렸습니다.")
        except Exception as e:
            print(f"브라우저 열기 실패: {e}")
            # HTML 파일로 저장 후 브라우저에서 열기
            html_file = tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False)
            fig.write_html(html_file.name)
            html_file.close()
            webbrowser.open(f'file://{html_file.name}')
            print(f"HTML 파일이 생성되었습니다: {html_file.name}")

    def create_plotly_figure(self, symbol: str, data: pd.DataFrame):
        """Plotly 차트 생성 (HTML 저장용)"""
        fig = subplots.make_subplots(
            rows=5, cols=1,
            subplot_titles=(f"{self.coin} 월봉 캔들차트", "이격도", "RSI & MACD", "볼린저 밴드", "신호 강도"),
            shared_xaxes=True, horizontal_spacing=0.03, vertical_spacing=0.03,
            row_heights=[0.3, 0.2, 0.2, 0.2, 0.1]
        )

        # Row 1: 캔들 + 이동평균
        fig.add_trace(go.Candlestick(x=data.index, open=data['Open'], high=data['High'], 
                                    low=data['Low'], close=data['Close'], name=f'{self.coin} 월봉'), row=1, col=1)
        
        # 이동평균선 표시
        for ma_col, color in [('MA3','red'),('MA6','blue'),('MA12','green'),('MA24','purple'),('MA36','brown')]:
            if ma_col in data.columns:
                fig.add_trace(go.Scatter(x=data.index, y=data[ma_col], name=ma_col, 
                                       mode='lines', line=dict(color=color, width=2)), row=1, col=1)
        
        # 매수 포인트 표시
        buy_signals = ['monthly_ultimate_breakout', 'monthly_strong_breakout', 'monthly_breakout', 
                      'monthly_bb_reversal', 'monthly_rsi_recovery']
        
        colors = ['darkred', 'red', 'orange', 'blue', 'green']
        sizes = [15, 12, 10, 8, 6]
        
        for sig, color, size in zip(buy_signals, colors, sizes):
            pts = data[(data['point']==1) & (data['signal']==sig)]
            if len(pts) > 0:
                marker_sizes = [size + (strength - 70) / 30 * 5 for strength in pts['signal_strength']]
                fig.add_trace(go.Scatter(x=pts.index, y=pts['Close'], mode='markers', 
                                       name=f'{sig} 매수', marker=dict(color=color, size=marker_sizes, symbol='circle')), row=1, col=1)

        # Row 2: 이격도
        for dev_col, color in [('Deviation3','red'),('Deviation6','blue'),('Deviation12','green'),('Deviation24','purple'),('Deviation36','brown')]:
            if dev_col in data.columns:
                fig.add_trace(go.Scatter(x=data.index, y=data[dev_col], name=dev_col, 
                                       mode='lines', line=dict(color=color, width=2)), row=2, col=1)
        
        # 기준선
        fig.add_hline(y=100, line_width=1, line_dash='dash', line_color='black', row=2, col=1)
        fig.add_hline(y=80, line_width=1, line_dash='dash', line_color='red', row=2, col=1)
        fig.add_hline(y=120, line_width=1, line_dash='dash', line_color='green', row=2, col=1)

        # Row 3: RSI & MACD
        if 'RSI' in data.columns:
            fig.add_trace(go.Scatter(x=data.index, y=data['RSI'], name='RSI', 
                                   mode='lines', line=dict(color='purple', width=2)), row=3, col=1)
            fig.add_hline(y=30, line_width=1, line_dash='dash', line_color='red', row=3, col=1)
            fig.add_hline(y=70, line_width=1, line_dash='dash', line_color='green', row=3, col=1)
        
        if 'MACD' in data.columns:
            fig.add_trace(go.Scatter(x=data.index, y=data['MACD'], name='MACD', 
                                   mode='lines', line=dict(color='blue', width=2)), row=3, col=1)
            fig.add_trace(go.Scatter(x=data.index, y=data['MACD_Signal'], name='MACD Signal', 
                                   mode='lines', line=dict(color='red', width=2)), row=3, col=1)

        # Row 4: 볼린저 밴드
        if 'BB_Upper' in data.columns and 'BB_Lower' in data.columns:
            fig.add_trace(go.Scatter(x=data.index, y=data['BB_Upper'], name='BB Upper', 
                                   mode='lines', line=dict(color='gray', width=1, dash='dot')), row=4, col=1)
            fig.add_trace(go.Scatter(x=data.index, y=data['BB_Lower'], name='BB Lower', 
                                   mode='lines', line=dict(color='gray', width=1, dash='dot')), row=4, col=1)
            fig.add_trace(go.Scatter(x=data.index, y=data['BB_MA'], name='BB MA', 
                                   mode='lines', line=dict(color='orange', width=1)), row=4, col=1)

        # Row 5: 신호 강도
        if 'signal_strength' in data.columns:
            signal_data = data[data['point'] == 1]
            if len(signal_data) > 0:
                fig.add_trace(go.Scatter(x=signal_data.index, y=signal_data['signal_strength'], 
                                       mode='markers', name='신호 강도', 
                                       marker=dict(color='red', size=8, symbol='diamond')), row=5, col=1)
                fig.add_hline(y=70, line_width=2, line_dash='dash', line_color='red', row=5, col=1)

        fig.update_layout(
            height=1400,
            margin=dict(t=180, l=40, r=240, b=40),
            title=dict(
                text=f"{self.coin} 통합 최적화 월봉 시뮬레이션 ({datetime.now().strftime('%Y-%m-%d %H:%M:%S')})",
                x=0.5,
                xanchor='center',
                y=0.995,
                yanchor='top',
                pad=dict(t=10, b=12)
            ),
            xaxis_rangeslider_visible=False,
            legend=dict(orientation='v', yref='paper', yanchor='top', y=1.0, xref='paper', xanchor='left', x=1.02),
            dragmode='zoom'
        )
        
        fig.update_xaxes(title_text='시간', row=5, col=1)
        fig.update_yaxes(title_text='가격 (KRW)', row=1, col=1)
        fig.update_yaxes(title_text='이격도 (%)', row=2, col=1)
        fig.update_yaxes(title_text='RSI / MACD', row=3, col=1)
        fig.update_yaxes(title_text='볼린저 밴드', row=4, col=1)
        fig.update_yaxes(title_text='신호 강도', row=5, col=1)

        return fig

    def run_optimized_simulation(self, symbol: str):
        """통합 최적화 월봉/주봉 시뮬레이션 실행 (월봉 부족시 주봉으로 자동 전환)"""
        print(f"\n=== {self.coin} 통합 최적화 월봉/주봉 시뮬레이션 시작 ===")
        
        # 월봉 데이터 가져오기
        monthly_data = self.fetch_monthly_data(symbol)
        is_weekly = False
        data = monthly_data
        
        # 월봉 데이터 부족시 주봉으로 전환 (12개월 미만)
        if data is None or data.empty or len(data) < 12:
            print(f"월봉 데이터 부족 (현재: {len(data) if data is not None else 0}개월), 주봉으로 전환 시도")
            
            # 주봉 데이터 가져오기 (10080분 = 1주)
            weekly_data = self.fetch_weekly_data(symbol)
            if weekly_data is None or weekly_data.empty or len(weekly_data) < 12:
                print(f"주봉 데이터도 부족 (현재: {len(weekly_data) if weekly_data is not None else 0}주)")
                return [], []
            
            # 주봉 데이터 사용
            data = weekly_data
            is_weekly = True
            print(f"주봉 데이터 사용 (현재: {len(data)}주)")
        
        timeframe = "주봉" if is_weekly else "월봉"
        print(f"데이터 기간: {data.index[0]} ~ {data.index[-1]}")
        print(f"총 {timeframe} 수: {len(data)}")
        
        # 기술적 지표 계산
        data = self.calculate_monthly_indicators(data, is_weekly)
        
        # 매수 신호 생성
        data = self.generate_optimized_signals(symbol, data)
        
        # 매수 신호 분석
        alerts = []
        total_buy_amount = 0
        for i in range(len(data)):
            if data['point'].iloc[i] == 1:
                signal = data['signal'].iloc[i]
                price = data['Close'].iloc[i]
                signal_strength = data['signal_strength'].iloc[i]
                
                buy_amount = self.strategy.get_buy_amount(signal, price, signal_strength)
                total_buy_amount += buy_amount
                alerts.append((data.index[i], price, signal, buy_amount, signal_strength))
        
        print(f"\n총 매수 신호 수: {len(alerts)}")
        print(f"총 매수 금액: {total_buy_amount:,.0f}원")
        
        # 신호별 분석
        signal_counts = {}
        signal_amounts = {}
        signal_strengths = {}
        for _, _, signal, amount, strength in alerts:
            signal_counts[signal] = signal_counts.get(signal, 0) + 1
            signal_amounts[signal] = signal_amounts.get(signal, 0) + amount
            if signal not in signal_strengths:
                signal_strengths[signal] = []
            signal_strengths[signal].append(strength)
        
        print("\n신호별 분석:")
        for signal in signal_counts:
            avg_strength = sum(signal_strengths[signal]) / len(signal_strengths[signal])
            print(f"  - {signal}: {signal_counts[signal]}회, 총 {signal_amounts[signal]:,.0f}원, 평균 강도: {avg_strength:.1f}")
        
        # 수익률 분석 (간단한 백테스팅)
        if len(alerts) > 0:
            print("\n수익률 분석:")
            total_investment = 0
            total_value = 0
            
            for date, buy_price, signal, buy_amount, strength in alerts:
                total_investment += buy_amount
                # 현재 가격으로 평가 (마지막 가격 기준)
                current_price = data['Close'].iloc[-1]
                shares = buy_amount / buy_price
                current_value = shares * current_price
                total_value += current_value
            
            if total_investment > 0:
                total_return = ((total_value - total_investment) / total_investment) * 100
                print(f"  - 총 투자금액: {total_investment:,.0f}원")
                print(f"  - 현재 평가금액: {total_value:,.0f}원")
                print(f"  - 총 수익률: {total_return:.2f}%")
        
        # Plotly 기반 시각화
        if SHOW_GRAPHS:
            self.render_optimized_plotly(symbol, data)
            
            # 추가로 HTML 파일 생성
            html_filename = f"{self.coin}_monthly_simulation_{datetime.now().strftime('%Y%m%d_%H%M%S')}.html"
            fig = self.create_plotly_figure(symbol, data)
            fig.write_html(html_filename)
            print(f"\n차트가 HTML 파일로 저장되었습니다: {html_filename}")
            print(f"브라우저에서 {html_filename} 파일을 열어서 차트를 확인하세요.")
        
        return alerts, []

# ========================================
# 메인 실행 부분
# ========================================

if __name__ == "__main__":
    print(f"\n=== 통합 최적화 월봉 시뮬레이션 시작 ===")
    print(f"코인: {COIN}")
    print(f"월봉 개수: {BONG_COUNT}개")
    print(f"그래프 표시: {'예' if SHOW_GRAPHS else '아니오'}")
    print("=" * 50)
    
    try:
        sim = OptimizedMonthlySimulation(COIN)
        buy_alerts, sell_alerts = sim.run_optimized_simulation(COIN)
        
        print(f"\n=== 통합 최적화 월봉 시뮬레이션 완료 ===")
        print(f"매수 신호: {len(buy_alerts)}회")
        
    except Exception as e:
        print(f"Error analyzing {COIN}: {str(e)}")
        print("\n지원되는 코인 목록:")
        print("XRP, ADA, APT, AVAX, BONK, BTC, ETC, HBAR, LINK, ONDO, PENGU, SEI, SOL, SUI, TRX, VIRTUAL, WLD, XLM")