Mapgax / ibpy

Automatically exported from code.google.com/p/ibpy
Other
0 stars 0 forks source link

Connection made (it seems) but no data downloaded before connection closed #8

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Running through Python's IDLE.
2. Previously submitted issue - API coverage tests (IBPy, not completing
either.
3. Only using for historical data at this point so no other modules are
being used or called.
4. Works fine using TWS Java sample client - data (using same request
parameters) appears fine.

What is the expected output? What do you see instead?
22-Feb-10 20:20:57 DEBUG     Server Version:  46
22-Feb-10 20:20:57 DEBUG     TWS Time at connection:  20100222 20:20:57 CST
<ReqHistoricalDataBefore tickerId=10, contract=<ib.ext.Contract.Contract
object at 0x30a5090>, endDateTime=20090224 11:00:00 EST, durationStr=1800
S, barSizeSetting=1 secs, whatToShow=TRADES, useRTH=0,
formatDate=1><ConnectionClosed>
<ReqHistoricalDataAfter tickerId=10, contract=<ib.ext.Contract.Contract
object at 0x30a5090>, endDateTime=20090224 11:00:00 EST, durationStr=1800
S, barSizeSetting=1 secs, whatToShow=TRADES, useRTH=0, formatDate=1>

What version of the product are you using? On what operating system?
R345 downloaded from SVN Feb-21-2010.  Linux/Ubuntu 9.10 Python 2.6 - all
updates in.  

Please provide any additional information below.
TWS reports incoming connection.  TWS returns connection time so I'm
assuming the connection was actually made.  Tried varying the sleep period
thinking I was closing connection too rapidly.  The message handling loop
is not getting invoked as I've tested it by putting simple "print"
statements which never appear.Enabled filtering at "root" level.  Listener
is using 'historicalData' for the con.register.

If you need any other info, let me know.  Thx.

Original issue reported on code.google.com by anyoneus...@yahoo.com on 23 Feb 2010 at 2:33

GoogleCodeExporter commented 8 years ago
OK..continued to examine.  Found that datastream is getting routed to
con.registerAll(MsgListener) even though the next line is 
con.unregister(MsgListener,
'historicalData') followed by con.register(HistoricalMsgListener, 
'historicalData').
 Using "print" statements found that the MsgListener function was getting called but
not the HistoricalMsgListener.  Therefore, no results were being processed as 
the
MsgListener was basically a "pass" function.

Original comment by anyoneus...@yahoo.com on 24 Feb 2010 at 2:04

GoogleCodeExporter commented 8 years ago
OK...continued to examine.  Appears that the TWS client ID is assigned and is 
not
recycled.  There doesn't seem to be any error trapping for this situation.  
Found it
by monitoring the TWS messages at the Unix terminal window where the program was
launched.  It seems that making more than 1 request with the same client ID is
rejected by TWS with the error message not (it seems) getting routed (or at 
least not
printed out the the Listener) back through IBPy.  Therefore, no data is 
returned from
the request.

Original comment by anyoneus...@yahoo.com on 24 Feb 2010 at 4:20

GoogleCodeExporter commented 8 years ago
OK...continued to examine.  The Listener object doesn't provide an easy way to 
pass
or forward multiline results to a file handling module pushing the data out to 
a CSV
file.  Thus, had to create a "global" variable for passing the results 
generated by
the message handler (not the preferred approach) but successfully passed out 
1800
lines to a file.  Will now continue to test with multiple requests being passed 
into
a stream of requests.  

I lack the expertise to revise some of the IBPy internals, but it would seem 
that
what is needed is a way to pass the data stream out to file.  This would be 
necessary
for audit trails for actual transactions and for further processing for 
historical data.

It would also be useful to have a standardized means of passing in a stream of
requests instead of hand-coding each one to get the data back out. 

I'll be glad to post my sample code once I've cleaned it up.

Original comment by anyoneus...@yahoo.com on 24 Feb 2010 at 7:25

GoogleCodeExporter commented 8 years ago
By passing in a method of an instance instead of just a function, you can have 
handlers keep state.  For instance:

# Example historical bar query where state is kept by handlers
from ib.opt import ibConnection, message
from ib.ext.Contract import Contract
import time

class Handler(object):
    def __init__(self):
        self.count = 0
    def hist_tick_handler(self,msg):
        self.count += 1
        print str(self.count) + " - " + str(msg)
    def error_handler(self,msg):
        self.count += 1
        print str(self.count) + " - " + str(msg)

connection = ibConnection()

######################
# The key lines
######################
h = Handler()
connection.register(h.hist_tick_handler,message.HistoricalData)
connection.register(h.error_handler,message.Error)
#####################

if not connection.connect():
    raise Exception("Connection to TWS failed.")

contract = Contract()
contract.m_secType = "STK" 
contract.m_symbol = "MSFT"
contract.m_currency = "USD"
contract.m_exchange = "SMART"

connection.reqHistoricalData(1,contract,"20101103 15:00:00","1 D","1 
hour","TRADES",1,1)
time.sleep(10)

Original comment by stephens...@gmail.com on 4 Nov 2010 at 11:29

GoogleCodeExporter commented 8 years ago
I have a similar issue: I am trying to get the filled=0 or filled=1 data from 
IB's orderStatus message. I came up with the following message handler code:

def print_orderstatus(msg):
    global fillStatus
    if msg.filled == 0  and msg.orderId==NextOrderId:
        fillStatus = 'NextOrderId=',msg.orderId,'filled=',msg.filled
        print 'FillStatus =', fillStatus
if __name__ == '__main__':

    con = ibConnection(port=7496,clientId=1234)
    con.registerAll(watcher)
    con.register(NextValidIdHandler, 'NextValidId')
    con.register(ContractDetailsHandler, 'ContractDetails')
    con.register(error_handler, 'Error')
    con.register(print_orderstatus, 'OrderStatus')

Unfortunatly,it only updates fillStatus once when it first sees a orderStatus() 
message. I don't think I can use something like 
connection.reqHistoricalData(1,contract,"20101103 15:00:00","1 D","1 
hour","TRADES",1,1)because orderStatus() only gets called from IB by 
placeOrder(). Anyone have any ideas?

Original comment by patrick....@gmail.com on 5 May 2014 at 7:01