示例#1
0
 def __str__(self):
     return 'orderSide ' + (OrderSideMapper.getDbValue(self.orderSide) if self.orderSide else str(None)) \
     + ', orderType ' + (OrderTypeMapper.getDbValue(self.orderType) if self.orderType else str(None)) \
     + ', qty ' + str(self.qty) \
     + ', price ' + str(self.price) \
     + ', stopPrice ' + str(self.stopPrice) \
     + ', orderState ' + (OrderStateMapper.getDbValue(self.orderState) if self.orderState else str(None)) \
     + ', orderId ' + str(self.orderId)
示例#2
0
 def setFromEntity(self, orderEntity):
     self.orderSide = OrderSideMapper.getCretenValue(orderEntity.order_side)
     self.orderType = OrderTypeMapper.getCretenValue(orderEntity.order_type)
     self.qty = orderEntity.qty
     self.price = orderEntity.price
     self.stopPrice = orderEntity.stop_price
     self.orderState = OrderStateMapper.getCretenValue(
         orderEntity.order_state)
     self.orderId = orderEntity.order_id
     self.tradeId = orderEntity.trade_id
     self.intOrderRef = orderEntity.int_order_ref
     self.initTmstmp = orderEntity.init_tmstmp
     self.openTmstmp = orderEntity.open_tmstmp
     self.filledTmstmp = orderEntity.filled_tmstmp
示例#3
0
	def _calcTradePerf(self, trade):
		orders = TradeManager.getAllOrders(tradeId = trade.trade_id, orderState = OrderStateMapper.getDbValue(OrderState.FILLED))

		buyPrice = Decimal(0.0)
		sellPrice = Decimal(0.0)
		for order in orders:
			if order.order_side == OrderSideMapper.getDbValue(OrderSide.BUY):
				buyPrice += order.qty * Decimal(order.price)
			else:
				sellPrice += order.qty * Decimal(order.price)

		diff = sellPrice - buyPrice

		rules = self.marketRulesManager.getSymbolRules(trade.base_asset, trade.quote_asset)
		if diff < 0:
			color = Style.BRIGHT + Fore.LIGHTWHITE_EX + Back.RED
		else:
			color = Style.BRIGHT + Fore.LIGHTWHITE_EX + Back.GREEN
		self.log.info(color + 'Gain: ' + str(('{:.' + str(rules.quoteAssetPrecision) + 'f}').format(diff)) + Style.RESET_ALL)
示例#4
0
	def openOrder(self, trade, candle, orders):
		self.log.debug('Orders to be created: ' + str(len(orders)))

		# adjust quantity and price such that it meets market rules
		if self.shapeNewOrders:
			self._shapeOrders(candle.getBaseAsset(), candle.getQuoteAsset(), orders)

		# validate orders before sending them to the exchange
		if self.validateOrders:
			self._validateOrders(candle.getBaseAsset(), candle.getQuoteAsset(), orders)

		# make sure that limit orders are not executed immediately
		if self.preventImmediateLimitOrder:
			self._validateImmediateLimitOrder(candle, orders)

		for order in orders:
			try:
				dbOrder = Orders()
				dbOrder.trade_id = trade.trade_id
				dbOrder.qty = order.getQty()
				dbOrder.stop_price = order.getStopPrice()
				if order.getOrderType() == OrderType.MARKET:
					dbOrder.price = candle.getClose()
				else:
					dbOrder.price = order.getPrice()
				dbOrder.order_side = OrderSideMapper.getDbValue(order.getOrderSide())
				dbOrder.order_type = OrderTypeMapper.getDbValue(order.getOrderType())
				dbOrder.order_state = OrderStateMapper.getDbValue(OrderState.OPEN_PENDING_INT)
				dbOrder.init_tmstmp = candle.getCloseTime()

				self.storeOrder(dbOrder)

				# save the generated order id
				order.setOrderId(dbOrder.order_id)
				# save the order state (for print)
				order.setOrderState(OrderState.OPEN_PENDING_INT)

				self.log.info('Order: ' + str(order))
			except:
				self.log.error('Could not create order ' + str(order))
				raise
