@@ -2161,3 +2161,124 @@ fn test_update_stop_limit_order_valid_update_not_triggered(
2161
2161
assert_eq ! ( order_updated. client_order_id, client_order_id) ;
2162
2162
assert_eq ! ( order_updated. trigger_price. unwrap( ) , new_trigger_price) ;
2163
2163
}
2164
+
2165
+ #[ rstest]
2166
+ fn test_process_market_if_touched_order_already_triggered (
2167
+ instrument_eth_usdt : InstrumentAny ,
2168
+ mut msgbus : MessageBus ,
2169
+ order_event_handler : ShareableMessageHandler ,
2170
+ account_id : AccountId ,
2171
+ ) {
2172
+ msgbus. register (
2173
+ msgbus. switchboard . exec_engine_process ,
2174
+ order_event_handler. clone ( ) ,
2175
+ ) ;
2176
+ let mut engine_l2 = get_order_matching_engine_l2 (
2177
+ instrument_eth_usdt. clone ( ) ,
2178
+ Rc :: new ( RefCell :: new ( msgbus) ) ,
2179
+ None ,
2180
+ None ,
2181
+ None ,
2182
+ ) ;
2183
+
2184
+ // Add SELL limit orderbook delta to have ask initialized
2185
+ let orderbook_delta_sell = OrderBookDeltaTestBuilder :: new ( instrument_eth_usdt. id ( ) )
2186
+ . book_action ( BookAction :: Add )
2187
+ . book_order ( BookOrder :: new (
2188
+ OrderSide :: Sell ,
2189
+ Price :: from ( "1500.00" ) ,
2190
+ Quantity :: from ( "1.000" ) ,
2191
+ 1 ,
2192
+ ) )
2193
+ . build ( ) ;
2194
+ engine_l2. process_order_book_delta ( & orderbook_delta_sell) ;
2195
+
2196
+ // Create MARKET IF TOUCHED order which is already activated as trigger price of 1500.00 is equal to current ask of 1500.00
2197
+ let client_order_id = ClientOrderId :: from ( "O-19700101-000000-001-001-1" ) ;
2198
+ let mut stop_market_order = OrderTestBuilder :: new ( OrderType :: MarketIfTouched )
2199
+ . instrument_id ( instrument_eth_usdt. id ( ) )
2200
+ . side ( OrderSide :: Buy )
2201
+ . trigger_price ( Price :: from ( "1500.00" ) )
2202
+ . quantity ( Quantity :: from ( "1.000" ) )
2203
+ . client_order_id ( client_order_id)
2204
+ . build ( ) ;
2205
+ engine_l2. process_order ( & mut stop_market_order, account_id) ;
2206
+
2207
+ // Check that order was filled immediately with correct price and quantity
2208
+ let saved_messages = get_order_event_handler_messages ( order_event_handler) ;
2209
+ assert_eq ! ( saved_messages. len( ) , 1 ) ;
2210
+ let order_event = saved_messages. first ( ) . unwrap ( ) ;
2211
+ let order_filled = match order_event {
2212
+ OrderEventAny :: Filled ( order_filled) => order_filled,
2213
+ _ => panic ! ( "Expected OrderFilled event in first message" ) ,
2214
+ } ;
2215
+ assert_eq ! ( order_filled. client_order_id, client_order_id) ;
2216
+ assert_eq ! ( order_filled. last_px, Price :: from( "1500.00" ) ) ;
2217
+ assert_eq ! ( order_filled. last_qty, Quantity :: from( "1.000" ) ) ;
2218
+ }
2219
+
2220
+ #[ rstest]
2221
+ fn test_update_market_if_touched_order_valid (
2222
+ instrument_eth_usdt : InstrumentAny ,
2223
+ mut msgbus : MessageBus ,
2224
+ order_event_handler : ShareableMessageHandler ,
2225
+ account_id : AccountId ,
2226
+ ) {
2227
+ msgbus. register (
2228
+ msgbus. switchboard . exec_engine_process ,
2229
+ order_event_handler. clone ( ) ,
2230
+ ) ;
2231
+ let mut engine_l2 = get_order_matching_engine_l2 (
2232
+ instrument_eth_usdt. clone ( ) ,
2233
+ Rc :: new ( RefCell :: new ( msgbus) ) ,
2234
+ None ,
2235
+ None ,
2236
+ None ,
2237
+ ) ;
2238
+
2239
+ // Create MARKET IF TOUCHED order which is not activated as trigger price of 1505.00 is above current ask of 1500.00
2240
+ let client_order_id = ClientOrderId :: from ( "O-19700101-000000-001-001-1" ) ;
2241
+ let mut stop_market_order = OrderTestBuilder :: new ( OrderType :: MarketIfTouched )
2242
+ . instrument_id ( instrument_eth_usdt. id ( ) )
2243
+ . side ( OrderSide :: Buy )
2244
+ . trigger_price ( Price :: from ( "1505.00" ) )
2245
+ . quantity ( Quantity :: from ( "1.000" ) )
2246
+ . client_order_id ( client_order_id)
2247
+ . build ( ) ;
2248
+ engine_l2. process_order ( & mut stop_market_order, account_id) ;
2249
+
2250
+ // Create modify command which moves trigger price to 1501.00 which won't trigger the stop price again
2251
+ // as ask is at 1500.00 and order will be correctly updated
2252
+ let new_trigger_price = Price :: from ( "1501.00" ) ;
2253
+ let modify_order_command = ModifyOrder :: new (
2254
+ TraderId :: from ( "TRADER-001" ) ,
2255
+ ClientId :: from ( "CLIENT-001" ) ,
2256
+ StrategyId :: from ( "STRATEGY-001" ) ,
2257
+ instrument_eth_usdt. id ( ) ,
2258
+ client_order_id,
2259
+ VenueOrderId :: from ( "V1" ) ,
2260
+ None ,
2261
+ None ,
2262
+ Some ( new_trigger_price) ,
2263
+ UUID4 :: new ( ) ,
2264
+ UnixNanos :: default ( ) ,
2265
+ ) ;
2266
+ engine_l2. process_modify ( & modify_order_command. unwrap ( ) , account_id) ;
2267
+
2268
+ // Check that we have received OrderAccepted and then OrderUpdated
2269
+ let saved_messages = get_order_event_handler_messages ( order_event_handler) ;
2270
+ assert_eq ! ( saved_messages. len( ) , 2 ) ;
2271
+ let order_event_first = saved_messages. first ( ) . unwrap ( ) ;
2272
+ let order_accepted = match order_event_first {
2273
+ OrderEventAny :: Accepted ( order_accepted) => order_accepted,
2274
+ _ => panic ! ( "Expected OrderAccepted event in first message" ) ,
2275
+ } ;
2276
+ assert_eq ! ( order_accepted. client_order_id, client_order_id) ;
2277
+ let order_event_second = saved_messages. get ( 1 ) . unwrap ( ) ;
2278
+ let order_updated = match order_event_second {
2279
+ OrderEventAny :: Updated ( order_updated) => order_updated,
2280
+ _ => panic ! ( "Expected OrderUpdated event in second message" ) ,
2281
+ } ;
2282
+ assert_eq ! ( order_updated. client_order_id, client_order_id) ;
2283
+ assert_eq ! ( order_updated. trigger_price. unwrap( ) , new_trigger_price) ;
2284
+ }
0 commit comments