[Mod]change ibapi to use relative import

This commit is contained in:
vn.py 2019-03-14 09:52:01 +08:00
parent 3758d13cd2
commit b105b08c9f
20 changed files with 327 additions and 347 deletions

View File

@ -1,5 +1,5 @@
[flake8]
exclude = __pycache__,__init__.py
exclude = __pycache__,__init__.py,ib,talib
ignore =
E501 line too long, fixed by black
W503 line break before binary operator

View File

@ -1308,14 +1308,14 @@ FID_RZXYLL = 1807 # 融资信用利率 DTR
FID_RQXYLL = 1808 # 融券信用利率 DTR
FID_RQLL = 1809 # 融券利率 DTR
FID_WYLB = 1810 # 违约类别 DTI
FID_SQL = 1811 # DTC
FID_SQL = 1811 # DTC
FID_FILENAME = 1812 # 文件名称 DTC
FID_FILEVERSION = 1813 # 文件版本 DTC
FID_ZJLB_GDH = 1814 # 股东证件类别 DTI
FID_MEMHEAD = 1815 # DTC
FID_MEMDATA = 1816 # DTC
FID_MEMCOUNT = 1817 # DTC
FID_MEMSIZE = 1818 # DTC
FID_MEMHEAD = 1815 # DTC
FID_MEMDATA = 1816 # DTC
FID_MEMCOUNT = 1817 # DTC
FID_MEMSIZE = 1818 # DTC
FID_GQZH_ZR = 1819 # 转入股权帐号 DTC
FID_PCCL = 1820 # 平仓策略 DTI
FID_RZXYED = 1821 # 融资信用额度 DTR
@ -1753,7 +1753,7 @@ FID_MLMC = 3042 # 目录名称 DTC
FID_MLSM = 3043 # 目录说明 DTC
FID_FORMAT = 3044 # 目录格式 DTC
FID_DEFAULT = 3045 # 缺省值 DTC
FID_DATA = 3046 # DTC
FID_DATA = 3046 # DTC
FID_JLBZ = 3047 # 记录标志 DT取值范围 DTC
FID_MBSMS = 3050 # 对方手机号码 DTC
FID_MBMAIL = 3051 # 对方邮件地址 DTC
@ -2079,13 +2079,13 @@ FID_JJFS = 9058 # 解决方式 DTC
FID_JJGC = 9059 # 解决过程 DTC
FID_CLYS = 9060 # 处理用时 DTC
FID_FSRQ = 9061 # 发生日期 DTC
FID_WTFL = 9062 # DTC
FID_WTFL = 9062 # DTC
FID_GROUP = 9063 # 组 DTC
FID_SECURITY = 9064 # DTC
FID_GXQ = 9065 # DTC
FID_SECURITY = 9064 # DTC
FID_GXQ = 9065 # DTC
FID_CPXX = 9066 # 产品信息 DTC
FID_KHZB = 9067 # 客户总部 DTC
FID_QYZB = 9068 # DTC
FID_QYZB = 9068 # DTC
FID_ZJL = 9070 # 总经理 DTC
FID_ZJLDH = 9071 # 总经理电话 DTC
FID_ZJLMAIL = 9072 # 总经理EMAIL DTC
@ -2405,16 +2405,14 @@ FID_PHYW_CFGSCC = 9612 # 盘后业务成分股市场串 DT:C
FID_PHYW_CFGSLC = 9613 # 盘后业务成分股数量串 DT:C
FID_PHYW_CFGJEC = 9614 # 盘后业务成分股金额串 DT:C
FID_PHYW_HSNODEID = 9615 # 盘后业务恒生节点ID DT:C
FID_QQHYDM = 9378
FID_QQHYMC = 9379
FID_QQLX = 9373
FID_MMFX = 9375
FID_ZZHBM = 9372
FID_QQBDBQ = 9377
FID_SBLX = 9616 # 申报类型DT:I
FID_ZCCSY = 9800 # 昨持仓使用
FID_MRSY = 9801 # 买入使用
FID_SGSY = 9802 # 申购使用
FID_SHSY = 9803 # 赎回使用
FID_QQHYDM = 9378
FID_QQHYMC = 9379
FID_QQLX = 9373
FID_MMFX = 9375
FID_QQBDBQ = 9377
FID_ZZHBM = 9372

View File

@ -18,18 +18,18 @@ import logging
import queue
import socket
from ibapi import (decoder, reader, comm)
from ibapi.connection import Connection
from ibapi.message import OUT
from ibapi.common import * # @UnusedWildImport
from ibapi.contract import Contract
from ibapi.order import Order
from ibapi.execution import ExecutionFilter
from ibapi.scanner import ScannerSubscription
from ibapi.comm import (make_field, make_field_handle_empty)
from ibapi.utils import (current_fn_name, BadMessage)
from ibapi.errors import * #@UnusedWildImport
from ibapi.server_versions import * # @UnusedWildImport
from . import (decoder, reader, comm)
from .connection import Connection
from .message import OUT
from .common import * # @UnusedWildImport
from .contract import Contract
from .order import Order
from .execution import ExecutionFilter
from .scanner import ScannerSubscription
from .comm import (make_field, make_field_handle_empty)
from .utils import (current_fn_name, BadMessage)
from .errors import * #@UnusedWildImport
from .server_versions import * # @UnusedWildImport
#TODO: use pylint