示例#5
0
	def processOrderUpdate(self, orderResponse):
		# update order in the database based on the update response
		order = TradeManager.getOrder(intOrderRef = orderResponse.getClientOrderId())
		order.order_state = OrderStateMapper.getDbValue(orderResponse.getOrderState())
		order.lst_upd_tmstmp = datetime.now()
		if orderResponse.getOrderState() == OrderState.OPENED:
			order.open_tmstmp = orderResponse.getOrderTmstmp()
		if orderResponse.getOrderState() == OrderState.FILLED:
			self.log.debug('Order ' + str(order.order_id) + ' FILLED.')
			order.filled_tmstmp = orderResponse.getOrderTmstmp()
		if orderResponse.getOrderState() == OrderState.CANCELED:
			self.log.debug('Order ' + str(order.order_id) + ' CANCELLED.')

		# update trade in the database based on the state of orders
		trade = TradeManager.getTrade(tradeId = order.trade_id)
		if trade.trade_type == TradeTypeMapper.getDbValue(TradeType.LONG):
			# open trade when first confirmed BUY is received
			if orderResponse.getOrderSide() == OrderSide.BUY and \
					orderResponse.getOrderState() == OrderState.OPENED and \
					trade.trade_state == TradeStateMapper.getDbValue(TradeState.OPEN_PENDING):
				trade.trade_state = TradeStateMapper.getDbValue(TradeState.OPENED)
				trade.open_tmstmp = orderResponse.getOrderTmstmp()

			# close trade when no pending order is left
			elif orderResponse.getOrderState() in [OrderState.CANCELED, OrderState.REJECTED, OrderState.EXPIRED]:
				openOrders = TradeManager.getPendOrders(trade.trade_id)
				if len(openOrders) == 0:
					self.closeTrade(trade, orderResponse.getOrderTmstmp())

			# handle closing of the trade based on the defined strategy
			elif orderResponse.getOrderState() == OrderState.FILLED:
				tradeCloseType = self.strategyManager.getStrategy(trade.strategy_exec_id).getTradeCloseType()
				TradeCloseStrategy.evalTradeClose(tradeCloseType, trade, orderResponse, self)
		else:
			raise Exception('Short trades not supported!')

		self.storeOrder(order)
		self._storeTrade(trade)
示例#6
0
	def sendOrders(self, cretenExecDetlId):
		ordersToBeSent = TradeManager.getAllOrders(cretenExecDetlId = cretenExecDetlId, orderState = OrderStateMapper.getDbValue([OrderState.OPEN_PENDING_INT, OrderState.CANCEL_PENDING_INT]))

		for dbOrder in ordersToBeSent:
			if dbOrder.order_state == OrderStateMapper.getDbValue(OrderState.OPEN_PENDING_INT):
				try:
					order = Order()
					order.setFromEntity(dbOrder)

					self.log.debug('Processing order [' + str(order) + ']')

					trade = TradeManager.getTrade(tradeId = dbOrder.trade_id)

					rules = self.marketRulesManager.getSymbolRules(trade.base_asset, trade.quote_asset)

					qty = ('{:.' + str(rules.baseAssetPrecision) + 'f}').format(order.getQty())
					price = ('{:.' + str(rules.quoteAssetPrecision) + 'f}').format(order.getPrice()) if order.getPrice() else None
					stopPrice = ('{:.' + str(rules.quoteAssetPrecision) + 'f}').format(order.getStopPrice()) if order.getStopPrice() else None
					self.log.debug('Values to be sent: qty [' + str(qty) + '], price [' + str(price) + '], stop price [' + str(stopPrice) + ']')

					response = self.exchangeClient.createOrder(order.getOrderSide(), order.getOrderType(),
					                                           trade.base_asset, trade.quote_asset, qty,
					                                            stopPrice, price, order.getIntOrderRef())

					self.log.debug('Response: ' + str(response.getRawData()))

					if not response.getOrderState() in [OrderState.OPENED, OrderState.FILLED]:
						raise Exception('Unexpected response received for order [' + str(order) + ']! Expected state [' + str([OrderState.OPENED, OrderState.FILLED]) + '], received [' + str(response.getOrderState()) + ']')

					if order.getOrderType() == OrderType.MARKET:
						dbOrder.price = response.getPrice()
					dbOrder.ext_order_ref = response.getExtOrderRef()
					dbOrder.order_state = OrderStateMapper.getDbValue(OrderState.OPEN_PENDING_EXT)
					self.storeOrder(dbOrder)
				except:
					self.log.error('Error while creating orders!')
					dbOrder.order_state = OrderStateMapper.getDbValue(OrderState.OPEN_FAILED)
					self.storeOrder(dbOrder)

					raise
			elif dbOrder.order_state == OrderStateMapper.getDbValue(OrderState.CANCEL_PENDING_INT):
				try:
					order = Order()
					order.setFromEntity(dbOrder)

					self.log.debug('Cancelling order [' + str(order) + ']')

					trade = TradeManager.getTrade(tradeId = dbOrder.trade_id)
					response = self.exchangeClient.cancelOrder(baseAsset = trade.base_asset, quoteAsset = trade.quote_asset, clientOrderId = order.getIntOrderRef())

					self.log.debug('Response: ' + str(response.getRawData()))

					if not response.getOrderState() in [OrderState.OPENED]:
						raise Exception('Unexpected response received for order [' + str(order) + ']! Expected state [' + str([OrderState.OPENED, OrderState.FILLED]) + '], received [' + str(response.getOrderState()) + ']')

					dbOrder.ext_order_ref = response.getExtOrderRef()
					dbOrder.order_state = OrderStateMapper.getDbValue(OrderState.CANCEL_PENDING_EXT)
					self.storeOrder(dbOrder)
				except:
					self.log.error('Error while cancelling orders!')
					dbOrder.order_state = OrderStateMapper.getDbValue(OrderState.CANCEL_FAILED)
					self.storeOrder(dbOrder)

					raise
			else:
				raise Exception('Creating orders for unsupporterd order state!')
