开云体育

ctrl + shift + ? for shortcuts
© 2025 开云体育
Date

Re: Is it possible to open multiple connection through TWS API?

 

Hello, Despair, Thanks for your message. Actually, I am not interested to store Historical Data in the database. I want to pull historical data direct from IB and calculate the required indicators.


Re: Is it possible to open multiple connection through TWS API?

 

You can be connected to the API with several different client IDs simultaneously.

However you don't really need the API to calculate indicators.


Is it possible to open multiple connection through TWS API?

 

Hello,
In one of our custom web-based applications for strategy making in trading, we are running a TWS API connection to stream data (which is run all-time). Now we want to open another connection to calculate different indicators like ATR, RSI, except closing the previous connection. I mean: one TWS API connection will run for streaming data, and another (or probably more than one) connection will run for calculating different indicator values. Although we have no idea whether it is a best practice or not to run multiple connections, we want to know whether opening a new connection will impact the previously running connection? I mean if a new connection is open for indicator whether the connection of streaming will work or not.

Does anyone have any idea?

Thanks

Tareq


ibapi nextValidId not always invoked

 

i built a small ibapi python app to run some strategy, while taking care to stay connected to tws.

if tws is inactive, the python app will start and wait, and will connect to tws when tws will start, but here's my problem:

nextValidId won't be invoked

here is my code. i repeat, nextValidId will be invoked only while connected to a tws session that was active before my app connects.

as you can see, in a tws session that wasn't active before this script starts, nextValidId won't get invoked at all, not even manually by reqIds.


from ibapi.client import EClient
from ibapi.wrapper import EWrapper
from ibapi.common import MarketDataTypeEnum
from ibapi.errors import *

connection_errors = (
    CONNECT_FAIL, UPDATE_TWS, NOT_CONNECTED, UNKNOWN_ID, UNSUPPORTED_VERSION, 
    #BAD_LENGTH, BAD_MESSAGE, 
    SOCKET_EXCEPTION, FAIL_CREATE_SOCK, SSL_FAIL, 
)
connection_error_codes = [error.code() for error in connection_errors]


import threading
import time
import logging


class IBapi(EWrapper, EClient):

#   connection_lost = True

    clientid = None
    hostname = None
    portno = None
    onConnected = None

    MarketDataType = None

    def __init__(
            self, clientid, hostname='127.0.0.1', portno=7497, 
            MarketDataType=None, onConnected=None, ka_interval=3):

        self.clientid = clientid
        self.hostname = hostname
        self.portno = portno
        self.ka_interval = ka_interval

        EClient.__init__(self, self)

        self.onConnected = onConnected
        self.MarketDataType = MarketDataType or MarketDataTypeEnum.DELAYED

        self.host_connect()

        # Initialise the threads for various components
        thread = threading.Thread(target=self.run)
        thread.start()
        setattr(self, "_thread", thread)

        thread = threading.Thread(target=self.keepAlive)
        thread.start()
        setattr(self, "_thread_ka", thread)

    def host_connect(self):
        """Connects to TWS with the appropriate connection parameters"""
        if not self.hostname or not self.portno:
            logging.error(f'hostname {self.hostname} or portno {self.portno} not [yet] defined')
            return
        super().connect(self.hostname, self.portno, self.clientid)

    def error(self, reqId, errorCode, errorString):
        """disconnect to handle communications errors"""
        # clean the connection status
        if errorCode in connection_error_codes and \
                self.connState not in (EClient.CONNECTING,):
            logging.error(
                f'reset on connection_error {errorCode} "{errorString}"???')
#           self.connection_lost = True
            self.disconnect()
        return super().error(reqId, errorCode, errorString)

    def keepAlive(self):
        data_lock = threading.Lock()
        while self.ka_interval:
            time.sleep(self.ka_interval)
#           isConnected = self.isConnected()
            connState = None
            with data_lock:
                connState = self.connState
