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. """ # ----------------------------------- # backtest mode? if self.backtest: if self.output is None: print("ERROR: Must provide an output file for backtesting mode") sys.exit(0) if self.backtest_start is None: print("ERROR: Must provide start date for backtesting mode") sys.exit(0) if self.backtest_end is None: self.backtest_end = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f') # backtest history self.blotter.drip( symbols = self.symbols, start = self.backtest_start, end = self.backtest_end, resolution = self.resolution, tz = self.timezone, quote_handler = self._quote_handler, tick_handler = self._tick_handler, bar_handler = self._bar_handler ) # ----------------------------------- # live data mode else: # preload history if self.preload is not None: try: # dbskip may be active self.bars = self.blotter.history( symbols = self.symbols, start = tools.backdate(self.preload), resolution = self.resolution, tz = self.timezone ) except: pass # print(self.bars) # add instruments to blotter in case they do not exist self.blotter.register(self.instruments) # listen for RT data self.blotter.listen( symbols = self.symbols, tz = self.timezone, quote_handler = self._quote_handler, tick_handler = self._tick_handler, bar_handler = self._bar_handler )
def trades(self, start=None, end=None, algo_id=None, json=True): if algo_id is not None: algo_id = algo_id.replace('/', '') if start is not None: start = start.replace('/', '') if end is not None: end = end.replace('/', '') if start is None: start = tools.backdate("7D", date=None, as_datetime=False) trades_query = "SELECT * FROM trades WHERE exit_time IS NOT NULL" trades_where = [] if isinstance(start, str): trades_where.append("entry_time>='" + start + "'") if isinstance(end, str): trades_where.append("exit_time<='" + end + "'") if algo_id is not None: trades_where.append("algo='" + algo_id + "'") if len(trades_where) > 0: trades_query += " AND " + " AND ".join(trades_where) trades = pd.read_sql(trades_query, self.dbconn) trades['exit_time'].fillna(0, inplace=True) trades['slippage'] = abs(trades['entry_price'] - trades['market_price']) trades['slippage'] = np.where( ((trades['direction'] == "LONG") & (trades['entry_price'] > trades['market_price'])) | ((trades['direction'] == "SHORT") & (trades['entry_price'] < trades['market_price'])), -trades['slippage'], trades['slippage']) trades = trades.sort_values(['exit_time', 'entry_time'], ascending=[False, False]) trades = trades.to_dict(orient="records") if json: return jsonify(trades) else: return trades
def bars(self, resolution, symbol, start=None, end=None, json=True): if start is not None: start = start.replace('/', '') if end is not None: end = end.replace('/', '') if start is None: start = tools.backdate("7D", date=None, as_datetime=False) bars = self.blotter.history(symbols=symbol, start=start, end=end, resolution=resolution) bars['datetime'] = bars.index bars = bars.to_dict(orient="records") if json: return jsonify(bars) return bars
def bars(self, resolution, symbol, start=None, end=None, json=True): if start is not None: start = start.replace('/', '') if end is not None: end = end.replace('/', '') if start is None: start = tools.backdate("7D", date=None, as_datetime=False) bars = self.blotter.history( symbols = symbol, start = start, end = end, resolution = resolution ) bars['datetime'] = bars.index bars = bars.to_dict(orient="records") if json: return jsonify(bars) else: return bars
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 ("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 or not validate_csv_columns(df, kind, raise_errors=False): self.log_algo.error("%s Doesn't appear to be 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: self.log_algo.error("Error reading data for %s (%s)" % (symbol, file)) sys.exit(0) history = prepare_history( data = pd.concat(dfs), 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 if self.backtest: # initiate strategy self.on_start() # drip history self.blotter.drip(history, self._tick_handler if self.resolution[-1] in ("K", "V") else self._bar_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 )