import os import csv import time import requests import json import ccxt import pybithumb import pandas as pd from math import nan import plotly.io as po from plotly import subplots import plotly.graph_objects as go from datetime import datetime from sklearn.linear_model import LinearRegression from sklearn.preprocessing import StandardScaler, MinMaxScaler from stock.analysis.AnalyzerSqlite import AnalyzerSqlite from hts.BuySellChecker import BuySellChecker from hts.HTS import HTS from bithumb.Bithumb_daily import Bithumb_daily class Bithumb_minute(HTS): RESOURCE_PATH = None buySellChecker = None analyzerSqlite = None bithumb = None binance = None def __init__(self, RESOURCE_PATH): super().__init__(RESOURCE_PATH) self.RESOURCE_PATH = RESOURCE_PATH con_key = "946dd0b0e6f8ad411144cd33f09518d3" # 본인의 Connect Key를 입력한다. sec_key = "56b2a3cdd9fe3a82aa3f38c97c161125" # 본인의 Secret Key를 입력한다. self.buySellChecker = BuySellChecker() self.analyzerSqlite = AnalyzerSqlite() # bithumb api에 연결한 클라스 객체를 선언한다. self.bithumb = pybithumb.Bithumb(con_key, sec_key) self.binance = ccxt.binance() return def bull_market(self, df, ticker): m5 = df['close'].rolling(5).mean() last_m5 = m5[-2] price = pybithumb.get_current_price(ticker) if price > last_m5: return True return False def append(self, df, stock): for i in range(len(df)): stock['PRICE'].append( { "ymd": df.index[i], "close": df['close'][i], "diff": 0, "open": df['open'][i], "high": df['high'][i], "low": df['low'][i], "volume": df['volume'][i], "avg3": -1, "avg4": -1, "avg5": -1, "avg6": -1, "avg10": -1, "avg12": -1, "avg20": -1, "avg36": -1, "avg40": -1, "avg48": -1, "avg60": -1, "avg120": -1, "avg200": -1, "avg240": -1, "avg300": -1, "disparity_avg5": -1, "disparity_avg10": -1, "disparity_avg20": -1, "disparity_avg60": -1, "disparity_avg120": -1, "bolingerband_upper": -1, "bolingerband_lower": -1, "bolingerband_middle": -1, "envelope_upper": -1, "envelope_lower": -1, "envelope_middle": -1, "ichimokucloud_changeLine": -1, "ichimokucloud_baseLine": -1, "ichimokucloud_leadingSpan1": -1, "ichimokucloud_leadingSpan2": -1, "stochastic_fast_k": -1, "stochastic_slow_k": -1, "stochastic_slow_d": -1, "rsi": -1, "rsis": -1, "macd": -1, "macds": -1, "macdo": -1, }) return def analyze(self, stock, days=120): stock["PRICE"] = sorted(stock["PRICE"], key=lambda x: x['ymd']) self.analyzerSqlite.get_moving_average(stock["PRICE"]) # 이동 평균을 이용한 이격도 계산 self.analyzerSqlite.get_disparity(stock["PRICE"]) self.analyzerSqlite.ichimokuCloud.analyze(stock) self.analyzerSqlite.stochastic.analyze(stock) self.analyzerSqlite.bolingerBand.analyze(stock) self.analyzerSqlite.envelope.analyze(stock) self.analyzerSqlite.rsi.analyze(stock) self.analyzerSqlite.macd.analyze(stock) result = { "ymd": [], "open": [], "close": [], "high": [], "low": [], "avg3": [], "avg4": [], "avg5": [], "avg6": [], "avg10": [], "avg12": [], "avg20": [], "avg36": [], "avg40": [], "avg48": [], "avg60": [], "avg120": [], "avg200": [], "avg240": [], "avg300": [], "disparity_avg5": [], "disparity_avg20": [], "disparity_avg60": [], "disparity_avg120": [], "disparity": [], "disparity_type": [], "envelope_upper": [], "envelope_lower": [], "envelope_middle": [], "rsi": [], "rsis": [], "macd": [], "macds": [], "slow_k": [], "slow_d": [], "buy": [], "sell": [], } for item in stock['PRICE']: result["ymd"].append(item['ymd']) result["open"].append(item['open']) result["close"].append(item['close']) result["high"].append(item['high']) result["low"].append(item['low']) result["avg3"].append(item['avg3']) result["avg4"].append(item['avg4']) result["avg5"].append(item['avg5']) result["avg6"].append(item['avg6']) result["avg10"].append(item['avg10']) result["avg12"].append(item['avg12']) result["avg20"].append(item['avg20']) result["avg36"].append(item['avg36']) result["avg40"].append(item['avg40']) result["avg48"].append(item['avg48']) result["avg60"].append(item['avg60']) result["avg120"].append(item['avg120']) result["avg200"].append(item['avg200']) result["avg240"].append(item['avg240']) result["avg300"].append(item['avg300']) result["disparity_avg5"].append(item['disparity_avg5']) result["disparity_avg20"].append(item['disparity_avg20']) result["disparity_avg60"].append(item['disparity_avg60']) result["disparity_avg120"].append(item['disparity_avg120']) result['disparity'].append( max(item['disparity_avg5'], item['disparity_avg20'], item['disparity_avg60']) - min( item['disparity_avg5'], item['disparity_avg20'], item['disparity_avg60'])) if item['disparity_avg60'] < item['disparity_avg20'] < item['disparity_avg5']: result['disparity_type'].append(1) elif item['disparity_avg5'] < item['disparity_avg20'] < item['disparity_avg60']: result['disparity_type'].append(-1) else: result['disparity_type'].append(0) result["envelope_upper"].append(item['envelope_upper']) result["envelope_lower"].append(item['envelope_lower']) result["envelope_middle"].append(item['envelope_middle']) result["rsi"].append(item['rsi']) result["rsis"].append(item['rsis']) result["macd"].append(item['macd']) result["macds"].append(item['macds']) result["slow_k"].append(item['stochastic_slow_k']) result["slow_d"].append(item['stochastic_slow_d']) result["buy"].append(-1) result["sell"].append(-1) data = pd.DataFrame(result) df_final_time = pd.DatetimeIndex(result['ymd']) data.index = df_final_time data = data.astype( { 'open': 'int', 'high': 'int', 'low': 'int', 'close': 'int', 'avg3': 'float', 'avg4': 'float', 'avg5': 'float', 'avg6': 'float', 'avg10': 'float', 'avg12': 'float', 'avg20': 'float', 'avg36': 'float', 'avg40': 'float', 'avg48': 'float', 'avg60': 'float', 'avg120': 'float', 'avg200': 'float', 'avg240': 'float', 'avg300': 'float', 'disparity_avg5': 'float', 'disparity_avg20': 'float', 'disparity_avg60': 'float', 'disparity_avg120': 'float', 'buy': 'int', 'sell': 'int', 'slow_k': 'float', 'slow_d': 'float', 'macd': 'float', 'macds': 'float', 'envelope_upper': 'float', 'envelope_lower': 'float', 'envelope_middle': 'float', 'rsi': 'float', 'rsis': 'float' } ) scaler = StandardScaler() low_df = pd.DataFrame(data['low']) low_df.index = [c for c in range(len(low_df))] low_std = scaler.fit_transform(data['low'].values.reshape(-1, 1)) low_std = pd.DataFrame(low_std, columns=['low_std']) min_df = pd.DataFrame({'open': data['open'].to_list(), 'close': data['close'].to_list()}) min_df['min_std'] = min_df.min(axis=1) min_df.index = [c for c in range(len(min_df))] min_std = scaler.fit_transform(min_df['min_std'].values.reshape(-1, 1)) min_std = pd.DataFrame(min_std, columns=['min_std']) line_fitter = LinearRegression() size = len(data["close"]) gradients_low = [] gradients_avg5 = [] gradients_avg20 = [] gradients_avg60 = [] for i in range(size): coef_low = -999 coef_avg5 = -999 coef_avg20 = -999 coef_avg60 = -999 if i > 0: l = days if i >= days else i x = pd.DataFrame([c for c in range(i - l, i + 1)]) y = pd.DataFrame(low_std.values.tolist()[i - l:i + 1]) line_fitter.fit(x.values.reshape(-1, 1), y) coef_low = line_fitter.coef_[0][0] l = 5 if i >= 5 else i x = pd.DataFrame([c for c in range(i - l, i + 1)]) y = pd.DataFrame(min_std.values.tolist()[i - l:i + 1]) line_fitter.fit(x.values.reshape(-1, 1), y) coef_avg5 = line_fitter.coef_[0][0] l = 20 if i >= 20 else i x = pd.DataFrame([c for c in range(i - l, i + 1)]) y = pd.DataFrame(min_std.values.tolist()[i - l:i + 1]) line_fitter.fit(x.values.reshape(-1, 1), y) coef_avg20 = line_fitter.coef_[0][0] l = 60 if i >= 60 else i x = pd.DataFrame([c for c in range(i - l, i + 1)]) y = pd.DataFrame(min_std.values.tolist()[i - l:i + 1]) line_fitter.fit(x.values.reshape(-1, 1), y) coef_avg60 = line_fitter.coef_[0][0] gradients_low.append(coef_low) gradients_avg5.append(coef_avg5) gradients_avg20.append(coef_avg20) gradients_avg60.append(coef_avg60) gradients_low_df = pd.DataFrame(gradients_low, columns=['gradients_low']) gradients_avg5_df = pd.DataFrame(gradients_avg5, columns=['gradients_avg5']) gradients_avg20_df = pd.DataFrame(gradients_avg20, columns=['gradients_avg20']) gradients_avg60_df = pd.DataFrame(gradients_avg60, columns=['gradients_avg60']) gradients_low_df.index = df_final_time gradients_avg5_df.index = df_final_time gradients_avg20_df.index = df_final_time gradients_avg60_df.index = df_final_time data = data.merge(gradients_low_df, left_index=True, right_index=True) data = data.merge(gradients_avg5_df, left_index=True, right_index=True) data = data.merge(gradients_avg20_df, left_index=True, right_index=True) data = data.merge(gradients_avg60_df, left_index=True, right_index=True) return data def writeFile(self, dirName, ticker, data, bsLine, today, type=None): if bsLine is None: return # 어제 데이터는 지운다. buy_line = bsLine['buy'] buy_weight_line = bsLine['buy_weight'] sell_line = bsLine['sell'] buy_size = [] buy_colors = [] for i in range(len(buy_line)): if buy_line[i] < 0: buy_colors.append("#ffffff") buy_line[i] = nan buy_size.append(0) else: buy_colors.append("#B2028C") buy_size.append(10 + (0.1 * buy_weight_line[i])) sell_colors = [] for i in range(len(sell_line)): if sell_line[i] < 0: sell_colors.append("#ffffff") sell_line[i] = nan else: sell_colors.append("#00ced1") # 그래프를 설정한다. buy_check = go.Scatter(x=data['ymd'], y=buy_line, mode='markers', name="buy", marker=dict(size=buy_size, color=buy_colors, line_width=0)) sell_check = go.Scatter(x=data['ymd'], y=sell_line, mode='markers', name="sell", marker=dict(size=14, color=sell_colors, line_width=0)) avg5 = go.Scatter(x=data['ymd'], y=data["avg5"], name="avg5", line_color='#6C2507') avg20 = go.Scatter(x=data['ymd'], y=data["avg20"], name="avg20", line_color='#f84c43') avg60 = go.Scatter(x=data['ymd'], y=data["avg60"], name="avg60", line_color='#f89543') candle_stick = go.Candlestick(x=data['ymd'], open=data['open'], high=data['high'], low=data['low'], close=data['close'], increasing_line_color='red', decreasing_line_color='blue', showlegend=False) macd_line = go.Scatter(x=data['ymd'], y=data["macd"], line=dict(color='red', width=2), name='macd') macd_s_line = go.Scatter(x=data['ymd'], y=data["macds"], line=dict(dash='dashdot', color='black', width=2), name='macds') # fast_k_line = go.Scatter(x=hts['date'], y=hts["fast_k"], mode='lines', name='fast_k') slow_k_line = go.Scatter(x=data['ymd'], y=data["slow_k"], line=dict(color='red', width=2), name='slow_k') slow_d_line = go.Scatter(x=data['ymd'], y=data["slow_d"], line=dict(dash='dashdot', color='black', width=2), name='slow_d') rsi_line = go.Scatter(x=data['ymd'], y=data["rsi"], line=dict(color='red', width=2), name='rsi') rsis_line = go.Scatter(x=data['ymd'], y=data["rsis"], line=dict(dash='dashdot', color='black', width=2), name='rsis') disparity_avg5 = go.Scatter(x=data['ymd'], y=data["disparity_avg5"], name="disparity_avg5", line_color='#8F8203') disparity_avg20 = go.Scatter(x=data['ymd'], y=data["disparity_avg20"], name="disparity_avg20", line_color='#ff00ff') disparity_avg60 = go.Scatter(x=data['ymd'], y=data["disparity_avg60"], name="disparity_avg60", line_color='#1469F4') candle_data = [candle_stick, avg5, avg20, avg60, buy_check, sell_check] disparity_data = [disparity_avg5, disparity_avg20, disparity_avg60] macd_data = [macd_line, macd_s_line] stochastic_data = [slow_k_line, slow_d_line] rsi_data = [rsi_line, rsis_line] # 그래프를 그린다. """ fig = go.Figure(data=candle_data) fig.update_layout(title=stock_code + "_" + given_day) fig.show() """ fig = subplots.make_subplots( rows=5, cols=1, subplot_titles=("MACD", "RSI", "스토캐스틱", '이격도', '캔들'), # specs=[[{}], [{}], [{}], [{}], [{}], [{}]], shared_xaxes=True, horizontal_spacing=0.03, vertical_spacing=0.01, row_heights=[200, 200, 200, 200, 750] ) for trace in macd_data: fig.append_trace(trace, 1, 1) for trace in rsi_data: fig.append_trace(trace, 2, 1) for trace in stochastic_data: fig.append_trace(trace, 3, 1) for trace in disparity_data: fig.append_trace(trace, 4, 1) for trace in candle_data: fig.append_trace(trace, 5, 1) df = pd.DataFrame(bsLine) df = df.fillna(-1) buy_count = len(df.loc[df["buy"] > 0]) sell_count = len(df.loc[df["sell"] > 0]) fig.update_layout(height=1700, title="_" + str(buy_count) + "," + str(sell_count)) fig['layout'].update() if type is None: fileName = "%s/%s_%s.html" % (dirName, ticker, today) po.write_html(fig, file=fileName, auto_open=False) else: fileName = "%s/%s_%s_%s.html" % (dirName, type, ticker, today) po.write_html(fig, file=fileName, auto_open=False) return def notBuy(self, data, i): if i > 5: check = True for l in range(i - 4, i + 1): if ( data['gradients_avg60'][l - 1] > data['gradients_avg60'][l] or data['gradients_avg20'][l - 1] > data['gradients_avg20'][l] or data['gradients_low'][l - 1] > data['gradients_low'][l] ): check = False break if not check: return False return True def checkWithEnvelope(self, data1, data2=None, isRealTime=False): bsLine = {} size = len(data1["close"]) bsLine['buy'] = [-1 for i in range(size)] bsLine['buy_weight'] = [-1 for i in range(size)] bsLine['sell'] = [-1 for i in range(size)] bsLine['sell_weight'] = [-1 for i in range(size)] for i in range(size): if isRealTime: if i < size - 1: continue if i > 10: """ # 만약 전일 저가와 오늘 종의 차이가 1만원이 넘으면 향후 60일은 분석하지 않는다. if data1['high'][i] < int(data1['low'][i - 1] * 0.7): gap_state = True gap_interval -= 1 continue if gap_state: if gap_interval <= 0: gap_state = False gap_interval = 60 else: gap_interval -= 1 continue if data1['disparity'][i] < 2: check = True for l in range(i - 3, i): if ( data1['gradients_avg60'][l - 1] > data1['gradients_avg60'][l] or data1['gradients_avg20'][l - 1] > data1['gradients_avg20'][l] or data1['gradients_low'][l - 1] > data1['gradients_low'][l] or data1['disparity_avg5'][l - 1] > data1['disparity_avg5'][l] or data1['disparity'][l - 1] < data1['disparity'][l] ): check = False break if check and 99 < sum(data1['disparity_avg5'][i - 4:i + 1]) / 5 < 100 and 99 < sum( data1['disparity_avg60'][i - 4:i + 1]) / 5 < 100: buy = data1['low'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.1 check = True for l in range(i - 2, i): if ( data1['gradients_avg60'][l - 1] > data1['gradients_avg60'][l] or data1['gradients_low'][l - 1] > data1['gradients_low'][l] ): check = False break if ( check and -0.0011 < data1['gradients_low'][i] < 0 and -0.007 < data1['gradients_avg5'][i] < 0.001 and -0.0012 < data1['gradients_avg60'][i] < 0 and 98.90 < data1['disparity_avg5'][i] < 101 ): buy = data1['low'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.1 check = True for l in range(i - 6, i): if ( data1['gradients_avg60'][l - 1] < data1['gradients_avg60'][l] or data1['gradients_avg20'][l - 1] < data1['gradients_avg20'][l] or data1['gradients_low'][l - 1] < data1['gradients_low'][l] or -0.039 < data1['gradients_low'][l - 1] < -0.35 or -0.05 < data1['gradients_avg20'][l - 1] < -0.30 or -0.40 < data1['gradients_avg60'][l - 1] < -0.30 ): check = False break if check and 99 < min(data1['disparity_avg5'][i - 6:i]) < max(data1['disparity_avg5'][i - 6:i]) < 101: buy = data1['low'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.1 check = True for l in range(i - 3, i): if ( data1['gradients_low'][l - 1] < data1['gradients_low'][l] or data1['gradients_avg60'][l - 1] < data1['gradients_avg60'][l] or data1['gradients_avg20'][l - 1] < data1['gradients_avg20'][l] or 0.01 < data1['gradients_low'][l - 1] < 0.21 or -0.09 < data1['gradients_avg20'][l - 1] < -0.002 or 0.01 < data1['gradients_avg60'][l - 1] < 0.021 ): check = False break if check: buy = data1['low'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.1 if (data1['disparity'][i] < 5 and 99.0 < data1['disparity_avg60'][i] < 99.1 and -0.009 < data1['gradients_avg60'][i] < -0.008 and 0.015 < data1['gradients_avg20'][i] < 0.016 and -0.006 < data1['gradients_avg5'][i] < -0.005 and -0.009 < data1['gradients_low'][i] < -0.008): check = True for l in range(i - 5, i): if ( data1['gradients_avg60'][l - 1] > data1['gradients_avg60'][l] or data1['gradients_low'][l - 1] > data1['gradients_low'][l] or data1['disparity'][l - 1] < data1['disparity'][l] ): check = False break if check: buy = data1['low'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.1 if data1['macd'][i] < -4000: if data1['macd'][i - 1] < data1['macd'][i]: if not self.notBuy(data1, i) and data1['slow_k'][i] < 30: buy = data1['low'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.1 # macd 이전에 없던 바닥인 경우 상승할 찰나 매수 if data1['macds'][i - 1] < min(data1['macds'][:i - 1]): if data1['macds'][i - 1] < data1['macds'][i]: if not self.notBuy(data1, i) and data1['slow_k'][i] < 30: buy = data1['low'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.1 if ( 98 < data1['disparity_avg5'][i] < 100 and data1['disparity_avg20'][i] < 93.5 and data1['disparity_avg60'][i] < 89 and -0.014 < data1['gradients_avg60'][i] < -0.013 and -0.03 < data1['gradients_avg20'][i] < -0.02 and -0.014 < data1['gradients_low'][i] < -0.013 and data1['slow_k'][i] < 11 ): if not self.notBuy(data1, i): buy = data1['low'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.1 """ if data1['slow_k'][i] < 20 and data1['slow_k'][i - 1] < data1['slow_d'][i - 1] and data1['slow_d'][i] < data1['slow_k'][i]: buy = data1['low'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.3 if data2['slow_k'][i] < 30: if data1['slow_k'][i] < 30 and data1['avg5'][i] < data1['close'][i]: buy = data1['close'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 1 if data1['slow_k'][i] > 80 and (data1['slow_d'][i-1] < data1['slow_k'][i-1] and data1['slow_k'][i] < data1['slow_d'][i]): sell = data1['close'][i] data1['sell'][i] = sell bsLine['sell'][i] = sell bsLine['sell_weight'][i] = 100 return bsLine def get_ohlcv(self, ticker, minute=5): url = "https://api.upbit.com/v1/candles/minutes/"+str(minute) querystring = {"market": "KRW-"+ticker, "count": "300"} response = requests.request("GET", url, params=querystring) json_response = json.loads(response.text) btc_ohlcv = [] for json_data in json_response: btc_ohlcv.append({'datetime': datetime.strptime(json_data['candle_date_time_kst'], '%Y-%m-%dT%H:%M:%S'), 'open': json_data['opening_price'], 'high': json_data['high_price'], 'low': json_data['low_price'], 'close': json_data['trade_price'], 'volume': json_data['candle_acc_trade_volume']}) btc_ohlcv = sorted(btc_ohlcv, key=lambda item: (item['datetime'])) df = pd.DataFrame(btc_ohlcv, columns=['datetime', 'open', 'high', 'low', 'close', 'volume']) df['datetime'] = pd.to_datetime(df['datetime'], unit='ms') df.set_index('datetime', inplace=True) return df def cancel_order(self, log_df, min=10): df = log_df[pd.DatetimeIndex(log_df.index).minute >= min] df.reset_index() if df is not None: for i in range(len(df)): order = (df['order0'][i], df['order1'][i], df['order2'][i], df['order3'][i]) cancel = self.bithumb.cancel_order(order) log_df = log_df[pd.DatetimeIndex(log_df.index).minute < min] return def getStock(self, ticker, analyzed_day, minute=5): stock = {"CODE": ticker, "NAME": ticker, "PRICE": []} df = self.get_ohlcv(ticker, minute) if df is None: return close = pybithumb.get_current_price(ticker) size = len(df) df['close'][size - 1] = close if close < df['low'][size - 1]: df['low'][size - 1] = close if df['high'][size - 1] < close: df['high'][size - 1] = close self.append(df, stock) data = self.analyze(stock, analyzed_day) # 분석일 데이터만 활용한다 (이전 데이터는 제거) data.drop(data.index[:len(data) - analyzed_day], inplace=True) return data def buyRealTime(self, ticker, analyzed_day=120, isRealTime=False): """ # binance btc_ohlcv = self.binance.fetch_ohlcv(ticker + "/BKRW") df = pd.DataFrame(btc_ohlcv, columns=['datetime', 'open', 'high', 'low', 'close', 'volume']) df['datetime'] = pd.to_datetime(df['datetime'], unit='ms') df.set_index('datetime', inplace=True) """ """ # bithumb df_ = pybithumb.get_ohlcv(ticker) """ stock1 = self.getStock(ticker, analyzed_day, minute=5) stock2 = self.getStock(ticker, analyzed_day, minute=30) # 매수 매도 체크 bsLine = self.checkWithEnvelope(stock1, stock2, isRealTime=isRealTime) print(ticker, "/", datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "/", stock1['close'][len(stock1['close'])-1], "/", stock2['slow_k'][len(stock1['slow_k'])-1], "/", stock1['slow_k'][len(stock1['slow_k'])-1]) # 그래프를 그린다. if len(stock1.index) > 10: today = datetime.today().strftime('%Y%m%d') log_filename = os.path.join(RESOURCE_PATH, 'order', "bithumb"+"_"+today + '.log') if os.path.exists(log_filename): log_df = pd.read_csv(log_filename) log_df.columns = ["type", "datetime", "order0", "order1", "order2", "order3", "slow_k", "price", "count"] else: log_df = pd.DataFrame(columns=["type", "datetime", "order0", "order1", "order2", "order3", "slow_k", "price", "count"]) log_df['datetime'] = pd.to_datetime(log_df['datetime'], unit='s') log_df.set_index('datetime', inplace=True) # 10분이 지난 미체결은 취소한다. self.cancel_order(log_df, 10) if isRealTime: if max(bsLine['buy'][len(bsLine['buy']) - 2:]) > 100: tmp = self.bithumb.get_balance(ticker) balance = tmp[2] count = round((balance * (bsLine['buy_weight'][len(bsLine['buy_weight']) - 1] / 100)) / bsLine['buy'][len(bsLine['buy']) - 1], 2) order = self.bithumb.buy_limit_order(ticker, bsLine['buy'][len(bsLine['buy']) - 1], count) # order: ('bid', 'BTC', 'C0101000000322993432', 'KRW') if len(stock1['close']) > 0: print(ticker, "/", datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "/", stock1['close'][len(stock1['close']) - 1], "/ BUY / ", stock1['slow_k'][len(stock1['slow_k']) - 1], "/", bsLine['buy'][len(bsLine['buy']) - 1], "/", count) value = {"type": "BUY", "datetime": datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "order0": order[0], "order1": order[1], "order2": order[2], "order3": order[3], "slow_k": stock1['slow_k'][len(stock1['slow_k']) - 1], "price": bsLine['buy'][len(bsLine['buy']) - 1], "count": count} log_df = log_df.append(value, ignore_index=True) log_df['datetime'] = pd.to_datetime(log_df['datetime'], unit='s') log_df.set_index('datetime', inplace=True) log_df.to_csv(log_filename, index=False) dirName = os.path.join(RESOURCE_PATH, 'analysis', 'bithumb') self.writeFile(dirName, ticker, stock1, bsLine, datetime.now().strftime('%Y%m%d %H%M%S'), 'buy') if max(bsLine['sell'][len(bsLine['sell']) - 2:]) > 100: tmp = self.bithumb.get_balance(ticker) if tmp is None: return count = tmp[0] order = self.bithumb.sell_limit_order(ticker, bsLine['sell'][len(bsLine['sell'])-1], count) if len(stock1['close'])>0: print(ticker, "/", datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "/", stock1['close'][len(stock1['close']) - 1], "/ SELL / ", stock1['slow_k'][len(stock1['slow_k']) - 1], "/", bsLine['sell'][len(bsLine['sell']) - 1], "/", count) value = {"type": "SELL", "datetime": datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "order0": order[0], "order1": order[1], "order2": order[2], "order3": order[3], "slow_k": stock1['slow_k'][len(stock1['slow_k']) - 1], "price": bsLine['buy'][len(bsLine['buy']) - 1], "count": count} log_df = log_df.append(value, ignore_index=True) log_df['datetime'] = pd.to_datetime(log_df['datetime'], unit='s') log_df.set_index('datetime', inplace=True) log_df.to_csv(log_filename, index=False) dirName = os.path.join(RESOURCE_PATH, 'analysis', 'bithumb') self.writeFile(dirName, ticker, stock1, bsLine, datetime.now().strftime('%Y%m%d %H%M%S'), 'sell') else: dirName = os.path.join(RESOURCE_PATH, 'analysis', 'bithumb') self.writeFile(dirName, ticker, stock1, bsLine, datetime.now().strftime('%Y%m%d %H%M%S')) return if __name__ == "__main__": PROJECT_HOME = os.getcwd() RESOURCE_PATH = os.path.join(PROJECT_HOME, "resources") if not os.path.exists(os.path.join(RESOURCE_PATH, 'analysis', 'bithumb')): os.mkdir(os.path.join(RESOURCE_PATH, 'analysis', 'bithumb')) dirName = os.path.join(RESOURCE_PATH, 'analysis', 'bithumb') if not os.path.exists(dirName): os.mkdir(dirName) # bithumb_daily = Bithumb_daily(RESOURCE_PATH) bithumb = Bithumb_minute(RESOURCE_PATH) tickers = ['XRP'] analyzed_day = 120 isRealTime = True if isRealTime: while True: for ticker in tickers: #data_daily = bithumb_daily.buyRealTime(ticker, analyzed_day) #size = len(data_daily) #if data_daily['slow_k'] < 30: bithumb.buyRealTime(ticker, analyzed_day, isRealTime) time.sleep(300) else: for ticker in tickers: bithumb.buyRealTime(ticker, analyzed_day, isRealTime)