class User: def __init__(self, test, key, secret, symbol, side): self.test = test self.symbol = symbol self.client = RestClient(test, key, secret, symbol) self.side = side self.take_profit_order = None self.limit_orders = [] self.last_entry_price = [] def time_to_close(self): close = False if self.take_profit_order is not None: o = self.client.get_orders(filter='{"orderID": "%s"}' % self.take_profit_order['orderID']) if o is not None and o['ordStatus'] == 'Filled': close = True return close def close(self): try: self.client.cancel_all() time.sleep(1) self.client.close_position() time.sleep(1) self.take_profit_order = None self.limit_orders = [] self.last_entry_price = [] except Exception as e: log.warning("Close warning: %s" % e) def manage_orders(self, position, orders): sign = 1 if self.side == 'Buy' else -1 for o in orders: if o['ordType'] == 'Limit' and o['side'] != self.side: self.take_profit_order = o tp_order = self.take_profit_order curr_open = False entry_price = None curr_qty = 0 if len(position) > 0 and position['isOpen'] is True: curr_open = True entry_price = position['avgEntryPrice'] curr_qty = abs(position['currentQty']) if curr_open is True and len(self.limit_orders) == 0: self.limit_orders.append((entry_price, curr_qty)) price = entry_price qty = curr_qty for i in fib_series[self.side]: price = int(price - i * data['step'] * price * sign) self.client.new_order(orderQty=qty, ordType="Limit", side=self.side, price=price) self.limit_orders.append((price, qty)) time.sleep(1) qty *= data['qtyFactor'] if curr_open is True: if len(self.last_entry_price) == 0: self.last_entry_price.append(int(entry_price)) if tp_order is None: if self.side == 'Buy': side = 'Sell' price = int(entry_price * (1 + data['step'])) else: side = 'Buy' price = int(entry_price * (1 - data['step'])) self.client.new_order(orderQty=curr_qty, ordType="Limit", side=side, price=price) else: if self.last_entry_price[-1] != int(entry_price): self.last_entry_price.append(int(entry_price)) if len(self.last_entry_price) > 1: tp_price = self.last_entry_price[-2] if (tp_order['orderQty'] != curr_qty) or (tp_order['price'] != tp_price): self.client.amend_order(orderID=tp_order['orderID'], orderQty=curr_qty, price=tp_price) time.sleep(5)
class User: def __init__(self, test, key, secret, symbol, side): self.test = test self.symbol = symbol self.client = RestClient(test, key, secret, symbol) self.take_profit_order = None self.stop_loss_order = None self.next_stop_order = None self.position = {} self.orders = [] self.side = side def time_to_close(self): close = False if self.take_profit_order is not None: o = self.client.get_orders(filter='{"orderID": "%s"}' % self.take_profit_order['orderID']) if o is not None and o['ordStatus'] == 'Filled': close = True return close def close(self): try: self.client.cancel_all() time.sleep(1) self.client.close_position() time.sleep(1) self.take_profit_order = None self.stop_loss_order = None self.next_stop_order = None except Exception as e: log.warning("Close warning: %s" % e) def update_orders(self): self.take_profit_order = None self.stop_loss_order = None self.next_stop_order = None for o in self.orders: if o['ordType'] == 'Limit': self.take_profit_order = o elif o['ordType'] == 'Stop': if o['side'] == self.side: self.next_stop_order = o else: self.stop_loss_order = o def manage_orders(self, opposite): sign = 1 if self.side == 'Buy' else -1 tp_order = self.take_profit_order opp_tp_order = opposite.take_profit_order curr_open = False opposite_open = False entry_price = None opp_entry_price = None curr_qty = 0 opp_qty = 0 if len(opposite.position) > 0 and opposite.position['isOpen'] is True: opposite_open = True opp_entry_price = opposite.position['avgEntryPrice'] opp_qty = abs(opposite.position['currentQty']) if len(self.position) > 0 and self.position['isOpen'] is True: curr_open = True entry_price = self.position['avgEntryPrice'] curr_qty = abs(self.position['currentQty']) if curr_open is True: # # Take profit order # if opposite_open is False: tp_price = int(entry_price + (sign * entry_price * data['profitPercent'] / 300)) else: tp_price = int(entry_price + (sign * entry_price * data['profitPercent'] / 100)) if tp_order is None: self.client.new_order(orderQty=curr_qty, ordType="Limit", side=opposite.side, price=tp_price) time.sleep(5) elif (tp_order['orderQty'] != curr_qty) or (tp_order['price'] != tp_price): self.client.amend_order(orderID=tp_order['orderID'], orderQty=curr_qty, price=tp_price) time.sleep(5) # # Stop loss order # stop_loss_order = self.stop_loss_order if stop_loss_order is None and opp_tp_order is not None: self.client.new_order(orderQty=curr_qty, ordType="Stop", execInst="LastPrice", side=opposite.side, stopPx=opp_tp_order['price']) time.sleep(5) elif stop_loss_order is not None and opp_tp_order is not None: if stop_loss_order['orderQty'] != curr_qty or stop_loss_order[ 'stopPx'] != opp_tp_order['price']: self.client.amend_order(orderID=stop_loss_order['orderID'], orderQty=curr_qty, stopPx=opp_tp_order['price']) time.sleep(5) # # Next stop order # next_order = self.next_stop_order if next_order is None and opposite_open is True and curr_qty < opp_qty and opposite.next_stop_order is None \ and opp_tp_order is not None: if opp_tp_order['ordStatus'] == 'Filled': return if entry_price is None: entry_price = int(opp_entry_price + (sign * opp_entry_price * data['swingPercent'] / 100)) qty = math.ceil(opp_qty * data['qtyFactor']) if tp_order is None: tp_price = int(entry_price + (sign * entry_price * data['profitPercent'] / 100)) else: tp_price = tp_order['price'] losing_sum = opp_qty * abs((1 / opp_entry_price) - (1 / tp_price)) gaining_sum = qty * abs((1 / entry_price) - (1 / tp_price)) if abs(gaining_sum - losing_sum) > tp_price: for n in range(1, 100000): gaining_sum = (opp_qty + n) * abs((1 / entry_price) - (1 / tp_price)) if gaining_sum - losing_sum > tp_price: break qty = opp_qty + n qty -= curr_qty if qty > 0: stop_price = int(entry_price) self.client.new_order(orderQty=qty, ordType="Stop", execInst="LastPrice", side=self.side, stopPx=stop_price) time.sleep(5)
class User: def __init__(self, test, key, secret, symbol, side): self.test = test self.symbol = symbol self.client = RestClient(test, key, secret, symbol) self.side = side self.take_profit_order = None self.order_menu = [] def time_to_close(self): close = False if self.take_profit_order is not None: # o = self.client.get_orders(filter='{"orderID": "%s"}' % self.take_profit_order['orderID']) if self.take_profit_order['ordStatus'] == 'Filled': close = True log.info("Side: %s, Close signal: %s" % (self.side, close)) log.info("Take profit order:\n%s" % self.take_profit_order) return close def close(self): try: self.client.cancel_all() time.sleep(1) self.client.close_position() time.sleep(1) self.take_profit_order = None self.order_menu = [] except Exception as e: log.warning("Close warning: %s" % e) def manage_orders(self, position, orders): stop_orders = [] for o in orders: if o['side'] == self.side: stop_orders.append(o) curr_open = False entry_price = None curr_qty = 0 if len(position) > 0 and position['isOpen'] is True: curr_open = True entry_price = position['avgEntryPrice'] curr_qty = abs(position['currentQty']) if curr_open is True and len(self.order_menu) == 0: self.order_menu = order_menu(entry_price, curr_qty, config['percent'], self.side, ratio=config['qtyFactor'], count=config['count']) log.info("Order menu:\n%s" % self.order_menu) for o in self.order_menu: price, qty = o order = self.client.new_order(orderQty=qty, ordType="Stop", side=self.side, stopPx=price, execInst='LastPrice') log.info("Stop order new:\n%s" % order) while order is None or order.get('ordStatus', None) != 'New': time.sleep(5) order = self.client.new_order(orderQty=qty, ordType="Stop", side=self.side, stopPx=price, execInst='LastPrice') log.info("Retrying Stop order new:\n%s" % order) time.sleep(1) if curr_qty > config['startQty'][self.side]: count = len(stop_orders) last_filled_order = self.order_menu[::-1][count] offset = int(abs(entry_price - last_filled_order[0]) / 2) side = 'Sell' if self.side == 'Buy' else 'Buy' if self.take_profit_order is None: self.take_profit_order = self.client.new_order(orderQty=curr_qty, ordType="Stop", side=side, pegPriceType='TrailingStopPeg', pegOffsetValue=offset) return else: response, order = self.client.get_orders(filter='{"orderID": "%s"}' % self.take_profit_order['orderID']) if response.status_code == 200 and order is None: self.take_profit_order = None elif response.status_code != 200: pass else: self.take_profit_order = order log.info("Take profit order:\n%s" % self.take_profit_order) tp_order = self.take_profit_order if tp_order is not None and \ (tp_order['orderQty'] != curr_qty) or (int(tp_order['pegOffsetValue']) != offset): self.client.amend_order(orderID=tp_order['orderID'], orderQty=curr_qty, pegOffsetValue=offset) time.sleep(5)