View File

@ -1,3 +1,6 @@
from .common import UNSET_INTEGER, UNSET_DOUBLE
import logging
import struct
"""
Copyright (C) 2018 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.
@ -9,11 +12,6 @@ This module has tools for implementing the IB low level messaging.
"""
import struct
import logging
from ibapi.common import UNSET_INTEGER, UNSET_DOUBLE
logger = logging.getLogger(__name__)
@ -48,20 +46,20 @@ def make_field_handle_empty(val) -> str:
return make_field(val)
def read_msg(buf:bytes) -> tuple:
def read_msg(buf: bytes) -> tuple:
""" first the size prefix and then the corresponding msg payload """
if len(buf) < 4:
return (0, "", buf)
size = struct.unpack("!I", buf[0:4])[0]
logger.debug("read_msg: size: %d", size)
if len(buf) - 4 >= size:
text = struct.unpack("!%ds" % size, buf[4:4+size])[0]
return (size, text, buf[4+size:])
text = struct.unpack("!%ds" % size, buf[4:4 + size])[0]
return (size, text, buf[4 + size:])
else:
return (size, "", buf)
def read_fields(buf:bytes) -> tuple:
def read_fields(buf: bytes) -> tuple:
if isinstance(buf, str):
buf = buf.encode()
@ -69,7 +67,5 @@ def read_fields(buf:bytes) -> tuple:
""" msg payload is made of fields terminated/separated by NULL chars """
fields = buf.split(b"\0")
return tuple(fields[0:-1]) #last one is empty; this may slow dow things though, TODO
# last one is empty; this may slow dow things though, TODO
return tuple(fields[0:-1])

View File