示例#7
0
    def evalTradeClose(tradeCloseType, trade, orderResponse, orderManager):
        # ORDER DRIVEN closing strategy
        # close trade when:
        #   - first SELL order is filled, or
        #   - first STOP LOSS SELL order is filled
        if TradeCloseTypeMapper.getCretenValue(
                tradeCloseType) == TradeCloseType.ORDER_DRIVEN:
            if orderResponse.getOrderSide() == OrderSide.SELL and \
                 orderResponse.getOrderState() == OrderState.FILLED and \
                 orderResponse.getOrderType() in [OrderType.LIMIT, OrderType.MARKET, OrderType.TAKE_PROFIT_LIMIT, OrderType.TAKE_PROFIT_MARKET]:
                pendSellOrders = TradeManager.getAllOrders(
                    tradeId=trade.trade_id,
                    orderSide=OrderSideMapper.getDbValue(OrderSide.SELL),
                    orderType=OrderTypeMapper.getDbValue([
                        OrderType.LIMIT, OrderType.MARKET,
                        OrderType.TAKE_PROFIT_LIMIT,
                        OrderType.TAKE_PROFIT_MARKET
                    ]),
                    orderState=OrderStateMapper.getDbValue(
                        [OrderState.OPENED, OrderState.OPEN_PENDING_EXT]))
                if len(pendSellOrders) == 0:
                    openOrders = TradeManager.getPendOrders(trade.trade_id)
                    if len(openOrders) > 0:
                        TradeCloseStrategy.log.debug('Trade ' +
                                                     str(trade.trade_id) +
                                                     ' CLOSING.')
                        trade.trade_state = TradeStateMapper.getDbValue(
                            TradeState.CLOSE_PENDING)

                        for openOrder in openOrders:
                            openOrder.order_state = OrderStateMapper.getDbValue(
                                OrderState.CANCEL_PENDING_INT)
                            orderManager.storeOrder(openOrder)
                    else:
                        orderManager.closeTrade(trade,
                                                orderResponse.getOrderTmstmp())

            # start closing trade when first STOP_LOSS_SELL is filled
            elif orderResponse.getOrderSide() == OrderSide.SELL and \
                 orderResponse.getOrderState() == OrderState.FILLED and \
                 orderResponse.getOrderType() in [OrderType.STOP_LOSS_LIMIT, OrderType.STOP_LOSS_MARKET]:
                openOrders = TradeManager.getPendOrders(trade.trade_id)
                if len(openOrders) > 0:
                    TradeCloseStrategy.log.debug('Trade ' +
                                                 str(trade.trade_id) +
                                                 ' CLOSING.')
                    trade.trade_state = TradeStateMapper.getDbValue(
                        TradeState.CLOSE_PENDING)

                    for openOrder in openOrders:
                        openOrder.order_state = OrderStateMapper.getDbValue(
                            OrderState.CANCEL_PENDING_INT)
                        orderManager.storeOrder(openOrder)
                else:
                    orderManager.closeTrade(trade,
                                            orderResponse.getOrderTmstmp())

        # QUANTITY DRIVEN closing strategy
        # close trade when:
        #   - sum of bought and sold quantities nets
        elif TradeCloseTypeMapper.getCretenValue(
                tradeCloseType) == TradeCloseType.QUANTITY_DRIVEN:
            TradeCloseStrategy.log.debug(
                'Evaluate quantity driven trade close condition...')
            filledOrders = TradeManager.getAllOrders(
                tradeId=trade.trade_id,
                orderState=OrderStateMapper.getDbValue([OrderState.FILLED]))
            qty = Decimal(0)
            for o in filledOrders:
                TradeCloseStrategy.log.debug(
                    str(o.order_side) + ' ' + str(o.qty))
                if o.order_side == OrderSideMapper.getDbValue(OrderSide.BUY):
                    qty += o.qty
                else:
                    qty -= o.qty
            TradeCloseStrategy.log.debug('Remaining quantity [' +
                                         ('{:.' + str(10) + 'f}').format(qty) +
                                         ']')

            if qty == 0:
                openOrders = TradeManager.getPendOrders(trade.trade_id)
                if len(openOrders) > 0:
                    TradeCloseStrategy.log.debug('Trade ' +
                                                 str(trade.trade_id) +
                                                 ' CLOSING.')
                    trade.trade_state = TradeStateMapper.getDbValue(
                        TradeState.CLOSE_PENDING)

                    for openOrder in openOrders:
                        openOrder.order_state = OrderStateMapper.getDbValue(
                            OrderState.CANCEL_PENDING_INT)
                        orderManager.storeOrder(openOrder)
                else:
                    orderManager.closeTrade(trade,
                                            orderResponse.getOrderTmstmp())

        else:
            raise Exception("Unrecognized trade close type [" +
                            tradeCloseType + "]!")