Repository: nautechsystems/nautilus_trader
File: nautilus_core/backtest/src/matching_engine/tests.rs (Rust)

Code before:
    let order_event_first = saved_messages.first().unwrap();
    let order_filled_first = match order_event_first {
        OrderEventAny::Filled(order_filled) => order_filled,
        _ => panic!("Expected OrderFilled event in first message"),
    };
    let order_event_second = saved_messages.get(1).unwrap();
    let order_filled_second = match order_event_second {
        OrderEventAny::Filled(order_filled) => order_filled,
        _ => panic!("Expected OrderFilled event in second message"),
    };
    // check correct prices and quantities
    assert_eq!(order_filled_first.last_px, Price::from("1500.00"));
    assert_eq!(order_filled_first.last_qty, Quantity::from("1.000"));
    assert_eq!(order_filled_second.last_px, Price::from("1510.00"));
    assert_eq!(order_filled_second.last_qty, Quantity::from("1.000"));
}

#[rstest]
fn test_process_limit_post_only_order_that_would_be_a_taker(
    instrument_eth_usdt: InstrumentAny,
    mut msgbus: MessageBus,
    order_event_handler: ShareableMessageHandler,
    account_id: AccountId,
    time: AtomicTime,
) {
    // Register saving message handler to exec engine endpoint
    msgbus.register(
        msgbus.switchboard.exec_engine_process,
        order_event_handler.clone(),
    );

    let mut engine_l2 = get_order_matching_engine_l2(
        instrument_eth_usdt.clone(),
        Rc::new(RefCell::new(msgbus)),
        None,
        None,
        None,
    );

    // add liquidity to the orderbook
    let orderbook_delta_sell = OrderBookDelta::new(
        instrument_eth_usdt.id(),
        BookAction::Add,
        BookOrder::new(
            OrderSide::Sell,
            Price::from("1500.00"),
            Quantity::from("1.000"),
            1,
        ),
        0,
        1,

Review comment (performance):
It might be better to have a helper (or `OrderBookDeltaBuilder`) for creating the delta which would make the price of 1500 clearer, which is important for the behavior of the test (and we'll want to be able to change price and size of deltas often in tests).

I think this fixture style could be reserved for fairly static things, without special values which are important to the test (such as `cache`, etc)?

Code after:
    engine_l2.process_order(&mut market_order, account_id);

    // We need to test that two Order filled events were generated where with correct prices and quantities
    let saved_messages = get_order_event_handler_messages(order_event_handler);
    assert_eq!(saved_messages.len(), 2);
    let order_event_first = saved_messages.first().unwrap();
    let order_filled_first = match order_event_first {
        OrderEventAny::Filled(order_filled) => order_filled,
        _ => panic!("Expected OrderFilled event in first message"),
    };
    let order_event_second = saved_messages.get(1).unwrap();
    let order_filled_second = match order_event_second {
        OrderEventAny::Filled(order_filled) => order_filled,
        _ => panic!("Expected OrderFilled event in second message"),
    };
    // check correct prices and quantities
    assert_eq!(order_filled_first.last_px, Price::from("1500.00"));
    assert_eq!(order_filled_first.last_qty, Quantity::from("1.000"));
    assert_eq!(order_filled_second.last_px, Price::from("1510.00"));
    assert_eq!(order_filled_second.last_qty, Quantity::from("1.000"));
}

#[rstest]
fn test_process_limit_post_only_order_that_would_be_a_taker(
    instrument_eth_usdt: InstrumentAny,
    orderbook_delta_sell: OrderBookDelta,
    mut msgbus: MessageBus,
    order_event_handler: ShareableMessageHandler,
    account_id: AccountId,
    time: AtomicTime,
) {
    // Register saving message handler to exec engine endpoint
    msgbus.register(
        msgbus.switchboard.exec_engine_process,
        order_event_handler.clone(),
    );

    let mut engine_l2 = get_order_matching_engine_l2(
        instrument_eth_usdt.clone(),
        Rc::new(RefCell::new(msgbus)),
        None,
        None,
        None,
    );

    // Create a post-only limit buy order with price above 1500.00
    // that would match the existing sell order and be a taker
    let mut post_only_limit_order = OrderTestBuilder::new(OrderType::Limit)
        .instrument_id(instrument_eth_usdt.id())
        .side(OrderSide::Buy)
        .price(Price::from("1501.00"))