From 7f052708ddf289338856c6b73d6c842c6598f77d Mon Sep 17 00:00:00 2001 From: dsyoon Date: Mon, 30 Jan 2023 09:49:11 +0900 Subject: [PATCH] init --- HTS_etf.py | 101 +++++++++++++++++++++----------------------- HTS_stocks.py | 4 +- hts/OrderChecker.py | 41 +++++++++--------- 3 files changed, 71 insertions(+), 75 deletions(-) diff --git a/HTS_etf.py b/HTS_etf.py index 75b0ffb..9377717 100644 --- a/HTS_etf.py +++ b/HTS_etf.py @@ -98,71 +98,68 @@ class HTS_etf (HTS): if datetime.strptime(today + " 090000", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151500", '%Y%m%d %H%M%S'): - # 3시 까지만 매수를 시도한다. - if THIS_TIME.strftime('%S') == "03": - # 매분 3초마다 실행한다. + for stock in stocks: - for stock in stocks: + # 데이터를 가지고 온다. + result = self.getRealTime(stock['stock_code'], today, LAST_DATA[stock['stock_code']]) - # 데이터를 가지고 온다. - result = self.getRealTime(stock['stock_code'], today, LAST_DATA[stock['stock_code']]) + result_5 = self.makeTickData(result, mins=5) + result_30 = self.makeTickData(result, mins=30) - result_5 = self.makeTickData(result, mins=5) - result_30 = self.makeTickData(result, mins=30) + data = self.buySellChecker.analyze(result) + data.drop(data.index[:len(data) - analyzed_day], inplace=True) - data = self.buySellChecker.analyze(result) - data.drop(data.index[:len(data) - analyzed_day], inplace=True) + # 5분 이동평균, RSI, MACD, 일목균형, 볼린저밴드 상/하단을 계산한다. + data_5 = self.buySellChecker.analyze(result_5) + # 분석일 데이터만 활용한다 (이전 데이터는 제거) + data_5.drop(data_5.index[:len(data_5) - analyzed_day], inplace=True) - # 5분 이동평균, RSI, MACD, 일목균형, 볼린저밴드 상/하단을 계산한다. - data_5 = self.buySellChecker.analyze(result_5) - # 분석일 데이터만 활용한다 (이전 데이터는 제거) - data_5.drop(data_5.index[:len(data_5) - analyzed_day], inplace=True) + # 30분 이동평균, RSI, MACD, 일목균형, 볼린저밴드 상/하단을 계산한다. + data_30 = self.buySellChecker.analyze(result_30) + # 분석일 데이터만 활용한다 (이전 데이터는 제거) + data_30.drop(data_30.index[:len(data_30) - analyzed_day], inplace=True) - # 30분 이동평균, RSI, MACD, 일목균형, 볼린저밴드 상/하단을 계산한다. - data_30 = self.buySellChecker.analyze(result_30) - # 분석일 데이터만 활용한다 (이전 데이터는 제거) - data_30.drop(data_30.index[:len(data_30) - analyzed_day], inplace=True) + # 사야 할 시점과 팔아야 할 시점을 체크한다. + bsLine = self.buySellChecker.checkTransaction(data, data_5, data_30, isRealTime=True) + bs_buy_price = bsLine['buy'][0] + bs_buy_weight = bsLine['buy_weight'][0] + bs_sell_price = bsLine['sell'][0] - # 사야 할 시점과 팔아야 할 시점을 체크한다. - bsLine = self.buySellChecker.checkTransaction(data, data_5, data_30, isRealTime=True) - bs_buy_price = bsLine['buy'][0] - bs_buy_weight = bsLine['buy_weight'][0] - bs_sell_price = bsLine['sell'][0] - - # 미체결 기록을 가져와서 10분 이상 된 매수 주문을 취소 한다. - ORDER_LIST = self.requestOrderList() - orderListToCancel = self.orderChecker.cancel(today, stock['stock_code'], ORDER_LIST) + # 미체결 기록을 가져와서 10분 이상 된 매수 주문을 취소 한다. + ORDER_LIST = self.requestOrderList() + orderListToCancel = self.orderChecker.cancel(today, stock['stock_code'], ORDER_LIST) + if len(orderListToCancel) > 0: self.cancelOrderList(orderListToCancel) - if bs_buy_price > 0: - buy_count = int(self.MAX_BUY_PRICE/bs_buy_price) + if bs_buy_price > 0: + buy_count = int(self.MAX_BUY_PRICE/bs_buy_price) - # 매수를 주문한다. - orderNum = self.requestOrder(OrderType.buy, stock['stock_code'], buy_count , bs_buy_price) - self.orderChecker.buy(today, stock['stock_code'], buy_count, bs_buy_price, orderNum) + # 매수를 주문한다. + orderNum = self.requestOrder(OrderType.buy, stock['stock_code'], buy_count , bs_buy_price) + self.orderChecker.buy(today, stock['stock_code'], buy_count, bs_buy_price, orderNum) - # slackbot에 메시지를 보냄 - self.slackBot.post_to_slack(stock['stock_code'], stock['stock_name'], "BUY", bsLine['buy'][len(bsLine['buy']) - 1], buy_count) - - # 로그 출력 - print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), orderNum, stock['stock_code'], stock['stock_name'], bs_buy_price, buy_count) - - - if bs_sell_price > 0: - # 매도한다. - orderNum = self.getSellingPrice(THIS_TIME, stock['stock_code'], bs_sell_price, without_loss=True) - self.orderChecker.sell(today, stock['stock_code']) - - # slackbot에 메시지를 보냄 - self.slackBot.post_to_slack(stock['stock_code'], stock['stock_name'], "SELL", bsLine['sell'][len(bsLine['sell']) - 1], -1) - - # 로그 출력 - print("SELL", THIS_TIME.strftime('%Y%m%d %H%M%S'), str(orderNum), stock['stock_code'], stock['stock_name'], bs_sell_price) + # slackbot에 메시지를 보냄 + self.slackBot.post_to_slack(stock['stock_code'], stock['stock_name'], "BUY", bsLine['buy'][len(bsLine['buy']) - 1], buy_count) # 로그 출력 - print("TIMECHECK: %s, code: %s, name: %s, buy: %d, sell: %d, avg5: %.2f, avg30: %.2f, open: %d, high: %d, low: %d, slow_k: %.2f, slow_k_5: %.2f, slow_k_30: %.2f" % - (str(THIS_TIME), stock['stock_code'], stock['stock_name'], bs_buy_price, bs_sell_price, data["avg5"][0], data["avg30"][0], - data["open"][0], data["high"][0], data["low"][0], data["slow_k"][0], data_5["slow_k"][0], data_30["slow_k"][0])) + print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), orderNum, stock['stock_code'], stock['stock_name'], bs_buy_price, buy_count) + + + if bs_sell_price > 0: + # 매도한다. + orderNum = self.getSellingPrice(THIS_TIME, stock['stock_code'], bs_sell_price, without_loss=True) + self.orderChecker.sell(today, stock['stock_code']) + + # slackbot에 메시지를 보냄 + self.slackBot.post_to_slack(stock['stock_code'], stock['stock_name'], "SELL", bsLine['sell'][len(bsLine['sell']) - 1], -1) + + # 로그 출력 + print("SELL", THIS_TIME.strftime('%Y%m%d %H%M%S'), str(orderNum), stock['stock_code'], stock['stock_name'], bs_sell_price) + + # 로그 출력 + print("TIMECHECK: %s, code: %s, name: %s, buy: %d, sell: %d, avg5: %.2f, avg30: %.2f, open: %d, high: %d, low: %d, slow_k: %.2f, slow_k_5: %.2f, slow_k_30: %.2f" % + (str(THIS_TIME), stock['stock_code'], stock['stock_name'], bs_buy_price, bs_sell_price, data["avg5"][0], data["avg30"][0], + data["open"][0], data["high"][0], data["low"][0], data["slow_k"][0], data_5["slow_k"][0], data_30["slow_k"][0])) elif datetime.strptime(today + " 151530", '%Y%m%d %H%M%S') < THIS_TIME < datetime.strptime(today + " 151600", '%Y%m%d %H%M%S'): # 3시 15분 30초부터 3시 16분 사이는 잔량을 매도한다. diff --git a/HTS_stocks.py b/HTS_stocks.py index e5a331d..4467cff 100644 --- a/HTS_stocks.py +++ b/HTS_stocks.py @@ -134,7 +134,7 @@ class HTS_Stocks (HTS): orderNum = self.requestOrder(OrderType.buy, stock_code, buy_count, bs_buy_price) # slackbot에 메시지를 보냄 self.slackBot.post_to_slack(stock_code, stock_name, "BUY", bsLine['buy'][len(bsLine['buy']) - 1], buy_count) - self.orderChecker.add(today, stock_code, 1, buy_count, bs_buy_price, orderNum) + self.orderChecker.buy(today, stock_code, buy_count, bs_buy_price, orderNum) # 로그 출력 print("BUY", THIS_TIME.strftime('%Y%m%d %H%M%S'), orderNum, stock_code, stock_name, bs_buy_price, buy_count) @@ -147,7 +147,7 @@ class HTS_Stocks (HTS): orderNum = self.getSellingPrice(THIS_TIME, stock_code, bs_sell_price) # slackbot에 메시지를 보냄 self.slackBot.post_to_slack(stock_code, stock_name, "SELL", bsLine['sell'][len(bsLine['sell']) - 1], -1) - self.orderChecker.delete(today, stock_code) + self.orderChecker.sell(today, stock_code) # 로그 출력 print("SELL", THIS_TIME.strftime('%Y%m%d %H%M%S'), orderNum, stock_code, stock_name, bs_sell_price) diff --git a/hts/OrderChecker.py b/hts/OrderChecker.py index be52611..33fcfe0 100644 --- a/hts/OrderChecker.py +++ b/hts/OrderChecker.py @@ -18,12 +18,12 @@ class OrderChecker: order_df = pd.read_csv(saveFileName) else: # (type) buy=0, sell=1 - order_df = pd.DataFrame(columns=["datetime", "stock_code", "type", "orderNum", "count", "price"]) + order_df = pd.DataFrame(columns=["datetime", "stock_code", "type", "orderNum", "canceled", "count", "price"]) if 'Unnamed: 0' in order_df.columns: order_df.drop(['Unnamed: 0'], axis=1, inplace=True) order_df = order_df.fillna(0) - order_df = order_df.astype({"stock_code": int, "type": int, "orderNum": int, "count": int, "price": int}) + order_df = order_df.astype({"stock_code": int, "type": int, "orderNum": int, "canceled": int, "count": int, "price": int}) order_df['datetime'] = pd.to_datetime(order_df['datetime']) return order_df @@ -45,11 +45,9 @@ class OrderChecker: order_df = self.read(ymd) # 새로운 주문을 추가한다. - order_df = order_df.append( - {"stock_code": "A" + stock_code, "type": 0, "orderNum": str(orderNum), "canceled": 0, "count": count, + order_df = order_df.append({"stock_code": "A" + stock_code, "type": 0, "orderNum": str(orderNum), "canceled": 0, "count": count, "price": price, "datetime": datetime.now()}, ignore_index=True) - order_df = order_df.astype( - {"stock_code": str, "type": int, "orderNum": str, "canceled": int, "count": int, "price": int}) + order_df = order_df.astype({"stock_code": str, "type": int, "orderNum": str, "canceled": int, "count": int, "price": int}) # 파일로 기록한다. saveFileName = os.path.join(self.RESOURCE_PATH, "etf_order", ymd + ".csv") @@ -72,25 +70,26 @@ class OrderChecker: def cancel(self, ymd, stock_code, ORDER_LIST, min=10): + orderListToCancel = [] order_df = self.read(ymd) - now = datetime.now() - timedelta(minutes=min) - # min 분 이상 된 시간인 내용을 가지고 옴 - df = order_df.loc[(order_df.index <= now)] - # 취소가 되지 않은 것만 가지고 옴 (0: 취소 되지 않음, 1: 취소함) - df = df.loc[(order_df["canceled"] == 0)] + if len(order_df) > 0: + now = datetime.now() - timedelta(minutes=min) + # min 분 이상 된 시간인 내용을 가지고 옴 + df = order_df.loc[(order_df.index <= now)] + # 취소가 되지 않은 것만 가지고 옴 (0: 취소 되지 않음, 1: 취소함) + df = df.loc[(order_df["canceled"] == 0)] - for i in range(len(df)): - order_df.loc[(order_df.index == df.index[i]), 'canceled'] = 1 + for i in range(len(df)): + order_df.loc[(order_df['stock_code']=="A" + stock_code) & (order_df.index == df.index[i]), 'canceled'] = 1 - saveFileName = os.path.join(self.RESOURCE_PATH, "etf_order", ymd + ".csv") - order_df.to_csv(saveFileName, index=False) + saveFileName = os.path.join(self.RESOURCE_PATH, "etf_order", ymd + ".csv") + order_df.to_csv(saveFileName, index=False) - orderListToCancel = [] - if ORDER_LIST is not None and len(ORDER_LIST) > 0: - orderNumSet = set(list(df["orderNum"])) - for item in ORDER_LIST: - if item.orderNum in orderNumSet: - orderListToCancel.append(item) + if ORDER_LIST is not None and len(ORDER_LIST) > 0: + orderNumSet = set(list(df["orderNum"])) + for item in ORDER_LIST: + if item.orderNum in orderNumSet: + orderListToCancel.append(item) return orderListToCancel