Ejemplo n.º 1
0
def test_pnl_percentage():
    set_up(zero_fee=True)

    # 1x leverage
    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 12,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTC-USD',
        'opened_at': jh.now_to_timestamp(),
        'closed_at': jh.now_to_timestamp(),
        'leverage': 1,
    })
    assert trade.pnl_percentage == 20

    # 2x leverage
    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 12,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTC-USD',
        'opened_at': jh.now_to_timestamp(),
        'closed_at': jh.now_to_timestamp(),
        'leverage': 2,
    })
    assert trade.pnl_percentage == 40
Ejemplo n.º 2
0
def test_trade_size():
    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 20,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTC-USD',
        'opened_at': jh.now_to_timestamp(),
        'closed_at': jh.now_to_timestamp()
    })

    assert trade.size == 10
Ejemplo n.º 3
0
def test_risk_percentage():
    set_up(zero_fee=True)

    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 12,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTC-USD',
        'opened_at': jh.now_to_timestamp(),
        'closed_at': jh.now_to_timestamp()
    })
Ejemplo n.º 4
0
def test_holding_period():
    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 20,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTC-USD',
        'opened_at': 1552309186171,
        'closed_at': 1552309186171 + 60000
    })

    # 1 minute == 60 seconds
    assert trade.holding_period == 60
Ejemplo n.º 5
0
def test_PNL_percentage():
    no_fee()

    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 12,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTCUSD',
        'opened_at': jh.now(),
        'closed_at': jh.now()
    })
    assert trade.PNL_percentage == 20
Ejemplo n.º 6
0
def test_risk_percentage():
    no_fee()

    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 12,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTC-USD',
        'opened_at': jh.now_to_timestamp(),
        'closed_at': jh.now_to_timestamp()
    })
    assert trade.risk_percentage == round((((10 - 5) / 1) * 10), 2)
Ejemplo n.º 7
0
def test_R():
    no_fee()

    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 12,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTC-USD',
        'opened_at': jh.now_to_timestamp(),
        'closed_at': jh.now_to_timestamp()
    })
    assert trade.risk_reward_ratio == 2
Ejemplo n.º 8
0
def test_pnl_with_fee():
    # set fee (0.20%)
    config['env']['exchanges']['Sandbox']['fee'] = 0.002

    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 20,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTC-USD',
        'opened_at': jh.now_to_timestamp(),
        'closed_at': jh.now_to_timestamp()
    })

    assert trade.fee == 0.06
    assert trade.pnl == 9.94
Ejemplo n.º 9
0
def test_can_add_trade_to_store():
    set_up()

    assert store.completed_trades.trades == []

    trade = CompletedTrade({
        'type': 'long',
        'exchange': 'Sandbox',
        'entry_price': 10,
        'exit_price': 20,
        'take_profit_at': 20,
        'stop_loss_at': 5,
        'qty': 1,
        'orders': [],
        'symbol': 'BTC-USD',
        'opened_at': 1552309186171,
        'closed_at': 1552309186171 + 60000
    })

    store.completed_trades.add_trade(trade)
    assert store.completed_trades.trades == [trade]
    store.reset()
    assert store.completed_trades.trades == []
Ejemplo n.º 10
0
    def _log_position_update(self, order: Order, role: str) -> None:
        """
        A log can be either about opening, adding, reducing, or closing the position.

        Arguments:
            order {order} -- the order object
        """
        # set the trade_id for the order if we're in the middle of a trade. Otherwise, it
        # is done at order_roles.OPEN_POSITION
        if self.trade:
            order.trade_id = self.trade.id

        if role == order_roles.OPEN_POSITION:
            self.trade = CompletedTrade()
            self.trade.leverage = self.leverage
            self.trade.orders = [order]
            self.trade.timeframe = self.timeframe
            self.trade.id = jh.generate_unique_id()
            order.trade_id = self.trade.id
            self.trade.strategy_name = self.name
            self.trade.exchange = order.exchange
            self.trade.symbol = order.symbol
            self.trade.type = trade_types.LONG if order.side == sides.BUY else trade_types.SHORT
            self.trade.qty = order.qty
            self.trade.opened_at = jh.now_to_timestamp()
            self.trade.entry_candle_timestamp = self.current_candle[0]
        elif role == order_roles.INCREASE_POSITION:
            self.trade.orders.append(order)
            self.trade.qty += order.qty
        elif role == order_roles.REDUCE_POSITION:
            self.trade.orders.append(order)
            self.trade.qty += order.qty
        elif role == order_roles.CLOSE_POSITION:
            self.trade.exit_candle_timestamp = self.current_candle[0]
            self.trade.orders.append(order)

            # calculate average stop-loss price
            sum_price = 0
            sum_qty = 0
            if self._log_stop_loss is not None:
                for l in self._log_stop_loss:
                    sum_qty += abs(l[0])
                    sum_price += abs(l[0]) * l[1]
                self.trade.stop_loss_at = sum_price / sum_qty
            else:
                self.trade.stop_loss_at = np.nan

            # calculate average take-profit price
            sum_price = 0
            sum_qty = 0
            if self._log_take_profit is not None:
                for l in self._log_take_profit:
                    sum_qty += abs(l[0])
                    sum_price += abs(l[0]) * l[1]
                self.trade.take_profit_at = sum_price / sum_qty
            else:
                self.trade.take_profit_at = np.nan

            # calculate average entry_price price
            sum_price = 0
            sum_qty = 0
            for l in self.trade.orders:
                if not l.is_executed:
                    continue

                if jh.side_to_type(l.side) != self.trade.type:
                    continue

                sum_qty += abs(l.qty)
                sum_price += abs(l.qty) * l.price
            self.trade.entry_price = sum_price / sum_qty

            # calculate average exit_price
            sum_price = 0
            sum_qty = 0
            for l in self.trade.orders:
                if not l.is_executed:
                    continue

                if jh.side_to_type(l.side) == self.trade.type:
                    continue

                sum_qty += abs(l.qty)
                sum_price += abs(l.qty) * l.price
            self.trade.exit_price = sum_price / sum_qty

            self.trade.closed_at = jh.now_to_timestamp()
            self.trade.qty = pydash.sum_by(
                filter(lambda o: o.side == jh.type_to_side(self.trade.type),
                       self.trade.orders), lambda o: abs(o.qty))

            store.completed_trades.add_trade(self.trade)
            if jh.is_livetrading():
                store_completed_trade_into_db(self.trade)
            self.trade = None
            self.trades_count += 1

        if jh.is_livetrading():
            store_order_into_db(order)