#               connection_lost = self.connection_lost
            isConnected = connState == EClient.CONNECTED
            logging.error(f'is connected: {isConnected}')
            if not isConnected:
                isConnecting = connState == EClient.CONNECTING
                if not isConnecting:
                    logging.error(f"let's connect")
                    self.host_connect()
                else:
                    logging.error(f'already connecting')
            else:
                logging.error(f'requesting CurrentTime for keepAlive')
#               if connection_lost:
#                   logging.error('reconnecting. should auto invoke nextValidId')
#                   self.reqIds(1)
#                   self.host_connected()
                self.reqCurrentTime()
                self.reqIds(1)

    def host_connected(self):
#       if self.connection_lost:
#           self.connection_lost = False
            self.reqMarketDataType(self.MarketDataType)
            self.reqPositions()

    def nextValidId(self, orderId):
        print('====================================================')
        logging.error(f'The next valid order id is: {orderId}')
        print('====================================================')
        super().nextValidId(orderId)
        self.nextorderId = orderId
        self.host_connected()

port_TWS_Live = 7496
port_IBGateway_Live = 4001
port_TWS_Simulated = 7497
port_IBGateway_Simulated = 4002

def main():
    logging.basicConfig(
        format='%(levelname)s:%(asctime)s:%(message)s', level=logging.WARN)
    logging.info('Started')

    logging.debug('This message should appear on the console')

    app = IBapi(
        1234, 
        #portno=port_TWS_Live, 
        portno=port_TWS_Simulated, 
    )

    logging.info('Finished')

if __name__ == '__main__':
    main()

i have also posted on?


Re: Contents of "SecIdList" within a contract object.

 

I doubt they'd have Ric or Sedol..? Those are also subscription based on the source side, which I haven't seen mentioned in IB..? I believe the SecIdList is populated with what's available regardless, and CUSIP is the only optional one subscription dependent.

As for support, calling is unlikely to be useful. The people who can answer these questions aren't ones you can call unless your account has 9+ digits in the balance.??

-Peter


Contents of "SecIdList" within a contract object.

Aquiles Páez
 

According to the TWS API guide, we have the following definition for this sub-field of the Contract object:

List<??>?
? A list of contract identifiers that the customer is allowed to view. CUSIP/ISIN/etc. For US stocks, receiving the ISIN requires the CUSIP market data subscription. For Bonds, the CUSIP or ISIN is input directly into the symbol field of the??class.

I have the CUSIP sub, so I can view the ISIN code for American Stocks. What if I wanted to see other ID's? Like RIC, CUSIP, SEDOL? I remember seeing them listed in the field of SecIdType when one specifies the contract.?

Which subscriptions would allow me to get that? Does anyone know? Lately it has been extremely difficult to get attended through the TOLL FREE number's Customer Support line of IB, I'd ask them directly but I think I prefer coming through here first.?


Historic ETF NAV

 

Hello,
Is there a way to get daily historic ETF NAV?, i.e. the NAV Prior Close value as shown in ETF watch list columns here:


Thanks


Can't finde "PURE" exchange on the list of validExchanges from a Contract object.

Aquiles Páez
 

Hello. I'm trying to request contracts and other types of data for the stocks listed under PURE inside the TWS exchange listings (please see this link so you can get see the full list of securities:?).

The issue I'm facing, is that when I request contract objects specificying Symbol, Exchange, Currency and SecType, I get a blank outcome. But, given some of these companies are also listed under TSE, when specified for TSE, these do appear. Even so, if I request data using SMART exchange I get outcomes for most, but it shocked me to find that none of the successful outcomes I got for contract objects are listing PURE under the validExchanges field. I scraped the whole listing of PURE for stocks, and the companies were either blank, SMART, Venture or TSE.?

Can someone explain this to me please? What could be the reason? Has anyone else faced this issue before? If so, please let me know.?

Best regards,

Aquiles?


Re: Pulling reqMktData for multiple tickers

 

Excellent Patrick - I'm happy it's working for you now!?? ?


