Example #1
0
    def commitOrderExecution(self, order, dateTime, fillInfo):
        if order.getId() is not None:
            self.__logger.debug('commitOrderExecution, order[%d] = %s' %
                                (order.getId(), str(order)))
        price = fillInfo.getPrice()
        quantity = fillInfo.getQuantity()

        if order.isBuy():
            cost = price * quantity * -1
            assert (cost < 0)
            sharesDelta = quantity
        elif order.isSell():
            cost = price * quantity
            assert (cost > 0)
            sharesDelta = quantity * -1
        else:  # Unknown action
            assert (False)

        commission = self.getCommission().calculate(order, price, quantity)
        cost -= commission
        resultingCash = self.getCash() + cost

        # Check that we're ok on cash after the commission.
        if resultingCash >= 0 or self.__allowNegativeCash:

            # Update the order before updating internal state since addExecutionInfo may raise.
            # addExecutionInfo should switch the order state.
            orderExecutionInfo = broker.OrderExecutionInfo(
                price, quantity, commission, dateTime)
            order.addExecutionInfo(orderExecutionInfo)

            # Commit the order execution.
            self.__cash = resultingCash
            updatedShares = order.getInstrumentTraits().roundQuantity(
                self.getShares(order.getInstrument()) + sharesDelta)
            if updatedShares == 0:
                del self.__shares[order.getInstrument()]
            else:
                self.__shares[order.getInstrument()] = updatedShares

            # Let the strategy know that the order was filled.
            self.__fillStrategy.onOrderFilled(self, order)

            # Notify the order update
            if order.isFilled():
                self._unregisterOrder(order)
                self.notifyOrderEvent(
                    broker.OrderEvent(order, broker.OrderEvent.Type.FILLED,
                                      orderExecutionInfo))
            elif order.isPartiallyFilled():
                self.notifyOrderEvent(
                    broker.OrderEvent(order,
                                      broker.OrderEvent.Type.PARTIALLY_FILLED,
                                      orderExecutionInfo))
            else:
                assert (False)
        else:
            self.__logger.debug(
                'Not enough cash to fill %s order [%s] for %s share/s' %
                (order.getInstrument(), order.getId(), order.getRemaining()))
    def cancelOrder(self, order):
        activeOrder = self.__activeOrders.get(order.getId())
        if activeOrder is None:
            common.logger.error("The order is not active anymore")
            return
        if activeOrder.isFilled():
            common.logger.error(
                "Can't cancel order that has already been filled")
            return
        if 'temp' in activeOrder.getId():
            self._unregisterOrder(order)
            order.switchState(broker.Order.State.CANCELED)
            self.notifyOrderEvent(
                broker.OrderEvent(order, broker.OrderEvent.Type.CANCELED,
                                  "temp order"))
            return

        for _ in range(5):
            try:
                canceled_order = self.__httpClient.Order.Order_cancel(
                    orderID=order.getId()).result()[0][0]

                if canceled_order['ordStatus'] == 'Canceled':
                    try:
                        self._unregisterOrder(order)
                        order.switchState(broker.Order.State.CANCELED)
                        self.notifyOrderEvent(
                            broker.OrderEvent(order,
                                              broker.OrderEvent.Type.CANCELED,
                                              "User requested cancellation"))
                        common.logger.info('order canceled: ' + order.getId())
                    except Exception as e:
                        common.logger.error('cancelOrder1: ' + str(e))
                else:
                    self.onExecution(Execution({"data": canceled_order}))
                break
            except Exception as e:
                common.logger.error('cancelOrder: ' + str(e))
                if 'Too Many'.lower() in str(
                        e).lower() or 'Service Unavailable'.lower() in str(
                            e).lower() or 'expired'.lower() in str(e).lower():
                    time.sleep(4)
                elif 'bad'.lower() in str(
                        e).lower() or 'Invalid'.lower() in str(e).lower():
                    break
                elif 'not found'.lower() in str(e).lower():
                    self._unregisterOrder(order)
                    order.switchState(broker.Order.State.CANCELED)
                    self.notifyOrderEvent(
                        broker.OrderEvent(order,
                                          broker.OrderEvent.Type.CANCELED,
                                          "not found cancellation"))
                    break
Example #3
0
    def commitOrderExecution(self, order, dateTime, fillInfo):
        price = fillInfo.getPrice()
        quantity = fillInfo.getQuantity()

        if order.isBuy():
            cost = price * quantity * -1
            assert (cost < 0)
            sharesDelta = quantity
        elif order.isSell():
            cost = price * quantity
            assert (cost > 0)
            sharesDelta = quantity * -1
        else:  # Unknown action
            assert (False)

        commission = self.getCommission().calculate(order, price, quantity)
        cost -= commission
        resultingCash = self.getCash() + cost

        # Check that we're ok on cash after the commission.
        if resultingCash >= 0 or self.__allowNegativeCash:

            # Update the order before updating internal state since addExecutionInfo may raise.
            # addExecutionInfo should switch the order state.
            orderExecutionInfo = broker.OrderExecutionInfo(
                price, quantity, commission, dateTime)
            order.addExecutionInfo(orderExecutionInfo)

            # Commit the order execution.
            self.__cash = resultingCash
            self.__shares[order.getInstrument()] = self.getShares(
                order.getInstrument()) + sharesDelta

            # Let the strategy know that the order was filled.
            self.__fillStrategy.onOrderFilled(order)

            # Notify the order update
            if order.isFilled():
                del self.__activeOrders[order.getId()]
                self.notifyOrderEvent(
                    broker.OrderEvent(order, broker.OrderEvent.Type.FILLED,
                                      orderExecutionInfo))
            elif order.isPartiallyFilled():
                self.notifyOrderEvent(
                    broker.OrderEvent(order,
                                      broker.OrderEvent.Type.PARTIALLY_FILLED,
                                      orderExecutionInfo))
            else:
                assert (False)
        else:
            self.__logger.debug("Not enough money to fill order %s" % (order))
Example #4
0
    def __orderStatusHandler(self, msg):
        order = self.__activeOrders.get(msg.orderId)
        if order == None:
            return

        #watch out for dupes - don't submit state changes or events if they were already submitted

        eventType = None
        if msg.status == 'Filled' and order.getState(
        ) != broker.Order.State.FILLED:
            eventType = broker.OrderEvent.Type.FILLED
            self._unregisterOrder(order)
            #order.setState(broker.Order.State.FILLED)
        if msg.status == 'Submitted' and msg.filled > 0:
            eventType = broker.OrderEvent.Type.PARTIALLY_FILLED
            #may already be partially filled
            #if order.getState() != broker.Order.State.PARTIALLY_FILLED:
            #    order.setState(broker.Order.State.PARTIALLY_FILLED)
        if msg.status == 'Cancelled' and order.getState(
        ) != broker.Order.State.CANCELED:
            #self._unregisterOrder(order)
            eventType = broker.OrderEvent.Type.CANCELED
            #order.setState(broker.Order.State.CANCELED)
            self._unregisterOrder(order)
            order.switchState(broker.Order.State.CANCELED)

            # Notify that the order was canceled.
            self.notifyOrderEvent(
                broker.OrderEvent(order, broker.OrderEvent.Type.CANCELED,
                                  "User requested cancellation"))

        orderExecutionInfo = None
        if eventType == broker.OrderEvent.Type.FILLED or eventType == broker.OrderEvent.Type.PARTIALLY_FILLED:
            orderExecutionInfo = broker.OrderExecutionInfo(
                msg.avgFillPrice, abs(msg.filled), 0, datetime.datetime.now())

            order.addExecutionInfo(orderExecutionInfo)

            if order.isFilled():
                #self._unregisterOrder(order)
                self.notifyOrderEvent(
                    broker.OrderEvent(order, broker.OrderEvent.Type.FILLED,
                                      orderExecutionInfo))
            elif order.isPartiallyFilled():
                self.notifyOrderEvent(
                    broker.OrderEvent(order,
                                      broker.OrderEvent.Type.PARTIALLY_FILLED,
                                      orderExecutionInfo))
Example #5
0
    def _onUserTrades(self, trades):
        for trade in trades:
            order = self.__activeOrders.get(trade.getOrderId())
            if order is not None:
                fee = trade.getFee()
                fillPrice = trade.getBTCUSD()
                btcAmount = trade.getBTC()
                dateTime = trade.getDateTime()

                # Update cash and shares.
                self.refreshAccountBalance()
                # Update the order.
                orderExecutionInfo = broker.OrderExecutionInfo(
                    fillPrice, abs(btcAmount), fee, dateTime)
                order.addExecutionInfo(orderExecutionInfo)
                if not order.isActive():
                    self._unregisterOrder(order)
                # Notify that the order was updated.
                if order.isFilled():
                    eventType = broker.OrderEvent.Type.FILLED
                else:
                    eventType = broker.OrderEvent.Type.PARTIALLY_FILLED
                self.notifyOrderEvent(
                    broker.OrderEvent(order, eventType, orderExecutionInfo))
            else:
                common.logger.info(
                    "Trade %d refered to order %d that is not active" %
                    (trade.getId(), trade.getOrderId()))
Example #6
0
 def dispatch(self):
     # Switch orders from SUBMITTED to ACCEPTED.
     ordersToProcess = self.__activeOrders.values()
     for order in ordersToProcess:
         if order.isSubmitted():
             order.switchState(broker.Order.State.ACCEPTED)
             self.notifyOrderEvent(broker.OrderEvent(order, broker.OrderEvent.Type.ACCEPTED, None))
Example #7
0
 def _onUserTrades(self, msg_dict):
     order = self.__activeOrders.get(msg_dict['order_id']) 
     if order is not None:
         commision = self.getInstrumentTraits().getCommission(msg_dict['instrument_id'])
         fill_price = msg_dict['price']
         volume = msg_dict['volume']
         datetime = msg_dict['datetime']
         
         # Update the order.
         orderExecutionInfo = broker.OrderExecutionInfo(fill_price, abs(volume), commision, datetime)
         order.addExecutionInfo(orderExecutionInfo)
         if not order.isActive():
             self._unregisterOrder(order)
         # Notify that the order was updated.
         if order.isFilled():
             eventType = broker.OrderEvent.Type.FILLED
         else:
             eventType = broker.OrderEvent.Type.PARTIALLY_FILLED
         self.notifyOrderEvent(broker.OrderEvent(order, eventType, orderExecutionInfo))
         
         self.__mongo.tradedb.trades.insert_one(msg_dict)
         
         # Update cash and shares.
         self.__api.qryAccount()
     else:
         logger.info("Trade %d refered to order %d that is not active" % (int(msg_dict['trade_id']), int(msg_dict['order_id'])))
Example #8
0
    def __onBarsImpl(self, order, bars):
        if order.getId() is not None:
            self.__logger.debug('__onBarsImpl, order[%d] = %s' %
                                (order.getId(), str(order)))
        # IF WE'RE DEALING WITH MULTIPLE INSTRUMENTS WE SKIP ORDER PROCESSING IF THERE IS NO BAR FOR THE ORDER'S
        # INSTRUMENT TO GET THE SAME BEHAVIOUR AS IF WERE BE PROCESSING ONLY ONE INSTRUMENT.
        bar_ = bars.getBar(order.getInstrument())
        if bar_ is not None:
            # Switch from SUBMITTED -> ACCEPTED
            if order.isSubmitted():
                order.setAcceptedDateTime(bar_.getDateTime())
                if order.getId() is not None:
                    self.__logger.debug(
                        '__onBarsImpl, order[%d] = %s, switchState from SUBMITTED -> ACCEPTED'
                        % (order.getId(), str(order)))
                order.switchState(broker.Order.State.ACCEPTED)
                self.notifyOrderEvent(
                    broker.OrderEvent(order, broker.OrderEvent.Type.ACCEPTED,
                                      None))

            if order.isActive():
                # This may trigger orders to be added/removed from __activeOrders.
                self.__processOrder(order, bar_)
            else:
                # If an order is not active it should be because it was canceled in this same loop and it should
                # have been removed.
                assert (order.isCanceled())
                assert (order not in self.__activeOrders)
Example #9
0
 def submitOrder(self, order):
     if order.isInitial():
         order.setSubmitted(self._getNextOrderId(), self._getCurrentDateTime())
         self._registerOrder(order)
         # Switch from INITIAL -> SUBMITTED
         order.switchState(broker.Order.State.SUBMITTED)
         self.notifyOrderEvent(broker.OrderEvent(order, broker.OrderEvent.Type.SUBMITTED, None))
     else:
         raise Exception("The order was already processed")
Example #10
0
    def commitOrderExecution(self, order, dateTime, fillInfo):
        instrument = order.getInstrument()
        instrumentSymbol = instrument.symbol
        priceCurrency = instrument.priceCurrency

        # Calculate deltas.
        price = fillInfo.getPrice()
        quantity = fillInfo.getQuantity()
        if order.isBuy():
            cost = price * quantity * -1
            assert (cost < 0)
            baseDelta = quantity
        else:
            assert order.isSell()
            cost = price * quantity
            assert (cost > 0)
            baseDelta = quantity * -1

        # Update the cost with the commission.
        commission = self.getCommission().calculate(order, price, quantity)
        cost -= commission

        baseBalanceFinal = self.getInstrumentTraits().round(
            self.getBalance(instrumentSymbol) + baseDelta, instrumentSymbol)
        quoteBalanceFinal = self.getInstrumentTraits().round(
            self.getBalance(priceCurrency) + cost, priceCurrency)

        if quoteBalanceFinal >= 0:
            # Update the order before updating internal state since addExecutionInfo may raise.
            # addExecutionInfo should switch the order state.
            orderExecutionInfo = broker.OrderExecutionInfo(
                price, quantity, commission, dateTime)
            order.addExecutionInfo(orderExecutionInfo)

            # Commit the order execution.
            self._balances[priceCurrency] = quoteBalanceFinal
            self._balances[instrumentSymbol] = baseBalanceFinal

            # Let the strategy know that the order was filled.
            self._fillStrategy.onOrderFilled(self, order)

            # Notify the order update
            if order.isFilled():
                self._unregisterOrder(order)
                eventType = broker.OrderEvent.Type.FILLED
            else:
                assert order.isPartiallyFilled(
                ), "Order was neither filled completely nor partially"
                eventType = broker.OrderEvent.Type.PARTIALLY_FILLED
            self.notifyOrderEvent(
                broker.OrderEvent(order, eventType, orderExecutionInfo))
        else:
            action = "buy" if order.isBuy() else "sell"
            self._logger.debug("Not enough %s to %s %s %s [order %s]" %
                               (priceCurrency, action, order.getQuantity(),
                                instrumentSymbol, order.getId()))
Example #11
0
    def cancelOrder(self, order):
        activeOrder = self.__activeOrders.get(order.getId())
        if activeOrder is None:
            raise Exception("The order is not active anymore")
        if activeOrder.isFilled():
            raise Exception("Can't cancel order that has already been filled")

        del self.__activeOrders[activeOrder.getId()]
        activeOrder.switchState(broker.Order.State.CANCELED)
        self.notifyOrderEvent(broker.OrderEvent(activeOrder, broker.OrderEvent.Type.CANCELED, "User requested cancellation"))
Example #12
0
 def _onOrderAction(self, msg_dict):
     order = self.__activeOrders.get(msg_dict['order_id'])
     if msg_dict['action'] == 'canceled':
         self._unregisterOrder(order)
         order.switchState(broker.Order.State.CANCELED)
         
         # Notify that the order was canceled.
         self.notifyOrderEvent(broker.OrderEvent(order, broker.OrderEvent.Type.CANCELED, "User requested cancellation"))
         
         # Update cash and shares.
         self.__api.qryAccount()
Example #13
0
    def __postProcessOrder(self, order, bar_):
        # For non-GTC orders and daily (or greater) bars we need to check if orders should expire right now
        # before waiting for the next bar.
        if not order.getGoodTillCanceled():
            expired = False
            if self.__barFeed.getFrequency() >= pyalgotrade.bar.Frequency.DAY:
                expired = bar_.getDateTime().date() >= order.getAcceptedDateTime().date()

            # Cancel the order if it will expire in the next bar.
            if expired:
                self._unregisterOrder(order)
                order.switchState(broker.Order.State.CANCELED)
                self.notifyOrderEvent(broker.OrderEvent(order, broker.OrderEvent.Type.CANCELED, "Expired"))
Example #14
0
    def cancelOrder(self, order):
        activeOrder = self.__activeOrders.get(order.getId())
        if activeOrder is None:
            common.logger.error("The order is not active anymore")
            return
        if activeOrder.isFilled():
            common.logger.error(
                "Can't cancel order that has already been filled")
            return

        self._unregisterOrder(activeOrder)
        activeOrder.switchState(broker.Order.State.CANCELED)
        self.notifyOrderEvent(
            broker.OrderEvent(activeOrder, broker.OrderEvent.Type.CANCELED,
                              "User requested cancellation"))
Example #15
0
    def __preProcessOrder(self, order, bar_):
        ret = True

        # For non-GTC orders we need to check if the order has expired.
        if not order.getGoodTillCanceled():
            expired = bar_.getDateTime().date() > order.getAcceptedDateTime().date()

            # Cancel the order if it is expired.
            if expired:
                ret = False
                self._unregisterOrder(order)
                order.switchState(broker.Order.State.CANCELED)
                self.notifyOrderEvent(broker.OrderEvent(order, broker.OrderEvent.Type.CANCELED, "Expired"))

        return ret
Example #16
0
    def cancelOrder(self, order):
        activeOrder = self.__activeOrders.get(order.getId())
        if activeOrder is None:
            raise Exception("The order is not active anymore")
        if activeOrder.isFilled():
            raise Exception("Can't cancel order that has already been filled")

        self.__httpClient.cancelOrder(order.getId())
        self._unregisterOrder(order)
        order.switchState(broker.Order.State.CANCELED)

        # Update cash and shares.
        self.refreshAccountBalance()

        # Notify that the order was canceled.
        self.notifyOrderEvent(broker.OrderEvent(order, broker.OrderEvent.Type.CANCELED, "User requested cancellation"))
Example #17
0
    def _onUserTrades(self, trades):
        ret = False
        for trade in trades:
            order = self.__activeOrders.get(trade.getOrderId())
            if order is not None:
                filled = order.getFilled()
                avgPrice = order.getAvgFillPrice()
                newQuantity = trade.getBTC() - filled
                if order.isBuy():
                    newQuantity -= trade.getFee()
                newQuantity = liveUtils.CoinRound(newQuantity)
                if newQuantity == 0:
                    continue
                ret = True
                newFillPrice = trade.getBTCUSD()
                if avgPrice is not None:
                    newFillPrice = (newFillPrice * trade.getBTC() -
                                    order.getFilled() * avgPrice) / newQuantity
                newFee = trade.getFee() - order.getCommissions()
                newDateTime = trade.getDateTime()

                logger.info('newTrade: price:%f btc:%f fee:%s time:%s' %
                            (newFillPrice, newQuantity, newFee, newDateTime))

                # Update cash and shares.
                self.refreshAccountBalance()
                # Update the order.
                orderExecutionInfo = broker.OrderExecutionInfo(
                    newFillPrice, abs(newQuantity), newFee, newDateTime)
                order.addExecutionInfo(orderExecutionInfo)
                if trade.isFilled():
                    order.setState(order.State.FILLED)
                #                order.updateExecutionInfo(orderExecutionInfo)
                if not order.isActive():
                    self._unregisterOrder(order)
                # Notify that the order was updated.
                if order.isFilled():
                    eventType = broker.OrderEvent.Type.FILLED
                else:
                    eventType = broker.OrderEvent.Type.PARTIALLY_FILLED
                self.notifyOrderEvent(
                    broker.OrderEvent(order, eventType, orderExecutionInfo))
            else:
                logger.info("Trade refered to order %d that is not active" %
                            (trade.getOrderId()))
        return ret
Example #18
0
    def cancelOrder(self, order):
        self.__logger.debug('cancelOrder, order = %s' % (str(order)))
        activeOrder = self.__activeOrders.get(order.getId())
        if activeOrder is None:
            raise Exception("The order is not active anymore")
        if activeOrder.isFilled():
            raise Exception("Can't cancel order that has already been filled")

        self._unregisterOrder(activeOrder)
        if order.getId() is not None:
            self.__logger.debug(
                'cancelOrder, order[%d] = %s, switchState to CANCELED' %
                (order.getId(), str(order)))
        activeOrder.switchState(broker.Order.State.CANCELED)
        self.notifyOrderEvent(
            broker.OrderEvent(activeOrder, broker.OrderEvent.Type.CANCELED,
                              "User requested cancellation"))
Example #19
0
 def dispatch(self):
     # Switch orders from SUBMITTED to ACCEPTED.
     ordersToProcess = self.__activeOrders.values()
     for order in ordersToProcess:
         if order.isSubmitted():
             order.switchState(broker.Order.State.ACCEPTED)
             self.notifyOrderEvent(broker.OrderEvent(order, broker.OrderEvent.Type.ACCEPTED, None))
     
     # Dispatch events from the trade monitor.
     while self.__msg_queue.qsize() > 0:
         msg = self.__msg_queue.get(True, LiveBroker.QUEUE_TIMEOUT)
         
         if msg['event_type'] == CTPTdApi.EventType.ON_TRADE:
             self._onUserTrades(msg)
         elif msg['event_type'] == CTPTdApi.EventType.ON_QUERY_ACCOUNT:
             self.refreshAccountBalance(msg)
         elif msg['event_type'] == CTPTdApi.EventType.ON_ORDER_ACTION:
             self._onOrderAction(msg)
Example #20
0
 def submitOrder(self, order):
     if order.isInitial():
         order.setSubmitted(self._getNextOrderId(),
                            self._getCurrentDateTime())
         self._registerOrder(order)
         # Switch from INITIAL -> SUBMITTED
         if order.getId() is not None:
             self.__logger.debug(
                 'submitOrder, order[%d] = %s, switchState from INITIAL -> SUBMITTED'
                 % (order.getId(), str(order)))
         order.switchState(broker.Order.State.SUBMITTED)
         self.notifyOrderEvent(
             broker.OrderEvent(order, broker.OrderEvent.Type.SUBMITTED,
                               None))
         self.__logger.debug('submitOrder -> processOrders')
         self.processOrders()
     else:
         raise Exception("The order was already processed")
Example #21
0
    def dispatch(self):
        # Switch orders from SUBMITTED to ACCEPTED.
        ordersToProcess = self.__activeOrders.values()
        for order in ordersToProcess:
            if order.isSubmitted():
                order.switchState(broker.Order.State.ACCEPTED)
                self.notifyOrderEvent(broker.OrderEvent(order, broker.OrderEvent.Type.ACCEPTED, None))

        # Dispatch events from the trade monitor.
        try:
            eventType, eventData = self.__tradeMonitor.getQueue().get(True, LiveBroker.QUEUE_TIMEOUT)

            if eventType == TradeMonitor.ON_USER_TRADE:
                self._onUserTrades(eventData)
            else:
                common.logger.error("Invalid event received to dispatch: %s - %s" % (eventType, eventData))
        except Queue.Empty:
            pass
Example #22
0
    def _order_filled(self, trade, order):
        fee = trade.get_fee()
        # 获取成交价
        fillPrice = float(trade.get_avg_price())
        # 获取成交量
        btcAmount = float(trade.get_amount_original())
        # 获取交易时间
        dateTime = trade.get_datetime()

        exe_info = broker.OrderExecutionInfo(fillPrice, abs(btcAmount), fee,
                                             dateTime)
        order.addExecutionInfo(exe_info)
        if order.isFilled():
            eventType = broker.OrderEvent.Type.FILLED
        else:
            eventType = broker.OrderEvent.Type.PARTIALLY_FILLED
        if not order.isActive():
            self._unregisterOrder(order)
        self.notifyOrderEvent(broker.OrderEvent(order, eventType, exe_info))
Example #23
0
    def __onBars(self, dateTime, bars):
        # THE ORDER HERE IS VERY IMPORTANT

        # 1: Let analyzers process bars.
        self.__notifyAnalyzers(lambda s: s.beforeOnBars(self, bars))

        # 2: Let the strategy process current bars and submit orders.
        self.onBars(bars)

        # 3: Notify that the bars were processed.
        self.__barsProcessedEvent.emit(self, bars)

        try:
            for key, position in self.getOrderToPosition().copy().items():
                for order in position.getActiveOrders().copy():
                    if order.isCanceled():
                        self.getBroker().notifyOrderEvent(
                            broker.OrderEvent(order, broker.OrderEvent.Type.CANCELED, "failed to submit"))
        except Exception as e:
            self.info('_onbars: ' + str(e))
Example #24
0
    def __preProcessOrder(self, order, bar_):
        if order.getId() is not None:
            self.__logger.debug('__preProcessOrder, order[%d] = %s' %
                                (order.getId(), str(order)))
        ret = True

        # For non-GTC orders we need to check if the order has expired.
        if not order.getGoodTillCanceled():
            expired = bar_.getDateTime().date() > order.getAcceptedDateTime(
            ).date()

            # Cancel the order if it is expired.
            if expired:
                ret = False
                self._unregisterOrder(order)
                self.__logger.debug(
                    '__preProcessOrder, order[%d] = %s, switchState to CANCELED'
                    % (order.getId(), str(order)))
                order.switchState(broker.Order.State.CANCELED)
                self.notifyOrderEvent(
                    broker.OrderEvent(order, broker.OrderEvent.Type.CANCELED,
                                      "Expired"))

        return ret
    def onExecution(self, data):
        order = self.__activeOrders.get(data.getId())
        if order is not None:
            self.onOrder(data)
            if order.isSubmitted():
                try:
                    order.switchState(broker.Order.State.ACCEPTED)
                    self.notifyOrderEvent(
                        broker.OrderEvent(order,
                                          broker.OrderEvent.Type.ACCEPTED,
                                          None))
                except Exception as e:
                    common.logger.info('onExecution accept: ' + str(e))

            fee = 0
            fillPrice = data.getPrice()
            btcAmount = data.getFilledQty()
            dateTime = data.getDateTime()
            old_state = order.getState()

            # Update the order.
            if btcAmount > 0 and (
                    order.getExecutionInfo() is None or order.getExecutionInfo().getDateTime() != dateTime) and 'Trade' in \
                    data.getData().get('execType', 'Trade'):
                self.updateCash(order, fillPrice, btcAmount)
                orderExecutionInfo = broker.OrderExecutionInfo(
                    fillPrice, btcAmount, fee, dateTime)
                order.addExecutionInfo(orderExecutionInfo)

            if data.getData()['ordStatus'] == 'New' and data.getFilledQty(
            ) == 0:
                new_state = broker.Order.State.ACCEPTED
                orderExecutionInfo = "New"
            elif order.isFilled():
                new_state = broker.Order.State.FILLED
            elif order.getFilled() != 0:
                new_state = broker.Order.State.PARTIALLY_FILLED
            elif data.getData()['ordStatus'] in ['Canceled', 'Rejected'
                                                 ] and order.getFilled() == 0:
                new_state = broker.Order.State.CANCELED
                orderExecutionInfo = data.getData()['text']
            else:
                common.logger.error('onExecution', data.getData()['ordStatus'])

            try:
                if new_state != order.getState():
                    order.switchState(new_state)
            except Exception as e:
                common.logger.info('onExecution switchstate: ' + str(e))
            if old_state != order.getState():
                try:
                    self.notifyOrderEvent(
                        broker.OrderEvent(order, new_state - 1,
                                          orderExecutionInfo))
                except Exception as e:
                    common.logger.error('onExecution notifyOrderEvent: ' +
                                        str(e))
                    self.notifyOrderEvent(
                        broker.OrderEvent(order, new_state - 1,
                                          orderExecutionInfo))
            if not order.isActive() and order.getId() in self.__activeOrders:
                self._unregisterOrder(order)
Example #26
0
 def _order_cancelled(self, order):
     order.switchState(broker.Order.State.CANCELED)
     self._unregisterOrder(order)
     self.notifyOrderEvent(
         broker.OrderEvent(order, broker.OrderEvent.Type.CANCELED, '挂单取消'))