Пример #1
0
    def _on_executed_order(self, order: Order):
        qty = order.qty
        price = order.price

        # TODO: detect reduce_only order, and if so, see if you need to adjust qty and price (above variables)

        self.exchange.charge_fee(qty * price)

        # order opens position
        if self.qty == 0:
            change_balance = order.type == order_types.MARKET
            self._open(qty, price, change_balance)
        # order closes position
        elif (sum_floats(self.qty, qty)) == 0:
            self._close(price)
        # order increases the size of the position
        elif self.qty * qty > 0:
            self._increase(qty, price)
        # order reduces the size of the position
        elif self.qty * qty < 0:
            # if size of the order is big enough to both close the
            # position AND open it on the opposite side
            if abs(qty) > abs(self.qty):
                logger.info(
                    'Executed order is big enough to not close, but flip the position type. Order QTY: {}, Position QTY: {}'
                    .format(qty, self.qty))
                diff_qty = sum_floats(self.qty, qty)
                self._close(price)
                self._open(diff_qty, price)
            else:
                self._reduce(qty, price)

        if self.strategy:
            self.strategy._on_updated_position(order)
Пример #2
0
    def _increase(self, qty: float, price: float) -> None:
        if not self.is_open:
            raise OpenPositionError(
                'position must be already open in order to increase its size')

        qty = abs(qty)
        size = qty * price

        # if self.exchange:
        #     self.exchange.decrease_futures_balance(size)

        self.entry_price = jh.estimate_average_price(qty, price, self.qty,
                                                     self.entry_price)

        if self.type == trade_types.LONG:
            self.qty = sum_floats(self.qty, qty)
        elif self.type == trade_types.SHORT:
            self.qty = subtract_floats(self.qty, qty)

        info_text = 'INCREASED position: {}, {}, {}, {}, ${}'.format(
            self.exchange_name, self.symbol, self.type, self.qty,
            round(self.entry_price, 2))

        if jh.is_debuggable('position_increased'):
            logger.info(info_text)

        if jh.is_live(
        ) and config['env']['notifications']['events']['updated_position']:
            notifier.notify(info_text)
Пример #3
0
    def _reduce(self, qty: float, price: float) -> None:
        if self.is_open is False:
            raise EmptyPosition('The position is closed.')

        # just to prevent confusion
        qty = abs(qty)

        estimated_profit = jh.estimate_PNL(qty, self.entry_price, price,
                                           self.type)

        if self.exchange:
            # self.exchange.increase_futures_balance(qty * self.entry_price + estimated_profit)
            self.exchange.add_realized_pnl(estimated_profit)
            self.exchange.temp_reduced_amount[jh.base_asset(
                self.symbol)] += abs(qty * price)

        if self.type == trade_types.LONG:
            self.qty = subtract_floats(self.qty, qty)
        elif self.type == trade_types.SHORT:
            self.qty = sum_floats(self.qty, qty)

        info_text = 'REDUCED position: {}, {}, {}, {}, ${}'.format(
            self.exchange_name, self.symbol, self.type, self.qty,
            round(self.entry_price, 2))

        if jh.is_debuggable('position_reduced'):
            logger.info(info_text)

        if jh.is_live(
        ) and config['env']['notifications']['events']['updated_position']:
            notifier.notify(info_text)
Пример #4
0
def test_sum_floats():
    assert utils.sum_floats(9.71, 9.813) == 19.523
    assert utils.sum_floats(-1.123, -1.2) == -2.323
    assert utils.sum_floats(1.19, -1.2) == -0.01
    assert utils.sum_floats(-1.19, 1.2) == 0.01