@ -3,19 +3,20 @@ Copyright (C) 2018 Interactive Brokers LLC. All rights reserved. This code is su
and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable.
"""
from ibapi.object_implem import Object
from ibapi import utils
from .object_implem import Object
from . import utils
class CommissionReport(Object):
def __init__(self):
self.execId = ""
self.commission = 0.
self.commission = 0.
self.currency = ""
self.realizedPNL = 0.
self.realizedPNL = 0.
self.yield_ = 0.
self.yieldRedemptionDate = 0 # YYYYMMDD format
def __str__(self):
return "ExecId: %s, Commission: %f, Currency: %s, RealizedPnL: %s, Yield: %s, YieldRedemptionDate: %d" % (self.execId, self.commission,
self.currency, utils.floatToStr(self.realizedPNL), utils.floatToStr(self.yield_), self.yieldRedemptionDate)
return "ExecId: %s, Commission: %f, Currency: %s, RealizedPnL: %s, Yield: %s, YieldRedemptionDate: %d" % (self.execId, self.commission,
self.currency, utils.floatToStr(self.realizedPNL), utils.floatToStr(self.yield_), self.yieldRedemptionDate)

View File

@ -5,8 +5,8 @@ and conditions of the IB API Non-Commercial License or the IB API Commercial Lic
import sys
from ibapi.enum_implem import Enum
from ibapi.object_implem import Object
from .enum_implem import Enum
from .object_implem import Object
NO_VALID_ID = -1

View File

@ -1,3 +1,8 @@
from .errors import * # @UnusedWildImport
from .common import * # @UnusedWildImport
import logging
import threading
import socket
"""
Copyright (C) 2018 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.
@ -10,15 +15,7 @@ It allows us to keep some other info along with it.
"""
import socket
import threading
import logging
from ibapi.common import * # @UnusedWildImport
from ibapi.errors import * # @UnusedWildImport
#TODO: support SSL !!
# TODO: support SSL !!
logger = logging.getLogger(__name__)
@ -31,23 +28,23 @@ class Connection:
self.wrapper = None
self.lock = threading.Lock()
def connect(self):
try:
self.socket = socket.socket()
#TODO: list the exceptions you want to catch
# TODO: list the exceptions you want to catch
except socket.error:
if self.wrapper:
self.wrapper.error(NO_VALID_ID, FAIL_CREATE_SOCK.code(), FAIL_CREATE_SOCK.msg())
self.wrapper.error(
NO_VALID_ID, FAIL_CREATE_SOCK.code(), FAIL_CREATE_SOCK.msg())
try:
self.socket.connect((self.host, self.port))
except socket.error:
if self.wrapper:
self.wrapper.error(NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg())
self.socket.settimeout(1) #non-blocking
self.wrapper.error(
NO_VALID_ID, CONNECT_FAIL.code(), CONNECT_FAIL.msg())
self.socket.settimeout(1) # non-blocking
def disconnect(self):
self.lock.acquire()
@ -61,19 +58,18 @@ class Connection:
finally:
self.lock.release()
def isConnected(self):
#TODO: also handle when socket gets interrupted/error
# TODO: also handle when socket gets interrupted/error
return self.socket is not None
def sendMsg(self, msg):
logger.debug("acquiring lock")
self.lock.acquire()
logger.debug("acquired lock")
if not self.isConnected():
logger.debug("sendMsg attempted while not connected, releasing lock")
logger.debug(
"sendMsg attempted while not connected, releasing lock")
self.lock.release()
return 0
try:
@ -90,10 +86,10 @@ class Connection:
return nSent
def recvMsg(self):
if not self.isConnected():
logger.debug("recvMsg attempted while not connected, releasing lock")
logger.debug(
"recvMsg attempted while not connected, releasing lock")
return b""
try:
buf = self._recvAllMsg()
@ -105,7 +101,6 @@ class Connection:
return buf
def _recvAllMsg(self):
cont = True
allbuf = b""
@ -119,4 +114,3 @@ class Connection:
cont = False
return allbuf

View File

@ -1,3 +1,4 @@
from .object_implem import Object
"""
Copyright (C) 2018 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.
@ -12,9 +13,6 @@ and conditions of the IB API Non-Commercial License or the IB API Commercial Lic
"""
from ibapi.object_implem import Object
(SAME_POS, OPEN_POS, CLOSE_POS, UNKNOWN_POS) = range(4)
@ -30,7 +28,6 @@ class ComboLeg(Object):
self.designatedLocation = ""
self.exemptCode = -1
def __str__(self):
return ",".join((
str(self.conId),
@ -66,7 +63,8 @@ class Contract(Object):
self.right = ""
self.multiplier = ""
self.exchange = ""
self.primaryExchange = "" # pick an actual (ie non-aggregate) exchange that the contract trades on. DO NOT SET TO SMART.
# pick an actual (ie non-aggregate) exchange that the contract trades on. DO NOT SET TO SMART.
self.primaryExchange = ""
self.currency = ""
self.localSymbol = ""
self.tradingClass = ""
@ -74,12 +72,12 @@ class Contract(Object):
self.secIdType = "" # CUSIP;SEDOL;ISIN;RIC
self.secId = ""
#combos
self.comboLegsDescrip = "" # type: str; received in open order 14 and up for all combos
# combos
# type: str; received in open order 14 and up for all combos
self.comboLegsDescrip = ""
self.comboLegs = None # type: list<ComboLeg>
self.deltaNeutralContract = None
def __str__(self):
s = ",".join((
str(self.conId),
@ -201,5 +199,3 @@ class ContractDescription(Object):
def __init__(self):
self.contract = Contract()
self.derivativeSecTypes = None # type: list of strings

View File

@ -12,20 +12,20 @@ It will call the corresponding method from the EWrapper so that customer's code
import logging
from ibapi import order_condition
from ibapi.message import IN
from ibapi.wrapper import * # @UnusedWildImport
from ibapi.order import OrderComboLeg
from ibapi.contract import ContractDescription
from ibapi.contract import ComboLeg
from ibapi.server_versions import * # @UnusedWildImport
from ibapi.utils import * # @UnusedWildImport
from ibapi.softdollartier import SoftDollarTier
from ibapi.ticktype import * # @UnusedWildImport
from ibapi.tag_value import TagValue
from ibapi.scanner import ScanData
from ibapi.errors import BAD_MESSAGE
from ibapi.common import * # @UnusedWildImport
from . import order_condition
from .message import IN
from .wrapper import * # @UnusedWildImport
from .order import OrderComboLeg
from .contract import ContractDescription
from .contract import ComboLeg
from .server_versions import * # @UnusedWildImport
from .utils import * # @UnusedWildImport
from .softdollartier import SoftDollarTier
from .ticktype import * # @UnusedWildImport
from .tag_value import TagValue
from .scanner import ScanData
from .errors import BAD_MESSAGE
from .common import * # @UnusedWildImport
logger = logging.getLogger(__name__)

View File

@ -4,37 +4,38 @@ and conditions of the IB API Non-Commercial License or the IB API Commercial Lic
"""
from .object_implem import Object
from ibapi.object_implem import Object
class Execution(Object):
def __init__(self):
self.execId = ""
self.time = ""
self.acctNumber = ""
self.exchange = ""
self.time = ""
self.acctNumber = ""
self.exchange = ""
self.side = ""
self.shares = 0.
self.price = 0.
self.price = 0.
self.permId = 0
self.clientId = 0
self.orderId = 0
self.liquidation = 0
self.cumQty = 0.
self.avgPrice = 0.
self.orderRef = ""
self.evRule = ""
self.orderRef = ""
self.evRule = ""
self.evMultiplier = 0.
self.modelCode = ""
self.modelCode = ""
self.lastLiquidity = 0
def __str__(self):
return "ExecId: %s, Time: %s, Account: %s, Exchange: %s, Side: %s, Shares: %f, Price: %f, PermId: %d, " \
"ClientId: %d, OrderId: %d, Liquidation: %d, CumQty: %f, AvgPrice: %f, OrderRef: %s, EvRule: %s, " \
"EvMultiplier: %f, ModelCode: %s, LastLiquidity: %d" % (self.execId, self.time, self.acctNumber,
self.exchange, self.side, self.shares, self.price, self.permId, self.clientId, self.orderId, self.liquidation,
self.cumQty, self.avgPrice, self.orderRef, self.evRule, self.evMultiplier, self.modelCode, self.lastLiquidity)
"ClientId: %d, OrderId: %d, Liquidation: %d, CumQty: %f, AvgPrice: %f, OrderRef: %s, EvRule: %s, " \
"EvMultiplier: %f, ModelCode: %s, LastLiquidity: %d" % (self.execId, self.time, self.acctNumber,
self.exchange, self.side, self.shares, self.price, self.permId, self.clientId, self.orderId, self.liquidation,
self.cumQty, self.avgPrice, self.orderRef, self.evRule, self.evMultiplier, self.modelCode, self.lastLiquidity)
class ExecutionFilter(Object):
@ -45,6 +46,5 @@ class ExecutionFilter(Object):
self.time = ""
self.symbol = ""
self.secType = ""
self.exchange = ""
self.exchange = ""
self.side = ""

