def setUp(self): self.mongodb = MongoDBHandler("local", "coiner", "price_info") self.mongodb.delete_items({}) docs = [ { "currency": "btc", "price": 10000 }, { "currency": "eth", "price": 1000 }, { "currency": "xrp", "price": 100 }, { "currency": "btc", "price": 20000 }, { "currency": "eth", "price": 2000 }, { "currency": "xrp", "price": 200 }, ] self.mongodb.insert_items(docs)
def order_transaction(self, machine=None, currency_type=None, price=None, side=None, order_type="limit", qty=None): """ 매수매도 주문의 데이터베이스로 저장을 담당 Args: machine(obj): 매수주문하려는 거래소 모듈 객체 db_handler(obj): 매수주문 정보를 입력할 데이터베이스 모듈 객체 currency_type(str): 매수주문하려는 화폐종류 item(dict): 매수 완료 후 데이터베이스에 저장하려는 데이터 order_type(str):매수방법 Returns: OrderId(str): 매수주문 완료 후의 주문 id """ if currency_type is None: raise Exception("Need to param") db_handler = MongoDBHandler(db_name="trader", collection_name="trade_status") db_handler.set_db_collection("trader", "trade_status") result = machine.order( currency_type=currency_type, price=price, qty=qty, # str(self.BUY_COUNT), ord_type=order_type, side=side) if (result["state"] == "wait") or (result["state"] == "done"): self.db_handler.insert_item({ "state": str(result["state"]), "market": currency_type, "uuid": str(result["uuid"]), "volume": float(result["volume"]), "side": str(result["side"]), "buy_order_time": str(datetime.now()), "trade_value": str(result["price"]), "fee": float(result["paid_fee"]), }) self.db_handler.set_db_collection("trader", side) if (result["state"] == "wait") or (result["state"] == "done"): self.db_handler.insert_item({ "state": str(result["state"]), "market": currency_type, "uuid": str(result["uuid"]), "volume": float(result["volume"]), "side": str(result["side"]), "buy_order_time": str(datetime.now()), "trade_value": str(result["price"]), "fee": float(result["paid_fee"]), }) return result["uuid"] else: logger.info(result) print("매매에 실패하였습니다") return None
def DB_order_list(self, state="wait"): db_handler = MongoDBHandler(db_name="trader", collection_name="trade_status") db_handler.set_db_collection("trader", "trade_status") return db_handler.find_items({"state": state}, db_name="trader", collection_name="trade_status")
def __init__(self, ): self.pusher = PushSlack() self.db_handler = MongoDBHandler(db_name="trader", collection_name="trade_status") self.machine = UpbitMachine() self.currency_type = self.machine.currency_type self.compare_disparity = None self.now_price = None self.order_balance = 20000 #float(self.machine.get_free_balance()) / 4# 총보유현금 4등분 self.free_balance = self.machine.get_free_balance() self.term = 5 self.Log_Text = None logger.info(self.currency_type)
def my_all_assets( self, machine=None, ): """ 매수매도 주문의 데이터베이스로 저장을 담당 Args: machine(obj): 매수주문하려는 거래소 모듈 객체 db_handler(obj): 매수주문 정보를 입력할 데이터베이스 모듈 객체 currency_type(str): 매수주문하려는 화폐종류 item(dict): 매수 완료 후 데이터베이스에 저장하려는 데이터 order_type(str):매수방법 Returns: OrderId(str): 매수주문 완료 후의 주문 id """ db_handler = MongoDBHandler(db_name="trader", collection_name="trade_status") db_handler.set_db_collection("trader", "assets") result = machine.get_All_balance() db_handler.insert_item({ "time": datetime.now(), "asset": result, }) logger.info(str(datetime.now()) + "자산 : " + str(result)) return result
def update_trade_status(self, item_id=None, value=None): """ 현재 상태를 업데이트 하는 메서드 Args: db_handler(obj): 대상 데이터베이스의 모듈 객체 item_id(dict): 업데이트 조건 value(dict): 업데이트 하려는 문서의 칼럼과 값 """ db_handler = MongoDBHandler(db_name="trader", collection_name="trade_status") if item_id is None or value is None: raise Exception("Need to buy value or status") db_handler.set_db_collection("trader", "trade_status") db_handler.update_items(item_id, {"$set": value})
def order_cancel_transaction(self, machine=None, currency_type=None, item=None): """취소주문과 함께 데이터베이스에 필요한 데이터를 업데이트 하는 메서드 Args: machine(obj): 취소주문하려는 거래소 모듈 객체 db_handler(obj):취소주문 정보를 입력할 데이터베이스 모듈 객체 currency_type(str): 취소주문하려는 화폐 종류 item(dict): 취소주문에 필요한 데이터 Returns: OrderId(str): 취소 완료 후의 주문 id """ db_handler = MongoDBHandler(db_name="trader", collection_name="trade_status") db_handler.set_db_collection("trader", "trade_status") if currency_type is None or item is None: raise Exception("Need to param") result = machine.cancel_order(order_id=item["uuid"]) if result[0].get(["error"]): logger.info(result) logger.info("주문 취소에 실패하였습니다") else: db_handler.update_items({"uuid": item["uuid"]}, { "$set": { "state": "cancel_ORDERED", "cancel_order_time": int( datetime.datetime.now().timestamp()), "transaction": "fail" } }) pprint.pprint(item['uuid'], item["market"], "주문이 취소되었습니다") return item["uuid"] logger.info(result) logger.info(item)
class MongoDBHandlerTestCase(unittest.TestCase): def setUp(self): self.mongodb = MongoDBHandler("local", "coiner", "price_info") self.mongodb.delete_items({}) docs = [ { "currency": "btc", "price": 10000 }, { "currency": "eth", "price": 1000 }, { "currency": "xrp", "price": 100 }, { "currency": "btc", "price": 20000 }, { "currency": "eth", "price": 2000 }, { "currency": "xrp", "price": 200 }, ] self.mongodb.insert_items(docs) def tearDown(self): pass def test_set_db_collection(self): """ test set_db """ self.mongodb.set_db_collection("trader", "trade_status") def test_get_db_name(self): dbname = self.mongodb.get_current_db_name() self.assertEqual(dbname, "coin") def test_get_collection_name(self): collection_name = self.mongodb.get_current_collection_name() self.assertEqual(collection_name, "price_info") def test_insert_item(self): doc = {"item": "item0", "name": "test_insert_item"} id = self.mongodb.insert_item(doc) assert id print(id) def test_insert_items(self): docs = [ { "item": "item1", "name": "test_insert_items" }, { "item": "item2", "name": "test_insert_items" }, ] ids = self.mongodb.insert_items(docs) assert ids print(ids) def test_find_item(self): doc = self.mongodb.find_item({"currency": "btc"}) print(doc) def test_find_items(self): cursor = self.mongodb.find_item({"currency": "eth"}) assert cursor for doc in cursor: print(doc) def test_delete_items(self): result = self.mongodb.delete_items({"currency": "xrp"}) assert result print(result.deleted_count) def test_update_items(self): result = self.mongodb.update_items({"currency": "xrp"}, {"$set": { "price": 300 }}) assert result print("matched_count:" + str(result.matched_count)) print("modified_count:" + str(result.modified_count)) def test_aggregate(self): print(inspect.stack()[0][3]) pipeline = [{ "$match": { "currency": "btc" } }, { "$group": { "_id": "$currency", "min_val": { "$min": "$price" }, "max_val": { "$max": "$price" }, "sum_val": { "$sum": "$price" }, } }] result = self.mongodb.aggregate(pipeline) assert result for item in result: print(item)
def Hope_List_Insert(self, result=None): db_handler = MongoDBHandler(db_name="trader", collection_name="trade_status") db_handler.set_db_collection("trader", "wish_list") db_handler.insert_item({"market": result, "time": datetime.now()})
class StepTrade(Strategy): def __init__(self, ): self.pusher = PushSlack() self.db_handler = MongoDBHandler(db_name="trader", collection_name="trade_status") self.machine = UpbitMachine() self.currency_type = self.machine.currency_type self.compare_disparity = None self.now_price = None self.order_balance = 20000 #float(self.machine.get_free_balance()) / 4# 총보유현금 4등분 self.free_balance = self.machine.get_free_balance() self.term = 5 self.Log_Text = None logger.info(self.currency_type) def run(self, term=10, Log_Text=None, Hope_coin_list=None, free_balance=None): if Hope_coin_list is None and Log_Text is None: raise Exception("I need Hope_coin_list and Conn") self.Log_Text = Log_Text self.term = term self.free_balance = free_balance self.check_my_order() buy_processes = [ multiprocessing.Process(target=self.buy_trading_logic, args=(arg, )) for arg in Hope_coin_list ] sell_processes = [ multiprocessing.Process(target=self.sell_trading_logic, args=(arg, )) for arg in self.machine.get_coin_list() ] for p1 in buy_processes[:4]: p1.start() for p in buy_processes[:4]: p.join() time.sleep(60) for p2 in buy_processes[4:]: p2.start() for p2 in buy_processes[4:]: p2.join() for p3 in sell_processes: p3.start() for p33 in sell_processes: p3.join() time.sleep(1) time.sleep(int(self.term) * 60) def check_my_order(self): assets = int( self.my_all_assets(machine=self.machine, db_handler=self.db_handler)) self.check_ordered_state() self.pusher.send_message( "#general", str(datetime.now()) + " 현재 자산 :" + str(assets) + "원 입니다") self.Log_Text.appendPlainText( str(datetime.now()) + " 현재 자산 :" + str(assets) + "원 입니다") self.pusher.send_message( "#general", "그 중 거래 가능 현금 :" + str(self.free_balance) + "원 입니다") self.Log_Text.appendPlainText("그 중 거래 가능 현금 :" + str(self.free_balance) + "원 입니다") #self.check_completed() self.check_keep_ordered() def check_ordered_state(self): DB_order_list = self.db_handler.find_items( {"state": "wait"}, db_name="trader", collection_name="trade_status") # print(DB_order_list) for list in DB_order_list: # print(list["uuid"]) item = self.machine.get_my_order_status( uuid=list["uuid"] ) # 구매 리스트를 불러옴 단 딱히 market을 지정하지 않음 전부다 조회하기 위해서 !!!나중에 페이지를 넓히던 방법 강구해야됨 logger.info(item) #로그파일저장분 # print(item) if (item.get('error')): pass else: # print("여기출력!!!!!!!!!!") # print(item['uuid']) if item["state"] == "done": #만약 디비에 wait되어 있던 게 완료되었으면 디비로 저장 order_result_dict = item real_amount = float( order_result_dict["executed_volume"]) #거래량 real_value = float( order_result_dict["avg_price"]) #평균 구매가격 created_at = float(order_result_dict["created_at"] / 1000) #구매시간 fee = float(order_result_dict["paid_fee"]) # 수수료비율 self.update_trade_status(db_handler=self.db_handler, item_id={"uuid": item["uuid"]}, value={ "status": "done", "real_amount": real_amount, "created_at": created_at, "real_value": real_value, "real_fee": fee, "side": item["side"] }) self.pusher.send_message("#general", "completed:" + item["side"] + str(item)) #이상없 self.Log_Text.appendPlainText("completed:" + item["side"] + str(item)) #이상없 elif item["state"] == "wait": if item["side"] == "bid": #아직 wait라면 if float(item["price"] ) * 1.05 <= self.machine.get_now_price( currency_type=item["market"]): #체크값 logger.info("CancelOrder") logger.info(item) try: self.order_cancel_trasaction( machine=self.machine, db_handler=self.db_handler, item=item) except: error = traceback.format_exc() logger.info(error) self.update_trade_status( db_handler=self.db_handler, item_id={"uuid": item["uuid"]}, value={"transaction": "failed"}) print("구매주문 취소") self.pusher.send_message( "#general", "해당 코인의 가격이 더 올라 취소되었습니다. 추격매수 말고 기다려주세요" + str(item)) self.Log_Text.appendPlainText( "해당 코인의 가격이 더 올라 취소되었습니다. 추격매수 말고 기다려주세요" + str(item)) elif item["side"] == "ask": if (item.get('price')): if float(item["price"] ) < self.machine.get_now_price( currency_type=item['market']) * 1.05: self.order_cancel_trasaction( machine=self.machine, db_handler=self.db_handler, item=item) #self.update_trade_status(db_handler=self.db_handler, item_id={"uuid": item["uuid"]}, value={"status": "wait"}) print("판매주문 취소") self.pusher.send_message( "#general", "해당 코인의 가격이 너무 내려 매도 주문이 취소되었습니다, 손절을 추천드립니다" + str(item)) self.Log_Text.appendPlainText( "해당 코인의 가격이 너무 내려 매도 주문이 취소되었습니다, 손절을 추천드립니다" + str(item)) else: self.update_trade_status( db_handler=self.db_handler, item_id={"uuid": item["uuid"]}, value={"status": "CANCEL_ORDERED"}) def check_completed(self): #굳이 있을 필요가 있나 DB_order_list = self.db_handler.find_items( {"state": "done"}, db_name="trader", collection_name="trade_status") logger.info("ORDER_COMPELETED") for item in DB_order_list: # print(item) logger.info(item) try: self.order_transaction(machine=self.machine, db_handler=self.db_handler, item=item, side=item["side"]) self.pusher.send_message( "#general", item["side"] + "ordered : " + str(item)) self.Log_Text.appendPlainText(item["side"] + "ordered : " + str(item)) except: error = traceback.format_exc() logger.info(error) if (item.get('uuid')): self.update_trade_status(db_handler=self.db_handler, item_id={"uuid": item["uuid"]}, value={"transactions": "failed"}) def get_hopeful_coin(self): #평균회귀 평가모델로 뽑아온 coin목록을 db에넣어 result = MeanReversionModel() self.db_handler.set_db_collection("trader", "wish_list") for coin in result: self.db_handler.insert_item({ "market": coin, "time": datetime.now() }) self.currency_type = result return self.currency_type def check_keep_ordered(self): #여기가 손익라인 #5프로 정도로 한다 has_coin_list = self.machine.get_has_coin_info_list() for item in has_coin_list: now_price = self.machine.get_now_price( currency_type=item["market"]) #print(item['market']) if (item['market'] == "KRW-ETH"): pass else: if float(item["price"]) * 1.05 < now_price and float( item["price"]) * 1.05 > 1000: #수익라인 self.order_transaction(machine=self.machine, db_handler=self.db_handler, currency_type=item["market"], side='ask', qty=item["balance"], price=now_price) self.pusher.send_message( "#general", "보유 중인 " + str(item["market"]) + "코인을 수익 매도 하였습니다. info : " + str(item)) logger.info("sell order from keeped" + str(item["uuid"])) self.Log_Text.appendPlainText("보유 중인 " + str(item["market"]) + "코인을 수익 매도 하였습니다. info : " + str(item)) elif float(item["price"]) * 0.95 > now_price and float( item["price"]) * 1.05 > 1000: #손절라인 self.order_transaction(machine=self.machine, db_handler=self.db_handler, currency_type=item["market"], side='ask', qty=item["balance"], price=now_price) self.pusher.send_message( "#general", "보유 중인 " + str(item["market"]) + "코인을 손절 매도 하였습니다. info : " + str(item)) self.Log_Text.appendPlainText("보유 중인 " + str(item["market"]) + "코인을 손절 매도 하였습니다. info : " + str(item)) logger.info(str(item["market"]) + "을 매도 하였습니다 ") def set_thread_price(self, currency_type=None): coin_type = currency_type #for coin_type in currency_type: price_info = {} price_info['market'] = coin_type price_info['pridict_price'] = tensorflow_algorithm_keras( term=self.term, count=100, currency_type=coin_type) bollingerband = self.machine.get_bollingerband(term=self.term, count=20, currency_type=coin_type) price_info['bolin_high'] = bollingerband['high'] price_info['bolin_mid'] = bollingerband['mid'] price_info['bolin_low'] = bollingerband['low'] price_info['disparity'] = self.machine.get_disparity( term=self.term, count=20, currency_type=coin_type) price_info['now_price'] = self.machine.get_now_price( currency_type=coin_type) return (price_info) # time.sleep(300) def buy_trading_logic(self, currency_type=None): if currency_type is None: raise Exception("I have to need info") print("구매로직 진입") print(currency_type) term = self.term info = self.set_thread_price(currency_type=currency_type) wallet = self.free_balance if (float(wallet) > self.order_balance): count = 0 if (float(info["pridict_price"]) > float(info['now_price'])): count += 1 if (float(info["disparity"]) < -1): disparity = float(info["disparity"]) count += 1 if (float(info["bolin_low"]) > float(info['now_price'])): count += 1 if (count >= 2): print("구매 검토 중") time.sleep(int(term) * 60) while (1): if (float( self.machine.get_disparity( currency_type=info["market"], term=self.term)) > disparity): wallet = self.free_balance now_price = self.machine.get_now_price( currency_type=info["market"]) if float(wallet) >= self.order_balance: volume = (self.order_balance) / float(now_price) self.order_transaction( machine=self.machine, db_handler=self.db_handler, qty=volume * 0.98, currency_type=info["market"], side="bid", price=now_price) time.sleep(int(term) * 60) self.check_ordered_state() self.pusher.send_message( "#general", "현재" + str(info["market"]) + "매수 하였습니다 info : " + str(info)) self.Log_Text.appendPlainText("현재" + str(info["market"]) + "매수 하였습니다 info : " + str(info)) logger.info("buy transaction") else: print("돈없어서 pass") self.Log_Text.appendPlainText( "보유 중인 금액이 부족하여 구매에 실패하였습니다") break disparity = float( self.machine.get_disparity( currency_type=info["market"], term=self.term)) print("매수 시점 기다리는 중") time.sleep(int(term) * 60) self.check_ordered_state() def sell_trading_logic(self, currency_type=None): if currency_type is None: raise Exception("I have to need info") print("판매 로직 진입") print(currency_type) term = self.term #info 는 가지고 있는 코인 리스트 has_coin_info = self.machine.get_has_coin_info() print("판매 위해 가지고 있는 코인들 조회") evalueation_coin = self.set_thread_price(currency_type=currency_type) #print(evalueation_coin) count = 0 if (float(evalueation_coin["pridict_price"]) < float( evalueation_coin['now_price'])): count += 1 if (float(evalueation_coin["disparity"]) > 1): disparity = float(evalueation_coin["disparity"]) count += 1 if (float(evalueation_coin["bolin_high"]) < float( evalueation_coin['now_price'])): count += 1 if (count >= 2): print("판매 검토중") time.sleep(int(term) * 60) now_price = self.machine.get_now_price( currency_type=evalueation_coin["market"]) while (1): if (float( self.machine.get_disparity( currency_type=evalueation_coin["market"], term=self.term)) < disparity): volume = self.machine.get_coin_valume( evalueation_coin["market"]) self.order_transaction( machine=self.machine, db_handler=self.db_handler, qty=float(volume) * 0.98, currency_type=evalueation_coin["market"], side="ask", price=now_price) time.sleep(int(term) * 60) self.check_ordered_state() logger.info("sell transaction") self.pusher.send_message( "#general", "현재" + str(evalueation_coin["market"]) + "매도 하였습니다 info : " + str(evalueation_coin)) self.Log_Text.appendPlainText( "현재" + str(evalueation_coin["market"]) + "매도 하였습니다 info : " + str(evalueation_coin)) print("판매 완료") break disparity = float( self.machine.get_disparity( currency_type=evalueation_coin["market"], term=self.term)) print("매도 시점 기다리는 중") time.sleep(int(term) * 60) self.check_ordered_state() def stop(self): return 0