Currency pairs prices from IB using Python API

Discussion in 'App Development' started by danjuma, Sep 12, 2017.

  1. danjuma

    danjuma

    Hello. I am trying to write a small program to place bracket orders on IB TWS through their Python API. I am not that versed in Python (or other IB APIs); just piecing together bits of code that I am come across here and here. I am using Python 3.6 and Tkinter as the GUI. Where I am current stuck is getting the prices for currency pairs. The code below works fine for stocks:


    def create_contract(self, symbol, sec_type, exch, prim_exch, curr):#*
    contract = Contract()
    contract.m_symbol = symbol
    contract.m_secType = sec_type
    contract.m_exchange = exch
    contract.m_primaryExch = prim_exch
    contract.m_currency = curr
    return contract


    def request_market_data(self, symbol_id, symbol):
    contract = self.create_contract(symbol,
    'STK',
    'SMART',
    'NASDAQ',
    'USD')
    self.tws_conn.reqMktData(symbol_id, contract, '', False)




    But when I amend it for a currency pair as follows:



    def create_contract(self, symbol, sec_type, exch, curr): # *
    contract = Contract()
    contract.m_symbol = symbol
    contract.m_secType = sec_type
    contract.m_exchange = exch
    contract.m_currency = curr
    return contract



    def request_market_data(self, symbol_id, symbol):
    contract = self.create_contract(symbol,
    'CASH',
    'IDEALPRO',
    'USD')
    self.tws_conn.reqMktData(symbol_id, contract, '', False)





    it does not work and geneartes the error: Server Error: <error id=0, errorCode=300, errorMsg=Can't find EId with tickerId:0>
    Would be most grateful for any assistance please. Thanks
     
  2. 2rosy

    2rosy

    What's symbol?
     
  3. danjuma

    danjuma

    Symbol is whatever symbol you selected from a list. In the original code, which was for stocks, this would have been for any stock in the list:

    self.cbSymbol = ttk.Combobox(f1, font=myFont, width=6, textvariable = varSymbol)
    self.cbSymbol.bind("<Return>", self.cbSymbol_onEnter) #when the enter key is press an event happens
    self.cbSymbol.bind('<<ComboboxSelect>>',self.cbSymbol_onEnter)
    self.cbSymbol['values'] = ('AAPL','FB','NFLX')
    self.cbSymbol.grid(row=1, column =1,sticky = W)


    which I changed the 5th line to read:
    self.cbSymbol['values'] = ('EUR','GBP','USD','AUD','NZD','GBP')

    Like already mentioned, I am not that versed in python or IB API in general, just piecing together codes here and there, and using python as I find it easier to follow than the other APIs
     
  4. RTFM:
    http://interactivebrokers.github.io/tws-api/basic_contracts.html#gsc.tab=0

    Here's the function I use:

    Code:
    def make_IB_fx_contract(ccy, baseccy):
       
        ibcontract = Contract()
        ibcontract.secType = "CASH"
        ibcontract.symbol=ccy
        ibcontract.exchange="IDEALPRO"
        ibcontract.currency=baseccy
    
        return ibcontract
    Note that certain pairings of ccy/baseccy don't work because of listing conventions - try switching them round and changing the sign of your trade.

    GAT
     
  5. danjuma

    danjuma


    Hi GAT, thanks for you reply, much appreciated. I copied your code and then amended the request market data function as such:

    def request_market_data(self, symbol_id, symbol):
    contract = self.make_IB_fx_contract(ccy, baseccy)
    self.tws_conn.reqMktData(symbol_id, contract, '', False)
    # time.sleep(1)


    but got error: ccy not defined. I am sure I have messed the codes some were and need to define some variables some where. Will have a look properly later when back from work. In the meantime, if you could steer me in the right direction, I will be most grateful. Just bl**dy need to get prices for currency pairs!
     
  6. Which ccy and baseccy are you using?

    GAT
     
  7. ... and what symbol_id and symbol...

    GAT
     
  8. danjuma

    danjuma

    Was trying EUR.USD
     
  9. Please give me the *full* code you're running and the exact error trace that comes back.

    GAT
     
  10. danjuma

    danjuma


    First bit of code:

    from ib.ext.Contract import Contract
    from ib.ext.Order import Order
    from ib.opt import Connection, message
    from tkinter import *
    from tkinter import ttk
    from decimal import Decimal
    import time

    class Application(Frame):
    #methods/functions
    def __init__(self, master):
    """Initialize the Frame"""
    ttk.Frame.__init__(self, master)
    #variables
    self.port=7496
    self.client_id = 86 # this can be any number
    self.grid()
    self.create_widgets()
    self.account_code = None
    self.symbol_id, self.symbol = 0, 'EUR'

    def create_widgets(self):
    """ create the window layout. """

    myFont = ('Lucida Grande', 10)



    subsequent codes (pieced together and amended and commented out in some areas by me:

    #create Label Symbol
    self.labe31 = Label(f1, font=myFont, text="Symbol").grid(row=2, column =0)

    #create combo box for the Symbol
    self.cbSymbol = ttk.Combobox(f1, font=myFont, width=9, textvariable = varSymbol)
    self.cbSymbol.bind("<Return>", self.cbSymbol_onEnter) #when the enter key is press an event happens
    self.cbSymbol.bind('<<ComboboxSelected>>',self.cbSymbol_onEnter) #updates combo box when you select a symbol from the dropdown box
    self.cbSymbol['values'] = ('EUR','GBP','USD','USD','USD','AUD','NZD','GBP')
    self.cbSymbol.grid(row=3, column =0,sticky = W)


    def cbSymbol_onEnter(self, event):
    # cancels Account updates
    self.tws_conn.reqAccountUpdates(False, self.account_code)
    # changes characters to upper case
    varSymbol.set(varSymbol.get().upper())
    # gets the value of the text from the combobox. cbSymbol
    # and adds it to the variable mytext
    mytext = varSymbol.get()
    # gets list of values from dropdwn list of
    # cbSymbol combobox
    vals = self.cbSymbol.cget('values')
    # selects all in the combobox. cbSymbol
    self.cbSymbol.select_range(0, END)
    # checks if symbol exists in the combobox if not it adds it
    # to the dropdown list
    if not vals:
    self.cbSymbol.configure(values=(mytext,))
    elif mytext not in vals:
    self.cbSymbol.configure(values=vals + (mytext,))
    mySymbol = varSymbol.get()
    self.symbol = mySymbol

    # calls the cancel_market_data() method
    self.cancel_market_data()
    # sets the text boxes for position and average price to zero
    # varPosition.set('0')
    # varAvgPrice.set('0.00')
    # calls the method to request streaming data
    self.request_market_data(self.symbol_id, self.symbol)
    # calls method to request account updates
    self.request_account_updates(self.account_code)
    # sets bid and ask price to zero
    # varBid.set('0.00')
    varAsk.set('0.00')


    def request_market_data(self, symbol_id, symbol):
    contract = self.create_contract(symbol, 'CASH', 'IDEALPRO', '', 'USD')
    self.tws_conn.reqMktData(symbol_id, contract, '', False)
    # time.sleep(1)


    def create_contract(self, symbol, sec_type, exch, prim_exch, curr): # *
    contract = Contract()
    contract.m_symbol = symbol
    contract.m_secType = sec_type
    contract.m_exchange = exch
    contract.m_primaryExch = prim_exch
    contract.m_currency = curr
    return contract



    So basically if I click on the list box 'Symbol' and select a symbol from the drop down box, I should get the Ask (will code for more prices - Bid, Last etc later)


    image10.PNG



     
    #10     Sep 13, 2017