import os 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, timedelta 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 stock.util.SlackBot import SlackBot class Bithumb_minute(HTS): RESOURCE_PATH = None buySellChecker = None analyzerSqlite = None bithumb = None binance = None TODAY = None slackBot = None stock_code = None def __init__(self, RESOURCE_PATH, today): super().__init__(RESOURCE_PATH) self.slackBot = SlackBot() self.stock_code = {"XRP": "리플"} 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() self.TODAY = today 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': 'float', 'high': 'float', 'low': 'float', 'close': 'float', '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': 'float', 'sell': 'float', '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, 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, self.TODAY) po.write_html(fig, file=fileName, auto_open=False) else: fileName = "%s/%s_%s_%s.html" % (dirName, type, ticker, self.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.0 for i in range(size)] bsLine['buy_weight'] = [-1.0 for i in range(size)] bsLine['sell'] = [-1.0 for i in range(size)] bsLine['sell_weight'] = [-1.0 for i in range(size)] for i in range(size): if isRealTime: if i < size - 1: continue if i > 10: if data1['slow_k'][i] < 20: if 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 and data1['slow_k'][i] < 30: if data1['slow_k'][i-1] < data1['slow_d'][i-1] and data1['slow_d'][i] < data2['slow_k'][i]: buy = data1['close'][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: if data1['avg5'][i] < data1['close'][i]: buy = data1['close'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.2 if data1['slow_k'][i-1] < data1['slow_d'][i-1] and data1['slow_d'][i] < data2['slow_k'][i]: buy = data1['close'][i] data1['buy'][i] = buy bsLine['buy'][i] = buy bsLine['buy_weight'][i] = 0.3 if data2['slow_k'][i] > 90: if (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 if data1['slow_k'][i] > 95 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 if data2['slow_k'][i] > 98 and data1['slow_k'][i] > 98: 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) df.insert(1, "datetime", df.index) return df def cancel_order(self, log_df, log_filename, min=5): now = datetime.now() - timedelta(minutes=min) # min 분 이상 된 시간인 내용을 가지고 옴 df = log_df.loc[(log_df.index <= now) ] # 취소가 되지 않은 것만 가지고 옴 (0: 취소 되지 않음, 1: 취소함) df = df.loc[(log_df["canceled"] == 0)] 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) # slackbot에 메시지를 보냄 #self.slackBot.post_to_slack(ticker, self.stock_code[ticker], "CANCEL", -1, -1) for i in range(len(df)): log_df.loc[(log_df.index == df.index[i]), 'canceled'] = 1 log_df.to_csv(log_filename, index=False) return log_df def check_buy_history(self, log_df, min=10): # min 분 이상 된 시간인 내용을 가지고 옴 now = datetime.now() - timedelta(minutes=min) # 취소가 되지 않은 것만 가지고 옴 (0: 취소 되지 않음, 1: 취소함) log_df = log_df.loc[(now < log_df.index)] if len(log_df) == 0: return False return True def getStock(self, ticker, analyzed_day, minute=5, day=None): stock = {"CODE": ticker, "NAME": ticker, "PRICE": []} if day is None: df = self.get_ohlcv(ticker, minute) else: df = pybithumb.get_ohlcv(ticker) df["datetime"] = df.index close = pybithumb.get_current_price(ticker) if df is None or close is None: return 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 getCount(self, price): if 2000 < price: MAX_BUY_PRICE = 3000 elif 1900 <= price < 2000: MAX_BUY_PRICE = 4000 elif 1800 <= price < 1900: MAX_BUY_PRICE = 5000 elif 1700 <= price < 1800: MAX_BUY_PRICE = 6000 elif 1600 <= price < 1700: MAX_BUY_PRICE = 6000 elif 1700 <= price < 1600: MAX_BUY_PRICE = 6000 elif 1400 <= price < 1500: MAX_BUY_PRICE = 6000 elif 1300 <= price < 1400: MAX_BUY_PRICE = 6000 elif 1200 <= price < 1300: MAX_BUY_PRICE = 7000 elif 1100 <= price < 1200: MAX_BUY_PRICE = 7000 elif 1000 <= price < 1100: MAX_BUY_PRICE = 7000 elif 900 <= price < 1000: MAX_BUY_PRICE = 8000 elif 800 <= price < 900: MAX_BUY_PRICE = 8000 elif 700 <= price < 800: MAX_BUY_PRICE = 9000 elif 600 <= price < 700: MAX_BUY_PRICE = 9000 elif 500 <= price < 600: MAX_BUY_PRICE = 10000 elif 400 <= price < 500: MAX_BUY_PRICE = 15000 elif 300 <= price < 400: MAX_BUY_PRICE = 30000 elif 200 <= price < 300: MAX_BUY_PRICE = 50000 elif 100 <= price < 200: MAX_BUY_PRICE = 100000 else: MAX_BUY_PRICE = 100000 count = int(MAX_BUY_PRICE / price) return count 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], "/", "{:.2f}".format(stock2['slow_k'][len(stock1['slow_k'])-1]), "/", "{:.2f}".format(stock1['slow_k'][len(stock1['slow_k'])-1]), "/", "{:.2f}".format(stock2['macd'][len(stock2['macd']) - 1]), "/", "{:.2f}".format(stock1['macd'][len(stock1['macd']) - 1])) # 그래프를 그린다. if len(stock1.index) > 10: # 매수 요청 n분 이상된 주문은 취소하기 위함 order_log_filename = os.path.join(RESOURCE_PATH, 'order', "bithumb"+"_"+self.TODAY + '.log') if os.path.exists(order_log_filename): order_log_df = pd.read_csv(order_log_filename) order_log_df.columns = ["type", "datetime", "order0", "order1", "order2", "order3", "canceled", "slow_k_30", "slow_k_5", "price", "count"] order_log_df["datetime"] = pd.to_datetime(order_log_df["datetime"], format='%Y-%m-%d %H:%M:%S') else: order_log_df = pd.DataFrame(columns=["type", "datetime", "order0", "order1", "order2", "order3", "canceled", "slow_k_30", "slow_k_5", "price", "count"]) order_log_df['datetime'] = pd.to_datetime(order_log_df['datetime'], unit='s') order_log_df.set_index('datetime', inplace=True) order_log_df.insert(1, "datetime", order_log_df.index) # 10분이 지난 미체결은 취소한다. order_log_df = self.cancel_order(order_log_df, order_log_filename, min=10) # 한번 매수 후 n분 이후 매수하기 위함 check_buy_history = self.check_buy_history(order_log_df, min=60) if isRealTime and not check_buy_history: # 매수 조건 if max(bsLine['buy'][len(bsLine['buy']) - 2:]) > 100: #stock = self.getStock(ticker, analyzed_day, day=30) #if stock["slow_k"][len(stock['close'])-1] > 40: # print (datetime.now().strftime('%Y-%m-%d %H:%M:%S'), ",", round(stock["slow_k"][len(stock['close'])-3],2), ",", round(stock["slow_k"][len(stock['close'])-2],2), ",", round(stock["slow_k"][len(stock['close'])-1], )) # return 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) count = self.getCount(bsLine['buy'][len(bsLine['buy']) - 1]) # 매수를 요청한다. order = self.bithumb.buy_limit_order(ticker, bsLine['buy'][len(bsLine['buy']) - 1], count) # slackbot에 메시지를 보냄 self.slackBot.post_to_slack(ticker, self.stock_code[ticker], "BUY", 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], "/", "{:.2f}".format(stock2['slow_k'][len(stock1['slow_k'])-1]), "/", "{:.2f}".format(stock1['slow_k'][len(stock1['slow_k'])-1]), "/", "{:.2f}".format(stock2['macd'][len(stock2['macd']) - 1]), "/", "{:.2f}".format(stock1['macd'][len(stock1['macd']) - 1]), "/", bsLine['buy'][len(bsLine['buy']) - 1], "/", count) datetime_value = datetime.now().strftime('%Y-%m-%d %H:%M:%S') value = {"type": "BUY", "datetime": datetime_value, "order0": order[0], "order1": order[1], "order2": order[2], "order3": order[3], "canceled": 0, "slow_k_30": stock2['slow_k'][len(stock2['slow_k']) - 1], "slow_k_5": stock1['slow_k'][len(stock1['slow_k']) - 1], "price": bsLine['buy'][len(bsLine['buy']) - 1], "count": count} value_df = pd.DataFrame(value, index=[datetime_value]) value_df["datetime"] = pd.to_datetime(value_df["datetime"], format='%Y-%m-%d %H:%M:%S') indexes1 = order_log_df.index.tolist() indexes1.append(datetime_value) order_log_df = order_log_df.append(value_df, ignore_index = True) order_log_df.index = indexes1 order_log_df['datetime'] = order_log_df.index order_log_df.to_csv(order_log_filename, index=False) # 파일에 매수 시점 그래프 dirName = os.path.join(RESOURCE_PATH, 'analysis', 'bithumb') self.writeFile(dirName, ticker, stock1, bsLine, '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) # slackbot에 메시지를 보냄 self.slackBot.post_to_slack(ticker, self.stock_code[ticker], "SELL", bsLine['sell'][len(bsLine['sell']) - 1], count) if len(order) > 2 and len(stock1['close']) > 0: print(ticker, "/", datetime.now().strftime('%Y-%m-%d %H:%M:%S'), "/", stock1['close'][len(stock1['close'])-1], "/", "{:.2f}".format(stock2['slow_k'][len(stock1['slow_k'])-1]), "/", "{:.2f}".format(stock1['slow_k'][len(stock1['slow_k'])-1]), "/", "{:.2f}".format(stock2['macd'][len(stock2['macd']) - 1]), "/", "{:.2f}".format(stock1['macd'][len(stock1['macd']) - 1]), "/", bsLine['sell'][len(bsLine['sell']) - 1], "/", count) value = {"type": "SELL","order0": order[0], "order1": order[1], "order2": order[2], "order3": order[3], "canceled": 0, "slow_k_30": stock2['slow_k'][len(stock2['slow_k']) - 1], "slow_k_5": stock1['slow_k'][len(stock1['slow_k']) - 1], "price": bsLine['sell'][len(bsLine['sell']) - 1], "count": count} datetime_value = datetime.now().strftime('%Y-%m-%d %H:%M:%S') value_df = pd.DataFrame(value, index=[datetime_value]) indexes = order_log_df.index.tolist() indexes.append(datetime_value) order_log_df = order_log_df.append(value_df, ignore_index=True) order_log_df.index = indexes order_log_df['datetime'] = order_log_df.index order_log_df.to_csv(order_log_filename, index=False) dirName = os.path.join(RESOURCE_PATH, 'analysis', 'bithumb') self.writeFile(dirName, ticker, stock1, bsLine, 'sell') #else: # dirName = os.path.join(RESOURCE_PATH, 'analysis', 'bithumb') # self.writeFile(dirName, ticker, stock1, bsLine) 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) today = datetime.today().strftime('%Y%m%d') bithumb = Bithumb_minute(RESOURCE_PATH, today) 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: try: time.sleep(10) bithumb.buyRealTime(ticker, analyzed_day, isRealTime) except: continue else: for ticker in tickers: bithumb.buyRealTime(ticker, analyzed_day, isRealTime)