def nullify_frame_stats(self, now): """ Save all period_stats to local directory erase old files from the folder and nullify self.frame_stats Parameters ---------- now: Timestamp Returns ------- """ save_algo_object(algo_name=self.algo_namespace, key=now.floor('1D').strftime('%Y-%m-%d'), obj=self.frame_stats, rel_path='frame_stats') error = remove_old_files(algo_name=self.algo_namespace, today=now, rel_path='frame_stats') if error: log.warning(error) self.frame_stats = list()
def handle_data(self, data): """ Wrapper around the handle_data method of each algo. Parameters ---------- data """ if not self.is_running: return # Resetting the frame stats every day to minimize memory footprint today = data.current_dt.floor('1D') if self.current_day is not None and today > self.current_day: self.frame_stats = list() self.performance_needs_update = False new_orders = self.perf_tracker.todays_performance.orders_by_id.keys() if new_orders != self._last_orders: self.performance_needs_update = True self._last_orders = new_orders if self.performance_needs_update: self.perf_tracker.update_performance() self.performance_needs_update = False if self.portfolio_needs_update: cash, positions_value = retry( action=self.synchronize_portfolio, attempts=self.attempts['synchronize_portfolio_attempts'], sleeptime=self.attempts['retry_sleeptime'], retry_exceptions=(ExchangeRequestError, ), cleanup=lambda: log.warn('Ordering again.')) self.portfolio_needs_update = False log.info('got totals from exchanges, cash: {} positions: {}'.format( cash, positions_value)) if self._handle_data: self._handle_data(self, data) # Unlike trading controls which remain constant unless placing an # order, account controls can change each bar. Thus, must check # every bar no matter if the algorithm places an order or not. self.validate_account_controls() try: self._save_stats_csv(self._process_stats(data)) except Exception as e: log.warn('unable to calculate performance: {}'.format(e)) save_algo_object( algo_name=self.algo_namespace, key='cumulative_performance', obj=self.perf_tracker.cumulative_performance, ) self.current_day = data.current_dt.floor('1D')
def _process_stats(self, data): today = data.current_dt.floor('1D') # Since the clock runs 24/7, I trying to disable the daily # Performance tracker and keep only minute and cumulative self.perf_tracker.update_performance() frame_stats = self.prepare_period_stats( data.current_dt, data.current_dt + timedelta(minutes=1) ) # Saving the last hour in memory self.frame_stats.append(frame_stats) self.add_pnl_stats(frame_stats) if self.recorded_vars: self.add_custom_signals_stats(frame_stats) recorded_cols = list(self.recorded_vars.keys()) else: recorded_cols = None self.add_exposure_stats(frame_stats) log.info( 'statistics for the last {stats_minutes} minutes:\n' '{stats}'.format( stats_minutes=self.stats_minutes, stats=get_pretty_stats( stats=self.frame_stats, recorded_cols=recorded_cols, num_rows=self.stats_minutes, ) )) # Saving the daily stats in a format usable for performance # analysis. daily_stats = self.prepare_period_stats( start_dt=today, end_dt=data.current_dt ) save_algo_object( algo_name=self.algo_namespace, key=today.strftime('%Y-%m-%d'), obj=daily_stats, rel_path='daily_perf' ) return recorded_cols
def _save_algo_state(self, data): today = data.current_dt.floor('1D') try: self._save_stats_csv(self._process_stats(data)) except Exception as e: log.warn('unable to calculate performance: {}'.format(e)) log.debug('saving cumulative performance object') save_algo_object( algo_name=self.algo_namespace, key='cumulative_performance', obj=self.perf_tracker.cumulative_performance, ) log.debug('saving todays performance object') save_algo_object( algo_name=self.algo_namespace, key=today.strftime('%Y-%m-%d'), obj=self.perf_tracker.todays_performance, rel_path='daily_performance' )