@@ -362,17 +362,21 @@ def __bool__(self):
362362 @property
363363 def size (self ) -> float :
364364 """Position size in units of asset. Negative if position is short."""
365- return sum (trade .size for trade in self .__broker .trades )
365+ if self .__broker ._trade_sums_dirty :
366+ self .__broker ._recalculate_trade_sums ()
367+ return self .__broker ._open_trade_size_sum
366368
367369 @property
368370 def pl (self ) -> float :
369371 """Profit (positive) or loss (negative) of the current position in cash units."""
370- return sum ( trade . pl for trade in self .__broker .trades )
372+ return self .__broker .unrealized_pl
371373
372374 @property
373375 def pl_pct (self ) -> float :
374376 """Profit (positive) or loss (negative) of the current position in percent."""
375- total_invested = sum (trade .entry_price * abs (trade .size ) for trade in self .__broker .trades )
377+ if self .__broker ._trade_sums_dirty :
378+ self .__broker ._recalculate_trade_sums ()
379+ total_invested = self .__broker ._open_trade_entry_abs_value_sum
376380 return (self .pl / total_invested ) * 100 if total_invested else 0
377381
378382 @property
@@ -772,6 +776,10 @@ def __init__(self, *, data, cash, spread, commission, margin,
772776 self .trades : List [Trade ] = []
773777 self .position = Position (self )
774778 self .closed_trades : List [Trade ] = []
779+ self ._trade_sums_dirty = True
780+ self ._open_trade_size_sum = 0
781+ self ._open_trade_entry_value_sum = 0.0
782+ self ._open_trade_entry_abs_value_sum = 0.0
775783
776784 def _commission_func (self , order_size , price ):
777785 return self ._commission_fixed + abs (order_size ) * price * self ._commission_relative
@@ -829,6 +837,28 @@ def new_order(self,
829837
830838 return order
831839
840+ def _mark_trade_sums_dirty (self ) -> None :
841+ self ._trade_sums_dirty = True
842+
843+ def _recalculate_trade_sums (self ) -> None :
844+ self ._open_trade_size_sum = sum (int (trade .size ) for trade in self .trades )
845+ self ._open_trade_entry_value_sum = sum (
846+ trade .size * trade .entry_price for trade in self .trades
847+ )
848+ self ._open_trade_entry_abs_value_sum = sum (
849+ abs (trade .size ) * trade .entry_price for trade in self .trades
850+ )
851+ self ._trade_sums_dirty = False
852+
853+ @property
854+ def unrealized_pl (self ) -> float :
855+ if self ._trade_sums_dirty :
856+ self ._recalculate_trade_sums ()
857+ if not self .trades :
858+ return 0.0
859+ current_price = float (self ._data .current_value ("Close" ))
860+ return current_price * self ._open_trade_size_sum - self ._open_trade_entry_value_sum
861+
832862 @property
833863 def last_price (self ) -> float :
834864 """ Price at the last (current) close. """
@@ -843,7 +873,7 @@ def _adjusted_price(self, size=None, price=None) -> float:
843873
844874 @property
845875 def equity (self ) -> float :
846- return self ._cash + sum ( trade . pl for trade in self .trades )
876+ return self ._cash + self .unrealized_pl
847877
848878 @property
849879 def margin_available (self ) -> float :
@@ -1071,6 +1101,7 @@ def _process_orders(self):
10711101 def _reduce_trade (self , trade : Trade , price : float , size : float , time_index : int ):
10721102 assert trade .size * size < 0
10731103 assert abs (trade .size ) >= abs (size )
1104+ self ._mark_trade_sums_dirty ()
10741105
10751106 size_left = trade .size + size
10761107 assert size_left * trade .size >= 0
@@ -1091,6 +1122,7 @@ def _reduce_trade(self, trade: Trade, price: float, size: float, time_index: int
10911122 self ._close_trade (close_trade , price , time_index )
10921123
10931124 def _close_trade (self , trade : Trade , price : float , time_index : int ):
1125+ self ._mark_trade_sums_dirty ()
10941126 self .trades .remove (trade )
10951127 if trade ._sl_order :
10961128 self .orders .remove (trade ._sl_order )
@@ -1114,6 +1146,7 @@ def _open_trade(self, price: float, size: int,
11141146 self .trades .append (trade )
11151147 # Apply broker commission at trade open
11161148 self ._cash -= self ._commission (size , price )
1149+ self ._mark_trade_sums_dirty ()
11171150 # Create SL/TP (bracket) orders.
11181151 if tp :
11191152 trade .tp = tp
0 commit comments