@@ -781,16 +781,18 @@ async def _bar_timer_loop(self) -> None:
781781 interval = tf_config ["interval" ]
782782 unit = tf_config ["unit" ]
783783
784- # Convert to seconds based on numeric unit
785- # Units: 1=seconds, 2=minutes, 4=days, 5=weeks, 6=months
786- if unit == 1 : # seconds
787- seconds = interval
788- elif unit == 2 : # minutes
789- seconds = interval * 60
790- elif unit == 4 : # days
791- seconds = interval * 86400
792- elif unit == 5 : # weeks
793- seconds = interval * 604800
784+ # Convert to seconds based on numeric unit value
785+ # Unit mapping: {1: seconds, 2: minutes, 4: days, 5: weeks, 6: months}
786+ unit_seconds_map = {
787+ 1 : 1 , # seconds
788+ 2 : 60 , # minutes
789+ 4 : 86400 , # days
790+ 5 : 604800 , # weeks
791+ 6 : 2629746 , # months (approximate)
792+ }
793+
794+ if unit in unit_seconds_map :
795+ seconds = interval * unit_seconds_map [unit ]
794796 else :
795797 continue # Skip unsupported units
796798
@@ -841,17 +843,24 @@ async def _check_and_create_empty_bars(self) -> None:
841843 current_data .select (pl .col ("timestamp" )).tail (1 ).item ()
842844 )
843845
844- # Calculate what the current bar time should be
845- expected_bar_time = self ._calculate_bar_time (
846- current_time , tf_config ["interval" ], tf_config ["unit" ]
847- )
846+ try :
847+ # Calculate what the current bar time should be
848+ expected_bar_time = self ._calculate_bar_time (
849+ current_time , tf_config ["interval" ], tf_config ["unit" ]
850+ )
851+ except Exception as e :
852+ self .logger .error (
853+ f"Error calculating bar time for { tf_key } : { e } "
854+ )
855+ continue # Skip this timeframe if calculation fails
848856
849857 # If we're missing bars, create empty ones
850858 if expected_bar_time > last_bar_time :
851859 # Get the last close price to use for empty bars
852860 last_close = current_data .select (pl .col ("close" )).tail (1 ).item ()
853861
854862 # Create empty bar with last close as OHLC, volume=0
863+ # Using DataFrame constructor is efficient for single rows
855864 new_bar = pl .DataFrame (
856865 {
857866 "timestamp" : [expected_bar_time ],
@@ -882,7 +891,9 @@ async def _check_and_create_empty_bars(self) -> None:
882891
883892 # Trigger events outside the lock (non-blocking)
884893 for event in events_to_trigger :
885- asyncio .create_task (self ._trigger_callbacks ("new_bar" , event ))
894+ # Store task reference to avoid warning (though we don't need to track it)
895+ _ = asyncio .create_task (self ._trigger_callbacks ("new_bar" , event ))
886896
887897 except Exception as e :
888898 self .logger .error (f"Error checking/creating empty bars: { e } " )
899+ # Don't re-raise - bar timer should continue even if one check fails
0 commit comments