""" Copyright (C) 2016 Interactive Brokers LLC. All rights reserved. This code is subject to the terms and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable. """ """ Collection of misc tools """ import sys import logging import inspect from ibapi.common import UNSET_INTEGER, UNSET_DOUBLE # I use this just to visually emphasize it's a wrapper overriden method def iswrapper(fn): return fn class BadMessage(Exception): def __init__(self, text): self.text = text class LogFunction(object): def __init__(self, text, logLevel): self.text = text self.logLevel = logLevel def __call__(self, fn): def newFn(origSelf, *args, **kwargs): if logging.getLogger().isEnabledFor(self.logLevel): argNames = [argName for argName in inspect.getfullargspec(fn)[0] if argName != 'self'] logging.log(self.logLevel, "{} {} {} kw:{}".format(self.text, fn.__name__, [nameNarg for nameNarg in zip(argNames, args) if nameNarg[1] is not origSelf], kwargs)) fn(origSelf, *args) return newFn def current_fn_name(parent_idx = 0): #depth is 1 bc this is already a fn, so we need the caller return sys._getframe(1 + parent_idx).f_code.co_name def setattr_log(self, var_name, var_value): #import code; code.interact(local=locals()) logging.debug("%s %s %s=|%s|", self.__class__, id(self), var_name, var_value) super(self.__class__, self).__setattr__(var_name, var_value) SHOW_UNSET = True def decode(the_type, fields, show_unset = False): try: s = next(fields) except StopIteration: raise BadMessage("no more fields") logging.debug("decode %s %s", the_type, s) if the_type is str: if type(s) is str: return s elif type(s) is bytes: return s.decode() else: raise TypeError("unsupported incoming type " + type(s) + " for desired type 'str") orig_type = the_type if the_type is bool: the_type = int if show_unset: if s is None or len(s) == 0: if the_type is float: n = UNSET_DOUBLE elif the_type is int: n = UNSET_INTEGER else: raise TypeError("unsupported desired type for empty value" + the_type) else: n = the_type(s) else: n = the_type(s or 0) if orig_type is bool: n = False if n == 0 else True return n def ExerciseStaticMethods(klass): import types, inspect #import code; code.interact(local=dict(globals(), **locals())) for (name, var) in inspect.getmembers(klass): #print(name, var, type(var)) if type(var) == types.FunctionType: print("Exercising: %s:" % var) print(var()) print()