Re: Pulling reqMktData for multiple tickers

 

The code worked Scott!

Once I get a little breather from the markets today, I'll sit down and dig through the code so I can mentally understand how it all went together. This is a good lesson right here! This program could turn out pretty neat for my buddy, its going to be a fun project AND should be a good learning project for me!?


?


Re: Submit orders to TWS via API

 

Hi Artyom

Thanks for your reply...? ?

Suggestion (1) resolved the issue

thanks all..? for your inputs

regards
ed


On Thu, May 6, 2021 at 10:03 AM Artyom T. <artyom.tyazhelov@...> wrote:
On Wed, May 5, 2021 at 08:08 PM, Ed Bell wrote:
# Disconnect from TWS ? ? ? ? ? ? ? ? ?
? ? ? ? tws_conn.disconnect()

two cents from my side, consider these steps:

1. bringing TWS connect disconnect outside of infinite loop

2. implement filesystem watchdog observer, for example:??

3. implement openOrder / orderStatus callbacks:??

as of now, your code disconnects from TWS immediately upon placing order, without waiting callbacks from TWS.

Artyom


Re: Pulling reqMktData for multiple tickers

 

Hi Patrick,
Ooops, my bad with the tickerId - I was trying to get the first tickerId to be 1 and to also use it as the index to the tickers list, but I failed to subtract 1 from the tickerId when using it to index the zero based tickers list.
In dataReturn, I should have had: app.reqMktData(tickerId, usTechStk(tickers[tickerId-1]), "", False, False, [])

What you have now will mean the first reqId will be zero - maybe that's OK, but I'm not sure.

But, here's the thing: In tickPrice, I see code that references tickerId. Which tickerId is that? It's not the local tickerId given to the thread. Seems it could be the tickerId used in the loop that spawns the threads.
This tickerId will now be 2 and will not change.
So, in tickPrice, you will be checking whether the reqId == 2 and printing the prices only for FB since that is the tickerId used when the reqMktDate request was made for FB.?

Just for fun, try the following code. I adjusted my original code to subtract 1 from the tickerId before using it as the index. I also modified the tickPrice method to NOT check the reqId against the tickerId.
Note that I also changed the print statement to an "f" style formatting string (a lower case f goes just before the string and braces contain the values) to print the symbol with the price to see whether we will now get all three symbols reporting.
I used reqId-1 as the index to tickers since the incoming reqId should be 1,2, or 3, so subtracting 1 will make it 0,1, or 2 to correctly index the tickers.?

--------------------------------------------------------------------------------

tickers = ["JG", "AAPL", "FB"]

def dataReturn(app, tickerId):

??? app.reqMktData(tickerId, usTechStk(tickers[tickerId-1]), "", False, False, [])?? # subtract 1 from tickerId to get correct tickers symbol

? ? time.sleep(5) #Add some breathing room for testing


threads = []

for tickerId in range(1, len(tickers)+1):? # start tickerId at 1

? ? t = threading.Thread(target=dataReturn, args=(app, tickerId))

? ? t.start()

? ? threads.append(t)

def tickPrice(self, reqId, tickType, price, attrib):
? ? ? ? if tickType == 1:
? ? ? ? ? ? self.bidprice = {"ReqId": reqId, "TickType": tickType, "Price": price, "Attrib": attrib}
? ? ? ? ? ? print(f"The current bid price for {tickers[reqId-1]} is: {price}")
? ? ? ? ? ??
? ? ? ? elif tickType == 2:
? ? ? ? ? ? self.askprice = {"ReqId": reqId, "TickType": tickType, "Price": price, "Attrib": attrib}
? ? ? ? ? ? print(f"The current ask price for {tickers[reqId-1]} is: {price}")
? ? ? ? ? ??
? ? ? ? elif tickType == 4:
? ? ? ? ? ? self.lastprice = {"ReqId": reqId, "TickType": tickType, "Price": price, "Attrib": attrib}
? ? ? ? ? ? print(f"The current last price for {tickers[reqId-1]} is: {price}")??

