In this tutorial we will request account updates and receive the position size and average price of our position.
Create 2 labels and 2 text boxes (entry box)
#create label for Average Price
self.label22 = Label(f1, font=myFont, text='Avg Price', width=8 )
self.label22.grid(row=6, column=3)
#create label for Position
self.label23 = Label(f1, font=myFont, text='Position', width=8)
self.label23.grid(row=7, column=3)
#create entrybox (textbox) for Average Price
self.tbAvgPrice = Entry(f1, font=myFont, width=7, textvariable=varAvgPrice)
self.tbAvgPrice.grid(row=6, column=4)
#create entrybox (textbox) for Position size
self.tbPosition = Entry(f1, font=myFont, width=7, textvariable=varPosition)
self.tbPosition.grid(row=7, column=4)
Add this to the server_handler function under "updatePortfolio"
Add this near the bottom with the rest of the StringVar variables
varAvgPrice = StringVar(root, value='0.00') # variable for average price
varPosition = StringVar(root, value='0') # variable for Position and set default to zero
All of the code up to tutorial 6
# Craig Hammond 2017 www.sharpertradingimage.comfrom ib.ext.Contract import Contract
from ib.ext.Order import Order
from ib.opt import Connection, message
from tkinter import *
from tkinter import ttk
import time
from msvcrt import getch
class Application(Frame):
def__init__(self, master):
"""Initialize the Frame"""
ttk.Frame.__init__(self, master)
self.port=7496
self.client_id = 82 # this can be any number
self.grid()
self.create_widgets()
self.account_code = None
self.symbol_id, self.symbol = 0, 'AAPL'
self.order_id = 555
def create_widgets(self): # Method or function""" create the window layout. """
myFont = ('Lucida Grande', 12)
# create connect button widget
self.btnConnect = ttk.Button(self, text='Connect', command=self.connect_to_tws)
self.btnConnect.grid(row=0, column=0)
self.btnDisconnect = ttk.Button(self, text = "Disconnect", command=self.disconnect_it).grid(row=0, column=1, sticky=W)
#notebook
n = ttk.Notebook(root, width=550, height=350)
f1 = ttk.Frame(n) # first page, which would get widgets gridded into it
f2 = ttk.Frame(n) # second page
n.add(f1, text='One')
n.add(f2, text='Two')
n.grid(row=3, column=0, padx=5, pady=5, sticky=W)
#create listbox
self.listbox1 = Listbox(f1, font=('Lucida Grande',9), width=7)
#self.listbox1.bind('', self.OnDoubleClick_listbox)
self.listbox1.insert(1, 'NFLX')
self.listbox1.insert(2, 'AAPL')
self.listbox1.insert(3, 'FB')
self.listbox1.grid(row=0, rowspan=5, column=0, padx=5)
#create Label Symbol
self.label4 = Label(f1, font=myFont, text="Symbol").grid(row=0, column =1)
#create Label Quantity
self.label5 = Label(f1, font=myFont, text="Quantity").grid(row=0, column =2)
#create Label Limit Price
self.label6 = Label(f1, font=myFont, text="Limit Price").grid(row=0, column =3)
#create Label Market
self.label7 = Label(f1, font=myFont, text="Market").grid(row=0, column =4)
#create combo box for the Symbol
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('<<ComboboxSelected>>',self.cbSymbol_onEnter)
self.cbSymbol['values'] = ('AAPL','FB','NFLX')
self.cbSymbol.grid(row=1, column =1,sticky = W)
#create spinbox (numericUpDown) for Limit Price
self.spinQuantity = Spinbox(f1, font=myFont, increment=100, from_=0, to=10000, width=7,
textvariable=varQuantity).grid(row=1, column=2)
#create spinbox (numericUpDown) for Limit Price
self.spinLimitPrice = Spinbox(f1, font=myFont, format='%8.2f', increment=.01, from_=0.0, to=1000.0, width=7,
textvariable=varLimitPrice)
# when control and up or down arrow are pressed call spenLimitDime()#self.spinLimitPrice.bind('', self.spinLimitDime)# when Alt and up or down arrow are pressed call spenLimitPenny()#self.spinLimitPrice.bind('', self.spinLimitPenny)
self.spinLimitPrice.grid(row=1, column=3)
#create textbox(Entry box) for the Market
self.cbMarket = ttk.Combobox(f1, font=myFont, width=7, textvariable=varMarket).grid(row=1, column=4, sticky = W)
#create Label OrderType ********-3-****
self.label8 = Label(f1, font=myFont, text="OrderType").grid(row=2, column =1, sticky=W)
#create Label Visible
self.label9 = Label(f1, font=myFont, text="Visible").grid(row=2, column =2)
#create Label Primary Exchange
self.labe20 = Label(f1, font=myFont, text="Primary Ex.").grid(row=2, column =3)
#create Label Time in Force
self.labe21 = Label(f1, font=myFont, text="TIF").grid(row=2, column =4)
#create textbox(Entry box) for the Order Type ****4****
self.cbOrderType = ttk.Combobox(f1, font=myFont, width=6, textvariable=varOrderType)
self.cbOrderType['values'] = ('LMT','MKT','STP', 'STP LMT', 'TRAIL', 'MOC', 'LOC')
self.cbOrderType.grid(row=3, column =1,sticky = W)
#create textbox(Entry box) for the Primary Exchange
self.tbPrimaryEx = Entry(f1, font=myFont, width=8, textvariable=varPrimaryEx).grid(row=3, column =3,sticky = W)
#create textbox(Entry box) for the Time in Force
self.cbTIF = ttk.Combobox(f1, font=myFont, width=7, textvariable=varTIF)
self.cbTIF['values'] = ('DAY','GTC')
self.cbTIF.grid(row=3, column =4,sticky = W)
#create Bid Label
self.label2 = Label(f1, font=myFont, text="Bid", width=7).grid(row=4, column=2)
#create Ask Label
self.label3 = Label(f1, font=myFont, text="Ask", width=7).grid(row=4, column=3)
#create textbox(Entry box) for the Bid price
self.tbBid = Entry(f1, font=myFont, width=7, textvariable = varBid)
self.tbBid.bind("<Button-1>", self.tbBid_Click)
self.tbBid.grid(row=5, column =2, sticky=E)
#create textbox(Entry box) for the Ask price
self.tbAsk = Entry(f1, font=myFont, width=7, textvariable = varAsk)
self.tbAsk.bind("<Button-1>", self.tbAsk_Click)
self.tbAsk.grid(row=5, column=3)
#create a sell button
self.btnSell = Button(f1, font=('',10,'bold'), text="SELL", width=9, bg="red", fg="white", command=self.sell)
self.btnSell.grid(row=5, column=1, sticky=W)
#create a buy button
self.btnBuy = Button(f1, font=('',10,'bold'), text="BUY", width=9, bg="green", fg="white", command=self.buy)
self.btnBuy.grid(row=5, column=4, sticky=E)
#create Label
self.label1 = Label(f1, font=myFont, width=8, text="Last").grid(row=6, column =1)
#create textbox(Entry box) for the last price
self.tbLast = Entry(f1, font=myFont, width=8, textvariable = varLast)
self.tbLast.bind("<Button-1>", self.tbLast_Click)
self.tbLast.grid(row=6, column =2,sticky = W)
# create button for cancel all
self.btnCancelAll = Button(f1, font= ('', 10), text= 'Cancel All',
width=8, bg="blue", fg="white", command=self.cancel_all)
self.btnCancelAll.grid(row=7, column=2)
#create label for Average Price
self.label22 = Label(f1, font=myFont, text='Avg Price', width=8 )
self.label22.grid(row=6, column=3)
#create label for Position
self.label23 = Label(f1, font=myFont, text='Position', width=8)
self.label23.grid(row=7, column=3)
#create entrybox (textbox) for Average Price
self.tbAvgPrice = Entry(f1, font=myFont, width=7, textvariable=varAvgPrice)
self.tbAvgPrice.grid(row=6, column=4)
#create entrybox (textbox) for Position size
self.tbPosition = Entry(f1, font=myFont, width=7, textvariable=varPosition)
self.tbPosition.grid(row=7, column=4)
deftbBid_Click(self, event):
LimitPrice = varBid.get()
varLimitPrice.set(LimitPrice)
deftbAsk_Click(self, event):
LimitPrice = varAsk.get()
varLimitPrice.set(LimitPrice)
deftbLast_Click(self, event):
LimitPrice = varLast.get()
varLimitPrice.set(LimitPrice)
defcancel_all(self):
self.tws_conn.reqGlobalCancel()
defconnect_to_tws(self):
self.tws_conn = Connection.create(port=self.port,
clientId=self.client_id)
self.tws_conn.connect()
self.register_callback_functions()
defdisconnect_it(self):
self.tws_conn.disconnect()
defbuy(self):
self.symbol = varSymbol.get() # gets the symbol string from the symbol combo box
self.quantity = varQuantity.get() # gets the share size from the quantity spinbox
self.order_type = varOrderType.get() # gets the order type for the order type combobox
self.limit_price = varLimitPrice.get() # gets the limit price from the limit price spinbox # calls the function place_market order passes variables# symbol, quantity, order type, buy or sell represeted by true or false, and limit price
self.place_market_order(self.symbol, self.quantity, self.order_type, True, self.limit_price)
defsell(self):
self.symbol = varSymbol.get()
self.quantity = varQuantity.get()
self.order_type = varOrderType.get()
self.limit_price = varLimitPrice.get()
self.place_market_order(self.symbol, self.quantity, self.order_type, False, self.limit_price)
# Place order ********************************************************************************place orderdefplace_market_order(self, symbol, quantity, order_type, is_buy, limit_price):
print (symbol, quantity, order_type, is_buy, limit_price)
contract = self.create_contract(symbol,
'STK',
'SMART',
'NASDAQ',
'USD')
# tests if is buy or sell
buysell = 'BUY' if is_buy else 'SELL'
order = self.create_order(order_type, quantity, buysell, limit_price)
self.tws_conn.placeOrder(self.order_id, contract, order)
# increses the order id by one
self.order_id += 1
defcbSymbol_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 of symbol exists in the combobox if not it adds it# to the dropdown listif 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()
# 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')
varPosition.set('0')
varAvgPrice.set('0.00')
defrequest_account_updates(self, account_code):
self.tws_conn.reqAccountUpdates(True, self.account_code)
defcancel_market_data(self):
self.tws_conn.cancelMktData(self.symbol_id)
defrequest_market_data(self, symbol_id, symbol):
contract = self.create_contract(symbol,
'STK',
'SMART',
'NASDAQ',
'USD')
self.tws_conn.reqMktData(symbol_id, contract, '', False)
deftick_event(self, msg):
if msg.tickerId == 0:
if msg.field == 1: # 1 is for the bid price
self.bid_price = msg.price
elif msg.field == 2: # 2 is for the ask price
self.ask_price = msg.price
elif msg.field == 4: # 4 represents the last price
self.last_prices = msg.price
self.monitor_position(msg)
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
defcreate_order(self, order_type, quantity, action, limit_price):
order = Order()
order.m_orderType = order_type
order.m_totalQuantity = quantity
order.m_action = action
order.m_lmtPrice = limit_price
return order
defregister_callback_functions(self):
# Assign server messages handling function.
self.tws_conn.registerAll(self.server_handler)
# Assign error handling function.
self.tws_conn.register(self.error_handler, 'Error')
# Register market data events.
self.tws_conn.register(self.tick_event,
message.tickPrice,
message.tickSize)
defserver_handler(self, msg):
if msg.typeName == "nextValidId":
self.order_id = msg.orderId
elif msg.typeName == "managedAccounts":
self.account_code = msg.accountsList
elif msg.typeName == "updatePortfolio" \
and msg.contract.m_symbol == self.symbol \
and msg.contract.m_secType == 'STK':
self.unrealized_pnl = msg.unrealizedPNL
self.realized_pnl = msg.realizedPNL
self.position = msg.position
self.average_price = msg.averageCost
elif msg.typeName == "error" and msg.id != -1:
returndeferror_handler(self, msg):
if msg.typeName == 'error'and msg.id != -1:
print ('Server Error:', msg)
def monitor_position(self, msg): #*print ('Last Price = %s' % (self.last_prices))
varLast.set(self.last_prices)
varBid.set(self.bid_price)
varAsk.set(self.ask_price)
# '%.2f' = formats to 2 decimal places
varAvgPrice.set('%.2f' % self.average_price)
varPosition.set(self.position)
root = Tk()
root.title("Connect to IB TWS with Python")
root.geometry('600x480')
root.attributes('-topmost', True)
varSymbol = StringVar(root, value='NFLX')
varQuantity = StringVar(root, value='100')
varLimitPrice = StringVar()
varMarket = StringVar(root, value='SMART')
varOrderType = StringVar(root, value='LMT')
varPrimaryEx = StringVar(root, value='NASDAQ')
varTIF = StringVar(root, value='DAY')
varLast = StringVar()
varBid = StringVar()
varAsk = StringVar()
varAvgPrice = StringVar(root, value='0.00')
varPosition = StringVar(root, value='0')
app = Application(root)
root.mainloop()
No comments:
Post a Comment