init
This commit is contained in:
@@ -111,4 +111,5 @@ KR_COINS = {
|
|||||||
# 볼린저 밴드 설정
|
# 볼린저 밴드 설정
|
||||||
BOLLINGER_PERIOD = 20 # 볼린저 밴드 기간
|
BOLLINGER_PERIOD = 20 # 볼린저 밴드 기간
|
||||||
BOLLINGER_STD = 2 # 표준편차 승수
|
BOLLINGER_STD = 2 # 표준편차 승수
|
||||||
ALERT_THRESHOLD = 0.20 # 하단 밴드 대비 10% 근접 시 알림
|
ALERT_THRESHOLD = 0.10 # 하단 밴드 대비 10% 근접 시 알림
|
||||||
|
BUY_THRESHOLD = 0.15
|
||||||
@@ -33,6 +33,19 @@ def calculate_bollinger_bands(data):
|
|||||||
def check_bollinger_bands(symbol, data):
|
def check_bollinger_bands(symbol, data):
|
||||||
if len(data) < BOLLINGER_PERIOD:
|
if len(data) < BOLLINGER_PERIOD:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
# 과거 10개 봉에서 ALERT_THRESHOLD 아래로 빠진 적이 있는지 체크
|
||||||
|
check = False
|
||||||
|
for i in range(-1, -10, -1):
|
||||||
|
past = data.iloc[i]
|
||||||
|
upper_band = past['Upper']
|
||||||
|
lower_band = past['Lower']
|
||||||
|
price = past['Close']
|
||||||
|
distance = (price - lower_band) / (upper_band - lower_band)
|
||||||
|
if distance < ALERT_THRESHOLD:
|
||||||
|
check = True
|
||||||
|
break
|
||||||
|
|
||||||
latest = data.iloc[-1]
|
latest = data.iloc[-1]
|
||||||
if isinstance(latest['Upper'], float):
|
if isinstance(latest['Upper'], float):
|
||||||
upper_band = latest['Upper']
|
upper_band = latest['Upper']
|
||||||
@@ -43,11 +56,17 @@ def check_bollinger_bands(symbol, data):
|
|||||||
lower_band = latest['Lower'].iloc[0]
|
lower_band = latest['Lower'].iloc[0]
|
||||||
current_price = latest['Close'].iloc[0]
|
current_price = latest['Close'].iloc[0]
|
||||||
distance = (current_price - lower_band) / (upper_band - lower_band)
|
distance = (current_price - lower_band) / (upper_band - lower_band)
|
||||||
|
|
||||||
|
buy = False
|
||||||
|
if check and BUY_THRESHOLD < distance:
|
||||||
|
buy = True
|
||||||
|
|
||||||
return {
|
return {
|
||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
'price': current_price,
|
'price': current_price,
|
||||||
'lower_band': lower_band,
|
'lower_band': lower_band,
|
||||||
'distance': distance
|
'distance': distance,
|
||||||
|
'buy': buy
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -113,13 +132,7 @@ def get_stock_data(symbol, retries=3):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def sendAlertMsg(info, market="US", alert=False):
|
def sendAlertMsg(message):
|
||||||
if alert:
|
|
||||||
message = "🔔"
|
|
||||||
else:
|
|
||||||
message = ""
|
|
||||||
|
|
||||||
message += "[{}] {} ({}) 현재가: ${:.2f}, 근접도: {:.2f}%".format(market, info['name'], info['symbol'], info['price'], info['distance'])
|
|
||||||
try:
|
try:
|
||||||
send_telegram_message(message)
|
send_telegram_message(message)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -128,6 +141,8 @@ def sendAlertMsg(info, market="US", alert=False):
|
|||||||
|
|
||||||
|
|
||||||
def monitor_us_stocks():
|
def monitor_us_stocks():
|
||||||
|
message = ""
|
||||||
|
|
||||||
# 미국 주식 모니터링
|
# 미국 주식 모니터링
|
||||||
print("US Stocks {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
|
print("US Stocks {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
for symbol in US_STOCKS:
|
for symbol in US_STOCKS:
|
||||||
@@ -139,22 +154,25 @@ def monitor_us_stocks():
|
|||||||
info['name'] = US_STOCKS[symbol]
|
info['name'] = US_STOCKS[symbol]
|
||||||
print(" - {} ({}): {:.2f} ({:.2f})".format(info['name'], symbol, info['price'], info['distance']))
|
print(" - {} ({}): {:.2f} ({:.2f})".format(info['name'], symbol, info['price'], info['distance']))
|
||||||
|
|
||||||
if info['distance'] > ALERT_THRESHOLD:
|
if info['buy']:
|
||||||
sendAlertMsg(info, "US")
|
message += '🛒'
|
||||||
else:
|
if info['distance'] < ALERT_THRESHOLD:
|
||||||
sendAlertMsg(info, "US", alert=True)
|
message += "🔔"
|
||||||
print(f"Alert generated for {symbol}")
|
message += "[{}] {} ({}) 현재가: ${:.2f}, 근접도: {:.2f}%\n".format('US', info['name'], info['symbol'], info['price'], info['distance'] * 100)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error processing data for {symbol}: {str(e)}")
|
print(f"Error processing data for {symbol}: {str(e)}")
|
||||||
else:
|
else:
|
||||||
print(f"Data for {symbol} is empty or None.")
|
print(f"Data for {symbol} is empty or None.")
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
sendAlertMsg(message)
|
||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def monitor_kr_stocks():
|
def monitor_kr_stocks():
|
||||||
|
message = ""
|
||||||
|
|
||||||
# 한국 ETF 모니터링
|
# 한국 ETF 모니터링
|
||||||
print("KR ETFs {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
|
print("KR ETFs {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
for symbol in KR_ETFS:
|
for symbol in KR_ETFS:
|
||||||
@@ -166,11 +184,11 @@ def monitor_kr_stocks():
|
|||||||
info['name'] = KR_ETFS[symbol]
|
info['name'] = KR_ETFS[symbol]
|
||||||
print(" - {} ({}): {:.2f} ({:.2f})".format(info['name'], symbol, info['price'], info['distance']))
|
print(" - {} ({}): {:.2f} ({:.2f})".format(info['name'], symbol, info['price'], info['distance']))
|
||||||
|
|
||||||
if info['distance'] > ALERT_THRESHOLD:
|
if info['buy']:
|
||||||
sendAlertMsg(info, "KR")
|
message += '🛒'
|
||||||
else:
|
if info['distance'] < ALERT_THRESHOLD:
|
||||||
sendAlertMsg(info, "KR", alert=True)
|
message += "🔔"
|
||||||
print(f"Alert generated for {symbol}")
|
message += "[{}] {} ({}) 현재가: ${:.2f}, 근접도: {:.2f}%\n".format('KR', info['name'], info['symbol'], info['price'], info['distance'] * 100)
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error processing data for {symbol}: {str(e)}")
|
print(f"Error processing data for {symbol}: {str(e)}")
|
||||||
@@ -178,10 +196,13 @@ def monitor_kr_stocks():
|
|||||||
print(f"Data for {symbol} is empty or None.")
|
print(f"Data for {symbol} is empty or None.")
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
sendAlertMsg(message)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def monitor_coins():
|
def monitor_coins():
|
||||||
|
message = "[KRW-Coin]\n"
|
||||||
|
|
||||||
# 코인 모니터링
|
# 코인 모니터링
|
||||||
print("KRW Coins {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
|
print("KRW Coins {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S')))
|
||||||
for symbol in KR_COINS:
|
for symbol in KR_COINS:
|
||||||
@@ -193,18 +214,19 @@ def monitor_coins():
|
|||||||
info['name'] = KR_COINS[symbol]
|
info['name'] = KR_COINS[symbol]
|
||||||
print(" - {} ({}): {:.2f} ({:.2f})".format(info['name'], symbol, info['price'], info['distance']))
|
print(" - {} ({}): {:.2f} ({:.2f})".format(info['name'], symbol, info['price'], info['distance']))
|
||||||
|
|
||||||
if info['distance'] > ALERT_THRESHOLD:
|
message += "· {} ({}) 현재가: ₩{}, 근접도: {:.2f}%".format(info['name'], info['symbol'], info['price'], info['distance'] * 100)
|
||||||
sendAlertMsg(info, "KRW")
|
if info['buy']:
|
||||||
else:
|
message += ' (🛒)'
|
||||||
sendAlertMsg(info, "KRW", alert=True)
|
if info['distance'] < ALERT_THRESHOLD:
|
||||||
print(f"Alert generated for {symbol}")
|
message += "(🔔)"
|
||||||
|
message += '\n'
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error processing data for {symbol}: {str(e)}")
|
print(f"Error processing data for {symbol}: {str(e)}")
|
||||||
else:
|
else:
|
||||||
print(f"Data for {symbol} is empty or None.")
|
print(f"Data for {symbol} is empty or None.")
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
sendAlertMsg(message)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user