Requesting Execution Details

877 views
Skip to first unread message

dave

unread,
Mar 17, 2009, 12:12:30 PM3/17/09
to IbPy Discuss
Hello, I am very new to IB and would like to use the optional
interface to request my executions. I have been unsucessful thus
far. Can anyone comment on the following code and what I may be
missing?

The execs term below is a 'None' type object.

Many thanks,
Dave

from ib.ext.ExecutionFilter import ExecutionFilter
from ib.opt import ibConnection, message

#-- message handlers
---------------------------------------------------------

# print all messages from TWS
def watcher(msg):
print msg

def ExecutionDetailsHandler(msg):
#global executionDetails
executionDetails = msg.execDetails

#-- factories
-----------------------------------------------------------------

def makeExecFilter():
filter=ExecutionFilter()
return filter

con = ibConnection()
con.registerAll(watcher)
con.register(ExecutionDetailsHandler, 'ExecDetails')
con.connect()

filter=makeExecFilter()
execs=con.reqExecutions(filter)

dave

unread,
Mar 17, 2009, 1:39:50 PM3/17/09
to IbPy Discuss
I made some headway here (see below code), I am able to output my
executions via the handler, but I am still unable to create variables
out of the individual execution details, such as price, etc...

Any help or advice would be greatly appreciated.

Thanks,
Dave

from ib.ext.Contract import Contract
from ib.ext.Execution import Execution
from ib.ext.ExecutionFilter import ExecutionFilter
from ib.opt import ibConnection, message

from time import sleep

import threading
#-- message handlers
---------------------------------------------------------

# print all messages from TWS
def watcher(msg):
pass
#print msg

def ExecutionDetailsHandler(msg):
global execDetails

execDetails = msg.execution
print execDetails.m_price
print execDetails.m_side

#-- factories
-----------------------------------------------------------------

def makeExecFilter():
filter=ExecutionFilter()
return filter

#-- utilities
----------------------------------------------------------------

def getExecutionPrice():
#global executionDetails
filter=makeExecFilter()
con.reqExecutions(filter)
execDetails=Execution()
print execDetails.m_price
# wait for TWS message to come back to message handler
while execDetails.m_price == 0:
print 'waiting'
sleep(1)
#
return execDetails.m_price
con = ibConnection()
con.registerAll(watcher)

con.register(ExecutionDetailsHandler, 'ExecDetails')


con.connect()

price=getExecutionPrice()

Dan Silberman

unread,
Mar 17, 2009, 6:26:48 PM3/17/09
to IbPy Discuss
Dave, heres your code fixed up a bit to do what you were trying for.
Basically you don't want to create execDetails in getExecutionPrice,
because you need to use the global one that your message handler is
using to store the execution. After this code, I'll paste a different
version thats a little more useful, since this one just stores
globally a single execution.

from ib.ext.ExecutionFilter import ExecutionFilter
from ib.opt import ibConnection, message

from time import sleep

#-- message handlers -------------------------------------------------

# print all messages from TWS
def watcher(msg):
pass

def ExecutionDetailsHandler(msg):
global execDetails
execDetails = msg.execution
#print execDetails.m_price
#print execDetails.m_side

# global variable that stores the last Execution seen by
ExecutionDetailsHandler
execDetails = None


#-- factories
-----------------------------------------------------------

def makeExecFilter():
filter=ExecutionFilter()
return filter

#-- utilities --------------------------------------------------------

def getExecutionPrice():
filter=makeExecFilter()
con.reqExecutions(filter)

# wait for TWS message to come back to message handler
while execDetails is None:
print 'waiting'
sleep(1)
return execDetails.m_price


con = ibConnection()
con.registerAll(watcher)
con.register(ExecutionDetailsHandler, 'ExecDetails')
con.connect()

price=getExecutionPrice()
print 'The price of one execution is:', price

--------------------------------------------------------------------------------------------------------------
Heres how I would do it. Very similar to what I posted above, except
theres a global dict that stores orderId : Execution.


from ib.ext.ExecutionFilter import ExecutionFilter
from ib.opt import ibConnection

from time import sleep

#-- message handlers ------------------------------

