IB API HOWTOs and Guidelines - For Beginners

Discussion in 'App Development' started by Butterfly, Nov 8, 2013.

  1. vicirek

    vicirek

    Good work!

    Just to clarify HFT with IB data is not quite possible because this is delta feed updating quote board with sample rate of 300 ms or less so I would not use HFT term in this context.

    The introduction for beginners could be a little bit confusing;

    Beginner should only know that communication/log in to IB servers is handled by TWS or Gateway and any custom application communicates with TWS or Gateway only.

    IB API is description of interface (type of messages being exchanged) in the form of functions with parameters;

    Connection initiates TCP/IP socket communication between custom app and TWS or Gateway(host, port etc) to sent strings back and forth between server (TWS/Gateway) and client (custom IB API based app)

    The underlying protocol is text message exchange (strings with null delimited fields) using sockets between TWS/Gateway and custom apps and IB API based app takes care of encoding and decoding those text messages into usable information on both ends of the socket end points.
     
    #11     Nov 8, 2013
  2. SteveH

    SteveH

    Does the Python interface to the IB API take care of eliminating the duplicate order status callbacks?
     
    #12     Nov 9, 2013
  3. Butterfly

    Butterfly

    not sure if we are talking about the same thing, but it's not really a duplicate status call back because the IB server sends back a long reply that can be handled by 2 different functions, but too often developers will use 1 function to trap the long reply.

    Below is the IB Server reply after I submitted a "placeOrder" request

    Code:
    IB: Server Response =  openOrder <openOrder orderId=5, contract=<ib.ext.Contract.Contract object at 0x012C3C90>, 
    order=<ib.ext.Order.Order object at 0x012C3BB0>, orderState=<ib.ext.OrderState.OrderState object at 0x012C3A50>>
    IB: Server Response =  orderStatus <orderStatus orderId=5, status=PreSubmitted, filled=0, remaining=100, 
    avgFillPrice=0.0, permId=XXXXXXX, parentId=0, lastFillPrice=0.0, clientId=123, whyHeld=None>
    
    The IB Server is sending a long reply with 2 types of messages, "openOrder" with the "contract" and "order" variables and a new orderState object, and a second type of message "orderStatus" with the orderID and some other variables, including a misleading label "status" for a variable. Catching the meaningful "status" for your trade therefore becomes quite tricky. It needs to be properly handled in your function code.
     
    #13     Nov 9, 2013
  4. Butterfly

    Butterfly

    In the following Python example we will write a simple SELL order for 100 shares in GTAT @ 11

    Code:
    # LOAD the ib.ext and ib.opt Libraries
    from ib.ext.Contract import Contract
    from ib.ext.Order import Order
    from ib.opt import Connection, message
    
    # DEFINE a basic function to capture error messages
    def error_handler(msg):
        print "IB: Server Error = ", msg
    
    # DEFINE a basic function to capture all server replies
    def all_replies_handler(msg):
        print "IB: Server Response = ", msg.typeName, msg
    
    # Main code
    
    # Create the connection to IBGW with client socket id=123
    # using a different method than ibConnection
    ibgw_conTradeChannel=Connection.create(port=4001,clientId=123)
    ibgw_conTradeChannel.connect()
    
    # Map server replies for "Error" messages to the "error_handler" function
    ibgw_conTradeChannel.register(error_handler, 'Error')
    
    # Map all server replies to "all_replies_handler"
    # Use typeName to distinguish between the different message types
    # This is easier than registering different actions for different messages
    ibgw_conTradeChannel.registerAll(all_replies_handler)
    
    # Create a global OrderID for simplicity
    # It will be submitted to the IB Server for executing the trade
    # To be incremented for the next trade with calls to the IB Server
    newOrderID=1
    
    # Create a contract object
    # Update the parameters to be sent to the Market Order request
    order_ticker = Contract()
    order_ticker.m_symbol = 'GTAT'
    order_ticker.m_secType = 'STK'
    order_ticker.m_exchange = 'SMART'
    order_ticker.m_primaryExch = 'SMART'
    order_ticker.m_currency = 'USD'
    order_ticker.m_localSymbol = 'GTAT'
    
    # Create an order object
    # Update the parameters to be sent to the Market Order request
    order_desc = Order()
    order_desc.m_minQty = 100
    order_desc.m_lmtPrice = 11.00
    order_desc.m_orderType = 'LMT'
    order_desc.m_totalQuantity = 100
    order_desc.m_action = 'SELL'
    
    # Send the Market Order request
    ibgw_conTradeChannel.placeOrder(newOrderID, order_ticker, order_desc)
    
    print 'disconnected', ibgw_conTradeChannel.disconnect()
    
    The Output will be something like this:

     
    #14     Nov 9, 2013
  5. SteveH

    SteveH

    This is a quote from the IB API Guide:

    "Note: It is possible that orderStatus() may return duplicate messages. It is essential that you filter the message accordingly."

    I have used the version of the C# socket interface which filtered them and had to take care of it myself for an order manager I wrote on top of the ActiveX component. I'll dig into the Python code and find out. I thought you probably knew off the top of your head. It probably does since you use ibpy and weren't even aware of this messaging quirk.

    [I'm working on a cross-platform charting/trading program for IB with Qt and it looks like PyQt with ibpy is a good way to do some very fast prototyping before going to C++ for the finalized form.]
     
    #15     Nov 9, 2013
  6. Butterfly

    Butterfly

    Does the IB server have echos for the Order Status messages ? quite possible, but as long as you trace the messages, don't see why this is a problem. If it's a simple echo of the same message, the attributes have not changed, and that still shouldn't affect your trading logic.

    What I did see on programming forums about this issue was the confusion regarding which "status" attribute was more meaningful. If the trade was executed immediately and the "echo" message had different attributes, then I could see how a poorly designed script or a HFT hack would have a problem. Your code should be designed to catch and process properly those changes regardless of the echo, even if you subsequently send a "reqOpenOrders" to IB Server. Too often there is the issue of a programming design.

    For HFT hack code however, this is more problematic because the trades logic are driven from the immediate server response, hence echos could trigger a different trading logic. I don't consider HFT trading logic like a real trading logic, it's more like hacking, so anything goes there.
     
    #16     Nov 10, 2013
  7. 2rosy

    2rosy

    I put up tutorial here. It will guide you to good times
    :cool:
     
    #17     Nov 10, 2013
  8. Butterfly

    Butterfly

    that's not a tutorial at all, but just another undocumented framework for IB API

    I understand a lot of developers confuse listing their source code with documenting their code, but really, that link above is just another example of poor documentation for the IB API in Python. I came across a dozens of those already and they are not helping at all.

    Next example, how to manage "OrderIDs" for successive trades
     
    #18     Nov 10, 2013
  9. crmorris

    crmorris

    a question for api users, especially those using the gateway instead of tws. what kind of front end do you use for your applications? excel is so easy -- gives you a lot for free. is there anything already built, anything out of the box, any simple development ideas, AND would anybody be willing to share some code or just snapshots?

    thanks.
     
    #19     Nov 11, 2013
  10. I just use java swing for gui w/ jfreecharts and d3 for visualization. It's pretty straightforward.
     
    #20     Nov 12, 2013