View File

@ -4,9 +4,9 @@ and conditions of the IB API Non-Commercial License or the IB API Commercial Lic
"""
from ibapi.common import UNSET_INTEGER, UNSET_DOUBLE
from ibapi.object_implem import Object
from ibapi.softdollartier import SoftDollarTier
from .common import UNSET_INTEGER, UNSET_DOUBLE
from .object_implem import Object
from .softdollartier import SoftDollarTier
# enum Origin
(CUSTOMER, FIRM, UNKNOWN) = range(3)
@ -28,67 +28,71 @@ class Order(Object):
def __init__(self):
self.softDollarTier = SoftDollarTier("", "", "")
# order identifier
self.orderId = 0
self.orderId = 0
self.clientId = 0
self.permId = 0
self.permId = 0
# main order fields
self.action = ""
self.totalQuantity = 0
self.orderType = ""
self.lmtPrice = UNSET_DOUBLE
self.auxPrice = UNSET_DOUBLE
self.lmtPrice = UNSET_DOUBLE
self.auxPrice = UNSET_DOUBLE
# extended order fields
self.tif = "" # "Time in Force" - DAY, GTC, etc.
self.activeStartTime = "" # for GTC orders
self.activeStopTime = "" # for GTC orders
self.ocaGroup = "" # one cancels all group name
self.ocaType = 0 # 1 = CANCEL_WITH_BLOCK, 2 = REDUCE_WITH_BLOCK, 3 = REDUCE_NON_BLOCK
self.orderRef = ""
self.transmit = True # if false, order will be created but not transmited
self.parentId = 0 # Parent order Id, to associate Auto STP or TRAIL orders with the original order.
self.blockOrder = False
self.sweepToFill = False
self.displaySize = 0
self.triggerMethod = 0 # 0=Default, 1=Double_Bid_Ask, 2=Last, 3=Double_Last, 4=Bid_Ask, 7=Last_or_Bid_Ask, 8=Mid-point
self.outsideRth = False
self.hidden = False
self.goodAfterTime = "" # Format: 20060505 08:00:00 {time zone}
self.goodTillDate = "" # Format: 20060505 08:00:00 {time zone}
self.rule80A = "" # Individual = 'I', Agency = 'A', AgentOtherMember = 'W', IndividualPTIA = 'J', AgencyPTIA = 'U', AgentOtherMemberPTIA = 'M', IndividualPT = 'K', AgencyPT = 'Y', AgentOtherMemberPT = 'N'
self.allOrNone = False
self.minQty = UNSET_INTEGER #type: int
self.percentOffset = UNSET_DOUBLE # type: float; REL orders only
self.ocaType = 0 # 1 = CANCEL_WITH_BLOCK, 2 = REDUCE_WITH_BLOCK, 3 = REDUCE_NON_BLOCK
self.orderRef = ""
self.transmit = True # if false, order will be created but not transmited
# Parent order Id, to associate Auto STP or TRAIL orders with the original order.
self.parentId = 0
self.blockOrder = False
self.sweepToFill = False
self.displaySize = 0
# 0=Default, 1=Double_Bid_Ask, 2=Last, 3=Double_Last, 4=Bid_Ask, 7=Last_or_Bid_Ask, 8=Mid-point
self.triggerMethod = 0
self.outsideRth = False
self.hidden = False
self.goodAfterTime = "" # Format: 20060505 08:00:00 {time zone}
self.goodTillDate = "" # Format: 20060505 08:00:00 {time zone}
self.rule80A = "" # Individual = 'I', Agency = 'A', AgentOtherMember = 'W', IndividualPTIA = 'J', AgencyPTIA = 'U', AgentOtherMemberPTIA = 'M', IndividualPT = 'K', AgencyPT = 'Y', AgentOtherMemberPT = 'N'
self.allOrNone = False
self.minQty = UNSET_INTEGER # type: int
self.percentOffset = UNSET_DOUBLE # type: float; REL orders only
self.overridePercentageConstraints = False
self.trailStopPrice = UNSET_DOUBLE # type: float
self.trailingPercent = UNSET_DOUBLE # type: float; TRAILLIMIT orders only
self.trailingPercent = UNSET_DOUBLE # type: float; TRAILLIMIT orders only
# financial advisors only
self.faGroup = ""
self.faProfile = ""
self.faMethod = ""
self.faPercentage = ""
self.faGroup = ""
self.faProfile = ""
self.faMethod = ""
self.faPercentage = ""
# institutional (ie non-cleared) only
self.designatedLocation = "" #used only when shortSaleSlot=2
self.openClose = "O" # O=Open, C=Close
self.origin = CUSTOMER # 0=Customer, 1=Firm
self.shortSaleSlot = 0 # type: int; 1 if you hold the shares, 2 if they will be delivered from elsewhere. Only for Action=SSHORT
self.exemptCode = -1
self.designatedLocation = "" # used only when shortSaleSlot=2
self.openClose = "O" # O=Open, C=Close
self.origin = CUSTOMER # 0=Customer, 1=Firm
# type: int; 1 if you hold the shares, 2 if they will be delivered from elsewhere. Only for Action=SSHORT
self.shortSaleSlot = 0
self.exemptCode = -1
# SMART routing only
self.discretionaryAmt = 0
self.eTradeOnly = True
self.firmQuoteOnly = True
self.nbboPriceCap = UNSET_DOUBLE # type: float
self.eTradeOnly = True
self.firmQuoteOnly = True
self.nbboPriceCap = UNSET_DOUBLE # type: float
self.optOutSmartRouting = False
# BOX exchange orders only
self.auctionStrategy = AUCTION_UNSET # type: int; AUCTION_MATCH, AUCTION_IMPROVEMENT, AUCTION_TRANSPARENT
self.startingPrice = UNSET_DOUBLE # type: float
self.stockRefPrice = UNSET_DOUBLE # type: float
self.delta = UNSET_DOUBLE # type: float
# type: int; AUCTION_MATCH, AUCTION_IMPROVEMENT, AUCTION_TRANSPARENT
self.auctionStrategy = AUCTION_UNSET
self.startingPrice = UNSET_DOUBLE # type: float
self.stockRefPrice = UNSET_DOUBLE # type: float
self.delta = UNSET_DOUBLE # type: float
# pegged to stock and VOL orders only
self.stockRangeLower = UNSET_DOUBLE # type: float
@ -98,11 +102,11 @@ class Order(Object):
self.randomizeSize = False
# VOLATILITY ORDERS ONLY
self.volatility = UNSET_DOUBLE # type: float
self.volatilityType = UNSET_INTEGER # type: int # 1=daily, 2=annual
self.volatility = UNSET_DOUBLE # type: float
self.volatilityType = UNSET_INTEGER # type: int # 1=daily, 2=annual
self.deltaNeutralOrderType = ""
self.deltaNeutralAuxPrice = UNSET_DOUBLE # type: float
self.deltaNeutralConId = 0
self.deltaNeutralAuxPrice = UNSET_DOUBLE # type: float
self.deltaNeutralConId = 0
self.deltaNeutralSettlingFirm = ""
self.deltaNeutralClearingAccount = ""
self.deltaNeutralClearingIntent = ""
@ -110,16 +114,16 @@ class Order(Object):
self.deltaNeutralShortSale = False
self.deltaNeutralShortSaleSlot = 0
self.deltaNeutralDesignatedLocation = ""
self.continuousUpdate = False
self.referencePriceType = UNSET_INTEGER # type: int; 1=Average, 2 = BidOrAsk
self.continuousUpdate = False
self.referencePriceType = UNSET_INTEGER # type: int; 1=Average, 2 = BidOrAsk
# COMBO ORDERS ONLY
self.basisPoints = UNSET_DOUBLE # type: float; EFP orders only
self.basisPoints = UNSET_DOUBLE # type: float; EFP orders only
self.basisPointsType = UNSET_INTEGER # type: int; EFP orders only
# SCALE ORDERS ONLY
self.scaleInitLevelSize = UNSET_INTEGER # type: int
self.scaleSubsLevelSize = UNSET_INTEGER # type: int
self.scaleInitLevelSize = UNSET_INTEGER # type: int
self.scaleSubsLevelSize = UNSET_INTEGER # type: int
self.scalePriceIncrement = UNSET_DOUBLE # type: float
self.scalePriceAdjustValue = UNSET_DOUBLE # type: float
self.scalePriceAdjustInterval = UNSET_INTEGER # type: int
@ -131,20 +135,21 @@ class Order(Object):
self.scaleTable = ""
# HEDGE ORDERS
self.hedgeType = "" # 'D' - delta, 'B' - beta, 'F' - FX, 'P' - pair
self.hedgeParam = "" # 'beta=X' value for beta hedge, 'ratio=Y' for pair hedge
self.hedgeType = "" # 'D' - delta, 'B' - beta, 'F' - FX, 'P' - pair
self.hedgeParam = "" # 'beta=X' value for beta hedge, 'ratio=Y' for pair hedge
# Clearing info
self.account = "" # IB account
self.settlingFirm = ""
self.clearingAccount = "" #True beneficiary of the order
self.clearingIntent = "" # "" (Default), "IB", "Away", "PTA" (PostTrade)
self.account = "" # IB account
self.settlingFirm = ""
self.clearingAccount = "" # True beneficiary of the order
# "" (Default), "IB", "Away", "PTA" (PostTrade)
self.clearingIntent = ""
# ALGO ORDERS ONLY
self.algoStrategy = ""
self.algoStrategy = ""
self.algoParams = None #TagValueList
self.smartComboRoutingParams = None #TagValueList
self.algoParams = None # TagValueList
self.smartComboRoutingParams = None # TagValueList
self.algoId = ""

View File

@ -4,11 +4,11 @@ and conditions of the IB API Non-Commercial License or the IB API Commercial Lic
"""
from ibapi import comm
from ibapi.common import UNSET_DOUBLE
from ibapi.object_implem import Object
from ibapi.enum_implem import Enum
from ibapi.utils import decode
from . import comm
from .common import UNSET_DOUBLE
from .object_implem import Object
from .enum_implem import Enum
from .utils import decode
#TODO: add support for Rebate, P/L, ShortableShares conditions

