# Craig Hammond 2016
from tkinter import *
from tkinter import ttk
class Application(Frame):
def __init__(self, master):
""" Initialize the Frame"""
ttk.Frame.__init__(self, master)
self.grid()
self.create_widgets()
def create_widgets(self):
self.btnConnect = ttk.Button(self, text = "Search Symbol", command=self.search_symbol).grid(row=0, column=0, sticky=W)
self.btnDisconnect = ttk.Button(self, text = "Add data", command=self.add_data).grid(row=0, column=1, sticky=W)
self.btnCancelMktData = ttk.Button(self, text = 'Remove All', command=self.remove_all).grid(row=0, column=2, sticky=W)
self.button_edit = Button(self, font=('',12), text="select row", width=7, command=self.add_data)
self.button_edit.grid(row=0, column=4)
# create Treeview widget to hold values in a table
self.tv = ttk.Treeview(root)
# create Treeview
self.tv = ttk.Treeview(self, height=8)
self.tv['columns'] = ('id', 'symbol', 'price', 'trigger', 'shares', 'side', 'type', 'status', 'fill')
self.tv.heading("#0", text='Time', anchor='w')
self.tv.column("#0", stretch=NO, width=5, anchor="w")
self.tv.heading('id', text='ID')
self.tv.column('id', anchor='center', width=70)
self.tv.heading('symbol', text='Symbol')
self.tv.column('symbol', anchor='center', width=70)
self.tv.heading('price', text='Price')
self.tv.column('price', anchor='center', width=70)
self.tv.heading('trigger', text='Trigger')
self.tv.column('trigger', anchor='center', width=70)
self.tv.heading('shares', text='Shares')
self.tv.column('shares', anchor='center', width=100)
self.tv.heading('side', text='Side')
self.tv.column('side', anchor='center', width=70)
self.tv.heading('type', text='Type')
self.tv.column('type', anchor='center', width=70)
self.tv.heading('status', text='Status')
self.tv.column('status', anchor='center', width=100)
self.tv.heading('fill', text='Fill')
self.tv.column('fill', anchor='center', width=70)
self.tv.bind('<ButtonRelease-1>', self.select_item)
self.tv.grid(row=1, column=0, columnspan=6, padx=5, pady=5)
self.treeview = self.tv
## self.ysb = ttk.Scrollbar(self, orient='vertical', command=self.tv.yview)
## self.xsb = ttk.Scrollbar(self, orient='horizontal', command=self.tv.xview)
## self.tv.configure(yscroll=self.ysb.set, xscroll=self.xsb.set)
## self.ysb.grid(row=1, column=7, sticky='ns')
## self.xsb.grid(row=2, column=0, sticky='ew')
ttk.Style().configure("Treeview", font= ('', 11), background="#383838",
foreground="white", fieldbackground="yellow")
self.tv.insert("","end",text = "Person",values = ("1254","MSFT","39.39", "", "0/200", "BUY", "LMT", "Filled", "39.39"), tags='hot')
self.tv.insert("","end",text = "Animal",values = ("1255","MSFT","39.58", ".10", "0/200", "SELL", "TRAIL", "PreSubmitted", "0.00"), tags='cold')
self.tv.insert("","end",text = "Name",values = ("1256","MSFT","39.58", "", "0/200", "SELL", "LMT", "Submitted", "0.00"), tags='pizza')
self.tv.insert("","end",text = "Evil Corp",values = ("1258","NFLX","102.55", "", "0/300", "SELL", "LMT", "Submitted", "0.00"), tags='tacos')
def select_item(self, a): # added self and a (event)
test_str_library = self.tv.item(self.tv.selection())# gets all the values of the selected row
print ('The test_str = ', type(test_str_library), test_str_library, '\n') # prints a dictionay of the selected row
item = self.tv.selection()[0] # which row did you click on
print ('item clicked ', item) # variable that represents the row you clicked on
print (self.tv.item(item)['values'][0]) # prints the first value of the values (the id value)
def remove_all(self):
pass
def search_symbol(self):
pass
def add_data(self):
pass
root = Tk()
app = Application(root)
root.mainloop()
Friday, 11 November 2016
Python Code Treeview Select Row
In this video you can observe how the operation of the click event works when you click on a row in the tree view widget
Saturday, 29 October 2016
IB TWS Trading Platform in Python 7
IB TWS Trading Platform in Python 3 part 7 - profit and loss
In this tutorial lesson you will add labels and textboxes to hold the unrealized, realized, and total profit and loss add code to calculate the marked profit and loss for both a long position and a short position Add these variables to your project self.unrealized = 0 # used in monitor position
self.realized = 0 # used in monitor position
self.unrealized_pnl = 0
self.realized_pnl = 0
self.marked_pnl = 0
Add this to the bottom of the create_widgets() function
# create label for unrealized
self.label_unrealized = Label(f1, font=('', 10), text='Unrealized').grid(row=10, column=2)
# create label for realized
self.label_realized = Label(f1, font=('', 10), text='Realized').grid(row=10, column=3)
# create label for Marked
self.label_Marked = Label(f1, font=('', 10), text='Marked').grid(row=10, column=4)
# create entry box for unrealized
self.tbUnrealized = Entry(f1, font=('', 10), width=12, textvariable=varUnrealized).grid(row=11, column=2)
# create entry box for realized
self.tbRealized = Entry(f1, font=('', 10), width=11, textvariable=varRealized).grid(row=11, column=3)
# create entry box for Marked
self.tbMarked = Entry(f1, font=('', 10), width=11, textvariable=varMarked).grid(row=11, column=4)
add this code to the bottom of the cbSymbol_onEnter() function
they set the text boxes for Position, average price, unrealized, realized, and marked to zero, also the 2 variables realized_pnl, and marked_pnl to zero
varPosition.set('0')
varAvgPrice.set('0.00')
self.realized_pnl = 0
self.marked_pnl = 0
varUnrealized.set('0.00')
varRealized.set('0.00')
varMarked.set('0.00')
Add this to the monitor_position() function
myShares = abs(self.position) # changes negative number to a position number
varRealized.set(self.realized_pnl)
if self.position > 0:
self.unrealized = '%.2f' %((self.last_prices - self.average_price) * myShares)
varUnrealized.set(self.unrealized)
self.marked_pnl = '%.2f' %(float(self.unrealized) + float(self.realized_pnl))
varMarked.set(self.marked_pnl)
elif self.position < 0:
self.unrealized = '%.2f' %((self.average_price - self.last_prices) * myShares)
varUnrealized.set(self.unrealized)
self.marked_pnl = '%.2f' %(float(self.unrealized) + float(self.realized_pnl))
varMarked.set(self.marked_pnl)
else:
self.marked_pnl = float(self.unrealized_pnl) + float(self.realized_pnl)
self.marked_pnl = '%.2f' % self.marked_pnl
self.realized_pnl = '%.2f' % float(self.realized_pnl)
varUnrealized.set('0.00')
varMarked.set(self.marked_pnl)
varRealized.set(self.realized_pnl)
add these string variables to the botton with the other textvariables for the 3 Entry boxes (text boxes)
varUnrealized = StringVar()
varRealized = StringVar()
varMarked = StringVar()
Pages: 1 2 3 4 5 6 7 8 9
Save Save Save Save Save Save
Tuesday, 11 October 2016
Python Historical Data 3
In this tutorial you will understand more about what goes into the code to request historical data for certain trading instruments. Check out the other properties for Options, Futures, and Forex at the end of the page. In the video example we will request data for stocks. This only works with Interactive Brokers Paste this call to a function at the end of the connect_to_tws function (The highlighted text in yellow below)
Interactive Brokers API identifies a financial instrument using an object class named contract.
The properties for contract are as follows:
http://interactivebrokers.github.io/tws-api/classIBApi_1_1Contract.html#gsc.tab=0 Examples, before a data request is made or before an order is submitted, an object of class contract will be created and its attributes will be populated with appropriate values used to identify the financial instrument. For example, to access market data for Netflix stock, set the properties:
Historical data limitations Link
To access a September 2016 $40 Call option on Netflix : I believe there is a data fee for options. You need to pay for a data feed for the options in order to request data through the API
To access a June 2017 Crude Oil Futures contract set the properties:
To access a foreign exchange quote such as Euro/USD:
Save Save Save Save Save Save Save Save Save Save Save Save Save Save Save
# make sure this is included in the connect_to_tws function
self.register_callback_functions()
Paste this code after the connect_to_tws function and make sure all your indents are correct def contract_creation(self):
self.listbox1.delete(0,END) # clears contents of the listbox
self.tws_conn.cancelHistoricalData(5) #cancels historical data
mySymbol = varSymbol.get() # get the symbol from the combobox
contract = self.create_contract(mySymbol,
'STK', # security STK = stock
'SMART', # exchange
'NASDAQ',# primary exchange
'USD') # currency
now = strftime('%Y%m%d %H:%M:%S', localtime(int(time())))
duration = varDuration.get() # get the duration ie. 1 D, 1 M, 1 Y
bar_size = varBarSize.get() # get the bar size ie. 5 mins, 2 mins, 1 day
self.tws_conn.reqHistoricalData(tickerId = 5, # contract number can be any number
contract=contract, # contract detail from above
endDateTime=now, # end date and time
durationStr=duration,
barSizeSetting=bar_size,
whatToShow='TRADES', # what to show ie. MIDPOINT, BID, ASK,
useRTH=1, # Regular trading hours 1 = RTH, 0 = all data
formatDate=1) # 1 = 20161021 09:30:00 2 = Unix time (Epoch)
def register_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')
def error_handler(self, msg):
if msg.typeName == 'error'and msg.id != -1:
print ('Server Error:', msg)
def server_handler(self, msg):
if msg.typeName == 'historicalData':
hd_date = msg.date
hd_open = msg.open
hd_high = msg.high
hd_low = msg.low
hd_close = msg.close
hd_volume = msg.volume
str_date = str(hd_date)
str_open = str(hd_open)
str_high = str(hd_high)
str_low = str(hd_low)
str_close = str(hd_close)
str_volume = str(hd_volume)
# creates a string containing date, open, high, low, close, volume
priceData2 = hd_date+","+str_open+","+str_high+","+str_low+","+str_close+","+str_volume
if 'finished' in hd_date:
pass
else:
str_data = hd_date, hd_open, hd_high, hd_low, hd_close, hd_volume
print (str_data) # prints info to the Python shell
self.listbox1.insert(END, priceData2) # adds info to the listbox
elif msg.typeName == "error" and msg.id != -1:
return
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
Interactive Brokers API identifies a financial instrument using an object class named contract.
The properties for contract are as follows:
| Property | Description |
|---|---|
| conId | Contract id for the financial instrument. |
| symbol | Stock symbol or symbol for Options or Futures |
| secType | Type of instrument: Stock=STK, Option=OPT, Future=FUT, etc. |
| expiry | used with Options or Futures: The expiration date format YYYYMMDD |
| strike | Options: The Options Strike Price |
| right | Options: The Options “PUT” or “CALL” |
| multiplier | Contract multiplier for Futures or Options "100" |
| exchange | Destination of order or requested. “SMART” = IB smart order router |
| primaryExchange | Primary listing exchange where the instrument trades. NYSE, NASDAQ, AMEX, BATS, ARCA, etc. |
| currency | Currency of the exchange USD or GBP or CAD or EUR, etc. |
http://interactivebrokers.github.io/tws-api/classIBApi_1_1Contract.html#gsc.tab=0 Examples, before a data request is made or before an order is submitted, an object of class contract will be created and its attributes will be populated with appropriate values used to identify the financial instrument. For example, to access market data for Netflix stock, set the properties:
| conID = 5 | # Contract identifier |
| symbol = "NFLX" | # Netflix stock symbol |
| secType = "STK" | # Security type is a stock (STK) |
| exchange = "SMART" | # Use IB’s Smart Order router to get the prices |
| primary exchange = "NASDAQ" | # Use NASDAQ |
| currency = "USD" | # USD Currency |
Historical data limitations Link
To access a September 2016 $40 Call option on Netflix : I believe there is a data fee for options. You need to pay for a data feed for the options in order to request data through the API
| conID = 3 | # Contract ID |
| symbol = "NFLX" | # Netflix’s stock symbol |
| secType = "OPT" | # Security type is an Option (OPT) |
| expiry = "20170120" | # January 20, 2017 Expiry YYYYMMDD |
| strike = 90 | # $90.00 strike price |
| right = "CALL" | # Call option |
| multiplier = "100" | # multiplier 100 shares per contract for options |
| exchange = "SMART" | # Use IB’s Smart Order router to get the prices |
| currency = "USD" | # USD Currency |
To access a June 2017 Crude Oil Futures contract set the properties:
| conID = 2 | # Contract Id |
| symbol = "CL" | # Crude Oil underlying symbol (CL) |
| secType = "FUT" | # Security type is an Future (FUT) |
| expiry = "20170120" | # January 20, 2017 Expiry third Friday of month |
| exchange = "NYMEX" | # Use IB’s Smart Order router to get the prices |
To access a foreign exchange quote such as Euro/USD:
| conID = 6 | # Contract Id |
| symbol = "EUR" | # Euro underlying (base currency) symbol (EUR/USD quote) |
| secType = "CASH" | # Security type is Cash / FX |
| exchange = "IDEALPRO" | # Use the IDEALPRO FX data source |
| currency = "USD" | # Quoted currency is USD |
Pages: 1 2 3 4 5 6
Save Save Save Save Save Save Save Save Save Save Save Save Save Save Save
Sunday, 9 October 2016
IB TWS Historical Data in Python 2
from time import sleep, strftime, localtime, time
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
class Application(Frame):
""" a gui application"""
def __init__(self, master):
""" Initialize the Frame"""
ttk.Frame.__init__(self, master)
self.port=7496
self.client_id = 97 # this number can be any number
self.symbol_id, self.symbol = 5, 'MSFT'
self.account_code = None
self.strData = ""
self.grid()
self.create_widgets()
def create_widgets(self):
""" create the window layout. """
now = strftime('%Y%m%d %H:%M:%S', localtime(int(time())))
myfont=('Arial', 12)
myFont = ('Lucida Grande',12)
# create a connect to tws button
self.btnConnect = ttk.Button(self, text = "Connect", command=self.connect_to_tws)
self.btnConnect.grid(row=0, column=1, sticky=W)
# create a button to request the data
self.btnGetData = ttk.Button(self, text = "Get Data", command=self.contract_creation)
self.btnGetData.grid(row=0, column=2, sticky=W)
# create a label for Symbol
self.label_symbol = Label(root, text='Symbol').grid(row=1, column=0)
# create a combobox for security symbol
self.cbSymbol = ttk.Combobox(root, font=myfont, textvariable=varSymbol).grid(row=2, column=0)
# create label for the endDateTime
self.label_datetime = Label(root, font=myfont, text='End Date').grid(row=3, column=0)
# create label for the duration
self.label_duration = Label(root, font=myfont, text='Duration').grid(row=3, column=1)
# create label for the barSizeSetting
self.label_bar_size = Label(root, font=myfont, text='Bar Size').grid(row=3, column=2)
# create Entry box (textbox) for the endDateTime
self.tbDateTime = Entry(root, font=myfont, textvariable=varDateTime).grid(row=4, column=0)
# create Combo box (textbox) for the duration
self.cbDuration = ttk.Combobox(root, font=myfont, textvariable=varDuration)
self.cbDuration['values'] = ('1 Y', '1 M', '6 M', '1 D', '2 D')
self.cbDuration.grid(row=4, column=1, sticky=W)
# create Combo box (textbox) for the barSizeSetting
self.cbBarSize = ttk.Combobox(root, font=myfont, textvariable=varBarSize)
self.cbBarSize['values'] = ('1 day', '1 min', '2 mins', '5 mins')
self.cbBarSize.grid(row=4, column=2, sticky=W)
varDateTime.set(now)
# create a listbox for the data make it 2 lines or the
# listbox1.insert will not work you get an error
# damn that is frustrating
self.listbox1 = Listbox(root, font= ('', 12), width=75, height=30)
self.listbox1.grid(row=6, column=0, columnspan=5, padx=5, pady=5, sticky='w')
def connect_to_tws(self):
self.tws_conn = Connection.create(port=7496, clientId=5)
self.tws_conn.connect()
def contract_creation(self):
pass
root = Tk()
root.title("Historical data from IB TWS in Python please donate")
root.geometry("600x670")
root.attributes("-topmost", True)
varDateTime = StringVar()
varDuration = StringVar(root, value='1 D')
varBarSize = StringVar(root, value='5 mins')
varSymbol = StringVar(root, value='MSFT')
app = Application(root)
root.mainloop()
Pages: 1 2 3 4 5 6
Save
Saturday, 8 October 2016
IB TWS Historical Data in Python
Programs you will need to install
Python 3.4 or 3.5 but should work with others versions with small variations. I am using version 3.5 https://www.python.org/ IBpy I have a video on YouTube which will show you how to install it Here is a link https://github.com/blampe/IbPy Ineractive brokers Traders Workstation https://www.interactivebrokers.com/en/index.php?f=14099#tws-software Interactive brokers API (Application Program Interface) http://interactivebrokers.github.io/# Make sure you global setting under the API menu are the same as below, although I don't think you need to check off the Enable DDE clients check boxPages: 1 2 3 4 5 6
Save Save SaveHistorical Data Examples Stocks Options Forex Futures
This will be a demo, I created an application on what the different attributes that you will need, and what data you can show with live examples.
The data that you can show is not the same for all securities for example the list below shows you can only request what is highlighted in yellow.
for a completes list of what to show and the times for requesting historical data you can use go to the following link below:
https://www.interactivebrokers.com/en/software/api/apiguide/tables/historical_data_limitations.htm
Wednesday, 28 September 2016
IB TWS Trading Platform Python 6
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)
Save Save Save Save Save Save Save Save Save Save Save Save Save Save
#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"
self.position = msg.position
self.average_price = msg.averageCost
Add this under the monitor_position function
# '%.2f' = formats to 2 decimal places
varAvgPrice.set('%.2f' % self.average_price)
varPosition.set(self.position)
add this to the bottom of the onEnter function
varPosition.set('0')
varAvgPrice.set('0.00')
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.com
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
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)
def tbBid_Click(self, event):
LimitPrice = varBid.get()
varLimitPrice.set(LimitPrice)
def tbAsk_Click(self, event):
LimitPrice = varAsk.get()
varLimitPrice.set(LimitPrice)
def tbLast_Click(self, event):
LimitPrice = varLast.get()
varLimitPrice.set(LimitPrice)
def cancel_all(self):
self.tws_conn.reqGlobalCancel()
def connect_to_tws(self):
self.tws_conn = Connection.create(port=self.port,
clientId=self.client_id)
self.tws_conn.connect()
self.register_callback_functions()
def disconnect_it(self):
self.tws_conn.disconnect()
def buy(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)
def sell(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 order
def place_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
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 of 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()
# 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')
def request_account_updates(self, account_code):
self.tws_conn.reqAccountUpdates(True, self.account_code)
def cancel_market_data(self):
self.tws_conn.cancelMktData(self.symbol_id)
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)
def tick_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
def create_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
def register_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)
def server_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:
return
def error_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()
Pages: 1 2 3 4 5 6 7 8 9
Save Save Save Save Save Save Save Save Save Save Save Save Save Save
Subscribe to:
Posts (Atom)