代码拉取完成,页面将自动刷新
"""
Copyright (C) 2019 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 decimal import Decimal
from ibapi.common import UNSET_INTEGER, UNSET_DOUBLE, UNSET_LONG, UNSET_DECIMAL
logger = logging.getLogger(__name__)
# I use this just to visually emphasize it's a wrapper overridden method
def iswrapper(fn):
return fn
class BadMessage(Exception):
def __init__(self, text):
self.text = text
class ClientException(Exception):
def __init__(self, code, msg, text):
self.code = code
self.msg = msg
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 logger.getLogger().isEnabledFor(self.logLevel):
argNames = [argName for argName in inspect.getfullargspec(fn)[0] if argName != 'self']
logger.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())
logger.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")
logger.debug("decode %s %s", the_type, s)
if the_type is Decimal:
if s is None or len(s) == 0 or s.decode() == "2147483647" or s.decode() == "9223372036854775807" or s.decode() == "1.7976931348623157E308":
return UNSET_DECIMAL
else:
return the_type(s.decode())
if the_type is str:
if type(s) is str:
return s
elif type(s) is bytes:
return s.decode(errors='backslashreplace')
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
#import code; code.interact(local=dict(globals(), **locals()))
for (_, var) in inspect.getmembers(klass):
#print(name, var, type(var))
if type(var) == types.FunctionType:
print("Exercising: %s:" % var)
print(var())
print()
def floatToStr(val):
return str(val) if val != UNSET_DOUBLE else ""
def longToStr(val):
return str(val) if val != UNSET_LONG else ""
def isAsciiPrintable(val):
return all(ord(c) >=32 and ord(c) < 128 for c in val)
def decimalMaxString(val: Decimal):
return "{:f}".format(val) if val != UNSET_DECIMAL else ""
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。