@@ -344,17 +344,17 @@ def __bool__(self):
344344 @property
345345 def size (self ) -> float :
346346 """Position size in units of asset. Negative if position is short."""
347- return self .__broker ._open_trade_size_sum
347+ return self .__broker ._position_size
348348
349349 @property
350350 def pl (self ) -> float :
351351 """Profit (positive) or loss (negative) of the current position in cash units."""
352- return self .__broker .unrealized_pl
352+ return self .__broker ._position_unrealized_pl
353353
354354 @property
355355 def pl_pct (self ) -> float :
356356 """Profit (positive) or loss (negative) of the current position in percent."""
357- total_invested = self .__broker ._open_trade_entry_abs_value_sum
357+ total_invested = self .__broker ._position_initial_value
358358 return (self .pl / total_invested ) * 100 if total_invested else 0
359359
360360 @property
@@ -812,28 +812,22 @@ def new_order(self,
812812 return order
813813
814814 @cached_property
815- def _open_trade_size_sum (self ) -> int :
815+ def _position_size (self ) -> int :
816816 return sum (int (trade .size ) for trade in self .trades )
817817
818818 @cached_property
819- def _open_trade_entry_value_sum (self ) -> float :
820- return sum (trade .size * trade .entry_price for trade in self .trades )
819+ def _position_initial_value (self ) -> float :
820+ return sum (abs ( trade .size ) * trade .entry_price for trade in self .trades )
821821
822822 @cached_property
823- def _open_trade_entry_abs_value_sum (self ) -> float :
824- return sum (abs (trade .size ) * trade .entry_price for trade in self .trades )
823+ def _position_unrealized_pl (self ) -> float :
824+ return (self .last_price * self ._position_size -
825+ sum (trade .size * trade .entry_price for trade in self .trades ))
825826
826- def _clear_trade_caches (self ) -> None :
827- self .__dict__ .pop ('_open_trade_size_sum' , None )
828- self .__dict__ .pop ('_open_trade_entry_value_sum' , None )
829- self .__dict__ .pop ('_open_trade_entry_abs_value_sum' , None )
830-
831- @property
832- def unrealized_pl (self ) -> float :
833- if not self .trades :
834- return 0.0
835- current_price = float (self ._data ._current_value ("Close" ))
836- return current_price * self ._open_trade_size_sum - self ._open_trade_entry_value_sum
827+ def _trades_cache_clear (self ) -> None :
828+ self .__dict__ .pop (self .__class__ ._position_size .func .__name__ , None )
829+ self .__dict__ .pop (self .__class__ ._position_initial_value .func .__name__ , None )
830+ self .__dict__ .pop (self .__class__ ._position_unrealized_pl .func .__name__ , None )
837831
838832 @property
839833 def last_price (self ) -> float :
@@ -849,7 +843,7 @@ def _adjusted_price(self, size=None, price=None) -> float:
849843
850844 @property
851845 def equity (self ) -> float :
852- return self ._cash + self .unrealized_pl
846+ return self ._cash + self ._position_unrealized_pl
853847
854848 @property
855849 def margin_available (self ) -> float :
@@ -858,6 +852,9 @@ def margin_available(self) -> float:
858852 return max (0 , self .equity - margin_used )
859853
860854 def next (self ):
855+ # Reset cached value here due to price change on every bar
856+ self .__dict__ .pop (self .__class__ ._position_unrealized_pl .func .__name__ , None )
857+
861858 i = self ._i = len (self ._data ) - 1
862859 self ._process_orders ()
863860
@@ -1054,7 +1051,7 @@ def _process_orders(self):
10541051 def _reduce_trade (self , trade : Trade , price : float , size : float , time_index : int ):
10551052 assert trade .size * size < 0
10561053 assert abs (trade .size ) >= abs (size )
1057- self ._clear_trade_caches ()
1054+ self ._trades_cache_clear ()
10581055
10591056 size_left = trade .size + size
10601057 assert size_left * trade .size >= 0
@@ -1075,7 +1072,7 @@ def _reduce_trade(self, trade: Trade, price: float, size: float, time_index: int
10751072 self ._close_trade (close_trade , price , time_index )
10761073
10771074 def _close_trade (self , trade : Trade , price : float , time_index : int ):
1078- self ._clear_trade_caches ()
1075+ self ._trades_cache_clear ()
10791076 self .trades .remove (trade )
10801077 if trade ._sl_order :
10811078 self .orders .remove (trade ._sl_order )
@@ -1097,9 +1094,9 @@ def _open_trade(self, price: float, size: int,
10971094 sl : Optional [float ], tp : Optional [float ], time_index : int , tag ):
10981095 trade = Trade (self , size , price , time_index , tag )
10991096 self .trades .append (trade )
1097+ self ._trades_cache_clear ()
11001098 # Apply broker commission at trade open
11011099 self ._cash -= self ._commission (size , price )
1102- self ._clear_trade_caches ()
11031100 # Create SL/TP (bracket) orders.
11041101 if tp :
11051102 trade .tp = tp
0 commit comments