def __init__(self, instruments=[], resolution="1T", tick_window=1, bar_window=100, timezone="UTC", preload=None, continuous=True, blotter=None, sms=[], log=None, backtest=False, start=None, end=None, data=None, output=None, ibclient=998, ibport=4001, ibserver="localhost", **kwargs): # detect algo name self.name = str(self.__class__).split('.')[-1].split("'")[0] # initilize algo logger self.log_algo = logging.getLogger(__name__) # initilize strategy logger tools.createLogger(self.name) self.log = logging.getLogger(self.name) # override args with any (non-default) command-line args self.args = {arg: val for arg, val in locals().items( ) if arg not in ('__class__', 'self', 'kwargs')} self.args.update(kwargs) self.args.update(self.load_cli_args()) # assign algo params self.bars = pd.DataFrame() self.ticks = pd.DataFrame() self.quotes = {} self.books = {} self.tick_count = 0 self.tick_bar_count = 0 self.bar_count = 0 self.bar_hashes = {} self.tick_window = tick_window if tick_window > 0 else 1 if "V" in resolution: self.tick_window = 1000 self.bar_window = bar_window if bar_window > 0 else 100 self.resolution = resolution.upper().replace("MIN", "T") self.timezone = timezone self.preload = preload self.continuous = continuous self.backtest = self.args["backtest"] self.backtest_start = self.args["start"] self.backtest_end = self.args["end"] self.backtest_csv = self.args["data"] # ----------------------------------- self.sms_numbers = self.args["sms"] self.trade_log_dir = self.args["log"] self.blotter_name = self.args["blotter"] self.record_output = self.args["output"] # ----------------------------------- # initiate broker/order manager super().__init__(instruments, **{arg: val for arg, val in self.args.items() if arg in ( 'ibport', 'ibclient', 'ibhost')}) # ----------------------------------- # signal collector self.signals = {} for sym in self.symbols: self.signals[sym] = pd.DataFrame() # ----------------------------------- # initilize output file self.record_ts = None if self.record_output: self.datastore = tools.DataStore(self.args["output"]) # --------------------------------------- # add stale ticks for more accurate time--based bars if not self.backtest and self.resolution[-1] not in ("K", "V"): self.bar_timer = asynctools.RecurringTask( self.add_stale_tick, interval_sec=1, init_sec=1, daemon=True) # --------------------------------------- # sanity checks for backtesting mode if self.backtest: if self.record_output is None: self.log_algo.error("Must provide an output file for Backtest mode") sys.exit(0) if self.backtest_start is None: self.log_algo.error("Must provide start date for Backtest mode") sys.exit(0) if self.backtest_end is None: self.backtest_end = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f') if self.backtest_csv is not None: if not os.path.exists(self.backtest_csv): self.log_algo.error("CSV directory cannot be found (%s)" % self.backtest_csv) sys.exit(0) elif self.backtest_csv.endswith("/"): self.backtest_csv = self.backtest_csv[:-1] else: self.backtest_start = None self.backtest_end = None self.backtest_csv = None # be aware of thread count self.threads = asynctools.multitasking.getPool(__name__)['threads']
import sys import logging from qtpylib import (tools, asynctools, path, futures, __version__) from qtpylib.crypto_updater import crypto_updater # ============================================= # check min, python version if sys.version_info < (3, 4): raise SystemError("QTPyLib requires Python version >= 3.4") # ============================================= # Configure logging tools.createLogger(__name__, logging.INFO) # Disable ezIBpy logging (Blotter handles errors itself) logging.getLogger('ezibpy').setLevel(logging.CRITICAL) # ============================================= class BtcConn(object): # ----------------------------------------- # generic callback function - can be used externally # ----------------------------------------- def callback(self, timestamp, value): pass def start(self): crypto_updater.start_websocket(1, ["bitcoin"], self.callback)
from qtpylib.workflow import validate_columns as validate_csv_columns from qtpylib.blotter import prepare_history from qtpylib import ( tools, sms, asynctools ) from abc import ABCMeta, abstractmethod # ============================================= # check min, python version if sys.version_info < (3, 4): raise SystemError("QTPyLib requires Python version >= 3.4") # ============================================= # Configure logging tools.createLogger(__name__) # ============================================= # set up threading pool __threads__ = tools.read_single_argv("--max_threads") __threads__ = int(__threads__) if tools.is_number(__threads__) else 1 asynctools.multitasking.createPool(__name__, __threads__) # ============================================= class Algo(Broker): """Algo class initilizer (sub-class of Broker) :Parameters:
from qtpylib import tools from qtpylib.blotter import ( load_blotter_args, get_symbol_id, mysql_insert_tick, mysql_insert_bar ) _IB_HISTORY_DOWNLOADED = False # ============================================= # check min, python version if sys.version_info < (3, 4): raise SystemError("QTPyLib requires Python version >= 3.4") # ============================================= tools.createLogger(__name__) # .setLevel(logging.DEBUG) # ============================================= def ibCallback(caller, msg, **kwargs): global _IB_HISTORY_DOWNLOADED if caller == "handleHistoricalData": if kwargs["completed"]: _IB_HISTORY_DOWNLOADED = True # print(kwargs) def get_data_ib(instrument, start, resolution="1 min", blotter=None, output_path=None): """ Downloads historical data from Interactive Brokers