--------------------------------------------------------------------------------------------------

Cheers,
Scott


Re: Pulling reqMktData for multiple tickers

 

So leaving the +1 in:

for tickerId in range(1, len(tickers)+1):?

was giving me an IndexError: list index out of range

So I removed the +1 and this is what I get. I get 3 threads running. But I'm still only getting prints from the last ticker FB

I attached an example screenshot of my Spyder screen. I tried to just attach the photo, but it kept making the photo which was 1500 x 900 way too small to read once it uploaded. And when I would adjust the already uploaded photo to 1500 x 900 it stretched the small photo and made it blurry... lol... and also here is a the code from my ticktype

------------------------

def tickPrice(self, reqId, tickType, price, attrib):
? ? ? ? if tickType == 1 and reqId == tickerId:
? ? ? ? ? ? self.bidprice = {"ReqId": reqId, "TickType": tickType, "Price": price, "Attrib": attrib}
? ? ? ? ? ? print("The current bid price is: ", price)
? ? ? ? ? ??
? ? ? ? elif tickType == 2 and reqId == tickerId:
? ? ? ? ? ? self.askprice = {"ReqId": reqId, "TickType": tickType, "Price": price, "Attrib": attrib}
? ? ? ? ? ? print("The current ask price is: ", price)
? ? ? ? ? ??
? ? ? ? elif tickType == 4 and reqId == tickerId:
? ? ? ? ? ? self.lastprice = {"ReqId": reqId, "TickType": tickType, "Price": price, "Attrib": attrib}
? ? ? ? ? ? print("The current last price is: ", price)? ? ? ? ? ??
? ? ? ? ? ??
? ? ? ? ? ? '''NOTES: BID Price = 1, ASK Price = 2, Last Price = 4'''

-----------------


Re: Pulling reqMktData for multiple tickers

 

You guys are rock stars, all of you guys! I'm gunna sit down and read through everything here a second time, and also test the code snip from Scott. I really really appreciate everyone trying to help me out with this problem! Seriously, I am very grateful! I'll let you know how things go!?


Re: Pulling reqMktData for multiple tickers

 

Hi Ray,
No ouch from me I hope. I thought your reply was very excellent and explained a lot about threading. I also think your advice to not use threading is sound for this current case of getting quotes.
I think I also might have failed to understand the original problem, so some clarification from Patrick might help.

