class OrderMaker(Information): """ InformationからはAPIの情報だけをもらっておく 実際にオーダーを行うときは、Mainから指令を受ける """ def __init__(self): super().__init__() self.recorder = Recorder() def cancel_parent_order(self, order_id): """ Nomen est omen :param order_id: :return: """ self.api.cancelparentorder(product_code=self.product, parent_order_acceptance_id=order_id) time.sleep(2) def profit_price_decider(self, order_side, order_price): """ 発注する際の利確ラインを決定する :return: """ board = self.api.board(product_code=self.product) asks = board['asks'] bids = board['bids'] ask_size = 0 ask_price = 0 bid_size = 0 bid_price = 0 default_target = 300 bottom_line = 400 # 最低でもこの価格までは利確を待つ upper_line = 1200 # 最高でもこの価格までで利確する if order_side == "BUY": for ask in asks: if (bottom_line <= ask['price'] - order_price <= upper_line) and (ask['_size'] >= ask_size): ask_size = ask['_size'] ask_price = ask['price'] if ask_size >= 2: break if ask_price == 0: ask_price = order_price + default_target elif -100 <= int(order_price - ask_price) <= 100: ask_price += 200 return int(ask_price - 10) elif order_side == "SELL": for bid in bids: if (bottom_line <= order_price - bid['price'] <= upper_line) and (bid['_size'] >= bid_size): bid_size = bid['_size'] bid_price = bid['price'] if bid_size >= 2: break if bid_price == 0: bid_price = order_price - default_target elif -100 <= int(order_price - bid_price) <= 100: bid_price -= 200 return int(bid_price + 10) def oco_order_maker(self, order_side, order_size, order_price): data = self.order_base_maker(order_side, order_price) profit_or_loss = self.api.sendparentorder( order_method="OCO", parameters=[ { "product_code": self.product, "condition_type": "LIMIT", "side": data['execution_side'], # 決済用 "price": data['profit_line'], "size": order_size # 所持しているビットコインの数量を入れる }, { "product_code": self.product, "condition_type": "STOP", # ストップ注文 "side": data['execution_side'], "price": data['loss_line'], # what? "trigger_price": data['loss_line'], "size": order_size } ] ) if 'status' in profit_or_loss.keys(): if profit_or_loss['status'] == -205: self.api.cancelallchildorders(product_code=self.product) print("ERROR OCCURRED, CANCELLING ALL ORDERS") time.sleep(2) return profit_or_loss def parent_order_maker(self, order_side, order_size, order_price, balance): data = self.order_base_maker(order_side, order_price) buy_btc = self.api.sendparentorder( order_method="IFDOCO", parameters=[{ "product_code": self.product, "condition_type": "LIMIT", "side": order_side, "price": order_price, "size": order_size, 'time_in_force': 'IOC' }, { "product_code": self.product, "condition_type": "LIMIT", "side": data['execution_side'], # 決済用 "price": data['profit_line'], "size": order_size # 所持しているビットコインの数量を入れる }, { "product_code": self.product, "condition_type": "STOP", # ストップ注文 "side": data['execution_side'], "price": 0, # "trigger_price": data['loss_line'], "size": order_size }] ) print("ordered: " + order_side, str(order_size) + "BTC at the price of " + str(order_price)) print(buy_btc) if 'status' in buy_btc.keys(): if buy_btc['status'] == -205: self.api.cancelallchildorders(product_code=self.product) print("ERROR OCCURED, CANCELLING ALL ORDERS") time.sleep(2) self.recorder.balance_recorder(balance, order_price) print(buy_btc) time.sleep(1) return buy_btc def order_base_maker(self, order_side, order_price): loss = None contrary = None if order_side == "BUY": contrary = "SELL" loss = int(order_price - self.lost_price) # 同上、損切ライン elif order_side == "SELL": contrary = "BUY" loss = int(order_price + self.lost_price) # 同上、損切ライン profit = self.profit_price_decider(order_side, order_price) data = {'execution_side': contrary, 'loss_line': loss, 'profit_line': profit} return data def market_order_maker(self, order_size, order_side): market = self.api.sendchildorder(product_code=self.product, child_order_type='MARKET', side=order_side, size=order_size, time_in_force='IOC' ) print(market) status = self.api.gethealth(product_code=self.product)['status'] if status == "NORMAL": time.sleep(1.5) else: time.sleep(10)
class OrderMaker(Information): """ InformationからはAPIの情報だけをもらっておく 実際にオーダーを行うときは、Mainから指令を受ける """ def __init__(self): super().__init__() self.recorder = Recorder() def oco_order_maker(self, position_side, position_size, position_price): data = self.order_base_maker(position_side, position_price) uniq_id = time.time() ord1 = self.bitmex.create_limit_order( self.product, data['execution_side'], position_size, data['profit_line'], { 'contingencyType': 'OneCancelsTheOther', 'clOrdLinkID': uniq_id, }) ord2 = self.bitmex.create_order(self.product, 'StopLimit', data['execution_side'], position_size, params={ 'contingencyType': 'OneCancelsTheOther', 'stopPx': data['trigger'], 'orderQty': position_size, 'price': data['loss_line'], 'clOrdLinkID': uniq_id, }) print('profit order:', ord1) print('loss exec order', ord2) time.sleep(2) def cancel_parent_order(self, order_id): """ Nomen est omen :param order_id: :return: """ self.bitmex.cancel_order(order_id) print('order cancelled') time.sleep(2) def stop_order_maker(self, position_side, size): """ makes stop order to execute loss :param position_side: :param size: :return: """ side = 'buy' if position_side == 'sell' else 'sell' self.bitmex.create_market_order(self.product, side, size) print('stop market order made') def ifdoco_order_maker(self, first_side, size, order_price, balance, order_type): """ IFDOCOオーダーを発注する :param first_side: :param size: :param order_price: :param balance Current Balance :param order_type MARKET or LIMIT :return: """ order_price = order_price - self.order_margin if first_side == 'buy' else order_price + self.order_margin data = self.order_base_maker(first_side, order_price) opposite_side = 'sell' if first_side == 'buy' else 'buy' uniq_id = int(time.time()) if order_type == 'Market': ord1 = self.first_market_order_maker_for_ifdoco( first_side, size, uniq_id, order_price, balance) else: ord1 = self.first_limit_order_maker_for_ifdoco( first_side, size, order_price, uniq_id, balance) ord2 = self.bitmex.create_limit_order(self.product, opposite_side, size, data['profit_line'], { # profit order 'contingencyType': 'OneCancelsTheOther', 'clOrdLinkID': uniq_id, } ) ord3 = self.bitmex.create_order(self.product, 'StopLimit', opposite_side, size, params={ # loss order 'contingencyType': 'OneCancelsTheOther', 'stopPx': data['trigger'], 'orderQty': size, 'price': data['loss_line'], 'clOrdLinkID': uniq_id, } ) print('first order:', ord1) print('oco no.1 order:', ord2) print('oco no.2 order:', ord3) print("ordered: " + str(first_side).capitalize() + ' ' + str(size) + " USD at " + str(order_price)) self.recorder.balance_recorder(balance, order_price, uniq_id) time.sleep(3) def first_limit_order_maker_for_ifdoco(self, first_side, size, order_price, uniq_id, balance): """ IFDOCOの一段目を作るやつ。指値注文。 :return: """ order = self.bitmex.create_limit_order(self.product, first_side, size, order_price, { # first order 'contingencyType': 'OneTriggersTheOther', 'clOrdLinkID': uniq_id, }) self.recorder.balance_recorder(balance, order_price, uniq_id) return order def first_market_order_maker_for_ifdoco(self, first_side, size, uniq_id, order_price, balance): """ Makes first market order of IFDOCO order. :param first_side: :param size: :param balance: :param order_price: :param uniq_id: :return: """ market = self.bitmex.create_market_order(self.product, first_side, size) self.recorder.balance_recorder(balance, order_price, uniq_id) return market def order_base_maker(self, order_side, order_price): profit = None loss = None trigger = None opposite = None if order_side == "buy": opposite = "sell" profit = float(order_price + self.profit_price) loss = float(order_price - self.lost_price) trigger = loss + 5 elif order_side == "sell": opposite = "buy" profit = float(order_price - self.profit_price) loss = float(order_price + self.lost_price) trigger = loss - 5 data = { 'execution_side': opposite, 'loss_line': loss, 'profit_line': profit, 'trigger': trigger } return data