This commit is contained in:
dsyoon
2025-05-18 22:41:14 +09:00
parent 6e891a178f
commit f7b290b847
2 changed files with 43 additions and 28 deletions

View File

@@ -7,3 +7,4 @@ pycurl
schedule schedule
python-dateutil python-dateutil
python-telegram-bot python-telegram-bot
finance-datareader

View File

@@ -9,6 +9,7 @@ import asyncio
from multiprocessing import Pool from multiprocessing import Pool
import schedule import schedule
from config import * from config import *
import FinanceDataReader as fdr
def send_coin_msg(text): def send_coin_msg(text):
@@ -144,7 +145,7 @@ def check_buy_signals(symbol, data):
'signal_line': latest['Signal'].iloc[0], 'signal_line': latest['Signal'].iloc[0],
'buy_signals': buy_signals, 'buy_signals': buy_signals,
'signal_count': signal_count, 'signal_count': signal_count,
'buy': (bb_signal and rsi_signal) or (signal_count >= 3 and (bb_signal or rsi_signal)) 'buy': (bb_signal and rsi_signal) or (signal_count >= 2 and (bb_signal or rsi_signal))
} }
else: else:
rsi_signal = latest['RSI'] < 30 rsi_signal = latest['RSI'] < 30
@@ -180,7 +181,7 @@ def check_buy_signals(symbol, data):
'signal_line': latest['Signal'], 'signal_line': latest['Signal'],
'buy_signals': buy_signals, 'buy_signals': buy_signals,
'signal_count': signal_count, 'signal_count': signal_count,
'buy': (bb_signal and rsi_signal) or (signal_count >= 3 and (bb_signal or rsi_signal)) 'buy': (bb_signal and rsi_signal) or (signal_count >= 2 and (bb_signal or rsi_signal))
} }
def format_message(info, market_type): def format_message(info, market_type):
@@ -252,24 +253,28 @@ def get_coin_data(symbol, retries=3):
return None return None
def get_stock_data(symbol, retries=3): def get_kr_stock_data(symbol, retries=3):
for attempt in range(retries): for attempt in range(retries):
try: try:
end = datetime.now() end = datetime.now()
start = end - timedelta(days=300) start = end - timedelta(days=300)
data = yf.download(
symbol, # FinanceDataReader를 사용하여 한국 주식 데이터 가져오기
start=start.strftime('%Y-%m-%d'), data = fdr.DataReader(symbol, start.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d'))
end=end.strftime('%Y-%m-%d'),
interval='1d',
auto_adjust=True,
progress=False
)
if not data.empty: if not data.empty:
# FinanceDataReader의 컬럼명을 yfinance 형식으로 변환
data = data.rename(columns={
'Open': 'Open',
'High': 'High',
'Low': 'Low',
'Close': 'Close',
'Volume': 'Volume'
})
return data return data
print(f"No data received for {symbol}, attempt {attempt + 1}") print(f"No data received for {symbol}, attempt {attempt + 1}")
time.sleep(0.5) time.sleep(2)
except Exception as e: except Exception as e:
print(f"Attempt {attempt + 1} failed for {symbol}: {str(e)}") print(f"Attempt {attempt + 1} failed for {symbol}: {str(e)}")
if attempt < retries - 1: if attempt < retries - 1:
@@ -282,7 +287,7 @@ def monitor_us_stocks():
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:
data = get_stock_data(symbol) data = get_kr_stock_data(symbol)
if data is not None and not data.empty: if data is not None and not data.empty:
try: try:
data = calculate_technical_indicators(data) data = calculate_technical_indicators(data)
@@ -311,23 +316,32 @@ def monitor_kr_stocks():
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:
data = get_stock_data(symbol) try:
if data is not None and not data.empty: # .KS 접미사 제거
try: clean_symbol = symbol.replace('.KS', '')
data = calculate_technical_indicators(data) data = get_kr_stock_data(clean_symbol)
info = check_buy_signals(symbol, data)
info['name'] = KR_ETFS[symbol] if data is not None and not data.empty:
print(f" - {info['name']} ({symbol}): {info['price']:.2f} -> {info['signal_count']}") try:
data = calculate_technical_indicators(data)
info = check_buy_signals(symbol, data)
info['name'] = KR_ETFS[symbol]
print(f" - {info['name']} ({symbol}): {info['price']:.2f} -> {info['signal_count']}")
if info['buy']: if info['buy']:
#if info['buy'] or any(info['buy_signals'].values()): message_list.append(format_message(info, 'KR'))
message_list.append(format_message(info, 'KR'))
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)
# 각 심볼 처리 후 1초 대기
time.sleep(1)
except Exception as e:
print(f"Unexpected error processing {symbol}: {str(e)}")
continue
if len(message_list) > 0: if len(message_list) > 0:
try: try: