Beispiel #1
0
    def testPartialFill(self):
        order = self.__buildAcceptedLimitOrder(broker.Order.Action.BUY, 2, 11)
        self.assertEqual(order.getRemaining(), 11)
        self.assertEqual(order.getFilled(), 0)
        self.assertEqual(order.getAvgFillPrice(), None)
        self.assertEqual(order.getExecutionInfo(), None)

        order.addExecutionInfo(broker.OrderExecutionInfo(1, 8, 0, datetime.datetime.now()))
        self.assertTrue(order.isPartiallyFilled())
        self.assertEqual(order.getRemaining(), 3)
        self.assertEqual(order.getFilled(), 8)
        self.assertEqual(order.getAvgFillPrice(), 1)
        self.assertEqual(order.getExecutionInfo().getQuantity(), 8)
        self.assertEqual(order.getExecutionInfo().getPrice(), 1)

        order.addExecutionInfo(broker.OrderExecutionInfo(1.5, 1, 0, datetime.datetime.now()))
        self.assertTrue(order.isPartiallyFilled())
        self.assertEqual(order.getRemaining(), 2)
        self.assertEqual(order.getFilled(), 9)
        self.assertEqual(round(order.getAvgFillPrice(), 4), round(1.055555556, 4))
        self.assertEqual(order.getExecutionInfo().getQuantity(), 1)
        self.assertEqual(order.getExecutionInfo().getPrice(), 1.5)

        order.addExecutionInfo(broker.OrderExecutionInfo(1.123, 2, 0, datetime.datetime.now()))
        self.assertTrue(order.isFilled())
        self.assertEqual(order.getRemaining(), 0)
        self.assertEqual(order.getFilled(), 11)
        self.assertEqual(round(order.getAvgFillPrice(), 4), round(1.067818182, 4))
        self.assertEqual(order.getExecutionInfo().getQuantity(), 2)
        self.assertEqual(order.getExecutionInfo().getPrice(), 1.123)
Beispiel #2
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()))
Beispiel #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
            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()))
Beispiel #4
0
 def testCompleteFillInvalidSize(self):
     order = self.__buildAcceptedLimitOrder(broker.Order.Action.BUY, 1, 1)
     with self.assertRaises(Exception):
         order.addExecutionInfo(broker.OrderExecutionInfo(1, 1.001, 0, datetime.datetime.now()))
     self.assertTrue(order.isAccepted())
     self.assertEqual(order.getRemaining(), 1)
     self.assertEqual(order.getFilled(), 0)
     self.assertEqual(order.getAvgFillPrice(), None)
     self.assertEqual(order.getExecutionInfo(), None)
Beispiel #5
0
 def __getFilledMarketOrder(self, quantity, price):
     order = backtesting.MarketOrder(
         broker.Order.Action.BUY,
         BaseTestCase.TestInstrument,
         quantity,
         False,
         broker.IntegerTraits()
     )
     order.setState(broker.Order.State.ACCEPTED)
     order.addExecutionInfo(broker.OrderExecutionInfo(price, quantity, 0, datetime.datetime.now()))
     return order
Beispiel #6
0
    def testCompleteFill(self):
        order = self.__buildAcceptedLimitOrder(broker.Order.Action.BUY, 1, 1)
        self.assertEqual(order.getRemaining(), 1)
        self.assertEqual(order.getFilled(), 0)
        self.assertEqual(order.getAvgFillPrice(), None)
        self.assertEqual(order.getExecutionInfo(), None)

        order.addExecutionInfo(broker.OrderExecutionInfo(0.9, 1, 0, datetime.datetime.now()))
        self.assertTrue(order.isFilled())
        self.assertEqual(order.getRemaining(), 0)
        self.assertEqual(order.getFilled(), 1)
        self.assertEqual(order.getAvgFillPrice(), 0.9)
Beispiel #7
0
    def _onUserTrades(self, msg_dict):
        print "_onUserTrades"
        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))

            print msg_dict
            self.__TradeDetailDB.update(
                {'strategy_id': find_strategy(get_task_id())},
                msg_dict,
                upsert=True)

            # Update cash and shares.
            self.__api.qryAccount()

            # Update position.
            self.__api.qryPosition()

        else:
            logger.info("Trade %d refered to order %d that is not active" %
                        (int(msg_dict['trade_id']), int(msg_dict['order_id'])))