Ejemplo n.º 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)
Ejemplo n.º 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()))
Ejemplo n.º 3
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
Ejemplo n.º 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)
Ejemplo n.º 5
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)
Ejemplo n.º 6
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
Ejemplo n.º 7
0
    def commitOrderExecution(self, order, dateTime, fillInfo):
        """Tries to commit an order execution. """

        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()))