@@ -27,7 +27,6 @@ from nautilus_trader.model.c_enums.liquidity_side cimport LiquiditySide
27
27
from nautilus_trader.model.c_enums.oms_type cimport OMSType
28
28
from nautilus_trader.model.c_enums.order_side cimport OrderSide
29
29
from nautilus_trader.model.c_enums.order_side cimport OrderSideParser
30
- from nautilus_trader.model.c_enums.order_state cimport OrderState
31
30
from nautilus_trader.model.c_enums.order_type cimport OrderType
32
31
from nautilus_trader.model.c_enums.price_type cimport PriceType
33
32
from nautilus_trader.model.commands cimport AmendOrder
@@ -499,10 +498,6 @@ cdef class SimulatedExchange:
499
498
self .exec_client.handle_event(accepted)
500
499
501
500
cdef inline void _reject_order(self , Order order, str reason) except * :
502
- if order.state_c() != OrderState.SUBMITTED:
503
- self ._log.error(f" Cannot reject order: state was {order.state_string_c()}." )
504
- return
505
-
506
501
# Generate event
507
502
cdef OrderRejected rejected = OrderRejected(
508
503
self .exec_client.account_id,
@@ -537,17 +532,8 @@ cdef class SimulatedExchange:
537
532
)
538
533
return # Cannot amend order
539
534
540
- cdef Price bid = self ._market_bids.get(order.symbol)
541
- cdef Price ask = self ._market_asks.get(order.symbol)
542
-
543
- # Check market exists
544
- if bid is None or ask is None : # Market not initialized
545
- self ._cancel_reject(
546
- cl_ord_id,
547
- " amend order" ,
548
- f" no market for {order.symbol}" ,
549
- )
550
- return # Cannot amend order
535
+ cdef Price bid = self ._market_bids[order.symbol] # Market must exist
536
+ cdef Price ask = self ._market_asks[order.symbol] # Market must exist
551
537
552
538
if order.type == OrderType.LIMIT:
553
539
self ._amend_limit_order(order, qty, price, bid, ask)
@@ -689,7 +675,7 @@ cdef class SimulatedExchange:
689
675
raise RuntimeError (f" Invalid order type" )
690
676
691
677
cdef inline void _process_market_order(self , MarketOrder order, Price bid, Price ask) except * :
692
- self ._accept_order(order) # Some exchanges just immediately fill
678
+ self ._accept_order(order)
693
679
694
680
# Immediately fill marketable order
695
681
self ._fill_order(
@@ -703,7 +689,7 @@ cdef class SimulatedExchange:
703
689
if self ._is_limit_marketable(order.side, order.price, bid, ask):
704
690
self ._reject_order(
705
691
order,
706
- f" {OrderSideParser.to_str(order.side)} POST_ONLY LIMIT order "
692
+ f" POST_ONLY LIMIT {OrderSideParser.to_str(order.side)} order "
707
693
f" limit px of {order.price} would have been a TAKER: bid={bid}, ask={ask}" ,
708
694
)
709
695
return # Invalid price
@@ -722,8 +708,8 @@ cdef class SimulatedExchange:
722
708
if self ._is_stop_marketable(order.side, order.price, bid, ask):
723
709
self ._reject_order(
724
710
order,
725
- f" {OrderSideParser.to_str(order.side)} STOP order "
726
- f" px of {order.price} was in the market: bid={bid}, ask={ask}" ,
711
+ f" STOP {OrderSideParser.to_str(order.side)} order "
712
+ f" stop px of {order.price} was in the market: bid={bid}, ask={ask}" ,
727
713
)
728
714
return # Invalid price
729
715
@@ -735,8 +721,8 @@ cdef class SimulatedExchange:
735
721
if self ._is_stop_marketable(order.side, order.trigger, bid, ask):
736
722
self ._reject_order(
737
723
order,
738
- f" {OrderSideParser.to_str(order.side)} STOP_LIMIT order "
739
- f" trigger px of {order.trigger} was in the market: bid={bid}, ask={ask}" ,
724
+ f" STOP_LIMIT {OrderSideParser.to_str(order.side)} order "
725
+ f" trigger stop px of {order.trigger} was in the market: bid={bid}, ask={ask}" ,
740
726
)
741
727
return # Invalid price
742
728
@@ -758,8 +744,8 @@ cdef class SimulatedExchange:
758
744
self ._cancel_reject(
759
745
order.cl_ord_id,
760
746
" amend order" ,
761
- f" {OrderSideParser.to_str(order.side)} POST_ONLY LIMIT order "
762
- f" amended limit px of {price} would have been TAKER: bid={bid}, ask={ask}" ,
747
+ f" POST_ONLY LIMIT {OrderSideParser.to_str(order.side)} order "
748
+ f" amended limit px of {price} would have been a TAKER: bid={bid}, ask={ask}" ,
763
749
)
764
750
return # Cannot amend order
765
751
else :
@@ -784,7 +770,7 @@ cdef class SimulatedExchange:
784
770
self ._cancel_reject(
785
771
order.cl_ord_id,
786
772
" amend order" ,
787
- f" {OrderSideParser.to_str(order.side)} STOP order "
773
+ f" STOP {OrderSideParser.to_str(order.side)} order "
788
774
f" amended stop px of {price} was in the market: bid={bid}, ask={ask}" ,
789
775
)
790
776
return # Cannot amend order
@@ -806,7 +792,7 @@ cdef class SimulatedExchange:
806
792
self ._cancel_reject(
807
793
order.cl_ord_id,
808
794
" amend order" ,
809
- f" {OrderSideParser.to_str(order.side)} STOP_LIMIT order "
795
+ f" STOP_LIMIT {OrderSideParser.to_str(order.side)} order "
810
796
f" amended stop px trigger of {price} was in the market: bid={bid}, ask={ask}" ,
811
797
)
812
798
return # Cannot amend order
@@ -819,8 +805,8 @@ cdef class SimulatedExchange:
819
805
self ._cancel_reject(
820
806
order.cl_ord_id,
821
807
" amend order" ,
822
- f" {OrderSideParser.to_str(order.side)} POST_ONLY LIMIT order "
823
- f" amended limit px of {price} would have been TAKER: bid={bid}, ask={ask}" ,
808
+ f" POST_ONLY LIMIT {OrderSideParser.to_str(order.side)} order "
809
+ f" amended limit px of {price} would have been a TAKER: bid={bid}, ask={ask}" ,
824
810
)
825
811
return # Cannot amend order
826
812
else :
@@ -873,33 +859,36 @@ cdef class SimulatedExchange:
873
859
self ._fill_order(
874
860
order,
875
861
self ._fill_price_stop(order.symbol, order.side, order.price),
876
- LiquiditySide.TAKER,
862
+ LiquiditySide.TAKER, # Triggered stop places market order
877
863
)
878
864
879
865
cdef inline void _match_stop_limit_order(self , StopLimitOrder order, Price bid, Price ask) except * :
880
- if not order.is_triggered:
866
+ if order.is_triggered:
867
+ if self ._is_limit_matched(order.side, order.price, bid, ask):
868
+ self ._fill_order(
869
+ order,
870
+ order.price, # Price is 'guaranteed' (negative slippage not currently modeled)
871
+ LiquiditySide.MAKER, # Providing liquidity
872
+ )
873
+ else : # Order not triggered
881
874
if self ._is_stop_triggered(order.side, order.trigger, bid, ask):
882
875
self ._trigger_order(order)
883
876
884
- # Check for immediate fill
885
- if self ._is_limit_marketable(order.side, order.price, bid, ask):
886
- if order.is_post_only: # Would be liquidity taker
887
- del self ._working_orders[order.cl_ord_id] # Remove order from working orders
888
- self ._reject_order(order, " post-only order would have been TAKER" )
889
- else :
890
- self ._fill_order(
891
- order,
892
- self ._fill_price_taker(order.symbol, order.side, bid, ask),
893
- LiquiditySide.TAKER, # Immediate fill takes liquidity
894
- )
895
- return # Triggered, rejected or filled
896
-
897
- if self ._is_limit_matched(order.side, order.price, bid, ask):
898
- self ._fill_order(
899
- order,
900
- order.price, # Price is 'guaranteed' (negative slippage not currently modeled)
901
- LiquiditySide.MAKER, # Providing liquidity
902
- )
877
+ # Check for immediate fill
878
+ if self ._is_limit_marketable(order.side, order.price, bid, ask):
879
+ if order.is_post_only: # Would be liquidity taker
880
+ del self ._working_orders[order.cl_ord_id] # Remove order from working orders
881
+ self ._reject_order(
882
+ order,
883
+ f" POST_ONLY LIMIT {OrderSideParser.to_str(order.side)} order "
884
+ f" limit px of {order.price} would have been a TAKER: bid={bid}, ask={ask}" ,
885
+ )
886
+ else :
887
+ self ._fill_order(
888
+ order,
889
+ self ._fill_price_taker(order.symbol, order.side, bid, ask),
890
+ LiquiditySide.TAKER, # Immediate fill takes liquidity
891
+ )
903
892
904
893
cdef inline bint _is_limit_marketable(self , OrderSide side, Price order_price, Price bid, Price ask) except * :
905
894
if side == OrderSide.BUY:
0 commit comments