This commit is contained in:
dsyoon
2025-08-02 10:52:30 +09:00
parent 84457b7c10
commit 572e1cc163

View File

@@ -89,6 +89,44 @@ def calculate_technical_indicators(data):
return data
def get_daily_bollinger_distance(data):
"""일봉 기준 볼린저 밴드 하단 근접도를 계산하여 distance, 하단 밴드, 종가를 반환한다."""
# 데이터 인덱스가 datetime이 아니면 변환
df = data.copy()
if not isinstance(df.index, pd.DatetimeIndex):
if 'datetime' in df.columns:
df = df.set_index('datetime')
# 일봉 리샘플링
daily = df.resample('D').agg({'Open': 'first',
'High': 'max',
'Low': 'min',
'Close': 'last',
'Volume': 'sum'}).dropna()
# 볼린저 밴드 계산
daily = calculate_bollinger_bands(daily)
if len(daily) < BOLLINGER_PERIOD:
return None, None, None
latest_daily = daily.iloc[-1]
# 볼린저 밴드 값이 존재하는지 확인
if pd.isna(latest_daily['Upper']) or pd.isna(latest_daily['Lower']):
return None, None, None
upper_band = latest_daily['Upper']
lower_band = latest_daily['Lower']
current_price = latest_daily['Close']
# 밴드 폭이 0이면 계산 불가
if upper_band - lower_band == 0:
return None, None, None
distance = (current_price - lower_band) / (upper_band - lower_band)
return distance, lower_band, current_price
def check_buy_signals(symbol, data):
if len(data) < 60: # 최소 60일치 데이터 필요
return None
@@ -96,18 +134,25 @@ def check_buy_signals(symbol, data):
latest = data.iloc[-1]
prev = data.iloc[-2]
# 볼린저 밴드 신호
bb_signal = False
if isinstance(latest['Upper'], float):
upper_band = latest['Upper']
lower_band = latest['Lower']
current_price = latest['Close']
else:
upper_band = latest['Upper'].iloc[0]
lower_band = latest['Lower'].iloc[0]
current_price = latest['Close'].iloc[0]
distance = (current_price - lower_band) / (upper_band - lower_band)
# 볼린저 밴드 신호 (일봉 기준)
distance, lower_band, current_price = get_daily_bollinger_distance(data)
if distance is None:
# 일봉 볼린저 계산이 불가능한 경우 기존 주기 데이터를 사용
if isinstance(latest['Upper'], float):
upper_band = latest['Upper']
lower_band = latest['Lower']
current_price = latest['Close']
else:
upper_band = latest['Upper'].iloc[0]
lower_band = latest['Lower'].iloc[0]
current_price = latest['Close'].iloc[0]
if upper_band - lower_band != 0:
distance = (current_price - lower_band) / (upper_band - lower_band)
else:
distance = 1 # 밴드폭이 0이면 신호 미충족으로 간주
bb_signal = distance < BOLLINGER_THRESHOLD
# U자 반등 후 이전 고점 돌파 여부 계산 (BREAKOUT)