# print all messages from TWS
def watcher(msg):
pass

# store the executions in global dict EXEC_DETAILS, keyed on orderId
def ExecutionDetailsHandler(msg):
EXEC_DETAILS[msg.orderId] = msg.execution

# global dict of orderId : Execution
EXEC_DETAILS = {}

#-- factories ----------------------------
def makeExecFilter():
filter=ExecutionFilter()
return filter

#-- utilities ----------------------------
def start_tracking_Executions():
filter=makeExecFilter()
con.reqExecutions(filter)


# connect to TWS
con = ibConnection()
con.registerAll(watcher)
con.register(ExecutionDetailsHandler, 'ExecDetails')
con.connect()

# start tracking all Executions, then sleep a bit to give time to fill
up global dict
start_tracking_Executions()
sleep(5)

# print out orderId, execution price
for orderId in EXEC_DETAILS:
print orderId, EXEC_DETAILS[orderId].m_price




hope that helps
Dan

dave

unread,
Mar 18, 2009, 9:13:47 AM3/18/09
to IbPy Discuss
Thanks Dan, This makes perfect sense. I had created a global list
since my last post but I think I like your dictionary and the other
improvements better. Am I right to assume that the nature of the
optional interface is such that global variables will always be
necessary in order for the message handlers to communicate with the
rest of the program?

Thanks again, Dave

Troy Melhase

unread,
Mar 18, 2009, 1:02:49 PM3/18/09
to ibpy-d...@googlegroups.com
> Am I right to assume that the nature of the
> optional interface is such that global variables will always be
> necessary in order for the message handlers to communicate with the
> rest of the program?

Globals aren't necessary for the optional interface (it maintains a
reference to each callable). You'll have to maintain a reference on
your own if you wish to use the callable another way.

dave

unread,
Mar 18, 2009, 1:44:35 PM3/18/09
to IbPy Discuss
A little over my head, so you are saying that the above code could
work the same without the global variables?

Troy Melhase

unread,
Mar 18, 2009, 1:52:58 PM3/18/09
to ibpy-d...@googlegroups.com
> A little over my head, so you are saying that the above code could
> work the same without the global variables?

Yes. You just have to keep a reference (a variable, a name) to your
code and data structures. That might be a global, a module global, or
values on an object (that is global), or values inside a function that
doesn't complete until your program completes.

If it doesn't make sense, ignore it and write code. That usually
works for me. :)

dave

unread,
Mar 19, 2009, 12:40:41 PM3/19/09
to IbPy Discuss
Cool, I think that makes sense. I was mostly referring to the fact
that the message handlers don't have traditional function aspects such
as a 'return' value, so you need some other way to get the stuff you
want out of them. While I should more often ignore things my
hankering for knowledge often keeps me from attaining optimal
productivity.

Thanks for all the input, here is the script that I wanted to create,
in the case someone else may find it useful. I stuck to lists rather
than dicts, since I couldn't see a real reason to change (though there
may very well be one). The code creates a candlestick plot of the
days action and shows the trades I made, something to help me keep
records and evaluate my trading decisions.

Thanks,
Dave

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# gets the days executions and plots on candlestick chart

from ib.ext.Contract import Contract
from ib.ext.ExecutionFilter import ExecutionFilter
from ib.opt import ibConnection, message

from matplotlib.finance import candlestick2
from matplotlib.ticker import Formatter


import time
import pylab as p



class minuteFormatter(Formatter):
def __init__(self, dates, fmt='%H:%M'):
self.dates = dates
self.fmt = fmt

def __call__(self, x, pos=0):
'Return the label for time x at position pos'
ind = int(round(x))
if ind>=len(self.dates) or ind<0: return ''

return time.strftime(self.fmt, time.localtime(int(self.dates
[ind])))


#-- message handlers
---------------------------------------------------------

# print all messages from TWS
def watcher(msg):
print msg
def getDataHandler(msg):
global dates,opens,highs,lows,closes
if int(msg.high) > 0:
dates.append(msg.date)
opens.append(msg.open)
closes.append(msg.close)
highs.append(msg.high)
lows.append(msg.low)
else:
con.meFinished = True