View File

@ -3,23 +3,23 @@ Copyright (C) 2018 Interactive Brokers LLC. All rights reserved. This code is su
and conditions of the IB API Non-Commercial License or the IB API Commercial License, as applicable.
"""
from ibapi.common import UNSET_DOUBLE
from .common import UNSET_DOUBLE
class OrderState:
def __init__(self):
self.status= ""
self.status = ""
self.initMarginBefore= ""
self.maintMarginBefore= ""
self.equityWithLoanBefore= ""
self.initMarginChange= ""
self.maintMarginChange= ""
self.equityWithLoanChange= ""
self.initMarginAfter= ""
self.maintMarginAfter= ""
self.equityWithLoanAfter= ""
self.initMarginBefore = ""
self.maintMarginBefore = ""
self.equityWithLoanBefore = ""
self.initMarginChange = ""
self.maintMarginChange = ""
self.equityWithLoanChange = ""
self.initMarginAfter = ""
self.maintMarginAfter = ""
self.equityWithLoanAfter = ""
self.commission = UNSET_DOUBLE # type: float
self.minCommission = UNSET_DOUBLE # type: float

View File

@ -1,3 +1,6 @@
from . import comm
from threading import Thread
import logging
"""
Copyright (C) 2018 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.
@ -11,11 +14,6 @@ It will read the packets from the wire, use the low level IB messaging to
remove the size prefix and put the rest in a Queue.
"""
import logging
from threading import Thread
from ibapi import comm
logger = logging.getLogger(__name__)
@ -38,7 +36,7 @@ class EReader(Thread):
(size, msg, buf) = comm.read_msg(buf)
#logger.debug("resp %s", buf.decode('ascii'))
logger.debug("size:%d msg.size:%d msg:|%s| buf:%s|", size,
len(msg), buf, "|")
len(msg), buf, "|")
if msg:
self.msg_queue.put(msg)
@ -47,5 +45,3 @@ class EReader(Thread):
break
logger.debug("EReader thread finished")

View File

@ -4,12 +4,12 @@ and conditions of the IB API Non-Commercial License or the IB API Commercial Lic
"""
from ibapi.object_implem import Object
from ibapi.common import UNSET_INTEGER, UNSET_DOUBLE
from .object_implem import Object
from .common import UNSET_INTEGER, UNSET_DOUBLE
class ScanData(Object):
def __init__(self, contract = None, rank = 0, distance = "", benchmark = "", projection = "", legsStr = ""):
def __init__(self, contract=None, rank=0, distance="", benchmark="", projection="", legsStr=""):
self.contract = contract
self.rank = rank
self.distance = distance
@ -18,40 +18,41 @@ class ScanData(Object):
self.legsStr = legsStr
def __str__(self):
return "Rank: %d, Symbol: %s, SecType: %s, Currency: %s, Distance: %s, Benchmark: %s, Projection: %s, Legs String: %s" % (self.rank,
self.contract.symbol, self.contract.secType, self.contract.currency, self.distance,
self.benchmark, self.projection, self.legsStr)
return "Rank: %d, Symbol: %s, SecType: %s, Currency: %s, Distance: %s, Benchmark: %s, Projection: %s, Legs String: %s" % (self.rank,
self.contract.symbol, self.contract.secType, self.contract.currency, self.distance,
self.benchmark, self.projection, self.legsStr)
NO_ROW_NUMBER_SPECIFIED = -1
class ScannerSubscription(Object):
def __init__(self):
self.numberOfRows = NO_ROW_NUMBER_SPECIFIED
self.instrument = ""
self.locationCode = ""
self.scanCode = ""
self.scanCode = ""
self.abovePrice = UNSET_DOUBLE
self.belowPrice = UNSET_DOUBLE
self.aboveVolume = UNSET_INTEGER
self.marketCapAbove = UNSET_DOUBLE
self.marketCapBelow = UNSET_DOUBLE
self.moodyRatingAbove = ""
self.moodyRatingBelow = ""
self.spRatingAbove = ""
self.spRatingBelow = ""
self.maturityDateAbove = ""
self.maturityDateBelow = ""
self.moodyRatingAbove = ""
self.moodyRatingBelow = ""
self.spRatingAbove = ""
self.spRatingBelow = ""
self.maturityDateAbove = ""
self.maturityDateBelow = ""
self.couponRateAbove = UNSET_DOUBLE
self.couponRateBelow = UNSET_DOUBLE
self.couponRateBelow = UNSET_DOUBLE
self.excludeConvertible = False
self.averageOptionVolumeAbove = UNSET_INTEGER
self.scannerSettingPairs = ""
self.stockTypeFilter = ""
self.scannerSettingPairs = ""
self.stockTypeFilter = ""
def __str__(self):
s = "Instrument: %s, LocationCode: %s, ScanCode: %s" % (self.instrument, self.locationCode, self.scanCode)
s = "Instrument: %s, LocationCode: %s, ScanCode: %s" % (
self.instrument, self.locationCode, self.scanCode)
return s

