init
This commit is contained in:
@@ -7,3 +7,4 @@ pycurl
|
|||||||
schedule
|
schedule
|
||||||
python-dateutil
|
python-dateutil
|
||||||
python-telegram-bot
|
python-telegram-bot
|
||||||
|
finance-datareader
|
||||||
@@ -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]
|
|
||||||
print(f" - {info['name']} ({symbol}): {info['price']:.2f} -> {info['signal_count']}")
|
|
||||||
|
|
||||||
if info['buy']:
|
if data is not None and not data.empty:
|
||||||
#if info['buy'] or any(info['buy_signals'].values()):
|
try:
|
||||||
message_list.append(format_message(info, 'KR'))
|
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']}")
|
||||||
|
|
||||||
except Exception as e:
|
if info['buy']:
|
||||||
print(f"Error processing data for {symbol}: {str(e)}")
|
message_list.append(format_message(info, 'KR'))
|
||||||
else:
|
|
||||||
print(f"Data for {symbol} is empty or None.")
|
except Exception as e:
|
||||||
time.sleep(0.5)
|
print(f"Error processing data for {symbol}: {str(e)}")
|
||||||
|
else:
|
||||||
|
print(f"Data for {symbol} is empty or None.")
|
||||||
|
|
||||||
|
# 각 심볼 처리 후 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:
|
||||||
|
|||||||
Reference in New Issue
Block a user