def ExecutionDetailsHandler(msg):
global execDetails
execDetails.append(msg.execution)

#-- factories
-----------------------------------------------------------------

def makeExecFilter():
filter=ExecutionFilter()
return filter
def makeESContract():
es = Contract()
es.m_localSymbol = 'ESM9'
es.m_secType = 'FUT'
es.m_exchange = 'GLOBEX'
return es
#-- utilities
----------------------------------------------------------------
def convertExecTime(eTime):
stdTime=time.strptime(eTime,"%Y%m%d %H:%M:%S")
return time.mktime(stdTime)
def execLocator(execution):
global dates
eTime=convertExecTime(execution.m_time)
ind=int((eTime-float(dates[0]))/60.)
return ind
def getData(contract):
global dates,opens,highs,lows,closes
con.meFinished=False
dates=[]
opens=[]
highs=[]
lows=[]
closes=[]
con.reqHistoricalData(1, contract, '', '1 D','1 min','TRADES', 1,
2)
countSecs = 0
while not con.meFinished and countSecs < 20: # give up after 20
seconds
time.sleep(1)
countSecs += 1
if con.meFinished==True:
print 'Data dump done'
else:
print 'time ran out'
def getExecutions():
global execDetails
filter=makeExecFilter()
execDetails=[]
con.reqExecutions(filter)
def plotData():
global dates,opens,highs,lows,closes,execDetails
left,width=0.05,0.9
bot,height=.05,.9
rect = [left, bot, width, height]
f=p.figure(1,figsize=(16,12))
a=p.axes(rect)
formatter = minuteFormatter(dates)
a.xaxis.set_major_formatter(formatter)
candlestick2(a, opens, closes, highs, lows, width=0.9)
angle=-90
integer=-1
totalNet=0
for eD in execDetails:
if integer==-1:
angle2=0
else:
angle2=180
index=execLocator(eD)
label='%s:%.2f'%(eD.m_side,eD.m_price)
if integer==1:
if eD.m_side=='BOT':
net=lastPrice-eD.m_price
else:
net=eD.m_price-lastPrice
label+=',Net: %.2f'%net
totalNet+=net
textPos=(index-10+integer*10,eD.m_price+integer*6.5)
a.annotate(label,
xy=(index,eD.m_price),xycoords='data',
xytext=textPos,textcoords='data',
arrowprops=dict(arrowstyle="->",
connectionstyle="angle,angleA=%i,angleB=%i,rad=10"%
(angle*integer,angle2)))
integer*=-1
lastPrice=eD.m_price

a.set_xlim((-.5, max(len(closes),textPos[0]+11)))
date=time.strftime('%m-%d-%y', time.localtime(int(dates[0])))
title=date
if totalNet>0:
title+=', Net:%.2f'%totalNet
p.title(title,fontsize=15)
p.savefig('%s.png'%date)

if __name__ == "__main__":
con = ibConnection()
con.registerAll(watcher)
con.unregister(watcher, 'ExecDetails')
con.unregister(watcher,message.HistoricalData)

con.register(ExecutionDetailsHandler, 'ExecDetails')
con.register(getDataHandler,message.HistoricalData)

con.connect()
ct=makeESContract()
getData(ct)
getExecutions()
time.sleep(5)
plotData()
con.disconnect()

alepik

unread,
Oct 15, 2015, 7:21:11 PM10/15/15
to IbPy Discuss
Does anyone have a functioning version or an example for reqExecutions.
The current ones provided here appear to be broken even if I give an extra parameter (reqId) to reqExecutions.
I suspect it's something to do with this newest API I'm using.

What I'm getting is only:
<execDetails reqId=0, contract=<ib.ext.Contract.Contract object at 0x0000000002D52...

Any help greatly appreciated.

Derek Tishler

unread,
May 24, 2016, 9:04:21 PM5/24/16
to IbPy Discuss
I think it might be working as expected. I suggest checking out the Java(I hear the other language docs contain more info sometimes as well) docs or other current docs to understand API calls(since ibpy wraps the java client).
Reply all
Reply to author
Forward
0 new messages