diff --git a/monitor.py b/monitor.py index 9ae7893..5a29399 100644 --- a/monitor.py +++ b/monitor.py @@ -151,6 +151,29 @@ class Monitor: # ------------- Strategy ------------- def buy_ticker(self, symbol: str, data: pd.DataFrame) -> bool: try: + check_5_week_lowest = False + + # 5주봉이 20주봉이나 40주봉보다 아래에 있는지 체크 + try: + # Convert hourly data to week-based rolling periods (5, 20, 40 weeks) + hours_in_week = 24 * 7 # 168 hours + period_5w = 5 * hours_in_week # 840 hours + period_20w = 20 * hours_in_week # 3,360 hours + period_40w = 40 * hours_in_week # 6,720 hours + + if len(data) >= period_40w: + wma5 = data['Close'].rolling(window=period_5w).mean().iloc[-1] + wma20 = data['Close'].rolling(window=period_20w).mean().iloc[-1] + wma40 = data['Close'].rolling(window=period_40w).mean().iloc[-1] + + # 5-week MA is the lowest among 5, 20, 40 week MAs + if (wma5 < wma20) and (wma5 < wma40): + check_5_week_lowest = True + + except Exception: + # Ignore errors in MA calculation so as not to block trading logic + pass + current_time = datetime.now() if data['buy_signal'].iloc[-1] == 'fall_6p': if data['Close'].iloc[-1] > 100: @@ -184,6 +207,10 @@ class Monitor: else: buy_amount = 50000 + if data['buy_signal'].iloc[-1] in ['movingaverage', 'deviation40', 'deviation240', 'deviation1440']: + if check_5_week_lowest: + buy_amount *= 2 + _ = self.hts.buyCoinMarket(symbol, buy_amount) if self.cooldown_file is not None: @@ -390,7 +417,7 @@ class Monitor: cursor.execute( "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" + + " order by ymdhms desc limit 7000) subquery order by datetime" ) result = cursor.fetchall() conn.commit() diff --git a/monitor_coin.py b/monitor_coin.py index b757f7b..79b1cfd 100644 --- a/monitor_coin.py +++ b/monitor_coin.py @@ -1,10 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json from config import * from monitor import Monitor @@ -15,119 +10,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self) -> None: print("[{}] KRW COINs: {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), ','.join(KR_COINS.keys()))) for symbol in KR_COINS: diff --git a/monitor_coin_1.py b/monitor_coin_1.py index 9cd87ca..45544c2 100644 --- a/monitor_coin_1.py +++ b/monitor_coin_1.py @@ -1,10 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json from config import * from monitor import Monitor @@ -15,119 +10,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS_1[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self) -> None: for symbol in KR_COINS_1: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_2.py b/monitor_coin_2.py index afd77f1..a26a48c 100644 --- a/monitor_coin_2.py +++ b/monitor_coin_2.py @@ -1,10 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json from config import * from monitor import Monitor @@ -15,119 +10,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS_2[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self) -> None: for symbol in KR_COINS_2: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_3.py b/monitor_coin_3.py index af7d6c7..c034ec7 100644 --- a/monitor_coin_3.py +++ b/monitor_coin_3.py @@ -1,10 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json from config import * from monitor import Monitor @@ -15,119 +10,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS_3[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self) -> None: for symbol in KR_COINS_3: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_4.py b/monitor_coin_4.py index 3eebb33..4577866 100644 --- a/monitor_coin_4.py +++ b/monitor_coin_4.py @@ -1,10 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json from config import * from monitor import Monitor @@ -15,119 +10,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS_4[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self) -> None: for symbol in KR_COINS_4: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_ADA.py b/monitor_coin_ADA.py index 8c4b160..a94a919 100644 --- a/monitor_coin_ADA.py +++ b/monitor_coin_ADA.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_APE.py b/monitor_coin_APE.py index 0b2fa02..b9a0783 100644 --- a/monitor_coin_APE.py +++ b/monitor_coin_APE.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_ARB.py b/monitor_coin_ARB.py index 615a242..d5752ee 100644 --- a/monitor_coin_ARB.py +++ b/monitor_coin_ARB.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_BONK.py b/monitor_coin_BONK.py index 67887d0..a10b621 100644 --- a/monitor_coin_BONK.py +++ b/monitor_coin_BONK.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_ENA.py b/monitor_coin_ENA.py index ea529ad..ba0bdb3 100644 --- a/monitor_coin_ENA.py +++ b/monitor_coin_ENA.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_HBAR.py b/monitor_coin_HBAR.py index 495d00b..88cbebf 100644 --- a/monitor_coin_HBAR.py +++ b/monitor_coin_HBAR.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_KAIA.py b/monitor_coin_KAIA.py index 1e890c4..74187e5 100644 --- a/monitor_coin_KAIA.py +++ b/monitor_coin_KAIA.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_LINK.py b/monitor_coin_LINK.py index cc54174..b6901f2 100644 --- a/monitor_coin_LINK.py +++ b/monitor_coin_LINK.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_ONDO.py b/monitor_coin_ONDO.py index 524af5e..c390de8 100644 --- a/monitor_coin_ONDO.py +++ b/monitor_coin_ONDO.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_PENGU.py b/monitor_coin_PENGU.py index 45be860..84209f3 100644 --- a/monitor_coin_PENGU.py +++ b/monitor_coin_PENGU.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_PEPE.py b/monitor_coin_PEPE.py index b9adc31..9d667bb 100644 --- a/monitor_coin_PEPE.py +++ b/monitor_coin_PEPE.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_POL.py b/monitor_coin_POL.py index 5e4439e..761d949 100644 --- a/monitor_coin_POL.py +++ b/monitor_coin_POL.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_SAND.py b/monitor_coin_SAND.py index 9ff9686..2b80c97 100644 --- a/monitor_coin_SAND.py +++ b/monitor_coin_SAND.py @@ -15,119 +15,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_SEI.py b/monitor_coin_SEI.py index 00fe7e2..f82ab4c 100644 --- a/monitor_coin_SEI.py +++ b/monitor_coin_SEI.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_SHIB.py b/monitor_coin_SHIB.py index 70b067f..a22a07d 100644 --- a/monitor_coin_SHIB.py +++ b/monitor_coin_SHIB.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_STORJ.py b/monitor_coin_STORJ.py index 95877f2..e8b1b6a 100644 --- a/monitor_coin_STORJ.py +++ b/monitor_coin_STORJ.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_SUI.py b/monitor_coin_SUI.py index 8727e4a..d7468d5 100644 --- a/monitor_coin_SUI.py +++ b/monitor_coin_SUI.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_TON.py b/monitor_coin_TON.py index e60dfd2..160464a 100644 --- a/monitor_coin_TON.py +++ b/monitor_coin_TON.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_TRX.py b/monitor_coin_TRX.py index 1db71cd..e286a55 100644 --- a/monitor_coin_TRX.py +++ b/monitor_coin_TRX.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_UXLINK.py b/monitor_coin_UXLINK.py index 6e9b5b4..fdc7dde 100644 --- a/monitor_coin_UXLINK.py +++ b/monitor_coin_UXLINK.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_VIRTUAL.py b/monitor_coin_VIRTUAL.py index 4460bd2..ddb8a1b 100644 --- a/monitor_coin_VIRTUAL.py +++ b/monitor_coin_VIRTUAL.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_WLD.py b/monitor_coin_WLD.py index 851c113..ea174bf 100644 --- a/monitor_coin_WLD.py +++ b/monitor_coin_WLD.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_XLM.py b/monitor_coin_XLM.py index 07025cb..8db88e7 100644 --- a/monitor_coin_XLM.py +++ b/monitor_coin_XLM.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/monitor_coin_XRP.py b/monitor_coin_XRP.py index 2723dbb..82a30e8 100644 --- a/monitor_coin_XRP.py +++ b/monitor_coin_XRP.py @@ -1,11 +1,5 @@ -import pandas as pd -from dateutil.relativedelta import relativedelta from datetime import datetime -import sqlite3 import time -import requests -import json -from config import * from monitor import Monitor @@ -15,119 +9,6 @@ class MonitorCoin (Monitor): def __init__(self, cooldown_file: str = 'coins_buy_time.json') -> None: super().__init__(cooldown_file) - # ------------- Data fetch ------------- - def get_coin_data(self, symbol: str, interval: int = 60, to: str | None = None, retries: int = 3) -> pd.DataFrame | None: - for attempt in range(retries): - try: - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - 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['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_coin_more_data(self, symbol: str, interval: int, bong_count: int = 3000) -> pd.DataFrame: - to = datetime.now() - data: pd.DataFrame | None = None - while data is None or len(data) < bong_count: - if data is None: - data = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - previous_count = len(data) - df = self.get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - if previous_count == len(data): - break - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - - def get_coin_saved_data(self, symbol: str, interval: int, data: pd.DataFrame) -> pd.DataFrame: - conn = sqlite3.connect('coins.db') - cursor = conn.cursor() - for i in range(1, len(data)): - cursor.execute( - "SELECT * from " + symbol + " where CODE = ? and ymdhms = ? and interval = ?", - (symbol, data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), interval), - ) - arr = cursor.fetchone() - if not arr: - cursor.execute( - "INSERT INTO " + symbol + " (interval, CODE, NAME, ymdhms, ymd, hms, close, open, high, low, volume) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", - ( - interval, - symbol, - KR_COINS[symbol], - data['datetime'].iloc[-i].strftime('%Y-%m-%d %H:%M:%S'), - data['datetime'].iloc[-i].strftime('%Y%m%d'), - data['datetime'].iloc[-i].strftime('%H%M%S'), - data['Close'].iloc[-i], - data['Open'].iloc[-i], - data['High'].iloc[-i], - data['Low'].iloc[-i], - data['Volume'].iloc[-i], - ), - ) - else: - break - cursor.execute( - "select * from (SELECT Open,Close,High,Low,Volume,ymdhms as datetime from " - + symbol - + " order by ymdhms desc limit 5000) subquery order by datetime" - ) - result = cursor.fetchall() - conn.commit() - cursor.close() - conn.close() - df = pd.DataFrame(result) - df.columns = ['Open', 'Close', 'High', 'Low', 'Volume', 'datetime'] - df = df.set_index('datetime') - df = df.sort_index() - df['datetime'] = df.index - return df - - def get_coin_some_data(self, symbol: str, interval: int) -> pd.DataFrame: - data = self.get_coin_data(symbol, interval) - data_1 = self.get_coin_data(symbol, interval=1) - data_1.at[data_1.index[-1], 'Volume'] = data_1['Volume'].iloc[-1] * 60 - saved_data = self.get_coin_saved_data(symbol, interval, data) - data = pd.concat([data, saved_data, data_1.iloc[[-1]]], ignore_index=True) - data['datetime'] = pd.to_datetime(data['datetime'], format='%Y-%m-%d %H:%M:%S') - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - return data - def monitor_coins(self, symbol) -> None: print("[{}] {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'), symbol)) diff --git a/stock_monitor_1.py.bak b/stock_monitor_1.py.bak deleted file mode 100644 index 46ea7a4..0000000 --- a/stock_monitor_1.py.bak +++ /dev/null @@ -1,535 +0,0 @@ -import yfinance as yf -import pandas as pd -from datetime import datetime, timedelta -import telegram -import time -import requests -import json -import asyncio -from multiprocessing import Pool -import schedule -from config import * -import FinanceDataReader as fdr - - -def send_coin_msg(text): - coin_client = telegram.Bot(token=COIN_TELEGRAM_BOT_TOKEN) - asyncio.run(coin_client.send_message(chat_id=COIN_TELEGRAM_CHAT_ID, text=text)) - return - - -def send_coin_telegram_message(message_list, header): - pStr = header + "\n" - for i, message in enumerate(message_list): - pStr += message - - if i + 1 % 20 == 0: - pool = Pool(12) - pool.map(send_coin_msg, [pStr]) - pStr = '' - - if len(message_list) % 20 != 0: - pool = Pool(12) - pool.map(send_coin_msg, [pStr]) - - return - - -def send_stock_msg(text): - stock_client = telegram.Bot(token=STOCK_TELEGRAM_BOT_TOKEN) - asyncio.run(stock_client.send_message(chat_id=STOCK_TELEGRAM_CHAT_ID, text=text)) - return - - -def send_stock_telegram_message(message_list, header): - pStr = header + "\n" - for i, message in enumerate(message_list): - pStr += message - - if i + 1 % 20 == 0: - pool = Pool(12) - pool.map(send_stock_msg, [pStr]) - pStr = '' - - if len(message_list) % 20 != 0: - pool = Pool(12) - pool.map(send_stock_msg, [pStr]) - - return - - -def calculate_bollinger_bands(data): - data['MA'] = data['Close'].rolling(window=BOLLINGER_PERIOD).mean() - data['STD'] = data['Close'].rolling(window=BOLLINGER_PERIOD).std() - data['Upper'] = data['MA'] + (BOLLINGER_STD * data['STD']) - data['Lower'] = data['MA'] - (BOLLINGER_STD * data['STD']) - return data - - -def calculate_technical_indicators(data): - # 볼린저 밴드 계산 - data = calculate_bollinger_bands(data) - - # RSI 계산 (14일 기준) - delta = data['Close'].diff() - gain = (delta.where(delta > 0, 0)).rolling(window=14).mean() - loss = (-delta.where(delta < 0, 0)).rolling(window=14).mean() - rs = gain / loss - data['RSI'] = 100 - (100 / (1 + rs)) - - # MACD 계산 - exp1 = data['Close'].ewm(span=12, adjust=False).mean() - exp2 = data['Close'].ewm(span=26, adjust=False).mean() - data['MACD'] = exp1 - exp2 - data['Signal'] = data['MACD'].ewm(span=9, adjust=False).mean() - - # 이동평균선 - data['MA5'] = data['Close'].rolling(window=5).mean() - data['MA20'] = data['Close'].rolling(window=20).mean() - data['MA40'] = data['Close'].rolling(window=40).mean() - data['MA60'] = data['Close'].rolling(window=60).mean() - - # 거래량 이동평균 - data['Volume_MA5'] = data['Volume'].rolling(window=5).mean() - - return data - - -def check_ma_alert(symbol, data, interval=0): - """1시간봉 기준 이동평균선 조건 알림 - - 5봉 이동평균(MA5) 상승 - - 20봉 이동평균(MA20) 상승 - - 40봉 이동평균(MA40)이 하락세에서 상승세로 전환되는 시점 (직전 기울기 < 0 and 현재 기울기 ≥ 0) - """ - # 40 이동평균선의 기울기를 계산하기 위해 최소 41개 캔들이 필요합니다. - if len(data) < 41: - return None - - # 이동평균선 값 추출 - ma5_current, ma5_prev = data['MA5'].iloc[-1], data['MA5'].iloc[-2] - ma20_current, ma20_prev = data['MA20'].iloc[-1], data['MA20'].iloc[-2] - ma40_current = data['MA40'].iloc[-1] - ma40_prev1, ma40_prev2 = data['MA40'].iloc[-2], data['MA40'].iloc[-3] - - # 조건 계산 - up5 = ma5_current > ma5_prev - up20 = ma20_current > ma20_prev - slope_prev = ma40_prev1 - ma40_prev2 # 직전 기울기 (음수: 하락) - slope_now = ma40_current - ma40_prev1 # 현재 기울기 - turning = (slope_prev < 0) and (slope_now >= 0) - - alert = up5 and up20 and turning - - return { - 'symbol': symbol, - 'price': data['Close'].iloc[-1], - 'alert': alert, - 'details': { - 'interval': interval, - 'up5': up5, - 'up20': up20, - 'ma40_turning': turning - } - } - - -def check_buy_signals(symbol, data): - if len(data) < 60: # 최소 60일치 데이터 필요 - return None - - 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) - bb_signal = distance < BOLLINGER_THRESHOLD - - # U자 반등 후 이전 고점 돌파 여부 계산 (BREAKOUT) - breakout_signal = False - if len(data) >= max(BREAKOUT_LOOKBACK, BREAKOUT_WEEK_LOOKBACK) + 1: - # ① U자 형태 확인 - window_close = data['Close'].iloc[-BREAKOUT_LOOKBACK - 1:-1] - prev_high = window_close.max() - prev_low = window_close.min() - - # ② 1주일(42캔들) 전 가격 대비 5% 이상 상승하지 않았는지 체크 - price_week_ago = data['Close'].iloc[-BREAKOUT_WEEK_LOOKBACK - 1] - if price_week_ago > 0: - week_change = (current_price - price_week_ago) / price_week_ago - else: - week_change = 1 # 값이 0이면 조건 불충족 처리 - - # ③ 조건 종합: U자+돌파 && 주간 상승률 ≤ 5% - if ( - prev_high > 0 and (prev_high - prev_low) / prev_high > BUY_THRESHOLD and current_price > prev_high - and week_change <= BREAKOUT_WEEK_LIMIT - ): - breakout_signal = True - - # 장기간 저항선 돌파 여부 계산 (LONG RESISTANCE BREAKOUT) - long_breakout_signal = False - if len(data) >= RESISTANCE_LOOKBACK + 1: - resistance_level = data['Close'].iloc[-RESISTANCE_LOOKBACK - 1:-1].max() - previous_closes = data['Close'].iloc[-RESISTANCE_LOOKBACK - 1:-1] - # 과거 구간에서 저항선 이상으로 종가가 한번도 올라가지 않은 경우 + 현재 가격이 저항선 돌파 - if (previous_closes <= resistance_level * (1 + RESISTANCE_BREAK_THRESHOLD)).all() and \ - current_price > resistance_level * (1 + RESISTANCE_BREAK_THRESHOLD): - long_breakout_signal = True - - # RSI 과매도 신호 (RSI < 30) - if not isinstance(latest['Upper'], float): - rsi_signal = latest['RSI'].iloc[0] < 30 - - # MACD 신호 (MACD가 시그널 라인을 상향 돌파) - macd_signal = (prev['MACD'].iloc[0] < prev['Signal'].iloc[0]) and ( - latest['MACD'].iloc[0] > latest['Signal'].iloc[0]) - - # 이동평균선 골든크로스 임박 또는 발생 - ma_signal = (prev['MA5'].iloc[0] < prev['MA20'].iloc[0]) and (latest['MA5'].iloc[0] >= latest['MA20'].iloc[0]) - - # 거래량 증가 신호 (5일 평균 대비 150% 이상) - volume_signal = latest['Volume'].iloc[0] > (latest['Volume_MA5'].iloc[0] * 1.5) - - # 종합 신호 - buy_signals = { - 'bb_signal': bb_signal, - 'rsi_signal': rsi_signal, - 'macd_signal': macd_signal, - 'ma_signal': ma_signal, - 'volume_signal': volume_signal, - 'breakout_signal': breakout_signal, - 'long_breakout_signal': long_breakout_signal - } - - # 최소 3개 이상의 신호가 동시에 발생할 때 매수 신호로 간주 - signal_count = sum(1 for signal in buy_signals.values() if signal) - - return { - 'symbol': symbol, - 'price': current_price, - 'lower_band': lower_band, - 'distance': distance, - 'rsi': latest['RSI'].iloc[0], - 'macd': latest['MACD'].iloc[0], - 'signal_line': latest['Signal'].iloc[0], - 'buy_signals': buy_signals, - 'signal_count': signal_count, - 'buy': long_breakout_signal or breakout_signal or ( - (bb_signal and rsi_signal) or (signal_count >= 2 and (bb_signal or rsi_signal))) - } - else: - rsi_signal = latest['RSI'] < 30 - - # MACD 신호 (MACD가 시그널 라인을 상향 돌파) - macd_signal = (prev['MACD'] < prev['Signal']) and (latest['MACD'] > latest['Signal']) - - # 이동평균선 골든크로스 임박 또는 발생 - ma_signal = (prev['MA5'] < prev['MA20']) and (latest['MA5'] >= latest['MA20']) - - # 거래량 증가 신호 (5일 평균 대비 150% 이상) - volume_signal = latest['Volume'] > (latest['Volume_MA5'] * 1.5) - - # 종합 신호 - buy_signals = { - 'bb_signal': bb_signal, - 'rsi_signal': rsi_signal, - 'macd_signal': macd_signal, - 'ma_signal': ma_signal, - 'volume_signal': volume_signal, - 'breakout_signal': breakout_signal, - 'long_breakout_signal': long_breakout_signal - } - - # 최소 3개 이상의 신호가 동시에 발생할 때 매수 신호로 간주 - signal_count = sum(1 for signal in buy_signals.values() if signal) - - return { - 'symbol': symbol, - 'price': current_price, - 'lower_band': lower_band, - 'distance': distance, - 'rsi': latest['RSI'], - 'macd': latest['MACD'], - 'signal_line': latest['Signal'], - 'buy_signals': buy_signals, - 'signal_count': signal_count, - 'buy': long_breakout_signal or breakout_signal or ( - (bb_signal and rsi_signal) or (signal_count >= 2 and (bb_signal or rsi_signal))) - } - - -def format_message(info, market_type): - message = "" - if info['buy']: - message += '🛒 ' - - message += f"[{market_type}] {info['name']} ({info['symbol']}) " - message += f"현재가: {'$' if market_type == 'US' else '₩'}{info['price']:.2f}, " - - # 매수 신호 상세 정보 - count = 0 - if any(info['buy_signals'].values()): - message += "📊신호 ({count}):" - if info['buy_signals']['bb_signal']: - message += "- 볼린저 밴드 하단 근접 (근접도: {:.1f}%),".format(info['distance'] * 100) - count += 1 - if info['buy_signals']['rsi_signal']: - message += f"- RSI 과매도 구간 (RSI: {info['rsi']:.1f})," - count += 1 - if info['buy_signals']['macd_signal']: - message += "- MACD 골든크로스," - count += 1 - if info['buy_signals']['ma_signal']: - message += "- 이동평균선 골든크로스," - count += 1 - if info['buy_signals']['volume_signal']: - message += "- 거래량 급증" - count += 1 - if info['buy_signals'].get('breakout_signal'): - message += "- U자 반등 돌파" - count += 1 - if info['buy_signals'].get('long_breakout_signal'): - message += "- 장기 저항 돌파" - count += 1 - message += "\n" - message = message.replace("{count}", str(count)) - return message - - -def format_ma_message(info, market_type): - """MA 알림 메시지 생성""" - prefix = '📈 ' if info.get('alert') else '' - message = prefix + f"[{market_type}] {info['name']} ({info['symbol']}) " - message += f"현재가: {'$' if market_type == 'US' else '₩'}{info['price']:.2f} \n" - return message - - -def get_coin_data(symbol, interval=240, retries=3): - for attempt in range(retries): - try: - url = "https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=3000".format(interval, 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_kr_stock_data(symbol, retries=3): - for attempt in range(retries): - try: - end = datetime.now() - start = end - timedelta(days=300) - - # FinanceDataReader를 사용하여 한국 주식 데이터 가져오기 - data = fdr.DataReader(symbol, start.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d')) - - if not data.empty: - # FinanceDataReader의 컬럼명을 yfinance 형식으로 변환 - data = data.rename(columns={ - 'Open': 'Open', - 'High': 'High', - 'Low': 'Low', - 'Close': 'Close', - 'Volume': 'Volume' - }) - return data - - print(f"No data received for {symbol}, attempt {attempt + 1}") - time.sleep(2) - 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 monitor_us_stocks(): - message_list = [] - print("US Stocks {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) - - for symbol in US_STOCKS: - data = get_kr_stock_data(symbol) - if data is not None and not data.empty: - try: - data = calculate_technical_indicators(data) - info = check_ma_alert(symbol, data, 0) - if info is None: - continue - info['name'] = US_STOCKS[symbol] - print(f" - {info['name']} ({symbol}): {info['price']:.2f} -> {info['alert']}") - - if info['alert']: - message_list.append(format_ma_message(info, 'US')) - except Exception as e: - print(f"Error processing data for {symbol}: {str(e)}") - time.sleep(0.5) - - if len(message_list) > 0: - try: - send_stock_telegram_message(message_list, header="[US-STOCK]") - except Exception as e: - print(f"Error sending Telegram message: {str(e)}") - - return - - -def monitor_kr_stocks(): - message_list = [] - print("KR ETFs {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) - - for symbol in KR_ETFS: - try: - # .KS 접미사 제거 - clean_symbol = symbol.replace('.KS', '') - data = get_kr_stock_data(clean_symbol) - - if data is not None and not data.empty: - try: - data = calculate_technical_indicators(data) - info = check_ma_alert(symbol, data, 0) - if info is None: - continue - info['name'] = KR_ETFS[symbol] - print(f" - {info['name']} ({symbol}): {info['price']:.2f} -> {info['alert']}") - - if info['alert']: - message_list.append(format_ma_message(info, 'KR')) - - except Exception as e: - 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: - try: - send_stock_telegram_message(message_list, header="[KR-STOCK]") - except Exception as e: - print(f"Error sending Telegram message: {str(e)}") - - return - - -def monitor_coins(): - message_list = [] - print("KRW COINs {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) - - for symbol in KR_COINS: - # 1시간 - interval = 60 - data = get_coin_data(symbol, interval=interval) - if data is not None and not data.empty: - try: - data = calculate_technical_indicators(data) - info = check_ma_alert(symbol, data, interval) - if info is None: - continue - info['name'] = KR_COINS[symbol] - print( - f" - {info['name']} ({symbol}): {info['price']:.2f} -> {info['alert']} ({info['details']['interval']})") - - if info['alert']: - message_list.append(format_ma_message(info, 'KR')) - 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) - - # 4시간 - interval = 240 - data = get_coin_data(symbol, interval=interval) - if data is not None and not data.empty: - try: - data = calculate_technical_indicators(data) - info = check_ma_alert(symbol, data, interval) - if info is None: - continue - info['name'] = KR_COINS[symbol] - print( - f" - {info['name']} ({symbol}): {info['price']:.2f} -> {info['alert']} ({info['details']['interval']})") - - if info['alert']: - message_list.append(format_ma_message(info, 'KR')) - 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) - - if len(message_list) > 0: - try: - send_coin_telegram_message(message_list, header="[KRW-COIN]") - except Exception as e: - print(f"Error sending Telegram message: {str(e)}") - - return - - -def run_schedule(): - # 코인 모니터링 스케줄 (매시간 1분, 11분, 21분, 31분, 41분, 51분) - for minute in [4, 14, 24, 34, 44, 54]: - schedule.every().hour.at(f":{minute:02d}").do(monitor_coins) - - # 미국 주식 모니터링 스케줄 (매일 저녁 5시 20분) - schedule.every().day.at("16:30").do(monitor_us_stocks) - schedule.every().day.at("23:30").do(monitor_us_stocks) - schedule.every().day.at("05:10").do(monitor_us_stocks) - - # 한국 ETF 모니터링 스케줄 (매일 오전 8시) - schedule.every().day.at("18:20").do(monitor_kr_stocks) - schedule.every().day.at("07:10").do(monitor_kr_stocks) - - print("Scheduler started. Monitoring will run at specified times.") - while True: - schedule.run_pending() - time.sleep(1) - - -if __name__ == "__main__": - run_schedule() diff --git a/stock_monitor_2.py.bak b/stock_monitor_2.py.bak deleted file mode 100644 index 84416b6..0000000 --- a/stock_monitor_2.py.bak +++ /dev/null @@ -1,460 +0,0 @@ -import pandas as pd -from HTS2 import HTS -from dateutil.relativedelta import relativedelta -from datetime import datetime, timedelta -import telegram -import time -import requests -import json -import asyncio -from multiprocessing import Pool -import schedule -from config import * -import FinanceDataReader as fdr -import numpy as np - -hts = HTS() - -def send_coin_msg(text): - coin_client = telegram.Bot(token=COIN_TELEGRAM_BOT_TOKEN) - asyncio.run(coin_client.send_message(chat_id=COIN_TELEGRAM_CHAT_ID, text=text)) - return - - -def send_coin_telegram_message(message_list, header): - pStr = header + "\n" - for i, message in enumerate(message_list): - pStr += message - - if i + 1 % 20 == 0: - pool = Pool(12) - pool.map(send_coin_msg, [pStr]) - pStr = '' - - if len(message_list) % 20 != 0: - pool = Pool(12) - pool.map(send_coin_msg, [pStr]) - - return - -def buy_ticker(symbole, data): - try: - BUY_AMOUNT = 5000 - - if data['buy_signal'].iloc[-1] == 'movingaverage': - BUY_AMOUNT = 50000 - elif data['buy_signal'].iloc[-1] == 'deviation40': - BUY_AMOUNT = 6000 - elif data['buy_signal'].iloc[-1] == 'deviation240': - BUY_AMOUNT = 5000 - - _ = hts.buyCoinMarket(symbole, BUY_AMOUNT) - except Exception as e: - print(f"Error buying {symbole}: {str(e)}") - return - - - -def send_stock_msg(text): - stock_client = telegram.Bot(token=STOCK_TELEGRAM_BOT_TOKEN) - asyncio.run(stock_client.send_message(chat_id=STOCK_TELEGRAM_CHAT_ID, text=text)) - return - - -def send_stock_telegram_message(message_list, header): - pStr = header + "\n" - for i, message in enumerate(message_list): - pStr += message - - if i + 1 % 20 == 0: - pool = Pool(12) - pool.map(send_stock_msg, [pStr]) - pStr = '' - - if len(message_list) % 20 != 0: - pool = Pool(12) - pool.map(send_stock_msg, [pStr]) - - return - - -def normalize_data(data): - """데이터 정규화 함수 - 모든 코인에 동일하게 적용""" - # Min-Max 정규화를 위한 컬럼 - columns_to_normalize = ['Open', 'High', 'Low', 'Close', 'Volume'] - - normalized_data = data.copy() - - # 각 컬럼별 정규화 (20일 롤링 윈도우 사용) - for column in columns_to_normalize: - min_val = data[column].rolling(window=20).min() - max_val = data[column].rolling(window=20).max() - # 0으로 나누기 방지 - denominator = max_val - min_val - normalized_data[f'{column}_Norm'] = np.where( - denominator != 0, - (data[column] - min_val) / denominator, - 0.5 # 기본값 설정 - ) - - return normalized_data - -def calculate_technical_indicators(data): - """기술적 지표 계산 - 모든 코인에 동일하게 적용""" - # 데이터 정규화 - data = normalize_data(data) - - # 이동평균선 계산 - data['MA5'] = data['Close'].rolling(window=5).mean() - data['MA20'] = data['Close'].rolling(window=20).mean() - data['MA40'] = data['Close'].rolling(window=40).mean() - data['MA120'] = data['Close'].rolling(window=120).mean() - data['MA200'] = data['Close'].rolling(window=200).mean() - data['MA240'] = data['Close'].rolling(window=240).mean() - data['MA720'] = data['Close'].rolling(window=720).mean() - data['MA1440'] = data['Close'].rolling(window=1440).mean() - - # --- 이격도(Deviation) 계산 --- - data['Deviation5'] = (data['Close'] / data['MA5']) * 100 - data['Deviation20'] = (data['Close'] / data['MA20']) * 100 - data['Deviation40'] = (data['Close'] / data['MA40']) * 100 - data['Deviation120'] = (data['Close'] / data['MA120']) * 100 - data['Deviation200'] = (data['Close'] / data['MA200']) * 100 - data['Deviation240'] = (data['Close'] / data['MA240']) * 100 - data['Deviation720'] = (data['Close'] / data['MA720']) * 100 - data['Deviation1440'] = (data['Close'] / data['MA1440']) * 100 - - # 매수 타이밍을 이동평균선으로 결정 - # 골든크로스: 단기 이동평균선이 장기 이동평균선을 상향 돌파할 때 매수 - data['golden_cross'] = (data['MA5'] > data['MA20']) & (data['MA5'].shift(1) <= data['MA20'].shift(1)) - - # 볼린저 밴드 계산 - data['MA'] = data['Close'].rolling(window=20).mean() - data['STD'] = data['Close'].rolling(window=20).std() - data['Upper'] = data['MA'] + (2 * data['STD']) - data['Lower'] = data['MA'] - (2 * data['STD']) - - return data - -def check_buy_point(data, simulation=None): - - """ - # 매수 포인트 탐지 및 표시 - if simulation: - recent_data = data - else: - # recent_data의 복사본 생성 - recent_data = data.tail(10).copy() - - # 'buy_point' 열 초기화 - recent_data['buy_point'] = 0 - - # FutureWarning 해결 - if recent_data['buy_point'].iloc[-1] != 1: - # 코드 계속 - for i in range(1, len(recent_data)): - if all(recent_data[f'MA{n}'].iloc[i] < recent_data['MA720'].iloc[i] for n in [5, 20, 40, 120, 200, 240]) and \ - all(recent_data[f'MA{n}'].iloc[i] > recent_data[f'MA{n}'].iloc[i-1] for n in [5, 20, 40, 120, 200, 240]) and \ - recent_data['MA720'].iloc[i] < recent_data['MA1440'].iloc[i]: - recent_data.at[recent_data.index[i], 'buy_point'] = 1 - - if not simulation: - if recent_data['buy_point'][-10:-1].sum() > 0: - recent_data.at[recent_data.index[-1], 'buy_point'] = 1 - - return recent_data - """ - - # 매수 포인트 탐지 및 표시 - # 'buy_point' 열 초기화 - data['buy_signal'] = '' - data['buy_point'] = 0 - - # FutureWarning 해결 - if data['buy_point'].iloc[-1] != 1: - # 코드 계속 - for i in range(1, len(data)): - # 이동평균선 기반 매수 조건 - if all(data[f'MA{n}'].iloc[i] < data['MA720'].iloc[i] for n in [5, 20, 40, 120, 200, 240]) and \ - all(data[f'MA{n}'].iloc[i] > data[f'MA{n}'].iloc[i - 1] for n in [5, 20, 40, 120, 200, 240]) and \ - data['MA720'].iloc[i] < data['MA1440'].iloc[i]: - data.at[data.index[i], 'buy_signal'] = 'movingaverage' - data.at[data.index[i], 'buy_point'] = 1 - if not simulation: - if data['buy_point'][-10:-1].sum() > 0: - data.at[data.index[-1], 'buy_signal'] = 'movingaverage' - data.at[data.index[-1], 'buy_point'] = 1 - - # Deviation40(이격도 40) 기반 매수 조건: 90 이하에서 상승 전환 - if data['Deviation40'].iloc[i - 1] < data['Deviation40'].iloc[i] and data['Deviation40'].iloc[i - 1] <= 90: - data.at[data.index[i], 'buy_signal'] = 'deviation40' - data.at[data.index[i], 'buy_point'] = 1 - if not simulation: - if data['buy_point'][-10:-1].sum() > 0: - data.at[data.index[-1], 'buy_signal'] = 'deviation40' - data.at[data.index[-1], 'buy_point'] = 1 - - # Deviation240(이격도 240) 기반 매수 조건: 90 이하에서 상승 전환 - if data['Deviation240'].iloc[i - 1] < data['Deviation240'].iloc[i] and data['Deviation240'].iloc[i - 1] <= 90: - data.at[data.index[i], 'buy_signal'] = 'deviation240' - data.at[data.index[i], 'buy_point'] = 1 - if not simulation: - if data['buy_point'][-10:-1].sum() > 0: - data.at[data.index[-1], 'buy_signal'] = 'deviation240' - data.at[data.index[-1], 'buy_point'] = 1 - - return data - -def format_message(market_type, symbol, symbol_name, close, buy_signal): - message = f"매수 [{market_type}] {symbol_name} ({symbol}): {buy_signal} " - message += f"현재가: {'$' if market_type == 'US' else '₩'}{close:.2f}, " - return message - - -def format_ma_message(info, market_type): - """MA 알림 메시지 생성""" - prefix = '상승 ' if info.get('alert') else '' - message = prefix + f"[{market_type}] {info['name']} ({info['symbol']}) " - message += f"현재가: {'$' if market_type == 'US' else '₩'}{info['price']:.2f} \n" - return message - - -def get_coin_data(symbol, interval=240, to=None, retries=3): - for attempt in range(retries): - try: - #url = "https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=3000".format(interval, symbol) - if to is None: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200").format(interval, symbol) - else: - url = ("https://api.bithumb.com/v1/candles/minutes/{}?market=KRW-{}&count=200&to={}").format(interval, symbol, to) - - - #url = 'https://api.bithumb.com/v1/candles/minutes/60?market=KRW-ADA&count=200' - #url = 'https://api.bithumb.com/v1/candles/minutes/minutes/60?market=KRW-ADA&count=200&to=2025-08-06 10:38:38' - 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_coin_more_data(symbol, interval, bong_count=3000): - # 코인 데이터 1500개 봉 가져오기 - to = datetime.now() - data = None - while data is None or len(data) < bong_count: - if data is None: - data = get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - else: - df = get_coin_data(symbol, interval, to.strftime("%Y-%m-%d %H:%M:%S")) - data = pd.concat([data, df], ignore_index=True) - time.sleep(0.3) - to = to - relativedelta(minutes=interval * 200) - - data = data.set_index('datetime') - data = data.sort_index() - data = data.drop_duplicates(keep='first') - data["datetime"] = data.index - # 코인 데이터 1500개 봉 가져오기 - - return data - - -def get_kr_stock_data(symbol, retries=3): - for attempt in range(retries): - try: - end = datetime.now() - start = end - timedelta(days=300) - - # FinanceDataReader를 사용하여 한국 주식 데이터 가져오기 - data = fdr.DataReader(symbol, start.strftime('%Y-%m-%d'), end.strftime('%Y-%m-%d')) - - if not data.empty: - # FinanceDataReader의 컬럼명을 yfinance 형식으로 변환 - data = data.rename(columns={ - 'Open': 'Open', - 'High': 'High', - 'Low': 'Low', - 'Close': 'Close', - 'Volume': 'Volume' - }) - return data - - print(f"No data received for {symbol}, attempt {attempt + 1}") - time.sleep(2) - 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 monitor_us_stocks(): - message_list = [] - print("US Stocks {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) - - for symbol in US_STOCKS: - data = get_kr_stock_data(symbol) - if data is not None and not data.empty: - try: - data = calculate_technical_indicators(data) - recent_data = check_buy_point(data) # Changed to check_buy_point - if recent_data['buy_point'].iloc[-1] != 1: - continue - print(f" - {US_STOCKS[symbol]} ({symbol}): {recent_data['Close'][-1]:.2f}") - message_list.append(format_message('US', symbol, US_STOCKS[symbol], recent_data['Close'][-1], recent_data['buy_signal'][-1])) - except Exception as e: - print(f"Error processing data for {symbol}: {str(e)}") - time.sleep(0.5) - - if len(message_list) > 0: - try: - send_stock_telegram_message(message_list, header="[US-STOCK]") - except Exception as e: - print(f"Error sending Telegram message: {str(e)}") - - return - - -def monitor_kr_stocks(): - message_list = [] - print("KR ETFs {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) - - for symbol in KR_ETFS: - try: - # .KS 접미사 제거 - clean_symbol = symbol.replace('.KS', '') - data = get_kr_stock_data(clean_symbol) - - if data is not None and not data.empty: - try: - data = calculate_technical_indicators(data) - recent_data = check_buy_point(data) # Changed to check_buy_point - if recent_data['buy_point'].iloc[-1] != 1: - continue - print(f" - {KR_ETFS[symbol]} ({symbol}): {recent_data['Close'][-1]:.2f}") - message_list.append(format_message('KR', symbol, US_STOCKS[symbol], recent_data['Close'][-1])) - - except Exception as e: - 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: - try: - send_stock_telegram_message(message_list, header="[KR-STOCK]") - except Exception as e: - print(f"Error sending Telegram message: {str(e)}") - - return - - -def monitor_coins(): - message_list = [] - print("KRW COINs {}".format(datetime.now().strftime('%Y-%m-%d %H:%M:%S'))) - - for symbol in KR_COINS: - - # 1시간 - interval = 60 - data = get_coin_more_data(symbol, interval) - - if data is not None and not data.empty: - try: - data = calculate_technical_indicators(data) - recent_data = check_buy_point(data) # Changed to check_buy_point - if recent_data['buy_point'].iloc[-1] != 1: - continue - print(f" - {KR_ETFS[symbol]} ({symbol}): {recent_data['Close'][-1]:.2f}") - message_list.append(format_message('COIN', symbol, US_STOCKS[symbol], recent_data['Close'][-1], recent_data['buy_signal'][-1])) - - # buy - buy_ticker(symbol, recent_data) - - 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) - - if len(message_list) > 0: - try: - # send message - send_coin_telegram_message(message_list, header="[KRW-COIN]") - except Exception as e: - print(f"Error sending Telegram message: {str(e)}") - - return - -# ---------------------- -# Turnaround Detector v6 -# ---------------------- - -def detect_turnaround_signal(symbol, data, interval=0, params=None): - if len(data) < 7: - return None - - # 이동평균을 기반으로 매수 신호 결정 - cur = data.iloc[-1] - prev = data.iloc[-2] - - return None - -def run_schedule(): - - # 코인 모니터링 스케줄 (매시간 1분, 11분, 21분, 31분, 41분, 51분) - for minute in [4, 14, 24, 34, 44, 54]: - schedule.every().hour.at(f":{minute:02d}").do(monitor_coins) - - # 미국 주식 모니터링 스케줄 (매일 저녁 5시 20분) - schedule.every().day.at("16:30").do(monitor_us_stocks) - schedule.every().day.at("23:30").do(monitor_us_stocks) - schedule.every().day.at("05:10").do(monitor_us_stocks) - - # 한국 ETF 모니터링 스케줄 (매일 오전 8시) - schedule.every().day.at("18:20").do(monitor_kr_stocks) - schedule.every().day.at("07:10").do(monitor_kr_stocks) - - print("Scheduler started. Monitoring will run at specified times.") - while True: - schedule.run_pending() - time.sleep(1) - - -if __name__ == "__main__": - run_schedule() - #monitor_coins()