async def test_stop_loss_limit_order_trigger(stop_loss_limit_order):
    order_price = random_price()
    stop_loss_limit_order.update(
        price=order_price,
        quantity=random_quantity(),
        symbol=DEFAULT_SYMBOL_ORDER,
        order_type=TraderOrderType.STOP_LOSS_LIMIT,
    )
    stop_loss_limit_order.exchange_manager.is_backtesting = True  # force update_order_status
    await stop_loss_limit_order.initialize()
    stop_loss_limit_order.exchange_manager.exchange_personal_data.orders_manager.upsert_order_instance(
        stop_loss_limit_order)
    price_events_manager = stop_loss_limit_order.exchange_manager.exchange_symbols_data.get_exchange_symbol_data(
        DEFAULT_SYMBOL_ORDER).price_events_manager
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=random_price(min_value=order_price + 1),
                            timestamp=stop_loss_limit_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert not stop_loss_limit_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=stop_loss_limit_order.timestamp - 1)
    ])
    await wait_asyncio_next_cycle()
    assert not stop_loss_limit_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=stop_loss_limit_order.timestamp)
    ])

    # wait for 2 cycles as secondary orders are created
    await wait_asyncio_next_cycle()
    await wait_asyncio_next_cycle()
    assert stop_loss_limit_order.is_filled()
Ejemplo n.º 2
0
async def test_stop_loss_buy_order_trigger(stop_loss_buy_order):
    order_price = random_price()
    stop_loss_buy_order.update(
        price=order_price,
        quantity=random_quantity(max_value=DEFAULT_SYMBOL_QUANTITY),
        symbol=DEFAULT_ORDER_SYMBOL,
        order_type=TraderOrderType.STOP_LOSS,
    )
    stop_loss_buy_order.exchange_manager.is_backtesting = True  # force update_order_status
    await stop_loss_buy_order.initialize()
    stop_loss_buy_order.exchange_manager.exchange_personal_data.orders_manager.upsert_order_instance(
        stop_loss_buy_order)
    price_events_manager = stop_loss_buy_order.exchange_manager.exchange_symbols_data.get_exchange_symbol_data(
        DEFAULT_ORDER_SYMBOL).price_events_manager
    # stop loss buy order triggers when price is above or equal to its trigger price
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=random_price(max_value=order_price - 1),
                            timestamp=stop_loss_buy_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert not stop_loss_buy_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=stop_loss_buy_order.timestamp - 1)
    ])
    await wait_asyncio_next_cycle()
    assert not stop_loss_buy_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=stop_loss_buy_order.timestamp)
    ])

    await wait_asyncio_next_cycle()
    assert stop_loss_buy_order.is_filled()
async def test_set_all_recent_trades(recent_trades_manager):
    # if setting no new trades
    recent_trades_manager.set_all_recent_trades([])
    assert not recent_trades_manager.recent_trades
    recent_trades_manager.set_all_recent_trades(None)
    assert not recent_trades_manager.recent_trades

    # test removing all previous values
    recent_trades_manager.recent_trades.append(1)
    assert 1 in recent_trades_manager.recent_trades
    trades = random_recent_trades()
    recent_trades_manager.set_all_recent_trades(trades)
    assert trades[-1] in recent_trades_manager.recent_trades
    assert 1 not in recent_trades_manager.recent_trades

    # test set values
    recent_trade_1 = random_recent_trade()
    recent_trade_2 = random_recent_trade()
    recent_trade_3 = random_recent_trade()
    trades = [recent_trade_3, recent_trade_2, recent_trade_1]
    recent_trades_manager.set_all_recent_trades(trades)
    assert recent_trade_1 in recent_trades_manager.recent_trades
    assert recent_trade_2 in recent_trades_manager.recent_trades
    assert recent_trades_manager.recent_trades[-1] == recent_trade_1
    assert recent_trades_manager.recent_trades[-2] == recent_trade_2
    assert recent_trades_manager.recent_trades[-3] == recent_trade_3
async def test_trailing_stop_with_new_price(trailing_stop_order):
    trailing_stop_order, order_price, price_events_manager = await initialize_trailing_stop(
        trailing_stop_order)
    await trailing_stop_order.set_trailing_percent(2)
    new_trailing_price = random_price(min_value=order_price + 1)

    # set mark price
    set_mark_price(trailing_stop_order, new_trailing_price)

    # move trailing price
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=new_trailing_price,
                            timestamp=trailing_stop_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert not trailing_stop_order.is_filled()

    # test fill stop loss with new order price reference
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=get_price_percent(
            new_trailing_price, trailing_stop_order.trailing_percent),
                            timestamp=trailing_stop_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert trailing_stop_order.is_filled()
