init
This commit is contained in:
13
config.py
13
config.py
@@ -95,6 +95,19 @@ KR_ETFS = {
|
|||||||
"376410.KS": 'TIGER 탄소효율그린뉴딜'
|
"376410.KS": 'TIGER 탄소효율그린뉴딜'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KR_COINS = {
|
||||||
|
"ADA": "ADA",
|
||||||
|
"BTC": "BTC",
|
||||||
|
"ETH": "ETH",
|
||||||
|
"HBAR": "HBAR",
|
||||||
|
"LINK": "LINK",
|
||||||
|
"ONDO": "ONDO",
|
||||||
|
"SOL": "SOL",
|
||||||
|
"SUI": "SUI",
|
||||||
|
"XLM": "XLM",
|
||||||
|
"XRP": "XRP",
|
||||||
|
}
|
||||||
|
|
||||||
# 볼린저 밴드 설정
|
# 볼린저 밴드 설정
|
||||||
BOLLINGER_PERIOD = 20 # 볼린저 밴드 기간
|
BOLLINGER_PERIOD = 20 # 볼린저 밴드 기간
|
||||||
BOLLINGER_STD = 2 # 표준편차 승수
|
BOLLINGER_STD = 2 # 표준편차 승수
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
yfinance
|
yfinance
|
||||||
pandas
|
pandas
|
||||||
numpy
|
numpy
|
||||||
|
ccxt
|
||||||
|
PyJWT
|
||||||
|
pycurl
|
||||||
|
certifi
|
||||||
|
python-dateutil
|
||||||
|
python-telegram-bot
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import pandas as pd
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
import telegram
|
import telegram
|
||||||
import time
|
import time
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
import asyncio
|
import asyncio
|
||||||
from multiprocessing import Pool
|
from multiprocessing import Pool
|
||||||
from config import *
|
from config import *
|
||||||
@@ -27,9 +29,14 @@ def check_bollinger_bands(symbol, data):
|
|||||||
if len(data) < BOLLINGER_PERIOD:
|
if len(data) < BOLLINGER_PERIOD:
|
||||||
return None
|
return None
|
||||||
latest = data.iloc[-1]
|
latest = data.iloc[-1]
|
||||||
upper_band = latest['Upper'].iloc[0]
|
if isinstance(latest['Upper'], float):
|
||||||
lower_band = latest['Lower'].iloc[0]
|
upper_band = latest['Upper']
|
||||||
current_price = latest['Close'].iloc[0]
|
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 = (current_price - lower_band) / (upper_band - lower_band)
|
||||||
return {
|
return {
|
||||||
'symbol': symbol,
|
'symbol': symbol,
|
||||||
@@ -38,6 +45,42 @@ def check_bollinger_bands(symbol, data):
|
|||||||
'distance': distance
|
'distance': distance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_coin_data(symbol, retries=3):
|
||||||
|
for attempt in range(retries):
|
||||||
|
try:
|
||||||
|
url = ('https://api.bithumb.com/v1/candles/days?market=KRW-{}&count=100').format(symbol)
|
||||||
|
headers = {"accept": "application/json"}
|
||||||
|
response = requests.get(url, headers=headers)
|
||||||
|
json_data = json.loads(response.text)
|
||||||
|
df_temp = pd.DataFrame(json_data)
|
||||||
|
df_temp = df_temp.sort_index(ascending=False)
|
||||||
|
if 'candle_date_time_kst' not in df_temp:
|
||||||
|
return None
|
||||||
|
|
||||||
|
data = pd.DataFrame()
|
||||||
|
# data.columns = ['datetime', 'open', 'close', 'high', 'low', 'volume']
|
||||||
|
# data['datetime'] = pd.to_datetime(data_temp['candle_date_time_kst'])
|
||||||
|
data['datetime'] = pd.to_datetime(df_temp['candle_date_time_kst'], format='%Y-%m-%dT%H:%M:%S')
|
||||||
|
data['Open'] = df_temp['opening_price']
|
||||||
|
data['Close'] = df_temp['trade_price']
|
||||||
|
data['High'] = df_temp['high_price']
|
||||||
|
data['Low'] = df_temp['low_price']
|
||||||
|
data['Volume'] = df_temp['candle_acc_trade_volume']
|
||||||
|
data = data.set_index('datetime')
|
||||||
|
data = data.astype(float)
|
||||||
|
data["datetime"] = data.index
|
||||||
|
|
||||||
|
if not data.empty:
|
||||||
|
return data
|
||||||
|
print(f"No data received for {symbol}, attempt {attempt + 1}")
|
||||||
|
time.sleep(0.5)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Attempt {attempt + 1} failed for {symbol}: {str(e)}")
|
||||||
|
if attempt < retries - 1:
|
||||||
|
time.sleep(5)
|
||||||
|
continue
|
||||||
|
return None
|
||||||
|
|
||||||
def get_stock_data(symbol, retries=3):
|
def get_stock_data(symbol, retries=3):
|
||||||
for attempt in range(retries):
|
for attempt in range(retries):
|
||||||
try:
|
try:
|
||||||
@@ -54,7 +97,7 @@ def get_stock_data(symbol, retries=3):
|
|||||||
if not data.empty:
|
if not data.empty:
|
||||||
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(2)
|
time.sleep(0.5)
|
||||||
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:
|
||||||
@@ -117,5 +160,30 @@ def monitor_stocks():
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def monitor_coins():
|
||||||
|
# 미국 주식 모니터링
|
||||||
|
print("Monitoring KR Coins...")
|
||||||
|
for symbol in KR_COINS:
|
||||||
|
data = get_coin_data(symbol)
|
||||||
|
if data is not None and not data.empty:
|
||||||
|
try:
|
||||||
|
data = calculate_bollinger_bands(data)
|
||||||
|
info = check_bollinger_bands(symbol, data)
|
||||||
|
info['name'] = KR_COINS[symbol]
|
||||||
|
print(" - {} ({}): {:.2f} ({:.2f})".format(info['name'], symbol, info['price'], info['distance']))
|
||||||
|
|
||||||
|
if info['distance'] <= ALERT_THRESHOLD:
|
||||||
|
sendAlertMsg(info, "US")
|
||||||
|
print(f"Alert generated for {symbol}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Error processing data for {symbol}: {str(e)}")
|
||||||
|
else:
|
||||||
|
print(f"Data for {symbol} is empty or None.")
|
||||||
|
time.sleep(0.5)
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
monitor_coins()
|
||||||
monitor_stocks()
|
monitor_stocks()
|
||||||
|
|||||||
Reference in New Issue
Block a user