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.

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
            )