Currency pairs prices from IB using Python API

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
 
What's symbol?

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
 
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


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!
 
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!

Which ccy and baseccy are you using?

GAT
 
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!

... and what symbol_id and symbol...

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

GAT


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



 
Back
Top