Ejemplo n.º 5
0
async def test_trailing_stop_with_new_price_inversed(trailing_stop_order):
    trailing_stop_order, order_price, price_events_manager = await initialize_trailing_stop(
        trailing_stop_order, side=TradeOrderSide.BUY)
    await trailing_stop_order.set_trailing_percent(5)
    new_trailing_price = random_price(min_value=order_price * 0.99,
                                      max_value=order_price * 1.01)

    # set mark price
    set_mark_price(trailing_stop_order, new_trailing_price)

    # move trailing price
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=new_trailing_price,
                            timestamp=trailing_stop_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert not trailing_stop_order.is_filled()

    # test fill stop loss with new order price reference
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=get_price_percent(
            new_trailing_price,
            trailing_stop_order.trailing_percent,
            selling_side=False),
                            timestamp=trailing_stop_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert trailing_stop_order.is_filled()
Ejemplo n.º 6
0
async def test_buy_limit_order_trigger(buy_limit_order):
    order_price = random_price()
    buy_limit_order.update(
        price=order_price,
        quantity=random_quantity(max_value=DEFAULT_MARKET_QUANTITY /
                                 order_price),
        symbol=DEFAULT_ORDER_SYMBOL,
        order_type=TraderOrderType.BUY_LIMIT,
    )
    buy_limit_order.exchange_manager.is_backtesting = True  # force update_order_status
    await buy_limit_order.initialize()
    buy_limit_order.exchange_manager.exchange_personal_data.orders_manager.upsert_order_instance(
        buy_limit_order)
    price_events_manager = buy_limit_order.exchange_manager.exchange_symbols_data.get_exchange_symbol_data(
        DEFAULT_ORDER_SYMBOL).price_events_manager
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=random_price(min_value=order_price + 1),
                            timestamp=buy_limit_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert not buy_limit_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=buy_limit_order.timestamp - 1)
    ])
    await wait_asyncio_next_cycle()
    assert not buy_limit_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=buy_limit_order.timestamp)
    ])

    await wait_asyncio_next_cycle()
    assert buy_limit_order.is_filled()
Ejemplo n.º 7
0
async def test_take_profit_sell_order_trigger(take_profit_sell_order):
    order_price = random_price(min_value=2)
    take_profit_sell_order.update(
        price=order_price,
        quantity=random_quantity(max_value=DEFAULT_SYMBOL_QUANTITY / 10),
        symbol=DEFAULT_ORDER_SYMBOL,
        order_type=TraderOrderType.TAKE_PROFIT,
    )
    take_profit_sell_order.exchange_manager.is_backtesting = True  # force update_order_status
    await take_profit_sell_order.initialize()
    take_profit_sell_order.exchange_manager.exchange_personal_data.orders_manager.upsert_order_instance(
        take_profit_sell_order)
    price_events_manager = take_profit_sell_order.exchange_manager.exchange_symbols_data.get_exchange_symbol_data(
        DEFAULT_ORDER_SYMBOL).price_events_manager
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=random_price(max_value=order_price - 1),
                            timestamp=take_profit_sell_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert not take_profit_sell_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=take_profit_sell_order.timestamp - 1)
    ])
    await wait_asyncio_next_cycle()
    assert not take_profit_sell_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=take_profit_sell_order.timestamp)
    ])

    # wait for 2 cycles as secondary orders are created
    await wait_asyncio_next_cycle()
    await wait_asyncio_next_cycle()
    assert take_profit_sell_order.is_filled()
async def test_handle_recent_trades(price_events_manager):
    random_price_1 = random_price(min_value=2)
    random_timestamp_1 = random_timestamp(min_value=2, max_value=1000)
    price_event_1 = price_events_manager.add_event(random_price_1,
                                                   random_timestamp_1, True)
    with patch.object(price_event_1, 'set', new=Mock()) as price_event_1_set:
        price_events_manager.handle_recent_trades([])
        with pytest.raises(AssertionError):
            price_event_1_set.assert_called_once()
        price_events_manager.handle_recent_trades([
            random_recent_trade(
                price=random_price(max_value=random_price_1 - 1),
                timestamp=random_timestamp(max_value=random_timestamp_1 - 1)),
            random_recent_trade(
                price=random_price(max_value=random_price_1 - 1),
                timestamp=random_timestamp(max_value=random_timestamp_1 - 1)),
            random_recent_trade(
                price=random_price(max_value=random_price_1 - 1),
                timestamp=random_timestamp(max_value=random_timestamp_1 - 1))
        ])
        with pytest.raises(AssertionError):
            price_event_1_set.assert_called_once()
        price_events_manager.handle_recent_trades([
            random_recent_trade(price=random_price(max_value=random_price_1 -
                                                   1)),
            random_recent_trade(price=random_price_1,
                                timestamp=random_timestamp_1),
            random_recent_trade(price=random_price(max_value=random_price_1 -
                                                   1)),
            random_recent_trade(price=random_price(max_value=random_price_1 -
                                                   1))
        ])
        price_event_1_set.assert_called_once()
