1212import warnings
1313from abc import ABCMeta , abstractmethod
1414from copy import copy
15- from functools import lru_cache , partial
15+ from functools import cached_property , lru_cache , partial
1616from itertools import chain , product , repeat
1717from math import copysign
1818from numbers import Number
@@ -362,8 +362,6 @@ def __bool__(self):
362362 @property
363363 def size (self ) -> float :
364364 """Position size in units of asset. Negative if position is short."""
365- if self .__broker ._trade_sums_dirty :
366- self .__broker ._recalculate_trade_sums ()
367365 return self .__broker ._open_trade_size_sum
368366
369367 @property
@@ -374,8 +372,6 @@ def pl(self) -> float:
374372 @property
375373 def pl_pct (self ) -> float :
376374 """Profit (positive) or loss (negative) of the current position in percent."""
377- if self .__broker ._trade_sums_dirty :
378- self .__broker ._recalculate_trade_sums ()
379375 total_invested = self .__broker ._open_trade_entry_abs_value_sum
380376 return (self .pl / total_invested ) * 100 if total_invested else 0
381377
@@ -776,10 +772,6 @@ def __init__(self, *, data, cash, spread, commission, margin,
776772 self .trades : List [Trade ] = []
777773 self .position = Position (self )
778774 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
783775
784776 def _commission_func (self , order_size , price ):
785777 return self ._commission_fixed + abs (order_size ) * price * self ._commission_relative
@@ -837,23 +829,25 @@ def new_order(self,
837829
838830 return order
839831
840- def _mark_trade_sums_dirty (self ) -> None :
841- self ._trade_sums_dirty = True
832+ @cached_property
833+ def _open_trade_size_sum (self ) -> int :
834+ return sum (int (trade .size ) for trade in self .trades )
842835
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
836+ @cached_property
837+ def _open_trade_entry_value_sum (self ) -> float :
838+ return sum (trade .size * trade .entry_price for trade in self .trades )
839+
840+ @cached_property
841+ def _open_trade_entry_abs_value_sum (self ) -> float :
842+ return sum (abs (trade .size ) * trade .entry_price for trade in self .trades )
843+
844+ def _clear_trade_caches (self ) -> None :
845+ self .__dict__ .pop ('_open_trade_size_sum' , None )
846+ self .__dict__ .pop ('_open_trade_entry_value_sum' , None )
847+ self .__dict__ .pop ('_open_trade_entry_abs_value_sum' , None )
852848
853849 @property
854850 def unrealized_pl (self ) -> float :
855- if self ._trade_sums_dirty :
856- self ._recalculate_trade_sums ()
857851 if not self .trades :
858852 return 0.0
859853 current_price = float (self ._data ._current_value ("Close" ))
@@ -1099,7 +1093,7 @@ def _process_orders(self):
10991093 def _reduce_trade (self , trade : Trade , price : float , size : float , time_index : int ):
11001094 assert trade .size * size < 0
11011095 assert abs (trade .size ) >= abs (size )
1102- self ._mark_trade_sums_dirty ()
1096+ self ._clear_trade_caches ()
11031097
11041098 size_left = trade .size + size
11051099 assert size_left * trade .size >= 0
@@ -1120,7 +1114,7 @@ def _reduce_trade(self, trade: Trade, price: float, size: float, time_index: int
11201114 self ._close_trade (close_trade , price , time_index )
11211115
11221116 def _close_trade (self , trade : Trade , price : float , time_index : int ):
1123- self ._mark_trade_sums_dirty ()
1117+ self ._clear_trade_caches ()
11241118 self .trades .remove (trade )
11251119 if trade ._sl_order :
11261120 self .orders .remove (trade ._sl_order )
@@ -1144,7 +1138,7 @@ def _open_trade(self, price: float, size: int,
11441138 self .trades .append (trade )
11451139 # Apply broker commission at trade open
11461140 self ._cash -= self ._commission (size , price )
1147- self ._mark_trade_sums_dirty ()
1141+ self ._clear_trade_caches ()
11481142 # Create SL/TP (bracket) orders.
11491143 if tp :
11501144 trade .tp = tp
0 commit comments