def exitPosition(self, position, limitPrice = None, stopPrice = None, goodTillCanceled = None): """Generates the exit order for the position. :param position: A position returned by any of the enterLongXXX or enterShortXXX methods. :type position: :class:`pyalgotrade.strategy.position.Position`. :param limitPrice: The limit price. :type limitPrice: float. :param stopPrice: The stop price. :type stopPrice: float. :param goodTillCanceled: True if the exit order is good till canceled. If False then the order gets automatically canceled when the session closes. If None, then it will match the entry order. :type goodTillCanceled: boolean. .. note:: * If the entry order was not filled yet, it will be canceled. * If a previous exit order for this position was filled, this won't have any effect. * If a previous exit order for this position is pending, it will get canceled and the new exit order submitted. * If limitPrice is not set and stopPrice is not set, then a :class:`pyalgotrade.broker.MarketOrder` is used to exit the position. * If limitPrice is set and stopPrice is not set, then a :class:`pyalgotrade.broker.LimitOrder` is used to exit the position. * If limitPrice is not set and stopPrice is set, then a :class:`pyalgotrade.broker.StopOrder` is used to exit the position. * If limitPrice is set and stopPrice is set, then a :class:`pyalgotrade.broker.StopLimitOrder` is used to exit the position. """ if position.exitFilled(): return # Before exiting a position, the entry order must have been filled. if position.getEntryOrder().isFilled(): position.close(limitPrice, stopPrice, goodTillCanceled) self.__registerActivePosition(position) else: # If the entry was not filled, cancel it. self.getBroker().cancelOrder(position.getEntryOrder())
def __onOrderUpdated(self, broker, order): position = self.__orderToPosition.get(order.getId(), None) if position == None: self.onOrderUpdated(order) elif position.getEntryOrder().getId() == order.getId(): if order.isFilled(): self.__unregisterOrder(position, order) self.onEnterOk(position) elif order.isCanceled(): self.__unregisterOrder(position, order) self.onEnterCanceled(position) else: assert (order.isAccepted()) elif position.getExitOrder().getId() == order.getId(): if order.isFilled(): self.__unregisterOrder(position, order) self.onExitOk(position) elif order.isCanceled(): self.__unregisterOrder(position, order) self.onExitCanceled(position) else: assert (order.isAccepted()) else: # The order used to belong to a position but it was ovewritten with a new one # and the previous order should have been canceled. assert (order.isCanceled())
def __onOrderUpdated(self, broker, order): position = self.__orderToPosition.get(order.getId(), None) if position == None: self.onOrderUpdated(order) elif position.getEntryOrder().getId() == order.getId(): if order.isFilled(): self.__unregisterOrder(position, order) self.onEnterOk(position) elif order.isCanceled(): self.__unregisterOrder(position, order) self.onEnterCanceled(position) else: assert(order.isAccepted()) elif position.getExitOrder().getId() == order.getId(): if order.isFilled(): self.__unregisterOrder(position, order) self.onExitOk(position) elif order.isCanceled(): self.__unregisterOrder(position, order) self.onExitCanceled(position) else: assert(order.isAccepted()) else: # The order used to belong to a position but it was ovewritten with a new one # and the previous order should have been canceled. assert(order.isCanceled())
def onEnterCanceled(self, position): inst = position.getEntryOrder().getInstrument() info = position.getCancelDesc() self.debug("%s inst - Execinfo: %s" % ( inst, info ))
def onExitOk(self, position): extorder = position.getExitOrder() execInfo = extorder.getExecutionInfo() inst = position.getEntryOrder().getInstrument() price = format(execInfo.getPrice(),'<6.2f') shares = format(execInfo.getQuantity(),'<10.2f') self.debug("SELL: " + str(inst) + " at $%s shares:%s orderid:%d" % (price,shares,extorder.getId()))
def onEnterOk(self, position): entorder = position.getEntryOrder() execInfo = entorder.getExecutionInfo() inst = entorder.getInstrument() price = format(execInfo.getPrice(),'<6.2f') shares = format(execInfo.getQuantity(),'<10.2f') self.debug(format("BUY:",'<6') + str(inst) + " at $%s shares:%s orderid:%d" % (price,shares,entorder.getId()))
def __registerActivePosition(self, position): for order in [position.getEntryOrder(), position.getExitOrder()]: if order and order.isAccepted(): self.__registerOrder(position, order)