async def test_limit_and_stop_loss(stop_loss_sell_order, sell_limit_order):
    # fill both orders: limit first
    limit_order_price = decimal_random_price()
    quantity = decimal_random_quantity(max_value=DEFAULT_SYMBOL_QUANTITY)
    sell_limit_order.update(
        price=limit_order_price,
        quantity=quantity,
        symbol=DEFAULT_ORDER_SYMBOL,
        order_type=TraderOrderType.SELL_LIMIT,
    )
    stop_order_price = decimal_random_price(max_value=limit_order_price - 1)
    stop_loss_sell_order.update(price=stop_order_price,
                                quantity=quantity,
                                symbol=DEFAULT_ORDER_SYMBOL,
                                order_type=TraderOrderType.STOP_LOSS,
                                linked_to=sell_limit_order)
    stop_loss_sell_order.linked_orders.append(sell_limit_order)
    sell_limit_order.linked_orders.append(stop_loss_sell_order)
    stop_loss_sell_order.exchange_manager.is_backtesting = True  # force update_order_status
    # initialize limit order first
    await sell_limit_order.initialize()
    await stop_loss_sell_order.initialize()
    price_events_manager = stop_loss_sell_order.exchange_manager.exchange_symbols_data.get_exchange_symbol_data(
        DEFAULT_ORDER_SYMBOL).price_events_manager
    # stop loss sell order triggers when price is bellow or equal to its trigger price
    # sell limit order triggers when price is above or equal to its trigger price
    # here trigger both: limit is triggered first (initialized first): sell stop loss order should be
    # cancelled and not filled even though its price has been hit
    price_events_manager.handle_recent_trades([
        random_recent_trade(
            price=random_price(max_value=float(stop_order_price - 1)),
            timestamp=sell_limit_order.timestamp),
        random_recent_trade(
            price=random_price(min_value=float(limit_order_price + 1)),
            timestamp=stop_loss_sell_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert stop_loss_sell_order.is_cancelled()
    assert sell_limit_order.is_filled()
async def test_add_new_trades(recent_trades_manager):
    # if adding no new trades
    recent_trades_manager.add_new_trades([])
    assert not recent_trades_manager.recent_trades
    recent_trades_manager.add_new_trades(None)
    assert not recent_trades_manager.recent_trades

    # test set values
    recent_trade_1 = random_recent_trade()
    recent_trade_2 = random_recent_trade()
    recent_trade_3 = random_recent_trade()
    recent_trade_4 = random_recent_trade()
    recent_trade_5 = random_recent_trade()
    trades = [recent_trade_1, recent_trade_2]
    recent_trades_manager.add_new_trades(trades)
    assert recent_trade_1 in recent_trades_manager.recent_trades
    assert recent_trade_2 in recent_trades_manager.recent_trades
    assert recent_trades_manager.recent_trades[0] == recent_trade_1
    assert recent_trades_manager.recent_trades[1] == recent_trade_2
    with pytest.raises(IndexError):
        recent_trades_manager.recent_trades[2]

    # test add duplicate
    trades = [recent_trade_2, recent_trade_3, recent_trade_4]
    recent_trades_manager.add_new_trades(trades)
    assert recent_trades_manager.recent_trades[0] == recent_trade_1
    assert recent_trades_manager.recent_trades[1] == recent_trade_2
    assert recent_trades_manager.recent_trades[2] == recent_trade_3
    assert recent_trades_manager.recent_trades[3] == recent_trade_4
    with pytest.raises(IndexError):
        recent_trades_manager.recent_trades[4]

    trades = [recent_trade_2, recent_trade_5]
    recent_trades_manager.add_new_trades(trades)
    assert recent_trades_manager.recent_trades[0] == recent_trade_1
    assert recent_trades_manager.recent_trades[1] == recent_trade_2
    assert recent_trades_manager.recent_trades[2] == recent_trade_3
    assert recent_trades_manager.recent_trades[3] == recent_trade_4
    assert recent_trades_manager.recent_trades[4] == recent_trade_5
async def test_trailing_stop_trigger(trailing_stop_order):
    trailing_stop_order, order_price, price_events_manager = await initialize_trailing_stop(
        trailing_stop_order)
    await trailing_stop_order.set_trailing_percent(10)
    max_trailing_hit_price = get_price_percent(
        order_price, trailing_stop_order.trailing_percent)

    # set mark price
    set_mark_price(trailing_stop_order, order_price)

    price_events_manager.handle_recent_trades([
        random_recent_trade(price=random_price(
            min_value=max_trailing_hit_price, max_value=order_price - 1),
                            timestamp=trailing_stop_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert not trailing_stop_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=trailing_stop_order.timestamp - 1)
    ])
    await wait_asyncio_next_cycle()
    assert not trailing_stop_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=order_price,
                            timestamp=trailing_stop_order.timestamp)
    ])

    await wait_asyncio_next_cycle()
    assert not trailing_stop_order.is_filled()
    price_events_manager.handle_recent_trades([
        random_recent_trade(price=max_trailing_hit_price,
                            timestamp=trailing_stop_order.timestamp)
    ])
    await wait_asyncio_next_cycle()
    assert trailing_stop_order.is_filled()