from datetime import datetime
import time
import pandas as pd
import numpy as np
from monitor_min import Monitor
from config import *

class MonthlyCoinMonitor2(Monitor):
    """월봉 기준 코인 모니터링 및 매수 실행 클래스 - 전략 2: 글로벌 전략 기반"""

    def __init__(self, cooldown_file: str = './resources/coins_buy_time_1mon_2.json') -> None:
        super().__init__(cooldown_file)

    def calculate_advanced_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()
        
        # 지수이동평균선 (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()
        
        # 이격도
        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
        
        # 볼린저 밴드 (다중 기간)
        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))
        
        # 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']
        
        # 스토캐스틱
        data['Stoch_K'] = data['Close'].rolling(window=14).apply(lambda x: (x.iloc[-1] - x.min()) / (x.max() - x.min()) * 100)
        data['Stoch_D'] = data['Stoch_K'].rolling(window=3).mean()
        
        # 윌리엄스 %R
        data['Williams_R'] = data['Close'].rolling(window=14).apply(lambda x: (x.max() - x.iloc[-1]) / (x.max() - x.min()) * -100)
        
        # CCI (Commodity Channel Index)
        data['CCI'] = data['Close'].rolling(window=20).apply(lambda x: (x.iloc[-1] - x.mean()) / (0.015 * x.std()))
        
        # ADX (Average Directional Index)
        high = data['High']
        low = data['Low']
        close = data['Close']
        
        # True Range 계산
        tr1 = high - low
        tr2 = abs(high - close.shift(1))
        tr3 = abs(low - close.shift(1))
        data['TR'] = np.maximum(tr1, np.maximum(tr2, tr3))
        
        # Directional Movement 계산
        dm_plus = high - high.shift(1)
        dm_minus = low.shift(1) - low
        data['DM_Plus'] = np.where((dm_plus > dm_minus) & (dm_plus > 0), dm_plus, 0)
        data['DM_Minus'] = np.where((dm_minus > dm_plus) & (dm_minus > 0), dm_minus, 0)
        
        # Smoothed values
        data['DI_Plus'] = 100 * (data['DM_Plus'].rolling(window=14).mean() / data['TR'].rolling(window=14).mean())
        data['DI_Minus'] = 100 * (data['DM_Minus'].rolling(window=14).mean() / data['TR'].rolling(window=14).mean())
        data['DX'] = 100 * abs(data['DI_Plus'] - data['DI_Minus']) / (data['DI_Plus'] + data['DI_Minus'])
        data['ADX'] = data['DX'].rolling(window=14).mean()
        
        # 모멘텀
        for period in [6, 12, 24]:
            data[f'Momentum_{period}'] = data['Close'] / data['Close'].shift(period) * 100
        
        # 변동성 지표
        data['Volatility'] = data['Close'].rolling(window=12).std() / data['Close'].rolling(window=12).mean() * 100
        
        return data

    def generate_advanced_monthly_signals(self, symbol: str, data: pd.DataFrame) -> pd.DataFrame:
        """simulation_1mon.py와 동일한 글로벌 전략 기반 매수 신호 생성"""
        data = data.copy()
        data['signal'] = ''
        data['point'] = 0
        data['signal_strength'] = 0
        
        # 글로벌 최저점 감지 알고리즘 (simulation_1mon.py와 완전 동일)
        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)
        
        # 2024년 10월부터 매수 제한 (데이터 인덱스 기반) - 2024년 9월 허용
        max_buy_index = len(data) - 5  # 마지막 5개월 제외 (2024년 9월 허용)
        
        # 특정 시점 매수 전략 (simulation_1mon.py와 완전 동일)
        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
            
            return False
        
        # 매수 신호 생성 로직 (simulation_1mon.py와 완전 동일)
        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_12'].iloc[i]
            
            # 볼린저 밴드
            bb_lower = data['BB_Lower_12'].iloc[i]
            bb_upper = data['BB_Upper_12'].iloc[i]
            bb_width = data['BB_Width_12'].iloc[i]
            
            # MACD
            macd = data['MACD'].iloc[i]
            macd_signal = data['MACD_Signal'].iloc[i]
            macd_hist = data['MACD_Histogram'].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
            
            # 특정 시점 매수 보너스 적용
            target_period_bonus = 0
            if is_target_period_buy_zone(data, i):
                target_period_bonus = 20  # 특정 시점 매수 보너스 20점
            
            # 고가 구간 매수 방지 로직 (조정된 글로벌 전략)
            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
                
                # 최근 12개월 평균 대비 가격 비율
                recent_12m_avg = data['Close'].iloc[current_index-12:current_index].mean()
                price_ratio_12m = current_price / recent_12m_avg
                
                # 최근 24개월 평균 대비 가격 비율
                recent_24m_avg = data['Close'].iloc[current_index-24:current_index].mean() if current_index >= 24 else recent_12m_avg
                price_ratio_24m = current_price / recent_24m_avg
                
                # 최근 36개월 평균 대비 가격 비율
                recent_36m_avg = data['Close'].iloc[current_index-36:current_index].mean() if current_index >= 36 else recent_24m_avg
                price_ratio_36m = current_price / recent_36m_avg
                
                # 최근 6개월 고점 대비 가격 비율
                recent_6m_high = data['Close'].iloc[current_index-6:current_index].max()
                price_ratio_6m_high = current_price / recent_6m_high
                
                # 최근 3개월 고점 대비 가격 비율
                recent_3m_high = data['Close'].iloc[current_index-3:current_index].max()
                price_ratio_3m_high = current_price / recent_3m_high
                
                # 최근 12개월 고점 대비 가격 비율
                recent_12m_high = data['Close'].iloc[current_index-12:current_index].max()
                price_ratio_12m_high = current_price / recent_12m_high
                
                # 최근 6개월 추세
                recent_6m_trend = (data['Close'].iloc[current_index] - data['Close'].iloc[current_index-6]) / data['Close'].iloc[current_index-6] * 100 if current_index >= 6 else 0
                
                # 연속 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]
                    consecutive_3m_up = month1_price < month2_price < month3_price
                else:
                    consecutive_3m_up = False
                
                # 고가 구간 판단 조건 (조정된 글로벌 전략)
                high_price_conditions = [
                    price_ratio_12m > 1.4,  # 12개월 평균 대비 40% 이상 높음
                    price_ratio_24m > 1.2,  # 24개월 평균 대비 20% 이상 높음
                    price_ratio_36m > 1.15,  # 36개월 평균 대비 15% 이상 높음
                    price_ratio_6m_high > 0.8,  # 6개월 고점 대비 80% 이상
                    price_ratio_3m_high > 0.9,  # 3개월 고점 대비 90% 이상
                    price_ratio_12m_high > 0.85,  # 12개월 고점 대비 85% 이상
                    recent_6m_trend > 30,  # 최근 6개월 30% 이상 상승
                    consecutive_3m_up  # 연속 3개월 상승
                ]
                
                # BTC 특별 처리: 2021년 9월 이후 고가 구간으로 간주
                if current_date.year == 2021 and current_date.month >= 9:
                    return True
                
                # BTC 특별 처리: 2021년 12월은 무조건 고가 구간
                if current_date.year == 2021 and current_date.month == 12:
                    return True
                
                # BTC 특별 처리: 2021년 11월은 무조건 고가 구간
                if current_date.year == 2021 and current_date.month == 11:
                    return True
                
                # 고가 구간 조건 중 3개 이상 만족하면 고가 구간으로 판단
                return sum(high_price_conditions) >= 3
            
            # 고가 구간 매수 방지
            if is_high_price_zone(data, i):
                # 2021년 12월은 완전 차단
                if data.index[i].year == 2021 and data.index[i].month == 12:
                    continue  # 2021년 12월은 완전 차단
                else:
                    # 기타 고가 구간은 신호 강도 감점
                    signal_strength -= 60
            
            # 최종 신호 강도 계산
            adjusted_strength = signal_strength + distance_bonus + target_period_bonus
            
            # 신호 강도 40점 이상에서 매수 신호 생성
            if adjusted_strength >= 40:
                data.at[data.index[i], 'signal'] = 'monthly_global_strategy'
                data.at[data.index[i], 'point'] = 1
                data.at[data.index[i], 'signal_strength'] = adjusted_strength
        
        return data

    def get_advanced_monthly_buy_amount(self, symbol: str, signal: str, current_price: float, data: pd.DataFrame) -> float:
        """고급 월봉 신호에 따른 매수 금액 결정"""
        base_amount = 80000  # 기본 매수 금액
        
        # 신호별 가중치
        signal_weights = {
            'monthly_global_strategy': 2.0,  # 글로벌 전략
        }
        
        base_weight = signal_weights.get(signal, 1.0)
        
        # 가격에 따른 조정 (고가 코인일수록 적게 매수)
        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 * price_factor
        
        # 최대/최소 제한
        return max(40000, min(400000, final_amount))

    def execute_advanced_monthly_buy(self, symbol: str, signal: str, current_price: float, data: pd.DataFrame) -> bool:
        """고급 월봉 매수 실행"""
        try:
            # 매수 금액 결정
            buy_amount = self.get_advanced_monthly_buy_amount(symbol, signal, current_price, data)
            
            # 매수 수량 계산
            buy_quantity = buy_amount / current_price
            
            print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] {symbol} 고급 월봉 매수 실행")
            print(f"  신호: {signal}")
            print(f"  현재가: {current_price:,.0f}원")
            print(f"  매수금액: {buy_amount:,.0f}원")
            print(f"  매수수량: {buy_quantity:.6f}")
            
            # 실제 매수 로직은 여기에 구현
            # self.buy_coin(symbol, buy_quantity, current_price)
            
            # 쿨다운 설정
            self.set_advanced_monthly_cooldown(symbol)
            
            return True
            
        except Exception as e:
            print(f"Error executing advanced monthly buy for {symbol}: {str(e)}")
            return False

    def check_advanced_monthly_cooldown(self, symbol: str) -> bool:
        """고급 월봉 매수 쿨다운 확인"""
        try:
            cooldown_data = self.load_cooldown_data()
            if symbol in cooldown_data:
                last_buy_time = datetime.fromisoformat(cooldown_data[symbol])
                # 월봉 매수는 30일 쿨다운
                if (datetime.now() - last_buy_time).days < 30:
                    return False
            return True
        except:
            return True

    def set_advanced_monthly_cooldown(self, symbol: str) -> None:
        """고급 월봉 매수 쿨다운 설정"""
        try:
            cooldown_data = self.load_cooldown_data()
            cooldown_data[symbol] = datetime.now().isoformat()
            self.save_cooldown_data(cooldown_data)
        except Exception as e:
            print(f"Error setting advanced monthly cooldown for {symbol}: {str(e)}")

    def monitor_advanced_monthly_coins(self) -> None:
        """고급 월봉/주봉 기준 코인 모니터링 (월봉 부족시 주봉으로 자동 전환)"""
        print(f"[{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}] 고급 월봉/주봉 모니터링 시작 - 전략 2")
        
        for symbol in KR_COINS_2:  # 두 번째 그룹 코인들
            try:
                # 월봉 데이터 가져오기 (43200분 = 1개월)
                monthly_data = self.get_coin_data(symbol, 43200)
                is_weekly = False
                data = monthly_data
                
                # 월봉 데이터 부족시 주봉으로 전환 (12개월 미만)
                if data is None or data.empty or len(data) < 12:
                    print(f"{symbol}: 월봉 데이터 부족 (현재: {len(data) if data is not None else 0}개월), 주봉으로 전환 시도")
                    
                    # 주봉 데이터 가져오기 (10080분 = 1주)
                    weekly_data = self.get_coin_data(symbol, 10080)
                    if weekly_data is None or weekly_data.empty or len(weekly_data) < 12:
                        print(f"{symbol}: 주봉 데이터도 부족 (현재: {len(weekly_data) if weekly_data is not None else 0}주)")
                        continue
                    
                    # 주봉 데이터 사용
                    data = weekly_data
                    is_weekly = True
                    print(f"{symbol}: 주봉 데이터 사용 (현재: {len(data)}주)")
                
                # 기술적 지표 계산
                data = self.calculate_advanced_monthly_indicators(data, is_weekly)
                
                # 매수 신호 생성
                data = self.generate_advanced_monthly_signals(symbol, data)
                
                # 최신 신호 확인
                if data['point'].iloc[-1] == 1:
                    signal = data['signal'].iloc[-1]
                    current_price = data['Close'].iloc[-1]
                    
                    # 쿨다운 확인
                    if not self.check_advanced_monthly_cooldown(symbol):
                        continue
                    
                    # 매수 실행
                    self.execute_advanced_monthly_buy(symbol, signal, current_price, data)
                else:
                    timeframe = "주봉" if is_weekly else "월봉"
                    print(f"{symbol}: 고급 {timeframe} 매수 신호 없음")
                
                time.sleep(1)  # API 호출 간격 조절
                
            except Exception as e:
                print(f"Error processing {symbol}: {str(e)}")
                continue

    def run_schedule(self) -> None:
        """스케줄러 실행"""
        while True:
            self.monitor_advanced_monthly_coins()
            time.sleep(2)  # 2시간마다 체크

if __name__ == "__main__":
    monitor = MonthlyCoinMonitor2()
    monitor.run_schedule()