Пример #1
0
    def onBars(self, broker_, bars):
        self.__volumeUsed = {}
        self.__volumeLeft = {}

        # Reset volumes.
        for bar in bars.getBars():
            instrument = bar.getInstrument()

            self.__volumeUsed[instrument] = 0.0

            if self.__volumeLimit is not None:
                # For TRADE bars we can use all the volume available.
                if bar.getFrequency() == pyalgotrade.bar.Frequency.TRADE:
                    volumeLeft = bar.getVolume()
                else:
                    volumeLeft = self.__instrumentTraits.round(
                        bar.getVolume() * self.__volumeLimit,
                        bar.getInstrument().symbol,
                        roundDown=True)
                self.__volumeLeft[instrument] = volumeLeft
Пример #2
0
    def fillStopOrder(self, broker_, order, bar):
        assert bar.getInstrument() == order.getInstrument()

        ret = None

        # First check if the stop price was hit so the market order becomes active.
        stopPriceTrigger = None
        if not order.getStopHit():
            stopPriceTrigger = get_stop_price_trigger(
                order.getAction(), order.getStopPrice(),
                broker_.getUseAdjustedValues(), bar)
            order.setStopHit(stopPriceTrigger is not None)

        # If the stop price was hit, check if we can fill the market order.
        if order.getStopHit():
            # Calculate the fill size for the order.
            fillSize = self.__calculateFillSize(broker_, order, bar)
            if fillSize == 0:
                broker_.getLogger().debug(
                    "Not enough volume to fill %s stop order [%s] for %s share/s"
                    % (order.getInstrument(), order.getId(),
                       order.getRemaining()))
                return None

            # If we just hit the stop price we'll use it as the fill price.
            # For the remaining bars we'll use the open price.
            if stopPriceTrigger is not None:
                price = stopPriceTrigger
            else:
                price = bar.getOpen(broker_.getUseAdjustedValues())
            assert price is not None

            # Don't slip prices when the bar represents the trading activity of a single trade.
            if bar.getFrequency() != pyalgotrade.bar.Frequency.TRADE:
                price = self.__slippageModel.calculatePrice(
                    order, price, fillSize, bar,
                    self.__volumeUsed[bar.getInstrument()])
            ret = FillInfo(price, fillSize)
        return ret
Пример #3
0
    def fillMarketOrder(self, broker_, order, bar):
        assert bar.getInstrument() == order.getInstrument()

        # Calculate the fill size for the order.
        fillSize = self.__calculateFillSize(broker_, order, bar)
        if fillSize == 0:
            broker_.getLogger().debug(
                "Not enough volume to fill %s market order [%s] for %s share/s"
                % (order.getInstrument(), order.getId(), order.getRemaining()))
            return None

        # Unless its a fill-on-close order, use the open price.
        if order.getFillOnClose():
            price = bar.getClose(broker_.getUseAdjustedValues())
        else:
            price = bar.getOpen(broker_.getUseAdjustedValues())
        assert price is not None

        # Don't slip prices when the bar represents the trading activity of a single trade.
        if bar.getFrequency() != pyalgotrade.bar.Frequency.TRADE:
            price = self.__slippageModel.calculatePrice(
                order, price, fillSize, bar,
                self.__volumeUsed[bar.getInstrument()])
        return FillInfo(price, fillSize)
Пример #4
0
    def __calculateFillSize(self, broker_, order, bar):
        ret = 0

        # If self.__volumeLimit is None then allow all the order to get filled.
        if self.__volumeLimit is not None:
            maxVolume = self.__instrumentTraits.round(
                self.__volumeLeft.get(bar.getInstrument(), 0),
                order.getInstrument().symbol)
        else:
            maxVolume = order.getRemaining()

        if not order.getAllOrNone():
            ret = min(maxVolume, order.getRemaining())
        elif order.getRemaining() <= maxVolume:
            ret = order.getRemaining()

        return ret
Пример #5
0
    def fillLimitOrder(self, broker_, order, bar):
        assert bar.getInstrument() == order.getInstrument()

        # Calculate the fill size for the order.
        fillSize = self.__calculateFillSize(broker_, order, bar)
        if fillSize == 0:
            broker_.getLogger().debug(
                "Not enough volume to fill %s limit order [%s] for %s share/s"
                % (order.getInstrument(), order.getId(), order.getRemaining()))
            return None

        ret = None
        price = get_limit_price_trigger(order.getAction(),
                                        order.getLimitPrice(),
                                        broker_.getUseAdjustedValues(), bar)
        if price is not None:
            ret = FillInfo(price, fillSize)
        return ret
Пример #6
0
    def fillStopLimitOrder(self, broker_, order, bar):
        assert bar.getInstrument() == order.getInstrument()

        ret = None

        # First check if the stop price was hit so the limit order becomes active.
        stopPriceTrigger = None
        if not order.getStopHit():
            stopPriceTrigger = get_stop_price_trigger(
                order.getAction(), order.getStopPrice(),
                broker_.getUseAdjustedValues(), bar)
            order.setStopHit(stopPriceTrigger is not None)

        # If the stop price was hit, check if we can fill the limit order.
        if order.getStopHit():
            # Calculate the fill size for the order.
            fillSize = self.__calculateFillSize(broker_, order, bar)
            if fillSize == 0:
                broker_.getLogger().debug(
                    "Not enough volume to fill %s stop limit order [%s] for %s share/s"
                    % (order.getInstrument(), order.getId(),
                       order.getRemaining()))
                return None

            price = get_limit_price_trigger(order.getAction(),
                                            order.getLimitPrice(),
                                            broker_.getUseAdjustedValues(),
                                            bar)
            if price is not None:
                # If we just hit the stop price, we need to make additional checks.
                if stopPriceTrigger is not None:
                    if order.isBuy():
                        # If the stop price triggered is lower than the limit price, then use that one.
                        # Else use the limit price.
                        price = min(stopPriceTrigger, order.getLimitPrice())
                    else:
                        # If the stop price triggered is greater than the limit price, then use that one.
                        # Else use the limit price.
                        price = max(stopPriceTrigger, order.getLimitPrice())

                ret = FillInfo(price, fillSize)

        return ret