Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge pull request #6 from benalexau/master

Update to TWS API 9.70 and support Python 3
  • Loading branch information...
commit 9056e3306cf88885e9ba3ee7e4fc7a32c87d6157 2 parents 003a216 + a05b4e1
Bryce Lampe authored
1  .README.in
View
@@ -22,6 +22,7 @@ What's new in this release?
* Added script to filter TWS log files; see `demo/log_filter`
* Added ib.sym package to hold various symbolic constants
* Many small enhancements to ib.opt package
+ * Python 3 support
Where can I get IbPy?
2  .gitignore
View
@@ -1,6 +1,8 @@
+build
release-*
*.py[oc]
*.sw[nop]
*~
._*
.DS_Store
+*.bak
4 README.mkd
View
@@ -13,8 +13,8 @@ submit orders for stocks and futures, and more.
What's new in this release?
------------------------------------------------------------------------------
-
- * TWS API version 9.67 now supported
+
+ * TWS API version 9.70 now supported
* Over 60% test coverage and growing
* Fixed outstanding bugs in EReader generated source
* Module ib.opt.logger moved to ib.lib.logger
67 demo/api_coverage
View
@@ -10,6 +10,7 @@
#
##
import logging
+import sys
from functools import partial
from logging import DEBUG, INFO, WARN, ERROR
@@ -31,7 +32,7 @@ order_ids = [0]
tick_msgs = []
short_sleep = partial(sleep, 1)
long_sleep = partial(sleep, 10)
-generic_tick_keys = '100,101,104,106,162,165,221,225,236'
+generic_tick_keys = '100,101,104,106,165,221,225,236'
unseen_hints = {
'OpenOrder' : 'only works with existing order(s) before connecting',
@@ -81,7 +82,10 @@ def gen_tick_id():
while True:
yield i
i += 1
-gen_tick_id = gen_tick_id().next
+if sys.version_info[0] < 3:
+ gen_tick_id = gen_tick_id().next
+else:
+ gen_tick_id = gen_tick_id().__next__
def make_contract(symbol):
@@ -116,7 +120,7 @@ def exec_filter(client_id):
def make_msg_counter(rec_map, unrec_map):
- for classes in message.registry.values():
+ for classes in list(message.registry.values()):
for cls in [c for c in classes if True]:
if not cls.__name__.endswith('Pre') and not cls.__name__.endswith('Post'):
rec_map[cls] = []
@@ -286,6 +290,19 @@ def test_009(connection, options):
short_sleep()
+def test_010(connection, options):
+ connection.reqPositions()
+ short_sleep()
+ connection.cancelPositions()
+
+
+def test_011(connection, options):
+ reqId = gen_tick_id()
+ connection.reqAccountSummary(reqId, 'All', 'AccountType,NetLiquidation')
+ short_sleep()
+ connection.cancelAccountSummary(reqId)
+
+
def test_999(connection, options):
short_sleep()
connection.eDisconnect()
@@ -341,8 +358,8 @@ def main(options):
## make_msg_counter fills in the defaults for the rec_msgs dict; now we can
## print those values and exit if the option is given
if options.printmsgs:
- for name in sorted(k[0].typeName for k in rec_msgs.keys()):
- print name
+ for name in sorted(k[0].typeName for k in list(rec_msgs.keys())):
+ print(name)
return
## if we're still here, we should connect
@@ -355,15 +372,15 @@ def main(options):
## and if we've connected, we shoud execute all of the test functions in
## the module namespace.
- calls = [v for k, v in globals().items() if k.startswith('test_')]
- for call in sorted(calls):
+ calls = [v for k, v in list(globals().items()) if k.startswith('test_')]
+ for call in sorted(calls, key=lambda f: f.__name__):
call = maybe_verbose(catch_errors(call))
errors = call(con, options)
for err in errors:
error_msgs[err] = call.__name__
type_count = len(rec_msgs)
- seen_items = rec_msgs.items()
+ seen_items = list(rec_msgs.items())
seen = [(k, v) for k, v in seen_items if v]
unseen = [(k, v) for k, v in seen_items if not v]
@@ -371,7 +388,7 @@ def main(options):
alls = [v for v in options.showmsgs if 'all' in v.lower()]
if any(alls):
all, count = name_count(alls[0])
- options.showmsgs = ['%s:%s' % (k.typeName, count) for k in rec_msgs.keys()]
+ options.showmsgs = ['%s:%s' % (k.typeName, count) for k in list(rec_msgs.keys())]
## ready, set, print!
for msg_typename in options.showmsgs:
@@ -382,41 +399,41 @@ def main(options):
msgs = msgs[0]
if not msg_showmax or msg_showmax > len(msgs):
msg_showmax = len(msgs)
- print '\n%s (%s of %s):' % (msg_typename, msg_showmax, len(msgs), )
+ print('\n%s (%s of %s):' % (msg_typename, msg_showmax, len(msgs), ))
for msg in msgs[0:msg_showmax]:
- print formatter(msg)
+ print(formatter(msg))
else:
- if msg_typename in [k.typeName for k in rec_msgs.keys()]:
- print '\n%s (%s):' % (msg_typename, 0, )
+ if msg_typename in [k.typeName for k in list(rec_msgs.keys())]:
+ print('\n%s (%s):' % (msg_typename, 0, ))
else:
- print '\nMessage type %s not recognized' % (msg_typename, )
+ print('\nMessage type %s not recognized' % (msg_typename, ))
## but wait, there's more! here we print a summary of seen message
## types and associated counts.
if seen:
- print '\nSeen Message Types (count):'
- for cls, seq in sorted(seen):
- print ' %s (%s)' % (cls.__name__, len(seq), )
+ print('\nSeen Message Types (count):')
+ for cls, seq in sorted(seen, key=lambda t: t[0].typeName):
+ print(' %s (%s)' % (cls.__name__, len(seq), ))
else:
- print '\nTotal failure; no messages received.'
+ print('\nTotal failure; no messages received.')
## but wait, there's more! here we print a summary of unseen message
## types and associated counts.
if unseen:
- print '\nUnseen Message Types (help):'
- for cls, zero in sorted(unseen):
+ print('\nUnseen Message Types (help):')
+ for cls, zero in sorted(unseen, key=lambda t: t[0].typeName):
name = cls.__name__
help = unseen_hints.get(name, '')
- print ' %s%s' % (name, ' (%s)' % help if help else '', )
+ print(' %s%s' % (name, ' (%s)' % help if help else '', ))
else:
- print '\nAll Message types received.'
+ print('\nAll Message types received.')
## last but not least we print the seen and unseen totals, and their ratio
- print '\nSummary:'
+ print('\nSummary:')
args = (type_count, len(seen), len(unseen), 100*len(seen)/float(type_count))
- print ' total:%s seen:%s unseen:%s coverage:%2.2f%%' % args
+ print(' total:%s seen:%s unseen:%s coverage:%2.2f%%' % args)
if __name__ == '__main__':
try:
main(get_options())
except (KeyboardInterrupt, ):
- print '\nKeyboard interrupt.\n'
+ print('\nKeyboard interrupt.\n')
10 demo/example_opt
View
@@ -12,11 +12,11 @@ from ib.opt import ibConnection, message
def my_account_handler(msg):
- print msg
+ print(msg)
def my_tick_handler(msg):
- print msg
+ print(msg)
if __name__ == '__main__':
@@ -36,10 +36,10 @@ if __name__ == '__main__':
inner()
sleep(5)
- print 'disconnected', con.disconnect()
+ print('disconnected', con.disconnect())
sleep(3)
- print 'reconnected', con.reconnect()
+ print('reconnected', con.reconnect())
inner()
sleep(3)
- print 'again disconnected', con.disconnect()
+ print('again disconnected', con.disconnect())
75 demo/reference_python
View
@@ -21,11 +21,11 @@ def showmessage(message, mapping):
del(mapping['self'])
except (KeyError, ):
pass
- items = mapping.items()
+ items = list(mapping.items())
items.sort()
- print '### %s' % (message, )
+ print(('### %s' % (message, )))
for k, v in items:
- print ' %s:%s' % (k, v)
+ print((' %s:%s' % (k, v)))
class ReferenceWrapper(EWrapper):
@@ -35,11 +35,17 @@ class ReferenceWrapper(EWrapper):
def tickSize(self, tickerId, field, size):
showmessage('tickSize', vars())
+ def tickOptionComputation(self, tickerId, field, impliedVol, delta, optPrice, pvDividend, gamma, vega, theta, undPrice):
+ showmessage('tickOptionComputation', vars())
+
+ def tickGeneric(self, tickerId, tickType, value):
+ showmessage('tickGeneric', vars())
+
def tickString(self, tickerId, tickType, value):
showmessage('tickString', vars())
- def tickOptionComputation(self, tickerId, field, impliedVolatility, delta):
- showmessage('tickOptionComputation', vars())
+ def tickEFP(self, tickerId, tickType, basisPoints, formattedBasisPoints, impliedFuture, holdDays, futureExpiry, dividendImpact, dividendsToExpiry):
+ showmessage('tickEFP', vars())
def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeId):
showmessage('orderStatus', vars())
@@ -47,8 +53,8 @@ class ReferenceWrapper(EWrapper):
def openOrder(self, orderId, contract, order, state):
showmessage('openOrder', vars())
- def connectionClosed(self):
- showmessage('connectionClosed', {})
+ def openOrderEnd(self):
+ showmessage('openOrderEnd', vars())
def updateAccountValue(self, key, value, currency, accountName):
showmessage('updateAccountValue', vars())
@@ -59,21 +65,39 @@ class ReferenceWrapper(EWrapper):
def updateAccountTime(self, timeStamp):
showmessage('updateAccountTime', vars())
+ def accountDownloadEnd(self, accountName):
+ showmessage('accountDownloadEnd', vars())
+
def nextValidId(self, orderId):
showmessage('nextValidId', vars())
- def contractDetails(self, contractDetails):
+ def contractDetails(self, reqId, contractDetails):
showmessage('contractDetails', vars())
- def bondContractDetails(self, contractDetails):
+ def contractDetailsEnd(self, reqId):
+ showmessage('contractDetailsEnd', vars())
+
+ def bondContractDetails(self, reqId, contractDetails):
showmessage('bondContractDetails', vars())
- def execDetails(self, orderId, contract, execution):
+ def execDetails(self, reqId, contract, execution):
showmessage('execDetails', vars())
+ def execDetailsEnd(self, reqId):
+ showmessage('execDetailsEnd', vars())
+
+ def connectionClosed(self):
+ showmessage('connectionClosed', {})
+
def error(self, id=None, errorCode=None, errorMsg=None):
showmessage('error', vars())
+ def error_0(self, strvalue=None):
+ showmessage('error_0', vars())
+
+ def error_1(self, id=None, errorCode=None, errorMsg=None):
+ showmessage('error_1', vars())
+
def updateMktDepth(self, tickerId, position, operation, side, price, size):
showmessage('updateMktDepth', vars())
@@ -95,7 +119,7 @@ class ReferenceWrapper(EWrapper):
def scannerParameters(self, xml):
showmessage('scannerParameters', vars())
- def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection):
+ def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection, legsStr):
showmessage('scannerData', vars())
def accountDownloadEnd(self, accountName):
@@ -146,6 +170,18 @@ class ReferenceWrapper(EWrapper):
def error_1(self, id, errorCode, errorMsg):
showmessage('error_1', vars())
+ def position(self, account, contract, pos, avgCost):
+ showmessage('position', vars())
+
+ def positionEnd(self):
+ showmessage('positionEnd', vars())
+
+ def accountSummary(self, reqId, account, tag, value, currency):
+ showmessage('accountSummary', vars())
+
+ def accountSummaryEnd(self, reqId):
+ showmessage('accountSummaryEnd', vars())
+
allMethods = []
def ref(method):
allMethods.append(method.__name__)
@@ -175,7 +211,7 @@ class ReferenceApp:
@ref
def reqExecutions(self):
filt = ExecutionFilter()
- self.connection.reqExecutions(filt)
+ self.connection.reqExecutions(0, filt)
@ref
def reqIds(self):
@@ -212,9 +248,10 @@ class ReferenceApp:
@ref
def reqMktData(self):
contract = Contract() #
- contract.m_symbol = 'QQQQ'
- contract.m_secType = 'STK'
- contract.m_exchange = 'SMART'
+ contract.m_symbol = 'AUD'
+ contract.m_currency = 'USD'
+ contract.m_secType = 'CASH'
+ contract.m_exchange = 'IDEALPRO'
self.connection.reqMktData(1, contract, '', False)
@ref
@@ -253,13 +290,13 @@ if __name__ == '__main__':
if 'eDisconnect' not in methods:
methods.append('eDisconnect')
- print '### calling functions:', str.join(', ', methods)
+ print(('### calling functions:', str.join(', ', methods)))
for mname in methods:
call = getattr(app, mname, None)
if call is None:
- print '### warning: no call %s' % (mname, )
+ print(('### warning: no call %s' % (mname, )))
else:
- print '## calling', call.im_func.func_name
+ print(('## calling', call.__func__.__name__))
call()
- print '## called', call.im_func.func_name
+ print(('## called', call.__func__.__name__))
8 ib/ext/Contract.py
View
@@ -29,6 +29,7 @@ class Contract(Cloneable):
m_currency = ""
m_localSymbol = ""
+ m_tradingClass = ""
m_primaryExch = "" # pick a non-aggregate (ie not the SMART exchange) exchange that the contract trades on. DO NOT SET TO SMART.
m_includeExpired = bool() # can not be set to true for orders.
@@ -56,8 +57,8 @@ def clone(self):
retval.m_comboLegs = self.m_comboLegs[:]
return retval
- @__init__.register(object, int, str, str, str, float, str, str, str, str, str, list, str, bool, str, str)
- def __init___0(self, p_conId, p_symbol, p_secType, p_expiry, p_strike, p_right, p_multiplier, p_exchange, p_currency, p_localSymbol, p_comboLegs, p_primaryExch, p_includeExpired, p_secIdType, p_secId):
+ @__init__.register(object, int, str, str, str, float, str, str, str, str, str, str, list, str, bool, str, str)
+ def __init___0(self, p_conId, p_symbol, p_secType, p_expiry, p_strike, p_right, p_multiplier, p_exchange, p_currency, p_localSymbol, p_tradingClass, p_comboLegs, p_primaryExch, p_includeExpired, p_secIdType, p_secId):
""" generated source for method __init___0 """
super(Contract, self).__init__()
self.m_conId = p_conId
@@ -71,6 +72,7 @@ def __init___0(self, p_conId, p_symbol, p_secType, p_expiry, p_strike, p_right,
self.m_currency = p_currency
self.m_includeExpired = p_includeExpired
self.m_localSymbol = p_localSymbol
+ self.m_tradingClass = p_tradingClass
self.m_comboLegs = p_comboLegs
self.m_primaryExch = p_primaryExch
self.m_secIdType = p_secIdType
@@ -92,7 +94,7 @@ def __eq__(self, p_other):
if not Util.NormalizeString(self.m_secType) == "BOND":
if self.m_strike != l_theOther.m_strike:
return False
- if (Util.StringCompare(self.m_expiry, l_theOther.m_expiry) != 0) or (Util.StringCompare(self.m_right, l_theOther.m_right) != 0) or (Util.StringCompare(self.m_multiplier, l_theOther.m_multiplier) != 0) or (Util.StringCompare(self.m_localSymbol, l_theOther.m_localSymbol) != 0):
+ if (Util.StringCompare(self.m_expiry, l_theOther.m_expiry) != 0) or (Util.StringCompare(self.m_right, l_theOther.m_right) != 0) or (Util.StringCompare(self.m_multiplier, l_theOther.m_multiplier) != 0) or (Util.StringCompare(self.m_localSymbol, l_theOther.m_localSymbol) != 0) or (Util.StringCompare(self.m_tradingClass, l_theOther.m_tradingClass) != 0):
return False
if Util.StringCompare(self.m_secIdType, l_theOther.m_secIdType) != 0:
return False
4 ib/ext/ContractDetails.py
View
@@ -19,7 +19,6 @@ class ContractDetails(object):
""" generated source for class ContractDetails """
m_summary = None
m_marketName = ""
- m_tradingClass = ""
m_minTick = float()
m_priceMagnifier = 0
m_orderTypes = ""
@@ -64,11 +63,10 @@ def __init__(self):
self.m_evMultiplier = 0
@__init__.register(object, Contract, str, str, float, str, str, int, str, str, str, str, str, str, str, str, str, float)
- def __init___0(self, p_summary, p_marketName, p_tradingClass, p_minTick, p_orderTypes, p_validExchanges, p_underConId, p_longName, p_contractMonth, p_industry, p_category, p_subcategory, p_timeZoneId, p_tradingHours, p_liquidHours, p_evRule, p_evMultiplier):
+ def __init___0(self, p_summary, p_marketName, p_minTick, p_orderTypes, p_validExchanges, p_underConId, p_longName, p_contractMonth, p_industry, p_category, p_subcategory, p_timeZoneId, p_tradingHours, p_liquidHours, p_evRule, p_evMultiplier):
""" generated source for method __init___0 """
self.m_summary = p_summary
self.m_marketName = p_marketName
- self.m_tradingClass = p_tradingClass
self.m_minTick = p_minTick
self.m_orderTypes = p_orderTypes
self.m_validExchanges = p_validExchanges
11 ib/ext/EClientErrors.py
View
@@ -49,10 +49,11 @@ def __init__(self, i, errString):
NO_VALID_ID = -1
+ NOT_CONNECTED = CodeMsgPair(504, "Not connected")
+ UPDATE_TWS = CodeMsgPair(503, "The TWS is out of date and must be upgraded.")
ALREADY_CONNECTED = CodeMsgPair(501, "Already connected.")
CONNECT_FAIL = CodeMsgPair(502, "Couldn't connect to TWS. Confirm that \"Enable ActiveX and Socket Clients\" is enabled on the TWS \"Configure->API\" menu.")
- UPDATE_TWS = CodeMsgPair(503, "The TWS is out of date and must be upgraded.")
- NOT_CONNECTED = CodeMsgPair(504, "Not connected")
+ FAIL_SEND = CodeMsgPair(509, "Failed to send message - ")
UNKNOWN_ID = CodeMsgPair(505, "Fatal Error: Unknown message id.")
FAIL_SEND_REQMKT = CodeMsgPair(510, "Request Market Data Sending Error - ")
FAIL_SEND_CANMKT = CodeMsgPair(511, "Cancel Market Data Sending Error - ")
@@ -84,5 +85,7 @@ def __init__(self, i, errString):
FAIL_SEND_CANCALCOPTIONPRICE = CodeMsgPair(537, "Cancel Calculate Option Price Sending Error - ")
FAIL_SEND_REQGLOBALCANCEL = CodeMsgPair(538, "Request Global Cancel Sending Error - ")
FAIL_SEND_REQMARKETDATATYPE = CodeMsgPair(539, "Request Market Data Type Sending Error - ")
-
-
+ FAIL_SEND_REQPOSITIONS = CodeMsgPair(540, "Request Positions Sending Error - ")
+ FAIL_SEND_CANPOSITIONS = CodeMsgPair(541, "Cancel Positions Sending Error - ")
+ FAIL_SEND_REQACCOUNTDATA = CodeMsgPair(542, "Request Account Data Sending Error - ")
+ FAIL_SEND_CANACCOUNTDATA = CodeMsgPair(543, "Cancel Account Data Sending Error - ")
278 ib/ext/EClientSocket.py
View
@@ -112,7 +112,12 @@ class EClientSocket(object):
# 58 = can receive CUSIP/ISIN/etc. in contractDescription/bondContractDescription
# 59 = can receive evRule, evMultiplier in contractDescription/bondContractDescription/executionDetails
# can receive multiplier in executionDetails
- CLIENT_VERSION = 59
+ # 60 = can receive deltaNeutralOpenClose, deltaNeutralShortSale, deltaNeutralShortSaleSlot and deltaNeutralDesignatedLocation in openOrder
+ # 61 = can receive multiplier in openOrder
+ # can receive tradingClass in openOrder, updatePortfolio, execDetails and position
+ # 62 = can receive avgCost in position message
+
+ CLIENT_VERSION = 62
SERVER_VERSION = 38
EOL = 0
BAG_SEC_TYPE = "BAG"
@@ -170,6 +175,10 @@ def faMsgTypeName(cls, faDataType):
CANCEL_CALC_OPTION_PRICE = 57
REQ_GLOBAL_CANCEL = 58
REQ_MARKET_DATA_TYPE = 59
+ REQ_POSITIONS = 61
+ REQ_ACCOUNT_SUMMARY = 62
+ CANCEL_ACCOUNT_SUMMARY = 63
+ CANCEL_POSITIONS = 64
MIN_SERVER_VER_REAL_TIME_BARS = 34
MIN_SERVER_VER_SCALE_ORDERS = 35
MIN_SERVER_VER_SNAPSHOT_MKT_DATA = 35
@@ -202,6 +211,10 @@ def faMsgTypeName(cls, faDataType):
MIN_SERVER_VER_SCALE_ORDERS3 = 60
MIN_SERVER_VER_ORDER_COMBO_LEGS_PRICE = 61
MIN_SERVER_VER_TRAILING_PERCENT = 62
+ MIN_SERVER_VER_DELTA_NEUTRAL_OPEN_CLOSE = 66
+ MIN_SERVER_VER_ACCT_SUMMARY = 67
+ MIN_SERVER_VER_TRADING_CLASS = 68
+ MIN_SERVER_VER_SCALE_TABLE = 69
m_anyWrapper = None # msg handler
m_dos = None # the socket output stream
@@ -327,7 +340,7 @@ def cancelScannerSubscription(self, tickerId):
""" generated source for method cancelScannerSubscription """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < 24:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support API scanner subscription.")
@@ -347,7 +360,7 @@ def reqScannerParameters(self):
""" generated source for method reqScannerParameters """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < 24:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support API scanner subscription.")
@@ -365,7 +378,7 @@ def reqScannerSubscription(self, tickerId, subscription):
""" generated source for method reqScannerSubscription """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < 24:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support API scanner subscription.")
@@ -394,7 +407,7 @@ def reqScannerSubscription(self, tickerId, subscription):
self.sendMax(subscription.couponRateBelow())
self.send(subscription.excludeConvertible())
if self.m_serverVersion >= 25:
- self.send(subscription.averageOptionVolumeAbove())
+ self.sendMax(subscription.averageOptionVolumeAbove())
self.send(subscription.scannerSettingPairs())
if self.m_serverVersion >= 27:
self.send(subscription.stockTypeFilter())
@@ -419,7 +432,11 @@ def reqMktData(self, tickerId, contract, genericTickList, snapshot):
if contract.m_conId > 0:
self.error(tickerId, EClientErrors.UPDATE_TWS, " It does not support conId parameter.")
return
- VERSION = 9
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if not self.IsEmpty(contract.m_tradingClass):
+ self.error(tickerId, EClientErrors.UPDATE_TWS, " It does not support tradingClass parameter in reqMarketData.")
+ return
+ VERSION = 10
try:
# send req mkt data msg
self.send(self.REQ_MKT_DATA)
@@ -441,6 +458,8 @@ def reqMktData(self, tickerId, contract, genericTickList, snapshot):
self.send(contract.m_currency)
if self.m_serverVersion >= 2:
self.send(contract.m_localSymbol)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_tradingClass)
if self.m_serverVersion >= 8 and self.BAG_SEC_TYPE.lower() == contract.m_secType.lower():
if contract.m_comboLegs is None:
self.send(0)
@@ -483,7 +502,7 @@ def cancelHistoricalData(self, tickerId):
""" generated source for method cancelHistoricalData """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < 24:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support historical data query cancellation.")
@@ -502,7 +521,7 @@ def cancelRealTimeBars(self, tickerId):
""" generated source for method cancelRealTimeBars """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_REAL_TIME_BARS:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support realtime bar data query cancellation.")
@@ -517,22 +536,29 @@ def cancelRealTimeBars(self, tickerId):
self.error(tickerId, EClientErrors.FAIL_SEND_CANRTBARS, str(e))
self.close()
+ # Note that formatData parameter affects intra-day bars only; 1-day bars always return with date in YYYYMMDD format.
@synchronized(mlock)
def reqHistoricalData(self, tickerId, contract, endDateTime, durationStr, barSizeSetting, whatToShow, useRTH, formatDate):
""" generated source for method reqHistoricalData """
# not connected?
if not self.m_connected:
- self.error(tickerId, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
- VERSION = 4
+ VERSION = 5
try:
if self.m_serverVersion < 16:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support historical data backfill.")
return
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if not self.IsEmpty(contract.m_tradingClass) or (contract.m_conId > 0):
+ self.error(tickerId, EClientErrors.UPDATE_TWS, " It does not support conId and trade parameters in reqHistroricalData.")
+ return
self.send(self.REQ_HISTORICAL_DATA)
self.send(VERSION)
self.send(tickerId)
# send contract fields
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_conId)
self.send(contract.m_symbol)
self.send(contract.m_secType)
self.send(contract.m_expiry)
@@ -543,6 +569,8 @@ def reqHistoricalData(self, tickerId, contract, endDateTime, durationStr, barSiz
self.send(contract.m_primaryExch)
self.send(contract.m_currency)
self.send(contract.m_localSymbol)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_tradingClass)
if self.m_serverVersion >= 31:
self.send(1 if contract.m_includeExpired else 0)
if self.m_serverVersion >= 20:
@@ -575,18 +603,24 @@ def reqRealTimeBars(self, tickerId, contract, barSize, whatToShow, useRTH):
""" generated source for method reqRealTimeBars """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_REAL_TIME_BARS:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support real time bars.")
return
- VERSION = 1
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if not self.IsEmpty(contract.m_tradingClass) or (contract.m_conId > 0):
+ self.error(tickerId, EClientErrors.UPDATE_TWS, " It does not support conId and tradingClass parameters in reqRealTimeBars.")
+ return
+ VERSION = 2
try:
# send req mkt data msg
self.send(self.REQ_REAL_TIME_BARS)
self.send(VERSION)
self.send(tickerId)
# send contract fields
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_conId)
self.send(contract.m_symbol)
self.send(contract.m_secType)
self.send(contract.m_expiry)
@@ -597,7 +631,10 @@ def reqRealTimeBars(self, tickerId, contract, barSize, whatToShow, useRTH):
self.send(contract.m_primaryExch)
self.send(contract.m_currency)
self.send(contract.m_localSymbol)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_tradingClass)
self.send(barSize)
+ # this parameter is not currently used
self.send(whatToShow)
self.send(useRTH)
except Exception as e:
@@ -609,7 +646,7 @@ def reqContractDetails(self, reqId, contract):
""" generated source for method reqContractDetails """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
# This feature is only available for versions of TWS >=4
if self.m_serverVersion < 4:
@@ -619,7 +656,11 @@ def reqContractDetails(self, reqId, contract):
if not self.IsEmpty(contract.m_secIdType) or not self.IsEmpty(contract.m_secId):
self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support secIdType and secId parameters.")
return
- VERSION = 6
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if not self.IsEmpty(contract.m_tradingClass):
+ self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support tradingClass parameter in reqContractDetails.")
+ return
+ VERSION = 7
try:
# send req mkt data msg
self.send(self.REQ_CONTRACT_DATA)
@@ -639,6 +680,8 @@ def reqContractDetails(self, reqId, contract):
self.send(contract.m_exchange)
self.send(contract.m_currency)
self.send(contract.m_localSymbol)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_tradingClass)
if self.m_serverVersion >= 31:
self.send(contract.m_includeExpired)
if self.m_serverVersion >= self.MIN_SERVER_VER_SEC_ID_TYPE:
@@ -653,19 +696,25 @@ def reqMktDepth(self, tickerId, contract, numRows):
""" generated source for method reqMktDepth """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
# This feature is only available for versions of TWS >=6
if self.m_serverVersion < 6:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS.code(), EClientErrors.UPDATE_TWS.msg())
return
- VERSION = 3
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if not self.IsEmpty(contract.m_tradingClass) or (contract.m_conId > 0):
+ self.error(tickerId, EClientErrors.UPDATE_TWS, " It does not support conId and tradingClass parameters in reqMktDepth.")
+ return
+ VERSION = 4
try:
# send req mkt data msg
self.send(self.REQ_MKT_DEPTH)
self.send(VERSION)
self.send(tickerId)
# send contract fields
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_conId)
self.send(contract.m_symbol)
self.send(contract.m_secType)
self.send(contract.m_expiry)
@@ -676,6 +725,8 @@ def reqMktDepth(self, tickerId, contract, numRows):
self.send(contract.m_exchange)
self.send(contract.m_currency)
self.send(contract.m_localSymbol)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_tradingClass)
if self.m_serverVersion >= 19:
self.send(numRows)
except Exception as e:
@@ -687,7 +738,7 @@ def cancelMktData(self, tickerId):
""" generated source for method cancelMktData """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
# send cancel mkt data msg
@@ -704,7 +755,7 @@ def cancelMktDepth(self, tickerId):
""" generated source for method cancelMktDepth """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
# This feature is only available for versions of TWS >=6
if self.m_serverVersion < 6:
@@ -725,17 +776,23 @@ def exerciseOptions(self, tickerId, contract, exerciseAction, exerciseQuantity,
""" generated source for method exerciseOptions """
# not connected?
if not self.m_connected:
- self.error(tickerId, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
- VERSION = 1
+ VERSION = 2
try:
if self.m_serverVersion < 21:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support options exercise from the API.")
return
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if not self.IsEmpty(contract.m_tradingClass) or (contract.m_conId > 0):
+ self.error(tickerId, EClientErrors.UPDATE_TWS, " It does not support conId and tradingClass parameters in exerciseOptions.")
+ return
self.send(self.EXERCISE_OPTIONS)
self.send(VERSION)
self.send(tickerId)
# send contract fields
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_conId)
self.send(contract.m_symbol)
self.send(contract.m_secType)
self.send(contract.m_expiry)
@@ -745,6 +802,8 @@ def exerciseOptions(self, tickerId, contract, exerciseAction, exerciseQuantity,
self.send(contract.m_exchange)
self.send(contract.m_currency)
self.send(contract.m_localSymbol)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_tradingClass)
self.send(exerciseAction)
self.send(exerciseQuantity)
self.send(account)
@@ -758,7 +817,7 @@ def placeOrder(self, id, contract, order):
""" generated source for method placeOrder """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_SCALE_ORDERS:
if (order.m_scaleInitLevelSize != Integer.MAX_VALUE) or (order.m_scalePriceIncrement != Double.MAX_VALUE):
@@ -826,6 +885,10 @@ def placeOrder(self, id, contract, order):
if order.m_deltaNeutralConId > 0 or not self.IsEmpty(order.m_deltaNeutralSettlingFirm) or not self.IsEmpty(order.m_deltaNeutralClearingAccount) or not self.IsEmpty(order.m_deltaNeutralClearingIntent):
self.error(id, EClientErrors.UPDATE_TWS, " It does not support deltaNeutral parameters: ConId, SettlingFirm, ClearingAccount, ClearingIntent")
return
+ if self.m_serverVersion < self.MIN_SERVER_VER_DELTA_NEUTRAL_OPEN_CLOSE:
+ if not self.IsEmpty(order.m_deltaNeutralOpenClose) or order.m_deltaNeutralShortSale or order.m_deltaNeutralShortSaleSlot > 0 or not self.IsEmpty(order.m_deltaNeutralDesignatedLocation):
+ self.error(id, EClientErrors.UPDATE_TWS, " It does not support deltaNeutral parameters: OpenClose, ShortSale, ShortSaleSlot, DesignatedLocation")
+ return
if self.m_serverVersion < self.MIN_SERVER_VER_SCALE_ORDERS3:
if order.m_scalePriceIncrement > 0 and order.m_scalePriceIncrement != Double.MAX_VALUE:
if order.m_scalePriceAdjustValue != Double.MAX_VALUE or order.m_scalePriceAdjustInterval != Integer.MAX_VALUE or order.m_scaleProfitOffset != Double.MAX_VALUE or order.m_scaleAutoReset or order.m_scaleInitPosition != Integer.MAX_VALUE or order.m_scaleInitFillQty != Integer.MAX_VALUE or order.m_scaleRandomPercent:
@@ -844,7 +907,15 @@ def placeOrder(self, id, contract, order):
if order.m_trailingPercent != Double.MAX_VALUE:
self.error(id, EClientErrors.UPDATE_TWS, " It does not support trailing percent parameter")
return
- VERSION = 27 if (self.m_serverVersion < self.MIN_SERVER_VER_NOT_HELD) else 38
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if not self.IsEmpty(contract.m_tradingClass):
+ self.error(id, EClientErrors.UPDATE_TWS, " It does not support tradingClass parameters in placeOrder.")
+ return
+ if self.m_serverVersion < self.MIN_SERVER_VER_SCALE_TABLE:
+ if not self.IsEmpty(order.m_scaleTable) or not self.IsEmpty(order.m_activeStartTime) or not self.IsEmpty(order.m_activeStopTime):
+ self.error(id, EClientErrors.UPDATE_TWS, " It does not support scaleTable, activeStartTime and activeStopTime parameters.")
+ return
+ VERSION = 27 if (self.m_serverVersion < self.MIN_SERVER_VER_NOT_HELD) else 41
# send place order msg
try:
self.send(self.PLACE_ORDER)
@@ -866,6 +937,8 @@ def placeOrder(self, id, contract, order):
self.send(contract.m_currency)
if self.m_serverVersion >= 2:
self.send(contract.m_localSymbol)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_tradingClass)
if self.m_serverVersion >= self.MIN_SERVER_VER_SEC_ID_TYPE:
self.send(contract.m_secIdType)
self.send(contract.m_secId)
@@ -1005,6 +1078,11 @@ def placeOrder(self, id, contract, order):
self.send(order.m_deltaNeutralSettlingFirm)
self.send(order.m_deltaNeutralClearingAccount)
self.send(order.m_deltaNeutralClearingIntent)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_DELTA_NEUTRAL_OPEN_CLOSE and not self.IsEmpty(order.m_deltaNeutralOrderType):
+ self.send(order.m_deltaNeutralOpenClose)
+ self.send(order.m_deltaNeutralShortSale)
+ self.send(order.m_deltaNeutralShortSaleSlot)
+ self.send(order.m_deltaNeutralDesignatedLocation)
self.send(order.m_continuousUpdate)
if self.m_serverVersion == 26:
# Volatility orders had specific watermark price attribs in server version 26
@@ -1034,6 +1112,10 @@ def placeOrder(self, id, contract, order):
self.sendMax(order.m_scaleInitPosition)
self.sendMax(order.m_scaleInitFillQty)
self.send(order.m_scaleRandomPercent)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_SCALE_TABLE:
+ self.send(order.m_scaleTable)
+ self.send(order.m_activeStartTime)
+ self.send(order.m_activeStopTime)
if self.m_serverVersion >= self.MIN_SERVER_VER_HEDGE_ORDERS:
self.send(order.m_hedgeType)
if not self.IsEmpty(order.m_hedgeType):
@@ -1078,7 +1160,7 @@ def reqAccountUpdates(self, subscribe, acctCode):
""" generated source for method reqAccountUpdates """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 2
# send cancel order msg
@@ -1098,7 +1180,7 @@ def reqExecutions(self, reqId, filter):
""" generated source for method reqExecutions """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 3
# send cancel order msg
@@ -1126,7 +1208,7 @@ def cancelOrder(self, id):
""" generated source for method cancelOrder """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
# send cancel order msg
@@ -1143,7 +1225,7 @@ def reqOpenOrders(self):
""" generated source for method reqOpenOrders """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
# send cancel order msg
@@ -1159,7 +1241,7 @@ def reqIds(self, numIds):
""" generated source for method reqIds """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
try:
@@ -1175,7 +1257,7 @@ def reqNewsBulletins(self, allMsgs):
""" generated source for method reqNewsBulletins """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
try:
@@ -1191,7 +1273,7 @@ def cancelNewsBulletins(self):
""" generated source for method cancelNewsBulletins """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
# send cancel order msg
@@ -1207,7 +1289,7 @@ def setServerLogLevel(self, logLevel):
""" generated source for method setServerLogLevel """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
# send the set server logging level message
@@ -1224,7 +1306,7 @@ def reqAutoOpenOrders(self, bAutoBind):
""" generated source for method reqAutoOpenOrders """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
# send req open orders msg
@@ -1241,7 +1323,7 @@ def reqAllOpenOrders(self):
""" generated source for method reqAllOpenOrders """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
# send req all open orders msg
@@ -1257,7 +1339,7 @@ def reqManagedAccts(self):
""" generated source for method reqManagedAccts """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
VERSION = 1
# send req FA managed accounts msg
@@ -1273,7 +1355,7 @@ def requestFA(self, faDataType):
""" generated source for method requestFA """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
# This feature is only available for versions of TWS >= 13
if self.m_serverVersion < 13:
@@ -1293,7 +1375,7 @@ def replaceFA(self, faDataType, xml):
""" generated source for method replaceFA """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
# This feature is only available for versions of TWS >= 13
if self.m_serverVersion < 13:
@@ -1314,7 +1396,7 @@ def reqCurrentTime(self):
""" generated source for method reqCurrentTime """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
# This feature is only available for versions of TWS >= 33
if self.m_serverVersion < 33:
@@ -1331,19 +1413,26 @@ def reqCurrentTime(self):
@synchronized(mlock)
def reqFundamentalData(self, reqId, contract, reportType):
""" generated source for method reqFundamentalData """
+ # not connected?
if not self.m_connected:
- self.error(reqId, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_FUNDAMENTAL_DATA:
self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support fundamental data requests.")
return
- VERSION = 1
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if contract.m_conId > 0:
+ self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support conId parameter in reqFundamentalData.")
+ return
+ VERSION = 2
try:
# send req fund data msg
self.send(self.REQ_FUNDAMENTAL_DATA)
self.send(VERSION)
self.send(reqId)
# send contract fields
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_conId)
self.send(contract.m_symbol)
self.send(contract.m_secType)
self.send(contract.m_exchange)
@@ -1358,8 +1447,9 @@ def reqFundamentalData(self, reqId, contract, reportType):
@synchronized(mlock)
def cancelFundamentalData(self, reqId):
""" generated source for method cancelFundamentalData """
+ # not connected?
if not self.m_connected:
- self.error(reqId, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_FUNDAMENTAL_DATA:
self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support fundamental data requests.")
@@ -1377,13 +1467,18 @@ def cancelFundamentalData(self, reqId):
@synchronized(mlock)
def calculateImpliedVolatility(self, reqId, contract, optionPrice, underPrice):
""" generated source for method calculateImpliedVolatility """
+ # not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_REQ_CALC_IMPLIED_VOLAT:
self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support calculate implied volatility requests.")
return
- VERSION = 1
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if not self.IsEmpty(contract.m_tradingClass):
+ self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support tradingClass parameter in calculateImpliedVolatility.")
+ return
+ VERSION = 2
try:
# send calculate implied volatility msg
self.send(self.REQ_CALC_IMPLIED_VOLAT)
@@ -1401,6 +1496,8 @@ def calculateImpliedVolatility(self, reqId, contract, optionPrice, underPrice):
self.send(contract.m_primaryExch)
self.send(contract.m_currency)
self.send(contract.m_localSymbol)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_tradingClass)
self.send(optionPrice)
self.send(underPrice)
except Exception as e:
@@ -1410,8 +1507,9 @@ def calculateImpliedVolatility(self, reqId, contract, optionPrice, underPrice):
@synchronized(mlock)
def cancelCalculateImpliedVolatility(self, reqId):
""" generated source for method cancelCalculateImpliedVolatility """
+ # not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_CANCEL_CALC_IMPLIED_VOLAT:
self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support calculate implied volatility cancellation.")
@@ -1429,13 +1527,18 @@ def cancelCalculateImpliedVolatility(self, reqId):
@synchronized(mlock)
def calculateOptionPrice(self, reqId, contract, volatility, underPrice):
""" generated source for method calculateOptionPrice """
+ # not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_REQ_CALC_OPTION_PRICE:
self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support calculate option price requests.")
return
- VERSION = 1
+ if self.m_serverVersion < self.MIN_SERVER_VER_TRADING_CLASS:
+ if not self.IsEmpty(contract.m_tradingClass):
+ self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support tradingClass parameter in calculateOptionPrice.")
+ return
+ VERSION = 2
try:
# send calculate option price msg
self.send(self.REQ_CALC_OPTION_PRICE)
@@ -1453,6 +1556,8 @@ def calculateOptionPrice(self, reqId, contract, volatility, underPrice):
self.send(contract.m_primaryExch)
self.send(contract.m_currency)
self.send(contract.m_localSymbol)
+ if self.m_serverVersion >= self.MIN_SERVER_VER_TRADING_CLASS:
+ self.send(contract.m_tradingClass)
self.send(volatility)
self.send(underPrice)
except Exception as e:
@@ -1462,8 +1567,9 @@ def calculateOptionPrice(self, reqId, contract, volatility, underPrice):
@synchronized(mlock)
def cancelCalculateOptionPrice(self, reqId):
""" generated source for method cancelCalculateOptionPrice """
+ # not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_CANCEL_CALC_OPTION_PRICE:
self.error(reqId, EClientErrors.UPDATE_TWS, " It does not support calculate option price cancellation.")
@@ -1483,7 +1589,7 @@ def reqGlobalCancel(self):
""" generated source for method reqGlobalCancel """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_REQ_GLOBAL_CANCEL:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support globalCancel requests.")
@@ -1502,7 +1608,7 @@ def reqMarketDataType(self, marketDataType):
""" generated source for method reqMarketDataType """
# not connected?
if not self.m_connected:
- self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
+ self.notConnected()
return
if self.m_serverVersion < self.MIN_SERVER_VER_REQ_MARKET_DATA_TYPE:
self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support marketDataType requests.")
@@ -1517,6 +1623,79 @@ def reqMarketDataType(self, marketDataType):
self.error(EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_REQMARKETDATATYPE, str(e))
self.close()
+ @synchronized(mlock)
+ def reqPositions(self):
+ """ generated source for method reqPositions """
+ # not connected?
+ if not self.m_connected:
+ self.notConnected()
+ return
+ if self.m_serverVersion < self.MIN_SERVER_VER_ACCT_SUMMARY:
+ self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support position requests.")
+ return
+ VERSION = 1
+ try:
+ self.send(self.REQ_POSITIONS)
+ self.send(VERSION)
+ except Exception as e:
+ self.error(EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_REQPOSITIONS, "" + e)
+
+ @synchronized(mlock)
+ def cancelPositions(self):
+ """ generated source for method cancelPositions """
+ # not connected?
+ if not self.m_connected:
+ self.notConnected()
+ return
+ if self.m_serverVersion < self.MIN_SERVER_VER_ACCT_SUMMARY:
+ self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support position cancellation.")
+ return
+ VERSION = 1
+ try:
+ self.send(self.CANCEL_POSITIONS)
+ self.send(VERSION)
+ except Exception as e:
+ self.error(EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_CANPOSITIONS, "" + e)
+
+ @synchronized(mlock)
+ def reqAccountSummary(self, reqId, group, tags):
+ """ generated source for method reqAccountSummary """
+ # not connected?
+ if not self.m_connected:
+ self.notConnected()
+ return
+ if self.m_serverVersion < self.MIN_SERVER_VER_ACCT_SUMMARY:
+ self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support account summary requests.")
+ return
+ VERSION = 1
+ try:
+ self.send(self.REQ_ACCOUNT_SUMMARY)
+ self.send(VERSION)
+ self.send(reqId)
+ self.send(group)
+ self.send(tags)
+ except Exception as e:
+ self.error(EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_REQACCOUNTDATA, "" + e)
+
+ @synchronized(mlock)
+ def cancelAccountSummary(self, reqId):
+ """ generated source for method cancelAccountSummary """
+ # not connected?
+ if not self.m_connected:
+ self.notConnected()
+ return
+ if self.m_serverVersion < self.MIN_SERVER_VER_ACCT_SUMMARY:
+ self.error(EClientErrors.NO_VALID_ID, EClientErrors.UPDATE_TWS, " It does not support account summary cancellation.")
+ return
+ VERSION = 1
+ try:
+ self.send(self.CANCEL_ACCOUNT_SUMMARY)
+ self.send(VERSION)
+ self.send(reqId)
+ except Exception as e:
+ self.error(EClientErrors.NO_VALID_ID, EClientErrors.FAIL_SEND_CANACCOUNTDATA, "" + e)
+
+ # @deprecated, never called.
@overloaded
@synchronized(mlock)
def error(self, err):
@@ -1557,7 +1736,7 @@ def send(self, strval):
# write string to data buffer; writer thread will
# write it to socket
if not self.IsEmpty(strval):
- self.m_dos.write(strval.getBytes())
+ self.m_dos.write(strval)
self.sendEOL()
def sendEOL(self):
@@ -1611,3 +1790,6 @@ def IsEmpty(cls, strval):
""" generated source for method IsEmpty """
return Util.StringIsEmpty(strval)
+ def notConnected(self):
+ """ generated source for method notConnected """
+ self.error(EClientErrors.NO_VALID_ID, EClientErrors.NOT_CONNECTED, "")
64 ib/ext/EReader.py
View
@@ -72,6 +72,10 @@ class EReader(Thread):
TICK_SNAPSHOT_END = 57
MARKET_DATA_TYPE = 58
COMMISSION_REPORT = 59
+ POSITION = 61
+ POSITION_END = 62
+ ACCOUNT_SUMMARY = 63
+ ACCOUNT_SUMMARY_END = 64
m_parent = None
m_dis = None
@@ -107,6 +111,11 @@ def run(self):
self.eWrapper().error(ex)
if self.parent().isConnected():
self.m_parent.close()
+ try:
+ self.m_dis.close()
+ self.m_dis = None
+ except Exception as e:
+ pass
# Overridden in subclass.
def processMsg(self, msgId):
@@ -148,6 +157,42 @@ def processMsg(self, msgId):
tickType = self.readInt()
size = self.readInt()
self.eWrapper().tickSize(tickerId, tickType, size)
+ elif msgId==self.POSITION:
+ version = self.readInt()
+ account = self.readStr()
+ contract = Contract()
+ contract.m_conId = self.readInt()
+ contract.m_symbol = self.readStr()
+ contract.m_secType = self.readStr()
+ contract.m_expiry = self.readStr()
+ contract.m_strike = self.readDouble()
+ contract.m_right = self.readStr()
+ contract.m_multiplier = self.readStr()
+ contract.m_exchange = self.readStr()
+ contract.m_currency = self.readStr()
+ contract.m_localSymbol = self.readStr()
+ if version >= 2:
+ contract.m_tradingClass = self.readStr()
+ pos = self.readInt()
+ avgCost = 0
+ if version >= 3:
+ avgCost = self.readDouble()
+ self.eWrapper().position(account, contract, pos, avgCost)
+ elif msgId==self.POSITION_END:
+ version = self.readInt()
+ self.eWrapper().positionEnd()
+ elif msgId==self.ACCOUNT_SUMMARY:
+ version = self.readInt()
+ reqId = self.readInt()
+ account = self.readStr()
+ tag = self.readStr()
+ value = self.readStr()
+ currency = self.readStr()
+ self.eWrapper().accountSummary(reqId, account, tag, value, currency)
+ elif msgId==self.ACCOUNT_SUMMARY_END:
+ version = self.readInt()
+ reqId = self.readInt()
+ self.eWrapper().accountSummaryEnd(reqId)
elif msgId == self.TICK_OPTION_COMPUTATION:
version = self.readInt()
tickerId = self.readInt()
@@ -258,6 +303,8 @@ def processMsg(self, msgId):
contract.m_currency = self.readStr()
if version >= 2:
contract.m_localSymbol = self.readStr()
+ if version >= 8:
+ contract.m_tradingClass = self.readStr()
position = self.readInt()
marketPrice = self.readDouble()
marketValue = self.readDouble()
@@ -303,10 +350,14 @@ def processMsg(self, msgId):
contract.m_expiry = self.readStr()
contract.m_strike = self.readDouble()
contract.m_right = self.readStr()
+ if version >= 32:
+ contract.m_multiplier = self.readStr()
contract.m_exchange = self.readStr()
contract.m_currency = self.readStr()
if version >= 2:
contract.m_localSymbol = self.readStr()
+ if version >= 32:
+ contract.m_tradingClass = self.readStr()
# read order fields
order.m_action = self.readStr()
order.m_totalQuantity = self.readInt()
@@ -396,6 +447,11 @@ def processMsg(self, msgId):
order.m_deltaNeutralSettlingFirm = self.readStr()
order.m_deltaNeutralClearingAccount = self.readStr()
order.m_deltaNeutralClearingIntent = self.readStr()
+ if version >= 31 and not Util.StringIsEmpty(order.m_deltaNeutralOrderType):
+ order.m_deltaNeutralOpenClose = self.readStr()
+ order.m_deltaNeutralShortSale = self.readBoolFromInt()
+ order.m_deltaNeutralShortSaleSlot = self.readInt()
+ order.m_deltaNeutralDesignatedLocation = self.readStr()
order.m_continuousUpdate = self.readInt()
if self.m_parent.serverVersion() == 26:
order.m_stockRangeLower = self.readDouble()
@@ -530,7 +586,7 @@ def processMsg(self, msgId):
contract.m_summary.m_currency = self.readStr()
contract.m_summary.m_localSymbol = self.readStr()
contract.m_marketName = self.readStr()
- contract.m_tradingClass = self.readStr()
+ contract.m_summary.m_tradingClass = self.readStr()
distance = self.readStr()
benchmark = self.readStr()
projection = self.readStr()
@@ -555,7 +611,7 @@ def processMsg(self, msgId):
contract.m_summary.m_currency = self.readStr()
contract.m_summary.m_localSymbol = self.readStr()
contract.m_marketName = self.readStr()
- contract.m_tradingClass = self.readStr()
+ contract.m_summary.m_tradingClass = self.readStr()
contract.m_summary.m_conId = self.readInt()
contract.m_minTick = self.readDouble()
contract.m_summary.m_multiplier = self.readStr()
@@ -613,7 +669,7 @@ def processMsg(self, msgId):
contract.m_summary.m_exchange = self.readStr()
contract.m_summary.m_currency = self.readStr()
contract.m_marketName = self.readStr()
- contract.m_tradingClass = self.readStr()
+ contract.m_summary.m_tradingClass = self.readStr()
contract.m_summary.m_conId = self.readInt()
contract.m_minTick = self.readDouble()
contract.m_orderTypes = self.readStr()
@@ -660,6 +716,8 @@ def processMsg(self, msgId):
contract.m_exchange = self.readStr()
contract.m_currency = self.readStr()
contract.m_localSymbol = self.readStr()
+ if version >= 10:
+ contract.m_tradingClass = self.readStr()
exec_ = Execution()
exec_.m_orderId = orderId
exec_.m_execId = self.readStr()
15 ib/ext/EWrapper.py
View
@@ -159,3 +159,18 @@ def marketDataType(self, reqId, marketDataType):
def commissionReport(self, commissionReport):
""" generated source for method commissionReport """
+ @abstractmethod
+ def position(self, account, contract, pos, avgCost):
+ """ generated source for method position """
+
+ @abstractmethod
+ def positionEnd(self):
+ """ generated source for method positionEnd """
+
+ @abstractmethod
+ def accountSummary(self, reqId, account, tag, value, currency):
+ """ generated source for method accountSummary """
+
+ @abstractmethod
+ def accountSummaryEnd(self, reqId):
+ """ generated source for method accountSummaryEnd """
67 ib/ext/EWrapperMsgGenerator.py
View
@@ -79,9 +79,18 @@ def openOrder(cls, orderId, contract, order, orderState):
msg = "open order: orderId=" + str(orderId) \
+ " action=" + str(order.m_action) \
+ " quantity=" + str(order.m_totalQuantity) \
+ + " conid=" + str(contract.m_conId) \
+ " symbol=" + str(contract.m_symbol) \
- + " exchange=" + str(contract.m_exchange) \
+ " secType=" + str(contract.m_secType) \
+ + " expiry=" + str(contract.m_expiry) \
+ + " strike=" + str(contract.m_strike) \
+ + " right=" + str(contract.m_right) \
+ + " multiplier=" + str(contract.m_multiplier) \
+ + " exchange=" + str(contract.m_exchange) \
+ + " primaryExch=" + str(contract.m_primaryExch) \
+ + " currency=" + str(contract.m_currency) \
+ + " localSymbol=" + str(contract.m_localSymbol) \
+ + " tradingClass=" + str(contract.m_tradingClass) \
+ " type=" + str(order.m_orderType) \
+ " lmtPrice=" + Util.DoubleMaxString(order.m_lmtPrice) \
+ " auxPrice=" + Util.DoubleMaxString(order.m_auxPrice) \
@@ -128,6 +137,10 @@ def openOrder(cls, orderId, contract, order, orderState):
+ " deltaNeutralSettlingFirm=" + str(order.m_deltaNeutralSettlingFirm) \
+ " deltaNeutralClearingAccount=" + str(order.m_deltaNeutralClearingAccount) \
+ " deltaNeutralClearingIntent=" + str(order.m_deltaNeutralClearingIntent) \
+ + " deltaNeutralOpenClose=" + str(order.m_deltaNeutralOpenClose) \
+ + " deltaNeutralShortSale=" + str(order.m_deltaNeutralShortSale) \
+ + " deltaNeutralShortSaleSlot=" + str(order.m_deltaNeutralShortSaleSlot) \
+ + " deltaNeutralDesignatedLocation=" + str(order.m_deltaNeutralDesignatedLocation) \
+ " continuousUpdate=" + str(order.m_continuousUpdate) \
+ " referencePriceType=" + str(order.m_referencePriceType) \
+ " trailStopPrice=" + Util.DoubleMaxString(order.m_trailStopPrice) \
@@ -263,7 +276,6 @@ def contractDetails(cls, reqId, contractDetails):
def contractDetailsMsg(cls, contractDetails):
""" generated source for method contractDetailsMsg """
msg = "marketName = " + str(contractDetails.m_marketName) + "\n" \
- + "tradingClass = " + str(contractDetails.m_tradingClass) + "\n" \
+ "minTick = " + str(contractDetails.m_minTick) + "\n" \
+ "price magnifier = " + str(contractDetails.m_priceMagnifier) + "\n" \
+ "orderTypes = " + str(contractDetails.m_orderTypes) + "\n" \
@@ -295,7 +307,8 @@ def contractMsg(cls, contract):
+ "exchange = " + str(contract.m_exchange) + "\n" \
+ "primaryExch = " + str(contract.m_primaryExch) + "\n" \
+ "currency = " + str(contract.m_currency) + "\n" \
- + "localSymbol = " + str(contract.m_localSymbol) + "\n"
+ + "localSymbol = " + str(contract.m_localSymbol) + "\n" \
+ + "tradingClass = " + str(contract.m_tradingClass) + "\n"
return msg
@classmethod
@@ -320,7 +333,7 @@ def bondContractDetails(cls, reqId, contractDetails):
+ "exchange = " + str(contract.m_exchange) + "\n" \
+ "currency = " + str(contract.m_currency) + "\n" \
+ "marketName = " + str(contractDetails.m_marketName) + "\n" \
- + "tradingClass = " + str(contractDetails.m_tradingClass) + "\n" \
+ + "tradingClass = " + str(contract.m_tradingClass) + "\n" \
+ "conid = " + str(contract.m_conId) + "\n" \
+ "minTick = " + str(contractDetails.m_minTick) + "\n" \
+ "orderTypes = " + str(contractDetails.m_orderTypes) + "\n" \
@@ -364,15 +377,7 @@ def execDetails(cls, reqId, contract, execution):
+ "reqId = " + str(reqId) + "\n" \
+ "orderId = " + str(execution.m_orderId) + "\n" \
+ "clientId = " + str(execution.m_clientId) + "\n" \
- + "symbol = " + str(contract.m_symbol) + "\n" \
- + "secType = " + str(contract.m_secType) + "\n" \
- + "expiry = " + str(contract.m_expiry) + "\n" \
- + "strike = " + str(contract.m_strike) + "\n" \
- + "right = " + str(contract.m_right) + "\n" \
- + "multiplier = " + str(contract.m_multiplier) + "\n" \
- + "contractExchange = " + str(contract.m_exchange) + "\n" \
- + "currency = " + str(contract.m_currency) + "\n" \
- + "localSymbol = " + str(contract.m_localSymbol) + "\n" \
+ + cls.contractMsg(contract) \
+ "execId = " + str(execution.m_execId) + "\n" \
+ "time = " + str(execution.m_time) + "\n" \
+ "acctNumber = " + str(execution.m_acctNumber) + "\n" \
@@ -387,7 +392,7 @@ def execDetails(cls, reqId, contract, execution):
+ "orderRef = " + str(execution.m_orderRef) + "\n" \
+ "evRule = " + str(execution.m_evRule) + "\n" \
+ "evMultiplier = " + str(execution.m_evMultiplier) + "\n" \
- + " ---- Execution Details end ----\n"
+ " ---- Execution Details end ----\n"
return msg
@classmethod
@@ -467,7 +472,7 @@ def scannerData(cls, reqId, rank, contractDetails, distance, benchmark, projecti
+ " currency=" + str(contract.m_currency) \
+ " localSymbol=" + str(contract.m_localSymbol) \
+ " marketName=" + str(contractDetails.m_marketName) \
- + " tradingClass=" + str(contractDetails.m_tradingClass) \
+ + " tradingClass=" + str(contract.m_tradingClass) \
+ " distance=" + distance \
+ " benchmark=" + benchmark \
+ " projection=" + projection \
@@ -516,3 +521,35 @@ def commissionReport(cls, commissionReport):
+ Util.IntMaxString(commissionReport.m_yieldRedemptionDate)
return msg
+ @classmethod
+ def position(cls, account, contract, position, avgCost):
+ """ generated source for method position """
+ msg = " ---- Position begin ----\n" \
+ + "account = " + str(account) + "\n" \
+ + cls.contractMsg(contract) \
+ + "position = " + Util.IntMaxString(position) + "\n" \
+ + "avgCost = " + Util.DoubleMaxString(avgCost) + "\n" + \
+ " ---- Position end ----\n"
+ return msg
+
+ @classmethod
+ def positionEnd(cls):
+ """ generated source for method positionEnd """
+ return " =============== end ==============="
+
+ @classmethod
+ def accountSummary(cls, reqId, account, tag, value, currency):
+ """ generated source for method accountSummary """
+ msg = " ---- Account Summary begin ----\n" \
+ + "reqId = " + str(reqId) + "\n" \
+ + "account = " + str(account) + "\n" \
+ + "tag = " + str(tag) + "\n" \
+ + "value = " + str(value) + "\n" \
+ + "currency = " + str(currency) + "\n" \
+ + " ---- Account Summary end ----\n"
+ return msg
+
+ @classmethod
+ def accountSummaryEnd(cls, reqId):
+ """ generated source for method accountSummaryEnd """
+ return "id=" + str(reqId) + " =============== end ==============="
2  ib/ext/ExecutionFilter.py
View
@@ -14,7 +14,7 @@
# package: com.ib.client
class ExecutionFilter(object):
""" generated source for class ExecutionFilter """
- m_clientId = 0
+ m_clientId = 0 # zero means no filtering on this field
m_acctCode = ""
m_time = ""
m_symbol = ""
2  ib/ext/Makefile
View
@@ -1,4 +1,4 @@
-srcdir := ./src/IBJts/java/com/ib/client/
+srcdir := ./src/IBJts/source/JavaClient/com/ib/client/
modules := $(addsuffix .py, $(notdir $(basename $(wildcard $(srcdir)*.java))))
32 ib/ext/Order.py
View
@@ -43,6 +43,8 @@ class Order(object):
# extended order fields
m_tif = "" # "Time in Force" - DAY, GTC, etc.
+ m_activeStartTime = "" # GTC orders
+ m_activeStopTime = "" # GTC orders
m_ocaGroup = "" # one cancels all group name
m_ocaType = 0 # 1 = CANCEL_WITH_BLOCK, 2 = REDUCE_WITH_BLOCK, 3 = REDUCE_NON_BLOCK
m_orderRef = ""
@@ -60,9 +62,9 @@ class Order(object):
m_rule80A = "" # Individual = 'I', Agency = 'A', AgentOtherMember = 'W', IndividualPTIA = 'J', AgencyPTIA = 'U', AgentOtherMemberPTIA = 'M', IndividualPT = 'K', AgencyPT = 'Y', AgentOtherMemberPT = 'N'
m_allOrNone = bool()
m_minQty = 0
- m_percentOffset = float() # REL orders only
+ m_percentOffset = float() # REL orders only; specify the decimal, e.g. .04 not 4
m_trailStopPrice = float() # for TRAILLIMIT orders only
- m_trailingPercent = float()
+ m_trailingPercent = float() # specify the percentage, e.g. 3, not .03
# Financial advisors only
m_faGroup = ""
@@ -98,20 +100,24 @@ class Order(object):
m_stockRangeUpper = float()
# VOLATILITY ORDERS ONLY
- m_volatility = float()
+ m_volatility = float() # enter percentage not decimal, e.g. 2 not .02
m_volatilityType = 0 # 1=daily, 2=annual
m_continuousUpdate = 0
- m_referencePriceType = 0 # 1=Average, 2 = BidOrAsk
+ m_referencePriceType = 0 # 1=Bid/Ask midpoint, 2 = BidOrAsk
m_deltaNeutralOrderType = ""
m_deltaNeutralAuxPrice = float()
m_deltaNeutralConId = 0
m_deltaNeutralSettlingFirm = ""
m_deltaNeutralClearingAccount = ""
m_deltaNeutralClearingIntent = ""
+ m_deltaNeutralOpenClose = ""
+ m_deltaNeutralShortSale = bool()
+ m_deltaNeutralShortSaleSlot = 0
+ m_deltaNeutralDesignatedLocation = ""
# COMBO ORDERS ONLY
- m_basisPoints = float() # EFP orders only
- m_basisPointsType = 0 # EFP orders only
+ m_basisPoints = float() # EFP orders only, download only
+ m_basisPointsType = 0 # EFP orders only, download only
# SCALE ORDERS ONLY
m_scaleInitLevelSize = 0
@@ -124,10 +130,11 @@ class Order(object):
m_scaleInitPosition = 0
m_scaleInitFillQty = 0
m_scaleRandomPercent = bool()
+ m_scaleTable = ""
# HEDGE ORDERS ONLY
m_hedgeType = "" # 'D' - delta, 'B' - beta, 'F' - FX, 'P' - pair
- m_hedgeParam = "" # beta value for beta hedge, ratio for pair hedge
+ m_hedgeParam = "" # beta value for beta hedge (in range 0-1), ratio for pair hedge
# Clearing info
m_account = "" # IB account
@@ -155,6 +162,8 @@ def __init__(self):
""" generated source for method __init__ """
self.m_lmtPrice = Double.MAX_VALUE
self.m_auxPrice = Double.MAX_VALUE
+ self.m_activeStartTime = self.EMPTY_STR
+ self.m_activeStopTime = self.EMPTY_STR
self.m_outsideRth = False
self.m_openClose = "O"
self.m_origin = self.CUSTOMER
@@ -178,6 +187,10 @@ def __init__(self):
self.m_deltaNeutralSettlingFirm = self.EMPTY_STR
self.m_deltaNeutralClearingAccount = self.EMPTY_STR
self.m_deltaNeutralClearingIntent = self.EMPTY_STR
+ self.m_deltaNeutralOpenClose = self.EMPTY_STR
+ self.m_deltaNeutralShortSale = False
+ self.m_deltaNeutralShortSaleSlot = 0
+ self.m_deltaNeutralDesignatedLocation = self.EMPTY_STR
self.m_referencePriceType = Integer.MAX_VALUE
self.m_trailStopPrice = Double.MAX_VALUE
self.m_trailingPercent = Double.MAX_VALUE
@@ -193,6 +206,7 @@ def __init__(self):
self.m_scaleInitPosition = Integer.MAX_VALUE
self.m_scaleInitFillQty = Integer.MAX_VALUE
self.m_scaleRandomPercent = False
+ self.m_scaleTable = self.EMPTY_STR
self.m_whatIf = False
self.m_notHeld = False
@@ -205,9 +219,9 @@ def __eq__(self, p_other):
l_theOther = p_other
if self.m_permId == l_theOther.m_permId:
return True
- if self.m_orderId != l_theOther.m_orderId or self.m_clientId != l_theOther.m_clientId or self.m_totalQuantity != l_theOther.m_totalQuantity or self.m_lmtPrice != l_theOther.m_lmtPrice or self.m_auxPrice != l_theOther.m_auxPrice or self.m_ocaType != l_theOther.m_ocaType or self.m_transmit != l_theOther.m_transmit or self.m_parentId != l_theOther.m_parentId or self.m_blockOrder != l_theOther.m_blockOrder or self.m_sweepToFill != l_theOther.m_sweepToFill or self.m_displaySize != l_theOther.m_displaySize or self.m_triggerMethod != l_theOther.m_triggerMethod or self.m_outsideRth != l_theOther.m_outsideRth or self.m_hidden != l_theOther.m_hidden or self.m_overridePercentageConstraints != l_theOther.m_overridePercentageConstraints or self.m_allOrNone != l_theOther.m_allOrNone or self.m_minQty != l_theOther.m_minQty or self.m_percentOffset != l_theOther.m_percentOffset or self.m_trailStopPrice != l_theOther.m_trailStopPrice or self.m_trailingPercent != l_theOther.m_trailingPercent or self.m_origin != l_theOther.m_origin or self.m_shortSaleSlot != l_theOther.m_shortSaleSlot or self.m_discretionaryAmt != l_theOther.m_discretionaryAmt or self.m_eTradeOnly != l_theOther.m_eTradeOnly or self.m_firmQuoteOnly != l_theOther.m_firmQuoteOnly or self.m_nbboPriceCap != l_theOther.m_nbboPriceCap or self.m_optOutSmartRouting != l_theOther.m_optOutSmartRouting or self.m_auctionStrategy != l_theOther.m_auctionStrategy or self.m_startingPrice != l_theOther.m_startingPrice or self.m_stockRefPrice != l_theOther.m_stockRefPrice or self.m_delta != l_theOther.m_delta or self.m_stockRangeLower != l_theOther.m_stockRangeLower or self.m_stockRangeUpper != l_theOther.m_stockRangeUpper or self.m_volatility != l_theOther.m_volatility or self.m_volatilityType != l_theOther.m_volatilityType or self.m_continuousUpdate != l_theOther.m_continuousUpdate or self.m_referencePriceType != l_theOther.m_referencePriceType or self.m_deltaNeutralAuxPrice != l_theOther.m_deltaNeutralAuxPrice or self.m_deltaNeutralConId != l_theOther.m_deltaNeutralConId or self.m_basisPoints != l_theOther.m_basisPoints or self.m_basisPointsType != l_theOther.m_basisPointsType or self.m_scaleInitLevelSize != l_theOther.m_scaleInitLevelSize or self.m_scaleSubsLevelSize != l_theOther.m_scaleSubsLevelSize or self.m_scalePriceIncrement != l_theOther.m_scalePriceIncrement or self.m_scalePriceAdjustValue != l_theOther.m_scalePriceAdjustValue or self.m_scalePriceAdjustInterval != l_theOther.m_scalePriceAdjustInterval or self.m_scaleProfitOffset != l_theOther.m_scaleProfitOffset or self.m_scaleAutoReset != l_theOther.m_scaleAutoReset or self.m_scaleInitPosition != l_theOther.m_scaleInitPosition or self.m_scaleInitFillQty != l_theOther.m_scaleInitFillQty or self.m_scaleRandomPercent != l_theOther.m_scaleRandomPercent or self.m_whatIf != l_theOther.m_whatIf or self.m_notHeld != l_theOther.m_notHeld or self.m_exemptCode != l_theOther.m_exemptCode:
+ if self.m_orderId != l_theOther.m_orderId or self.m_clientId != l_theOther.m_clientId or self.m_totalQuantity != l_theOther.m_totalQuantity or self.m_lmtPrice != l_theOther.m_lmtPrice or self.m_auxPrice != l_theOther.m_auxPrice or self.m_ocaType != l_theOther.m_ocaType or self.m_transmit != l_theOther.m_transmit or self.m_parentId != l_theOther.m_parentId or self.m_blockOrder != l_theOther.m_blockOrder or self.m_sweepToFill != l_theOther.m_sweepToFill or self.m_displaySize != l_theOther.m_displaySize or self.m_triggerMethod != l_theOther.m_triggerMethod or self.m_outsideRth != l_theOther.m_outsideRth or self.m_hidden != l_theOther.m_hidden or self.m_overridePercentageConstraints != l_theOther.m_overridePercentageConstraints or self.m_allOrNone != l_theOther.m_allOrNone or self.m_minQty != l_theOther.m_minQty or self.m_percentOffset != l_theOther.m_percentOffset or self.m_trailStopPrice != l_theOther.m_trailStopPrice or self.m_trailingPercent != l_theOther.m_trailingPercent or self.m_origin != l_theOther.m_origin or self.m_shortSaleSlot != l_theOther.m_shortSaleSlot or self.m_discretionaryAmt != l_theOther.m_discretionaryAmt or self.m_eTradeOnly != l_theOther.m_eTradeOnly or self.m_firmQuoteOnly != l_theOther.m_firmQuoteOnly or self.m_nbboPriceCap != l_theOther.m_nbboPriceCap or self.m_optOutSmartRouting != l_theOther.m_optOutSmartRouting or self.m_auctionStrategy != l_theOther.m_auctionStrategy or self.m_startingPrice != l_theOther.m_startingPrice or self.m_stockRefPrice != l_theOther.m_stockRefPrice or self.m_delta != l_theOther.m_delta or self.m_stockRangeLower != l_theOther.m_stockRangeLower or self.m_stockRangeUpper != l_theOther.m_stockRangeUpper or self.m_volatility != l_theOther.m_volatility or self.m_volatilityType != l_theOther.m_volatilityType or self.m_continuousUpdate != l_theOther.m_continuousUpdate or self.m_referencePriceType != l_theOther.m_referencePriceType or self.m_deltaNeutralAuxPrice != l_theOther.m_deltaNeutralAuxPrice or self.m_deltaNeutralConId != l_theOther.m_deltaNeutralConId or self.m_deltaNeutralShortSale != l_theOther.m_deltaNeutralShortSale or self.m_deltaNeutralShortSaleSlot != l_theOther.m_deltaNeutralShortSaleSlot or self.m_basisPoints != l_theOther.m_basisPoints or self.m_basisPointsType != l_theOther.m_basisPointsType or self.m_scaleInitLevelSize != l_theOther.m_scaleInitLevelSize or self.m_scaleSubsLevelSize != l_theOther.m_scaleSubsLevelSize or self.m_scalePriceIncrement != l_theOther.m_scalePriceIncrement or self.m_scalePriceAdjustValue != l_theOther.m_scalePriceAdjustValue or self.m_scalePriceAdjustInterval != l_theOther.m_scalePriceAdjustInterval or self.m_scaleProfitOffset != l_theOther.m_scaleProfitOffset or self.m_scaleAutoReset != l_theOther.m_scaleAutoReset or self.m_scaleInitPosition != l_theOther.m_scaleInitPosition or self.m_scaleInitFillQty != l_theOther.m_scaleInitFillQty or self.m_scaleRandomPercent != l_theOther.m_scaleRandomPercent or self.m_whatIf != l_theOther.m_whatIf or self.m_notHeld != l_theOther.m_notHeld or self.m_exemptCode != l_theOther.m_exemptCode:
return False
- if Util.StringCompare(self.m_action, l_theOther.m_action) != 0 or Util.StringCompare(self.m_orderType, l_theOther.m_orderType) != 0 or Util.StringCompare(self.m_tif, l_theOther.m_tif) != 0 or Util.StringCompare(self.m_ocaGroup, l_theOther.m_ocaGroup) != 0 or Util.StringCompare(self.m_orderRef, l_theOther.m_orderRef) != 0 or Util.StringCompare(self.m_goodAfterTime, l_theOther.m_goodAfterTime) != 0 or Util.StringCompare(self.m_goodTillDate, l_theOther.m_goodTillDate) != 0 or Util.StringCompare(self.m_rule80A, l_theOther.m_rule80A) != 0 or Util.StringCompare(self.m_faGroup, l_theOther.m_faGroup) != 0 or Util.StringCompare(self.m_faProfile, l_theOther.m_faProfile) != 0 or Util.StringCompare(self.m_faMethod, l_theOther.m_faMethod) != 0 or Util.StringCompare(self.m_faPercentage, l_theOther.m_faPercentage) != 0 or Util.StringCompare(self.m_openClose, l_theOther.m_openClose) != 0 or Util.StringCompare(self.m_designatedLocation, l_theOther.m_designatedLocation) != 0 or Util.StringCompare(self.m_deltaNeutralOrderType, l_theOther.m_deltaNeutralOrderType) != 0 or Util.StringCompare(self.m_deltaNeutralSettlingFirm, l_theOther.m_deltaNeutralSettlingFirm) != 0 or Util.StringCompare(self.m_deltaNeutralClearingAccount, l_theOther.m_deltaNeutralClearingAccount) != 0 or Util.StringCompare(self.m_deltaNeutralClearingIntent, l_theOther.m_deltaNeutralClearingIntent) != 0 or Util.StringCompare(self.m_hedgeType, l_theOther.m_hedgeType) != 0 or Util.StringCompare(self.m_hedgeParam, l_theOther.m_hedgeParam) != 0 or Util.StringCompare(self.m_account, l_theOther.m_account) != 0 or Util.StringCompare(self.m_settlingFirm, l_theOther.m_settlingFirm) != 0 or Util.StringCompare(self.m_clearingAccount, l_theOther.m_clearingAccount) != 0 or Util.StringCompare(self.m_clearingIntent, l_theOther.m_clearingIntent) != 0 or Util.StringCompare(self.m_algoStrategy, l_theOther.m_algoStrategy) != 0:
+ if Util.StringCompare(self.m_action, l_theOther.m_action) != 0 or Util.StringCompare(self.m_orderType, l_theOther.m_orderType) != 0 or Util.StringCompare(self.m_tif, l_theOther.m_tif) != 0 or Util.StringCompare(self.m_activeStartTime, l_theOther.m_activeStartTime) != 0 or Util.StringCompare(self.m_activeStopTime, l_theOther.m_activeStopTime) != 0 or Util.StringCompare(self.m_ocaGroup, l_theOther.m_ocaGroup) != 0 or Util.StringCompare(self.m_orderRef, l_theOther.m_orderRef) != 0 or Util.StringCompare(self.m_goodAfterTime, l_theOther.m_goodAfterTime) != 0 or Util.StringCompare(self.m_goodTillDate, l_theOther.m_goodTillDate) != 0 or Util.StringCompare(self.m_rule80A, l_theOther.m_rule80A) != 0 or Util.StringCompare(self.m_faGroup, l_theOther.m_faGroup) != 0 or Util.StringCompare(self.m_faProfile, l_theOther.m_faProfile) != 0 or Util.StringCompare(self.m_faMethod, l_theOther.m_faMethod) != 0 or Util.StringCompare(self.m_faPercentage, l_theOther.m_faPercentage) != 0 or Util.StringCompare(self.m_openClose, l_theOther.m_openClose) != 0 or Util.StringCompare(self.m_designatedLocation, l_theOther.m_designatedLocation) != 0 or Util.StringCompare(self.m_deltaNeutralOrderType, l_theOther.m_deltaNeutralOrderType) != 0 or Util.StringCompare(self.m_deltaNeutralSettlingFirm, l_theOther.m_deltaNeutralSettlingFirm) != 0 or Util.StringCompare(self.m_deltaNeutralClearingAccount, l_theOther.m_deltaNeutralClearingAccount) != 0 or Util.StringCompare(self.m_deltaNeutralClearingIntent, l_theOther.m_deltaNeutralClearingIntent) != 0 or Util.StringCompare(self.m_deltaNeutralOpenClose, l_theOther.m_deltaNeutralOpenClose) != 0 or Util.StringCompare(self.m_deltaNeutralDesignatedLocation, l_theOther.m_deltaNeutralDesignatedLocation) != 0 or Util.StringCompare(self.m_hedgeType, l_theOther.m_hedgeType) != 0 or Util.StringCompare(self.m_hedgeParam, l_theOther.m_hedgeParam) != 0 or Util.StringCompare(self.m_account, l_theOther.m_account) != 0 or Util.StringCompare(self.m_settlingFirm, l_theOther.m_settlingFirm) != 0 or Util.StringCompare(self.m_clearingAccount, l_theOther.m_clearingAccount) != 0 or Util.StringCompare(self.m_clearingIntent, l_theOther.m_clearingIntent) != 0 or Util.StringCompare(self.m_algoStrategy, l_theOther.m_algoStrategy) != 0 or Util.StringCompare(self.m_scaleTable, l_theOther.m_scaleTable) != 0:
return False
if not Util.VectorEqualsUnordered(self.m_algoParams, l_theOther.m_algoParams):
return False
3  ib/ext/TickType.py
View
@@ -72,6 +72,7 @@ class TickType(object):
TRADE_RATE = 55
VOLUME_RATE = 56
LAST_RTH_TRADE = 57
+ REGULATORY_IMBALANCE = 61
@classmethod
def getField(cls, tickType):
@@ -192,6 +193,8 @@ def getField(cls, tickType):
return "volume/min"
elif tickType == cls.LAST_RTH_TRADE:
return "lastRTHTrade"
+ elif tickType == cls.REGULATORY_IMBALANCE:
+ return "regulatoryImbalance"
else:
return "unknown"
1  ib/ext/cfg/EClientSocket.py
View
@@ -4,6 +4,7 @@
"""
from java2python.config.default import modulePrologueHandlers
+from java2python.config.default import methodPrologueHandlers
from java2python.mod.basic import maybeSynchronizedMethod
from cfg import outputSubs
2  ib/ext/cfg/Makefile
View
@@ -1,4 +1,4 @@
-configs := $(addsuffix .py, $(notdir $(basename $(wildcard ../src/IBJts/com/ib/client/*.java))))
+configs := $(addsuffix .py, $(notdir $(basename $(wildcard ../src/IBJts/source/JavaClient/com/ib/client/*.java))))
.PHONY: all clean
2  ib/ext/src/.gitignore
View
@@ -0,0 +1,2 @@
+IBJts
+*.jar
4 ib/ext/src/Makefile
View
@@ -1,5 +1,5 @@
-ibsources_jar := twsapi_unixmac_967.jar
-ibsources_url := "http://www.interactivebrokers.com/download/$(ibsources_jar)"
+ibsources_jar := twsapi_unixmac_969.02.jar
+ibsources_url := "http://interactivebrokers.github.io/downloads/$(ibsources_jar)"
.PHONY: all clean
2  ib/lib/__init__.py
View
@@ -147,6 +147,8 @@ def write(self, data, pack=struct.pack, eol=struct.pack('!b', 0)):
send(eol)
else:
for char in data:
+ if sys.version_info[0] > 2:
+ char = char.encode('utf-8')
send(pack('!c', char))
4 ib/lib/overloading.py
View
@@ -36,7 +36,7 @@
"""
-import new
+from types import MethodType as instancemethod
# Make the environment more like Python 3.0
__metaclass__ = type
@@ -55,7 +55,7 @@ def __init__(self, default_func):
def __get__(self, obj, type=None):
if obj is None:
return self
- return new.instancemethod(self, obj)
+ return instancemethod(self, obj)
def register(self, *types):
"""Decorator to register an implementation for a specific set of types.
6 ib/opt/message.py
View
@@ -9,6 +9,7 @@
# that the Receiver class then uses to determine message types.
##
+import sys
from ast import NodeVisitor, parse
from inspect import getsourcefile
from re import match
@@ -30,7 +31,10 @@ def __init__(self, classes):
self.visit(parse(open(filename).read()))
def visit_FunctionDef(self, node):
- args = [arg.id for arg in node.args.args]
+ if sys.version_info[0] < 3:
+ args = [arg.id for arg in node.args.args]
+ else:
+ args = [arg.arg for arg in node.args.args]
self.signatures.append((node.name, args[1:]))
7 setup.py.in → setup.py
View
@@ -28,7 +28,12 @@
doclines = __doc__.split('\n')
-setup(
+try: # Python 3
+ from distutils.command.build_py import build_py_2to3 as build_py
+except ImportError: # Python 2
+ from distutils.command.build_py import build_py
+
+setup(cmdclass = {'build_py': build_py},
name = 'IbPy',
version = "0", # make value
description = doclines[0],
Please sign in to comment.
Something went wrong with that request. Please try again.