docs: def run(self):
          """Starts the algo
  
          Connects to the Blotter, processes market data and passes
          tick data to the ``on_tick`` function and bar data to the
          ``on_bar`` methods.
          """
  
          history = pd.DataFrame()
  
          # get history from csv dir
          if self.backtest and self.backtest_csv:
              kind = "TICK" if self.resolution[-1] in ("S", "K", "V") else "BAR"
              dfs = []
              for symbol in self.symbols:
                  file = "%s/%s.%s.csv" % (self.backtest_csv, symbol, kind)
                  if not os.path.exists(file):
                      self.log_algo.error(
                          "Can't load data for %s (%s doesn't exist)",
                          symbol, file)
                      sys.exit(0)
                  try:
                      df = pd.read_csv(file)
                      if "expiry" not in df.columns:
                          df.loc[:, "expiry"] = nan
  
                      if not validate_csv_columns(df, kind, raise_errors=False):
                          self.log_algo.error(
                              "%s isn't a QTPyLib-compatible format", file)
                          sys.exit(0)
  
                      if df['symbol'].values[-1] != symbol:
                          self.log_algo.error(
                              "%s Doesn't content data for %s", file, symbol)
                          sys.exit(0)
  
                      dfs.append(df)
  
                  except Exception as e:
                      self.log_algo.error(
                          "Error reading data for %s (%s)", symbol, file)
                      sys.exit(0)
  
              history = prepare_history(
                  data=pd.concat(dfs, sort=True),
                  resolution=self.resolution,
                  tz=self.timezone,
                  continuous=self.continuous
              )
              history = history[history.index >= self.backtest_start]
  
          elif not self.blotter_args["dbskip"] and (
                  self.backtest or self.preload):
  
              start = self.backtest_start if self.backtest else tools.backdate(
                  self.preload)
              end = self.backtest_end if self.backtest else None
  
              history = self.blotter.history(
                  symbols=self.symbols,
                  start=start,
                  end=end,
                  resolution=self.resolution,
                  tz=self.timezone,
                  continuous=self.continuous
              )
  
              # history needs backfilling?
              # self.blotter.backfilled = True
              if not self.blotter.backfilled:
                  # "loan" Blotter our ibConn
                  self.blotter.ibConn = self.ibConn
  
                  # call the back fill
                  self.blotter.backfill(data=history,
                                        resolution=self.resolution,
                                        start=start, end=end)
  
                  # re-get history from db
                  history = self.blotter.history(
                      symbols=self.symbols,
                      start=start,
                      end=end,
                      resolution=self.resolution,
                      tz=self.timezone,
                      continuous=self.continuous
                  )
  
                  # take our ibConn back :)
                  self.blotter.ibConn = None
  
          # optimize pandas
          if not history.empty:
              history['symbol'] = history['symbol'].astype('category')
              history['symbol_group'] = history['symbol_group'].astype('category')
              history['asset_class'] = history['asset_class'].astype('category')
  
          if self.backtest:
              # initiate strategy
              self.on_start()
  
              # drip history
              drip_handler = self._tick_handler if self.resolution[-1] in (
                  "S", "K", "V") else self._bar_handler
              self.blotter.drip(history, drip_handler)
  
          else:
              # place history self.bars
              self.bars = history
  
              # add instruments to blotter in case they do not exist
              self.blotter.register(self.instruments)
  
              # initiate strategy
              self.on_start()
  
              # listen for RT data
              self.blotter.stream(
                  symbols=self.symbols,
                  tz=self.timezone,
                  quote_handler=self._quote_handler,
                  tick_handler=self._tick_handler,
                  bar_handler=self._bar_handler,
                  book_handler=self._book_handler
              )