docs: def record(self, timestamp, *args, **kwargs):
          """ add custom data to data store """
          if self.output_file is None:
              return
  
          data = {'datetime': timestamp}
  
          # append all data
          if len(args) == 1:
              if isinstance(args[0], dict):
                  data.update(dict(args[0]))
              elif isinstance(args[0], pd.DataFrame):
                  data.update(args[0][-1:].to_dict(orient='records')[0])
  
          # add kwargs
          if kwargs:
              data.update(dict(kwargs))
  
          data['datetime'] = timestamp
          # self.rows.append(pd.DataFrame(data=data, index=[timestamp]))
  
          new_data = {}
          if "symbol" not in data.keys():
              new_data = dict(data)
          else:
              sym = data["symbol"]
              new_data["symbol"] = data["symbol"]
              for key in data.keys():
                  if key not in ['datetime', 'symbol_group', 'asset_class']:
                      new_data[sym + '_' + str(key).upper()] = data[key]
  
          new_data['datetime'] = timestamp
  
          # append to rows
          self.rows.append(pd.DataFrame(data=new_data, index=[timestamp]))
  
          # create dataframe
          recorded = pd.concat(self.rows, sort=True)
  
          if "symbol" not in recorded.columns:
              return
  
  
          # group by symbol
          recorded['datetime'] = recorded.index
          data = recorded.groupby(['symbol', 'datetime'], as_index=False).sum()
          data.set_index('datetime', inplace=True)
  
          symbols = data['symbol'].unique().tolist()
          data.drop(columns=['symbol'], inplace=True)
  
  
          # cleanup:
  
          # remove symbols
          recorded.drop(['symbol'] + [sym + '_SYMBOL' for sym in symbols],
                        axis=1, inplace=True)
  
          # remove non-option data if not working with options
          for sym in symbols:
              try:
                  opt_cols = recorded.columns[
                      recorded.columns.str.startswith(sym + '_OPT_')].tolist()
                  if len(opt_cols) == len(recorded[opt_cols].isnull().all()):
                      recorded.drop(opt_cols, axis=1, inplace=True)
              except Exception as e:
                  pass
  
          # group df
          recorded = recorded.groupby(recorded['datetime']).first()
  
          # shift position
          for sym in symbols:
              recorded[sym + '_POSITION'] = recorded[sym + '_POSITION'
                                                     ].shift(1).fillna(0)
  
          # make this public
          self.recorded = recorded.copy()
  
          # cleanup columns names before saving...
          recorded.columns = [col.replace('_FUT_', '_').replace(
                              '_OPT_OPT_', '_OPT_') for col in recorded.columns]
  
          # save
          if ".csv" in self.output_file:
              recorded.to_csv(self.output_file)
          elif ".h5" in self.output_file:
              recorded.to_hdf(self.output_file, 0)
          elif (".pickle" in self.output_file) | (".pkl" in self.output_file):
              recorded.to_pickle(self.output_file)
  
          chmod(self.output_file)