from ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.ext.EWrapper import EWrapper
from ib.ext.EClientSocket import EClientSocket
from ib.ext.ExecutionFilter import ExecutionFilter
def showmessage(message, mapping):
try:
del(mapping['self'])
except (KeyError, ):
pass
items = mapping.items()
items.sort()
print '### %s' % (message, )
for k, v in items:
print ' %s:%s' % (k, v)
import logging as logger
import types
class Observable(object):
"""
Sender -> dispatches messages to interested callables
"""
def __init__(self):
self.listeners = {}
self.logger = logger.getLogger()
def register(self,listener,events=None):
"""
register a listener function
Parameters
-----------
listener : external listener function
events : tuple or list of relevant events (default=None)
"""
if events is not None and type(events) not in (types.TupleType,types.ListType):
events = (events,)
self.listeners[listener] = events
def dispatch(self,event=None, msg=None):
"""notify listeners """
for listener,events in self.listeners.items():
if events is None or event is None or event in events:
try:
listener(self,event,msg)
except (Exception,):
self.unregister(listener)
errmsg = "Exception in message dispatch: Handler '{0}' unregistered for event '{1}' ".format(listener.func_name,event)
self.logger.exception(errmsg)
def unregister(self,listener):
""" unregister listener function """
del self.listeners[listener]
class ReferenceWrapper(EWrapper,Observable):
def __init__ (self,subs={}):
super(ReferenceWrapper, self).__init__()
self.orderID = None
self.subscriptions = subs
def setSubscriptions (self,subs):
self.subscriptions = subs
def tickGeneric(self, tickerId, field, price):
pass
def tickPrice(self, tickerId, field, price, canAutoExecute):
showmessage('tickPrice', vars())
def tickSize(self, tickerId, field, size):
showmessage('tickSize', vars())
def tickString(self, tickerId, tickType, value):
#showmessage('tickString', vars())
pass
def tickOptionComputation(self, tickerId, field, impliedVolatility, delta,x,c,q,w,e,r):
#showmessage('tickOptionComputation', vars())
pass
def openOrderEnd(self):
pass
def orderStatus(self, orderId, status, filled, remaining, avgFillPrice, permId, parentId, lastFillPrice, clientId, whyHeId):
if filled:
self.dispatch(event='execution',msg=[1,2,3])
showmessage('orderStatus', vars())
def openOrder(self, orderId, contract, order, state):
showmessage('openOrder', vars())
def connectionClosed(self):
showmessage('connectionClosed', {})
def updateAccountValue(self, key, value, currency, accountName):
showmessage('updateAccountValue', vars())
def updatePortfolio(self, contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName):
showmessage('updatePortfolio', vars())
def updateAccountTime(self, timeStamp):
showmessage('updateAccountTime', vars())
def nextValidId(self, orderId):
self.orderID = orderId
showmessage('nextValidId', vars())
def contractDetails(self, contractDetails):
showmessage('contractDetails', vars())
def bondContractDetails(self, contractDetails):
showmessage('bondContractDetails', vars())
def execDetails(self, orderId, contract, execution):
showmessage('execDetails', vars())
def error(self, id=None, errorCode=None, errorMsg=None):
showmessage('error', vars())
def updateMktDepth(self, tickerId, position, operation, side, price, size):
showmessage('updateMktDepth', vars())
def updateMktDepthL2(self, tickerId, position, marketMaker, operation, side, price, size):
showmessage('updateMktDepthL2', vars())
def updateNewsBulletin(self, msgId, msgType, message, origExchange):
showmessage('updateNewsBulletin', vars())
def managedAccounts(self, accountsList):
showmessage('managedAccounts', vars())
def receiveFA(self, faDataType, xml):
showmessage('receiveFA', vars())
def historicalData(self, reqId, date, open, high, low, close, volume, count, WAP, hasGaps):
showmessage('historicalData', vars())
def scannerParameters(self, xml):
showmessage('scannerParameters', vars())
def scannerData(self, reqId, rank, contractDetails, distance, benchmark, projection):
showmessage('scannerData', vars())
allMethods = []
def ref(method):
allMethods.append(method.__name__)
return method
class Listener(object):
def __init__(self,name=None):
self.name = name
def method(self,sender,event,msg=None):
print "[{0}] got event {1} with message {2}".format(self.name,event,msg)
import random
class BaseApp(Listener):
def __init__(self, host='localhost', port=7496, clientId=random.randint(0,1000),name=None,**kwargs):
self.host = host
self.port = port
self.clientId = clientId
self.subscriptions = {}
if kwargs.has_key('wrapper'):
self.wrapper = kwargs['wrapper']
self.wrapper.setSubscriptions(self.subscriptions)
else:
self.wrapper = ReferenceWrapper(self.subscriptions)
self.connection = EClientSocket(self.wrapper)
self.oms= OrderManager()
self.conid = 1
self.name = name
self.wrapper.register(self.method,events='execution') # listen to execution
def method(self,sender,event,msg=None):
print "[{0}] got event {1} with message {2}".format(self.name,event,msg)
#self.cancelAll()
@ref
def eConnect(self):
self.connection.eConnect(self.host, self.port, self.clientId)
@ref
def reqAccountUpdates(self):
self.connection.reqAccountUpdates(1, '')
@ref
def reqOpenOrders(self):
self.connection.reqOpenOrders()
@ref
def reqContractDetails(self,instrument):
self.connection.reqContractDetails(instrument.id, instrument.contract)
@ref
def reqExecutions(self):
filt = ExecutionFilter()
self.connection.reqExecutions(filt)
@ref
def reqIds(self):
self.connection.reqIds(10)
@ref
def reqNewsBulletins(self):
self.connection.reqNewsBulletins(1)
@ref
def cancelNewsBulletins(self):
self.connection.cancelNewsBulletins()
@ref
def setServerLogLevel(self):
self.connection.setServerLogLevel(3)
@ref
def reqAutoOpenOrders(self):
self.connection.reqAutoOpenOrders(1)
@ref
def reqAllOpenOrders(self):
self.connection.reqAllOpenOrders()
@ref
def reqManagedAccts(self):
self.connection.reqManagedAccts()
@ref
def requestFA(self):
self.connection.requestFA(1)
@ref
def reqMktData(self,contract):
self.connection.reqMktData(1, contract, '', False)
def nextOrderID(self):
self.wrapper.orderID += 1
return self.wrapper.orderID
def nextConID(self):
self.conid += 1
return self.conid
@ref
def reqHistoricalData(self,contract):
endtime = strftime('%Y%m%d %H:%M:%S')
self.connection.reqHistoricalData(
tickerId=1,
contract=contract,
endDateTime=endtime,
durationStr='1 D',
barSizeSetting='1 min',
whatToShow='TRADES',
useRTH=0,
formatDate=1)
def placeOrder (self,soid, optContractX, optOrderS):
self.oms.add(optOrderS)
self.connection.placeOrder(soid, optContractX, optOrderS)
def cancelOrder (self,soid):
self.oms.remove(soid)
self.connection.cancelOrder(soid)
def cancelAll(self):
for oid in self.oms.getOpenOrderIds():
self.cancelOrder(oid)
@ref
def eDisconnect(self):
sleep(5)
self.connection.eDisconnect()
class BagBuilder(object):
def __init__(self):
self.addAllLegs = []
def addLeg (self,cid,ratio,side,exchange):
leg = ComboLeg()
#print "conid in bag %s" % (cid)
leg.m_conId = cid
leg.m_ratio = ratio
leg.m_action = side
leg.m_exchange = exchange
leg.m_openClose = 0
leg.m_shortSaleSlot = 0
leg.m_designatedLocation = ""
self.addAllLegs.append(leg)
def create(self,symbol):
contract = Contract()
contract.m_symbol = "USD" # For combo order use ?USD? as the symbol value all the time
contract.m_secType = "BAG" # BAG is the security type for COMBO order
contract.m_exchange = self.addAllLegs[0].m_exchange
contract.m_currency = "USD"
contract.m_comboLegs = self.addAllLegs #including combo order in contract object
contract.m_symbol = symbol
return contract
class Side(object):
def __init__(self,s):
self.sides=['dummy','BUY','SELL']
self.s = self.sides[s]
def side(self):
return self.s
def flip(self):
return self.sides[2] if self.s == 'BUY' else self.side[1]
@staticmethod
def flipside(s):
if s.lower() == 'sell':
return 'BUY'
else:
return 'SELL'
class Utils(object):
months=['','F','G','H','J','K','M','N','Q','U','V','X','Z']
@staticmethod
def makeContract(sym, exchange,sectype,exp=None):
newContract = Contract()
newContract.m_symbol = sym
newContract.m_secType = sectype
newContract.m_expiry = exp
newContract.m_exchange = exchange
newContract.m_currency = 'USD'
return newContract
@staticmethod
def makeOptOrder(action, oID, tif, orderType,price,qty):
newOptOrder = Order()
newOptOrder.m_orderId = oID
newOptOrder.m_clientId = 0
newOptOrder.m_permid = 0
newOptOrder.m_action = action
newOptOrder.m_lmtPrice = price
newOptOrder.m_auxPrice = 0
newOptOrder.m_tif = tif
newOptOrder.m_transmit = True
newOptOrder.m_orderType = orderType
newOptOrder.m_totalQuantity = qty
return newOptOrder
@staticmethod
def createBracketOrder(origOrder, oID, tif, orderType,price):
bracketoptOrder = Utils.makeOptOrder( Side.flipside(origOrder.m_action), oID, tif, orderType,price,origOrder.m_totalQuantity)
bracketoptOrder.m_parentId = origOrder.m_orderId
return bracketoptOrder
class OrderManager(object):
def __init__(self):
self.orders = {}
def add(self,order):
self.orders[order.m_orderId] = order
def remove(self,oid):
try:
del self.orders[oid]
except:
pass
def get(self,order_id):
return self.orders[order_id]
def status(self,order_id):
return self.orders[order_id].status
def onFill(self,order_id,fillqty):
self.orders[order_id].m_quantity -= fillqty
def getOpenOrderIds(self):
return self.orders.keys()