@@ -870,7 +870,9 @@ def next(self):
870870
871871 def _process_orders (self ):
872872 data = self ._data
873- open , high , low = data .Open [- 1 ], data .High [- 1 ], data .Low [- 1 ]
873+ open_price = data .current_value ("Open" )
874+ high_price = data .current_value ("High" )
875+ low_price = data .current_value ("Low" )
874876 reprocess_orders = False
875877
876878 # Process orders
@@ -883,7 +885,9 @@ def _process_orders(self):
883885 # Check if stop condition was hit
884886 stop_price = order .stop
885887 if stop_price :
886- is_stop_hit = ((high >= stop_price ) if order .is_long else (low <= stop_price ))
888+ is_stop_hit = (
889+ high_price >= stop_price if order .is_long else low_price <= stop_price
890+ )
887891 if not is_stop_hit :
888892 continue
889893
@@ -894,7 +898,9 @@ def _process_orders(self):
894898 # Determine purchase price.
895899 # Check if limit order can be filled.
896900 if order .limit :
897- is_limit_hit = low <= order .limit if order .is_long else high >= order .limit
901+ is_limit_hit = (
902+ low_price <= order .limit if order .is_long else high_price >= order .limit
903+ )
898904 # When stop and limit are hit within the same bar, we pessimistically
899905 # assume limit was hit before the stop (i.e. "before it counts")
900906 is_limit_hit_before_stop = (is_limit_hit and
@@ -905,14 +911,20 @@ def _process_orders(self):
905911 continue
906912
907913 # stop_price, if set, was hit within this bar
908- price = (min (stop_price or open , order .limit )
909- if order .is_long else
910- max (stop_price or open , order .limit ))
914+ price = (
915+ min (stop_price or open_price , order .limit )
916+ if order .is_long
917+ else max (stop_price or open_price , order .limit )
918+ )
911919 else :
912920 # Market-if-touched / market order
913921 # Contingent orders always on next open
914922 prev_close = data .Close [- 2 ]
915- price = prev_close if self ._trade_on_close and not order .is_contingent else open
923+ price = (
924+ prev_close
925+ if self ._trade_on_close and not order .is_contingent
926+ else open_price
927+ )
916928 if stop_price :
917929 price = max (price , stop_price ) if order .is_long else min (price , stop_price )
918930
@@ -1018,12 +1030,28 @@ def _process_orders(self):
10181030 reprocess_orders = True
10191031 # Order.stop and TP hit within the same bar, but SL wasn't. This case
10201032 # is not ambiguous, because stop and TP go in the same price direction.
1021- elif stop_price and not order .limit and order .tp and (
1022- (order .is_long and order .tp <= high and (order .sl or - np .inf ) < low ) or
1023- (order .is_short and order .tp >= low and (order .sl or np .inf ) > high )):
1033+ elif (
1034+ stop_price
1035+ and not order .limit
1036+ and order .tp
1037+ and (
1038+ (
1039+ order .is_long
1040+ and order .tp <= high_price
1041+ and (order .sl or - np .inf ) < low_price
1042+ )
1043+ or (
1044+ order .is_short
1045+ and order .tp >= low_price
1046+ and (order .sl or np .inf ) > high_price
1047+ )
1048+ )
1049+ ):
10241050 reprocess_orders = True
1025- elif (low <= (order .sl or - np .inf ) <= high or
1026- low <= (order .tp or - np .inf ) <= high ):
1051+ elif (
1052+ low_price <= (order .sl or - np .inf ) <= high_price
1053+ or low_price <= (order .tp or - np .inf ) <= high_price
1054+ ):
10271055 warnings .warn (
10281056 f"({ data .index [- 1 ]} ) A contingent SL/TP order would execute in the "
10291057 "same bar its parent stop/limit order was turned into a trade. "
0 commit comments