Hi Patrick,
When I look at the code you posted (and if I'm seeing correctly), I now see something that seems problematic. Near the bottom, you have a loop that is spawning 3 threads (i.e., apparently one for each ticker symbol based on the count of tickers).?
Each thread, however, is targeted to dataReturn which is making 3 reqMktData requests, one for each of the tickers. So, the end result is 9 reqMktData requests (i.e., 3 from each thread).
But, (and here's where it gets fun), since tickerId is global, and each thread is bumping it, and there are no locks around the bump, you have a classic race condition that will likely lead to chaos.
So, you could be seeing a case where one thread tries to bump the tickerId for the next reqMktData request with the next symbol, but another thread was in the process of bumping it for a different symbol, and the end result could be that the same tickerId value
is assigned to two different symbols. Processing from this point is unpredictable.

I agree with Ray that threads are probably not needed for your case, but just for fun, here's your code with some adjustments that might get this to work:


----------------------------------------------------------------------

tickers = ["JG", "AAPL", "FB"]

def dataReturn(app, tickerId):

??? app.reqMktData(tickerId, usTechStk(tickers[tickerId]), "", False, False, [])

? ? time.sleep(5) #Add some breathing room for testing


threads = []

for tickerId in range(1, len(tickers)+1):

? ? t = threading.Thread(target=dataReturn, args=(app, tickerId))

? ? t.start()

? ? threads.append(t)

-----------------------------------------------------------------------------

Cheers,
Scott


? ? ? ?


Re: Submit orders to TWS via API

 

On Wed, May 5, 2021 at 08:08 PM, Ed Bell wrote:
# Disconnect from TWS ? ? ? ? ? ? ? ? ?
? ? ? ? tws_conn.disconnect()

two cents from my side, consider these steps:

1. bringing TWS connect disconnect outside of infinite loop

2. implement filesystem watchdog observer, for example:??

3. implement openOrder / orderStatus callbacks:??

as of now, your code disconnects from TWS immediately upon placing order, without waiting callbacks from TWS.

Artyom


Re: Submit orders to TWS via API

 

Hi Bruce,

many thanks for your reply

please see response?inline

On Thu, May 6, 2021 at 1:30 AM Bruce B <bruceb444@...> wrote:
Ed,

Here is the key line from you:

"However when connected to live mode it does not execute successfully"?

If you detail what you mean by "successfully" your problem will be solved. This is a general term. You didn't say if you are getting an error OR not. And if Yes, what is the error?
>>>I am connected to TWS and get a confirmation message... but when the order is placed there is no confirmation from TWS of success or failure...? ?no messages....but will check logs as suggested
i am also catching all exception with following code..? ?this may be preventing any messages from tws... will check again
?except: # catch *all* exceptions
? ? ? ? #e = sys.exc_info()[0]
? ? ? ? #print( "<p>Error: %s</p>" % e )
? ? ? ? print (file=sys.stderr)?



If you are not getting an error in your callback, check API logs in TWS.
>>>will do
?

If this works in demo, it should work in love too.
>>>i agree...? and the single execution version works live as well... however that is not useful for me as i need the program to run independently in the background
?

Mostly, this issue comes back to IDs. Reset ID in TWS helps.
>>>?i did reset the ID to 1...? ?the latest ID is always captured before order is placed... which removes the potential for that issue?

Also, sometimes you need to turn API settings OFF and ON for connection. Maybe it misbehaves with binding to ports.
>>>not sure what you mean by turning API settings off/on...pls explain

Thanks again
Ed

?
- Bruce

On Wed, May 5, 2021, 7:19 PM Ed Bell <ed.ebell@...> wrote:
Hi Scott

Thanks for reply..? Read-Only box is unchecked?

I need to mention that when i run the version of the program which is single execution it works...? ?however the version i shared which runs in a continuous loop does not work


regards
Ed



On Wed, May 5, 2021 at 11:25 PM <sbtuttle@...> wrote:
Hi Ed,
Just a wild guess - check to ensure the "Read-Only API" setting in the TWS API Settings dialog is NOT checked.

Cheers,
Scott


Re: Pulling reqMktData for multiple tickers

 

Ouch.? So my reply was more damaging then helpful.?

To follow up.

As some pointed out there is the IBK 2-Thread and 3-Thread model that is explaned in the iBK doc really well.? I conflated the internal socket reading thread with the separate call back thread for ease of discussion but probably muddied things up.

The link to the Ruby Library is pretty illustrative.? It shows that that library supports a snapshot request for market data that one may use sequentially.? It shows an async version and then a threaded version, as the library offers the capabiility for a syncronous request/response? on a per thread basis.? Note however this is a "higher level" library where the author did a lot of work to support that.

The standard IBK libarry is (deliberately) pretty bare bones.? If you use it, over time, as you do more sophiisticated things,? you will end up building an additionals layer of code? on top of the library with various abstractions, such as a synchronous request / reponse per thread capability,etc. (Notice that is quite different from just sending the requests each on their own thread.)

More specificallyl to your original dilemna.?
  1. ?I am using the base IBK client library and need to do a handful of basic Market Data requests should I use threading??? Probably not.?? The sketch of code you were laying out was the start of a slippery slop of writing your own layer of code to support an abstraction of a synchronous request/response on a single thread.? True once you wrote that, yes then you could loop N times, create N req/resp threads, and join (sync) on thread completion. BUT that is a lot of work for your simple problem.
  2. I am using a higher level, third party? (Python, Ruby etc) library that offers threaded Market Data request capability out of the box, should I leverage this capability.? Probably, as someone has already done a lot of heavy lifting for you and made it "simple". There is a highler level. open source, Python library that gets taked about here on the list.? I'd suggest looking into that.


On Wed, May 5, 2021 at 1:18 PM Patrick C <zenfiretrading@...> wrote:

Hey guys, what I am trying to perform is a reqMktData pull (I'm pulling the bid,ask,last prices) for multiple tickers. Normally I would just change the ID number for each ticker.. but for this specific program I am building. The ticker amounts are going to change each day. One day it could be 3 stocks, next day it could be 7.?

So I am trying to come up with a fancy way to "spin off" the reqMktData into its own threads so that can change by the input.?

What is happening is, that the threads spin off fine, but the reqMktData just keeps getting "replaced" by the next ticker in line in the function.?

Really what I need it to do is this

1) For ticker in tickers (the loop through). After we loop the first one. Stop the function and loop. And seal that up as the first thread.
2) Run the function again, for ticker in tickers (the loop) but we pick back up where we left off. Creates another ReqMktData in the 2nd thread. Stop the function and loop from continuing.
3) Function runs again, for ticker in tickers (the loop), and we once again pick back up where we left off. Creates another reqMktData in the 3rd thread. Stop the function and loop.

