@@ -105,18 +105,26 @@ where
105105 mut order : Order ,
106106 recv_timestamp : i64 ,
107107 ) -> Result < ( ) , BacktestError > {
108+ order. req = Status :: None ;
109+
108110 // Processes a new order.
109111 if order. req == Status :: New {
110- order. req = Status :: None ;
111- self . ack_new ( order, recv_timestamp) ?;
112+ self . ack_new ( & mut order, recv_timestamp) ?;
112113 }
113114 // Processes a cancel order.
114115 else if order. req == Status :: Canceled {
115- order. req = Status :: None ;
116- self . ack_cancel ( order, recv_timestamp) ?;
116+ self . ack_cancel ( & mut order, recv_timestamp) ?;
117+ }
118+ // Processes a modify order.
119+ else if order. req == Status :: Replaced {
120+ self . ack_modify :: < false > ( & mut order, recv_timestamp) ?;
117121 } else {
118122 return Err ( BacktestError :: InvalidOrderRequest ) ;
119123 }
124+ // Makes the response.
125+ let local_recv_timestamp =
126+ recv_timestamp + self . order_latency . response ( recv_timestamp, & order) ;
127+ self . orders_to . append ( order, local_recv_timestamp) ;
120128 Ok ( ( ) )
121129 }
122130
@@ -125,14 +133,14 @@ where
125133 order. leaves_qty = 0.0 ;
126134 order. status = Status :: Expired ;
127135 order. exch_timestamp = timestamp;
136+
128137 let local_recv_timestamp =
129138 order. exch_timestamp + self . order_latency . response ( timestamp, & order) ;
130-
131139 self . orders_to . append ( order, local_recv_timestamp) ;
132140 Ok ( ( ) )
133141 }
134142
135- fn fill (
143+ fn fill < const INSERT_BUS : bool > (
136144 & mut self ,
137145 order : & mut Order ,
138146 timestamp : i64 ,
@@ -157,11 +165,14 @@ where
157165 order. leaves_qty = 0.0 ;
158166 order. status = Status :: Filled ;
159167 order. exch_timestamp = timestamp;
160- let local_recv_timestamp =
161- order. exch_timestamp + self . order_latency . response ( timestamp, order) ;
162168
163169 self . state . apply_fill ( order) ;
164- self . orders_to . append ( order. clone ( ) , local_recv_timestamp) ;
170+
171+ if INSERT_BUS {
172+ let local_recv_timestamp =
173+ order. exch_timestamp + self . order_latency . response ( timestamp, order) ;
174+ self . orders_to . append ( order. clone ( ) , local_recv_timestamp) ;
175+ }
165176 Ok ( ( ) )
166177 }
167178
@@ -176,7 +187,7 @@ where
176187 . on_best_bid_update ( prev_best_tick, new_best_tick) ?;
177188 for mut order in filled {
178189 let price_tick = order. price_tick ;
179- self . fill ( & mut order, timestamp, true , price_tick) ?;
190+ self . fill :: < true > ( & mut order, timestamp, true , price_tick) ?;
180191 }
181192 Ok ( ( ) )
182193 }
@@ -192,12 +203,12 @@ where
192203 . on_best_ask_update ( prev_best_tick, new_best_tick) ?;
193204 for mut order in filled {
194205 let price_tick = order. price_tick ;
195- self . fill ( & mut order, timestamp, true , price_tick) ?;
206+ self . fill :: < true > ( & mut order, timestamp, true , price_tick) ?;
196207 }
197208 Ok ( ( ) )
198209 }
199210
200- fn ack_new ( & mut self , mut order : Order , timestamp : i64 ) -> Result < ( ) , BacktestError > {
211+ fn ack_new ( & mut self , order : & mut Order , timestamp : i64 ) -> Result < ( ) , BacktestError > {
201212 if self . queue_model . contains_backtest_order ( order. order_id ) {
202213 return Err ( BacktestError :: OrderIdExist ) ;
203214 }
@@ -210,18 +221,19 @@ where
210221 match order. time_in_force {
211222 TimeInForce :: GTX => {
212223 order. status = Status :: Expired ;
213-
214224 order. exch_timestamp = timestamp;
215- let local_recv_timestamp =
216- timestamp + self . order_latency . response ( timestamp, & order) ;
217- self . orders_to . append ( order. clone ( ) , local_recv_timestamp) ;
218225 Ok ( ( ) )
219226 }
220227 TimeInForce :: GTC | TimeInForce :: FOK | TimeInForce :: IOC => {
221228 // Since this always fills the full quantity, both FOK and IOC
222229 // orders are also fully filled at the best price.
223230 // Takes the market.
224- self . fill ( & mut order, timestamp, false , self . depth . best_ask_tick ( ) )
231+ self . fill :: < false > (
232+ order,
233+ timestamp,
234+ false ,
235+ self . depth . best_ask_tick ( ) ,
236+ )
225237 }
226238 TimeInForce :: Unsupported => Err ( BacktestError :: InvalidOrderRequest ) ,
227239 }
@@ -234,19 +246,11 @@ where
234246
235247 self . queue_model
236248 . add_backtest_order ( order. clone ( ) , & self . depth ) ?;
237-
238- let local_recv_timestamp =
239- timestamp + self . order_latency . response ( timestamp, & order) ;
240- self . orders_to . append ( order, local_recv_timestamp) ;
241249 Ok ( ( ) )
242250 }
243251 TimeInForce :: FOK | TimeInForce :: IOC => {
244252 order. status = Status :: Expired ;
245-
246253 order. exch_timestamp = timestamp;
247- let local_recv_timestamp =
248- timestamp + self . order_latency . response ( timestamp, & order) ;
249- self . orders_to . append ( order. clone ( ) , local_recv_timestamp) ;
250254 Ok ( ( ) )
251255 }
252256 TimeInForce :: Unsupported => Err ( BacktestError :: InvalidOrderRequest ) ,
@@ -255,7 +259,7 @@ where
255259 }
256260 OrdType :: Market => {
257261 // Takes the market.
258- self . fill ( & mut order, timestamp, false , self . depth . best_ask_tick ( ) )
262+ self . fill :: < false > ( order, timestamp, false , self . depth . best_ask_tick ( ) )
259263 }
260264 OrdType :: Unsupported => Err ( BacktestError :: InvalidOrderRequest ) ,
261265 }
@@ -267,18 +271,19 @@ where
267271 match order. time_in_force {
268272 TimeInForce :: GTX => {
269273 order. status = Status :: Expired ;
270-
271274 order. exch_timestamp = timestamp;
272- let local_recv_timestamp =
273- timestamp + self . order_latency . response ( timestamp, & order) ;
274- self . orders_to . append ( order. clone ( ) , local_recv_timestamp) ;
275275 Ok ( ( ) )
276276 }
277277 TimeInForce :: GTC | TimeInForce :: FOK | TimeInForce :: IOC => {
278278 // Since this always fills the full quantity, both FOK and IOC
279279 // orders are also fully filled at the best price.
280280 // Takes the market.
281- self . fill ( & mut order, timestamp, false , self . depth . best_bid_tick ( ) )
281+ self . fill :: < false > (
282+ order,
283+ timestamp,
284+ false ,
285+ self . depth . best_bid_tick ( ) ,
286+ )
282287 }
283288 TimeInForce :: Unsupported => Err ( BacktestError :: InvalidOrderRequest ) ,
284289 }
@@ -291,19 +296,11 @@ where
291296
292297 self . queue_model
293298 . add_backtest_order ( order. clone ( ) , & self . depth ) ?;
294-
295- let local_recv_timestamp =
296- timestamp + self . order_latency . response ( timestamp, & order) ;
297- self . orders_to . append ( order, local_recv_timestamp) ;
298299 Ok ( ( ) )
299300 }
300301 TimeInForce :: FOK | TimeInForce :: IOC => {
301302 order. status = Status :: Expired ;
302-
303303 order. exch_timestamp = timestamp;
304- let local_recv_timestamp =
305- timestamp + self . order_latency . response ( timestamp, & order) ;
306- self . orders_to . append ( order. clone ( ) , local_recv_timestamp) ;
307304 Ok ( ( ) )
308305 }
309306 TimeInForce :: Unsupported => Err ( BacktestError :: InvalidOrderRequest ) ,
@@ -312,42 +309,54 @@ where
312309 }
313310 OrdType :: Market => {
314311 // Takes the market.
315- self . fill ( & mut order, timestamp, false , self . depth . best_bid_tick ( ) )
312+ self . fill :: < false > ( order, timestamp, false , self . depth . best_bid_tick ( ) )
316313 }
317314 OrdType :: Unsupported => Err ( BacktestError :: InvalidOrderRequest ) ,
318315 }
319316 }
320317 }
321318
322- fn ack_cancel ( & mut self , mut order : Order , timestamp : i64 ) -> Result < ( ) , BacktestError > {
319+ fn ack_cancel ( & mut self , order : & mut Order , timestamp : i64 ) -> Result < ( ) , BacktestError > {
323320 match self
324321 . queue_model
325322 . cancel_backtest_order ( order. order_id , & self . depth )
326323 {
327- Ok ( mut exch_order) => {
328- // Makes the response.
329- exch_order. status = Status :: Canceled ;
330- exch_order. exch_timestamp = timestamp;
331- let local_recv_timestamp =
332- timestamp + self . order_latency . response ( timestamp, & exch_order) ;
333- self . orders_to
334- . append ( exch_order. clone ( ) , local_recv_timestamp) ;
324+ Ok ( exch_order) => {
325+ let _ = std:: mem:: replace ( order, exch_order) ;
326+
327+ order. status = Status :: Canceled ;
328+ order. exch_timestamp = timestamp;
335329 Ok ( ( ) )
336330 }
337331 Err ( BacktestError :: OrderNotFound ) => {
338332 order. req = Status :: Rejected ;
339333 order. exch_timestamp = timestamp;
340- let local_recv_timestamp =
341- timestamp + self . order_latency . response ( timestamp, & order) ;
342- self . orders_to . append ( order, local_recv_timestamp) ;
343334 Ok ( ( ) )
344335 }
345336 Err ( e) => Err ( e) ,
346337 }
347338 }
348339
349- fn ack_modify ( & mut self , mut order : Order , timestamp : i64 ) -> Result < ( ) , BacktestError > {
350- todo ! ( )
340+ fn ack_modify < const RESET_QUEUE_POS : bool > (
341+ & mut self ,
342+ order : & mut Order ,
343+ timestamp : i64 ,
344+ ) -> Result < ( ) , BacktestError > {
345+ match self
346+ . queue_model
347+ . modify_backtest_order ( order. order_id , order, & self . depth )
348+ {
349+ Ok ( ( ) ) => {
350+ order. exch_timestamp = timestamp;
351+ Ok ( ( ) )
352+ }
353+ Err ( BacktestError :: OrderNotFound ) => {
354+ order. req = Status :: Rejected ;
355+ order. exch_timestamp = timestamp;
356+ Ok ( ( ) )
357+ }
358+ Err ( e) => Err ( e) ,
359+ }
351360 }
352361}
353362
@@ -428,7 +437,7 @@ where
428437 let timestamp = event. exch_ts ;
429438 for mut order in filled {
430439 let price_tick = order. price_tick ;
431- self . fill ( & mut order, timestamp, true , price_tick) ?;
440+ self . fill :: < true > ( & mut order, timestamp, true , price_tick) ?;
432441 }
433442 }
434443 }
0 commit comments