View File

@ -4,11 +4,11 @@ and conditions of the IB API Non-Commercial License or the IB API Commercial Lic
"""
from ibapi.object_implem import Object
from .object_implem import Object
class SoftDollarTier(Object):
def __init__(self, name = "", val = "", displayName = ""):
def __init__(self, name="", val="", displayName=""):
self.name = name
self.val = val
self.displayName = displayName

View File

@ -1,3 +1,4 @@
from .object_implem import Object
"""
Copyright (C) 2018 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.
@ -8,11 +9,9 @@ Simple class mapping a tag to a value. Both of them are strings.
They are used in a list to convey extra info with the requests.
"""
from ibapi.object_implem import Object
class TagValue(Object):
def __init__(self, tag:str=None, value:str=None):
def __init__(self, tag: str = None, value: str = None):
self.tag = str(tag)
self.value = str(value)
@ -20,5 +19,3 @@ class TagValue(Object):
# this is not only used for Python dump but when encoding to send
# so don't change it lightly !
return "%s=%s;" % (self.tag, self.value)

View File

@ -1,3 +1,4 @@
from .enum_implem import Enum
"""
Copyright (C) 2018 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.
@ -8,102 +9,97 @@ and conditions of the IB API Non-Commercial License or the IB API Commercial Lic
TickType type
"""
from ibapi.enum_implem import Enum
# TickType
TickType = int
TickTypeEnum = Enum("BID_SIZE",
"BID",
"ASK",
"ASK_SIZE",
"LAST",
"LAST_SIZE",
"HIGH",
"LOW",
"VOLUME",
"CLOSE",
"BID_OPTION_COMPUTATION",
"ASK_OPTION_COMPUTATION",
"LAST_OPTION_COMPUTATION",
"MODEL_OPTION",
"OPEN",
"LOW_13_WEEK",
"HIGH_13_WEEK",
"LOW_26_WEEK",
"HIGH_26_WEEK",
"LOW_52_WEEK",
"HIGH_52_WEEK",
"AVG_VOLUME",
"OPEN_INTEREST",
"OPTION_HISTORICAL_VOL",
"OPTION_IMPLIED_VOL",
"OPTION_BID_EXCH",
"OPTION_ASK_EXCH",
"OPTION_CALL_OPEN_INTEREST",
"OPTION_PUT_OPEN_INTEREST",
"OPTION_CALL_VOLUME",
"OPTION_PUT_VOLUME",
"INDEX_FUTURE_PREMIUM",
"BID_EXCH",
"ASK_EXCH",
"AUCTION_VOLUME",
"AUCTION_PRICE",
"AUCTION_IMBALANCE",
"MARK_PRICE",
"BID_EFP_COMPUTATION",
"ASK_EFP_COMPUTATION",
"LAST_EFP_COMPUTATION",
"OPEN_EFP_COMPUTATION",
"HIGH_EFP_COMPUTATION",
"LOW_EFP_COMPUTATION",
"CLOSE_EFP_COMPUTATION",
"LAST_TIMESTAMP",
"SHORTABLE",
"FUNDAMENTAL_RATIOS",
"RT_VOLUME",
"HALTED",
"BID_YIELD",
"ASK_YIELD",
"LAST_YIELD",
"CUST_OPTION_COMPUTATION",
"TRADE_COUNT",
"TRADE_RATE",
"VOLUME_RATE",
"LAST_RTH_TRADE",
"RT_HISTORICAL_VOL",
"IB_DIVIDENDS",
"BOND_FACTOR_MULTIPLIER",
"REGULATORY_IMBALANCE",
"NEWS_TICK",
"SHORT_TERM_VOLUME_3_MIN",
"SHORT_TERM_VOLUME_5_MIN",
"SHORT_TERM_VOLUME_10_MIN",
"DELAYED_BID",
"DELAYED_ASK",
"DELAYED_LAST",
"DELAYED_BID_SIZE",
"DELAYED_ASK_SIZE",
"DELAYED_LAST_SIZE",
"DELAYED_HIGH",
"DELAYED_LOW",
"DELAYED_VOLUME",
"DELAYED_CLOSE",
"DELAYED_OPEN",
"RT_TRD_VOLUME",
"CREDITMAN_MARK_PRICE",
"CREDITMAN_SLOW_MARK_PRICE",
"DELAYED_BID_OPTION",
"DELAYED_ASK_OPTION",
"DELAYED_LAST_OPTION",
"DELAYED_MODEL_OPTION",
"LAST_EXCH",
"LAST_REG_TIME",
"FUTURES_OPEN_INTEREST",
"AVG_OPT_VOLUME",
"DELAYED_LAST_TIMESTAMP",
"SHORTABLE_SHARES",
"NOT_SET")
"BID",
"ASK",
"ASK_SIZE",
"LAST",
"LAST_SIZE",
"HIGH",
"LOW",
"VOLUME",
"CLOSE",
"BID_OPTION_COMPUTATION",
"ASK_OPTION_COMPUTATION",
"LAST_OPTION_COMPUTATION",
"MODEL_OPTION",
"OPEN",
"LOW_13_WEEK",
"HIGH_13_WEEK",
"LOW_26_WEEK",
"HIGH_26_WEEK",
"LOW_52_WEEK",
"HIGH_52_WEEK",
"AVG_VOLUME",
"OPEN_INTEREST",
"OPTION_HISTORICAL_VOL",
"OPTION_IMPLIED_VOL",
"OPTION_BID_EXCH",
"OPTION_ASK_EXCH",
"OPTION_CALL_OPEN_INTEREST",
"OPTION_PUT_OPEN_INTEREST",
"OPTION_CALL_VOLUME",
"OPTION_PUT_VOLUME",
"INDEX_FUTURE_PREMIUM",
"BID_EXCH",
"ASK_EXCH",
"AUCTION_VOLUME",
"AUCTION_PRICE",
"AUCTION_IMBALANCE",
"MARK_PRICE",
"BID_EFP_COMPUTATION",
"ASK_EFP_COMPUTATION",
"LAST_EFP_COMPUTATION",
"OPEN_EFP_COMPUTATION",
"HIGH_EFP_COMPUTATION",
"LOW_EFP_COMPUTATION",
"CLOSE_EFP_COMPUTATION",
"LAST_TIMESTAMP",
"SHORTABLE",
"FUNDAMENTAL_RATIOS",
"RT_VOLUME",
"HALTED",
"BID_YIELD",
"ASK_YIELD",
"LAST_YIELD",
"CUST_OPTION_COMPUTATION",
"TRADE_COUNT",
"TRADE_RATE",
"VOLUME_RATE",
"LAST_RTH_TRADE",
"RT_HISTORICAL_VOL",
"IB_DIVIDENDS",
"BOND_FACTOR_MULTIPLIER",
"REGULATORY_IMBALANCE",
"NEWS_TICK",
"SHORT_TERM_VOLUME_3_MIN",
"SHORT_TERM_VOLUME_5_MIN",
"SHORT_TERM_VOLUME_10_MIN",
"DELAYED_BID",
"DELAYED_ASK",
"DELAYED_LAST",
"DELAYED_BID_SIZE",
"DELAYED_ASK_SIZE",
"DELAYED_LAST_SIZE",
"DELAYED_HIGH",
"DELAYED_LOW",
"DELAYED_VOLUME",
"DELAYED_CLOSE",
"DELAYED_OPEN",
"RT_TRD_VOLUME",
"CREDITMAN_MARK_PRICE",
"CREDITMAN_SLOW_MARK_PRICE",
"DELAYED_BID_OPTION",
"DELAYED_ASK_OPTION",
"DELAYED_LAST_OPTION",
"DELAYED_MODEL_OPTION",
"LAST_EXCH",
"LAST_REG_TIME",
"FUTURES_OPEN_INTEREST",
"AVG_OPT_VOLUME",
"DELAYED_LAST_TIMESTAMP",
"SHORTABLE_SHARES",
"NOT_SET")

View File

@ -1,3 +1,7 @@
from .common import UNSET_INTEGER, UNSET_DOUBLE
import inspect
import logging
import sys
"""
Copyright (C) 2018 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.
@ -9,13 +13,6 @@ Collection of misc tools
"""
import sys
import logging
import inspect
from ibapi.common import UNSET_INTEGER, UNSET_DOUBLE
logger = logging.getLogger(__name__)
@ -37,27 +34,31 @@ class LogFunction(object):
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']
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))
"{} {} {} 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
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)
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):
def decode(the_type, fields, show_unset=False):
try:
s = next(fields)
except StopIteration:
@ -71,7 +72,8 @@ def decode(the_type, fields, show_unset = False):
elif type(s) is bytes:
return s.decode()
else:
raise TypeError("unsupported incoming type " + type(s) + " for desired type 'str")
raise TypeError("unsupported incoming type " +
type(s) + " for desired type 'str")
orig_type = the_type
if the_type is bool:
@ -84,7 +86,8 @@ def decode(the_type, fields, show_unset = False):
elif the_type is int:
n = UNSET_INTEGER
else:
raise TypeError("unsupported desired type for empty value" + the_type)
raise TypeError(
"unsupported desired type for empty value" + the_type)
else:
n = the_type(s)
else:
@ -96,7 +99,6 @@ def decode(the_type, fields, show_unset = False):
return n
def ExerciseStaticMethods(klass):
import types
@ -108,8 +110,6 @@ def ExerciseStaticMethods(klass):
print(var())
print()
def floatToStr(val):
return str(val) if val != UNSET_DOUBLE else "";
return str(val) if val != UNSET_DOUBLE else ""

View File

@ -21,14 +21,14 @@ server and client.
import logging
from ibapi.common import * # @UnusedWildImport
from ibapi.utils import * # @UnusedWildImport
from ibapi.contract import (Contract, ContractDetails, DeltaNeutralContract)
from ibapi.order import Order
from ibapi.order_state import OrderState
from ibapi.execution import Execution
from ibapi.ticktype import * # @UnusedWildImport
from ibapi.commission_report import CommissionReport
from .common import * # @UnusedWildImport
from .utils import * # @UnusedWildImport
from .contract import (Contract, ContractDetails, DeltaNeutralContract)
from .order import Order
from .order_state import OrderState
from .execution import Execution
from .ticktype import * # @UnusedWildImport
from .commission_report import CommissionReport
logger = logging.getLogger(__name__)