Since there is only 3 "tickercount" its all finished. Now I had 3 threads all running a reqMktData but each thread has a unique "tickerId" corresponding with each stock in the tickers list.?

Does that make sense? Am I just over complicating this? Here is the code for you to study. Its obviously not the whole program. Everything else in the program works fine.?

tickerId = 0
tickercount = 0

tickers = ["JG", "AAPL", "FB"]

def dataReturn(app):

? ? global tickerId

? ? for ticker in tickers:

? ? ? ? tickerId += 1

? ? ? ? app.reqMktData(tickerId, usTechStk(ticker), "", False, False, [])

? ? ? ? time.sleep(5) #Add some breathing room for testing

? ? ? ??

threads = []

for ticker in tickers:

? ? tickercount += 1

? ? ? ??

for _ in range(tickercount):

? ? t = threading.Thread(target=dataReturn, args=(app,))

? ? t.start()

?

? ? threads.append(t)


Re: Submit orders to TWS via API

 

Ed,

Here is the key line from you:

"However when connected to live mode it does not execute successfully"

If you detail what you mean by "successfully" your problem will be solved. This is a general term. You didn't say if you are getting an error OR not. And if Yes, what is the error?

If you are not getting an error in your callback, check API logs in TWS.

If this works in demo, it should work in love too.

Mostly, this issue comes back to IDs. Reset ID in TWS helps.

Also, sometimes you need to turn API settings OFF and ON for connection. Maybe it misbehaves with binding to ports.

- Bruce


On Wed, May 5, 2021, 7:19 PM Ed Bell <ed.ebell@...> wrote:
Hi Scott

Thanks for reply..? Read-Only box is unchecked?

I need to mention that when i run the version of the program which is single execution it works...? ?however the version i shared which runs in a continuous loop does not work


regards
Ed



On Wed, May 5, 2021 at 11:25 PM <sbtuttle@...> wrote:
Hi Ed,
Just a wild guess - check to ensure the "Read-Only API" setting in the TWS API Settings dialog is NOT checked.

Cheers,
Scott


Re: Submit orders to TWS via API

 

Hi Scott

Thanks for reply..? Read-Only box is unchecked?

I need to mention that when i run the version of the program which is single execution it works...? ?however the version i shared which runs in a continuous loop does not work


regards
Ed



On Wed, May 5, 2021 at 11:25 PM <sbtuttle@...> wrote:
Hi Ed,
Just a wild guess - check to ensure the "Read-Only API" setting in the TWS API Settings dialog is NOT checked.

Cheers,
Scott