Create a Trading Platform in Python

Bingazingas Craig Hammond Youtube Create a Trading Platform https://sharpertradingimage.blogspot.com/
mail@pastecode.io avatar
unknown
csharp
2 years ago
72 kB
4
Indexable
Never
¬¬¬¬¬¬¬¬¬¬IB TWS Historical Data in Python 2
https://sharpertradingimage.blogspot.com/2018/01/ib-tws-historical-data-in-python-2.html

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

¬¬¬¬¬¬¬¬¬¬Trading platform in Python 3
https://sharpertradingimage.blogspot.com/2018/02/trading-platform-in-python-3.html


        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("", self.cbSymbol_onEnter) #when the enter key is press an event happens
        #self.cbSymbol.bind('<>',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 ****** note: make sure there is an underscore at the end of the word from
        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("", 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("", self.tbAsk_Click)
        self.tbAsk.grid(row=5, column=3)

 #create a sell button ***
        self.btnSell = Button(f1, font=('Lucida Grande',10,'bold'), text="SELL", width=9, bg="red", fg="white")
        self.btnSell.grid(row=5, column=1, sticky=W)

        #create a buy button ***
        self.btnBuy = Button(f1, font=('Lucida Grande',10,'bold'), text="BUY", width=9, bg="green", fg="white")
        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).grid(row=6, column =2,sticky = W) 


* Show code for the disconnect method

def disconnect_it(self):
    self.tws_conn.disconnect()

* Show code for the variables

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


 ¬¬¬¬¬¬¬¬¬¬Trading platform in Python 4
https://sharpertradingimage.blogspot.com/2018/02/trading-platform-in-python-4.html
In this tutorial we will
add some methods or functions for requesting streaming data
add events to the combobox
change text from lowercase to upper case
select all text in combobox
add items to the drop down list

Uncomment out these 2 lines of code in the widgets function under the combo box widget the one that is called cbSymbol combobox symbol

     self.cbSymbol.bind('<Return>', self.cbSymbol_onEnter) #when the enter key is press an event happens 
     self.cbSymbol.bind('<<ComboboxSelected>>',self.cbSymbol_onEnter)

 add these two variables under """ initialize the frame"""
     self.account_code = None
     self.symbol_id, self.symbol = 0, 'AAPL'

 Add this to the connect_ to_tws  function
     self.register_callback_functions()

 add all these functions to your Python program.  Added some extra code that was not covered in the YouTube video that is highlighted in yellow.

    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_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)
        #time.sleep(1)    
 
    def tick_event(self, msg):
        if msg.tickerId == 0: # added this to the code not shown in video ********* 
            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 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':  # added this to my code not shown in video ******
            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)





 ¬¬¬¬¬¬¬¬¬¬IB TWS Trading Platform in Python 5
https://sharpertradingimage.blogspot.com/2018/02/ib-tws-trading-platform-in-python-5.html

create a variable to hold the next valid id ( nextValidId )
	self.order_id = 555

create button for cancel all orders
 # create button for cancel all
        self.btnCancelAll = Button(f1, font= ('Lucida Grande', 10), text= 'Cancel All',
                                   width=8, bg="blue", fg="white", command=self.cancel_all)
        self.btnCancelAll.grid(row=7, column=2)


click events for text box (Entry) Bid, Ask, and Last prices

    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)


Function for Cancel All

 def cancel_all(self):
            self.tws_conn.reqGlobalCancel()


buy and sell click events

    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 function


    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 # add number to order id so it is ready for the next order
        # must be increase higher than the previous number


create_order function

    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 

 ¬¬¬¬¬¬¬¬¬¬IB TWS Trading Platform Python 6
https://sharpertradingimage.blogspot.com/2018/02/ib-tws-trading-platform-python-6.html
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"
            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() 

 ¬¬¬¬¬¬¬¬¬¬IB TWS Trading Platform in Python 7
IB TWS Trading Platform in Python 3 part 7 - profit and loss
https://sharpertradingimage.blogspot.com/2018/02/ib-tws-trading-platform-in-python-7.html

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





 ¬¬¬¬¬¬¬¬¬¬IB TWS Trading Platform in Python 8 outsideRTH
IB TWS Trading Platform in Python 8 outsideRTH
https://sharpertradingimage.blogspot.com/2018/02/ib-tws-trading-platform-in-python-8_3.html

In this tutorial you will add a check box to your gui form window that will allow you to trade after hours and pre-market.

Add this variable to hold the variable for the checkbox just above the create widgets function.

self.my_outsideRTH = False 


Add this to the end of the create_widgets(self): function

        # create a check button box for outside RTH
        self.chkOutsideRTH = Checkbutton(f1, font=('', 10),
                                         text='OutsideRTH', variable=varOutsideRTH)
        self.chkOutsideRTH.grid(row=9, column=6)

  Add highlighted text to the buy(self): function and the sell(self): function

  def buy(self):
        self.symbol = varSymbol.get()
        self.quantity = varQuantity.get()
        self.order_type = varOrderType.get()
        self.limit_price = varLimitPrice.get()
        self.my_outside = varOutsideRTH.get() # add here
        the_outsideRTH = 0
        if self.my_outside == True:
            the_outsideRTH = 1
        self.place_market_order(self.symbol, self.quantity, self.order_type,
                                True, self.limit_price, the_outsideRTH) # add here

    def sell(self):
        self.symbol = varSymbol.get()
        self.quantity = varQuantity.get()
        self.order_type = varOrderType.get()
        self.limit_price = varLimitPrice.get()
        self.my_outside = varOutsideRTH.get() # add here
        the_outsideRTH = 0
        if self.my_outside == True:
            the_outsideRTH = 1
        self.place_market_order(self.symbol, self.quantity, self.order_type,
                                False, self.limit_price, the_outsideRTH) # add here


Add the variable my_outsideRTH to the highlighted areas in the place_market_order() function as shown below.

    def place_market_order(self, symbol, quantity, order_type, is_buy, limit_price, my_outsideRTH): # add here
        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, my_outsideRTH)# add here
        self.tws_conn.placeOrder(self.order_id, contract, order)
        # increses the order id by one
        self.order_id += 1


Add the variable outsideRTH to the highlighted areas in the create_order() function as shown below.


    def create_order(self, order_type, quantity, action, limit_price, outside_Rth):    # add  outside_Rth 
        order = Order()
        order.m_orderType = order_type
        order.m_totalQuantity = quantity
        order.m_action = action
        order.m_lmtPrice = limit_price  
        order.m_outsideRth = outside_Rth                  # add order.m_outsideRth = outside_Rth 
        return order

Add this to the bottom where all the variables are for your window form widgets.

varOutsideRTH = StringVar(root, value=False) 


 ¬¬¬¬¬¬¬¬¬¬Get The Unique id conId Number from TWS
 https://sharpertradingimage.blogspot.com/2018/02/get-unique-id-conid-number-from-tws.html
Learn how to get the unique id (conId) from Interactive brokers using a gui application. 
Every option has a different number since there are so many variations. 
The contract id (conid) is a number not a symbol, and this number you will need in order to trade options. 
For example the IBM 170 CALL option with an expiry on January 6, 2017 has a unique id number of  256910869. 
The number may be different on the next trading day.  
I am not sure if they stay the same from now, until the next day until they expire. 
You can search for a contract id number 
here: https://pennies.interactivebrokers.com/cstools/contract_info/v3.9/index.php


 see the code here 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 2017 Expiry format 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 pricesTo 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


 ¬¬¬¬¬¬¬¬¬¬Sunday, 4 February 2018
Listbox Scroll bars Horizontal Vertical
https://sharpertradingimage.blogspot.com/2018/02/listbox-scroll-bars-horizontal-vertical.html

Listbox Scroll bars tkinter Python Copy and paste the highlighted text into the section
of your code where you create your widgets, and also add the x and yscrollcommands to the listbox parameters.

# Craig Hammond 2017
# www.sharpertradingimage.com
        # create scroll bars for your listbox
        self.scrollbar_V = Scrollbar(self)
        self.scrollbar_H = Scrollbar(self, orient=HORIZONTAL)
        self.scrollbar_V.grid(row=1, column=1, sticky=N+S+W)
        self.scrollbar_H.grid(row=5, column=0, sticky=N+E+S+W)
        
        # create listbox widget
        self.listbox1 = Listbox(self, font=('', 12), width=15, height=10, yscrollcommand=self.scrollbar_V.set, xscrollcommand=self.scrollbar_H.set)
        self.listbox1.bind('<<ListboxSelect>>', self.select_item)
        self.listbox1.insert(1, 'FB')
        self.listbox1.grid(row=1, column=0)
        # add some text to the listbox 
        evil_corporations = ['EVIL CORPORATIONS y gobiernos', 'cranAAPLe', 'SBUckX', 'XOMobil',
                                  'Any oil company that you care to name',
                                  'OPECs', 'MSFaT', 'AMEXica', 'ALL COUNTRIES THAT DO NOT PROSECUTE THE BANKERS',
                                  'most TRADING FIRMS', 'BUT NOT INTERACTIVE BROKERS BEST COMMISSIONS not as bad',
                                  'banking cartels, the FED', 'las paisas que le gusta la guerra', 'foundations created by evil elitists']
        for evil in evil_corporations:
            self.listbox1.insert('end', evil)
        # also needed for scroll bars
        self.scrollbar_V.config(command=self.listbox1.yview)
        self.scrollbar_H.config(command=self.listbox1.xview)

 ¬¬¬¬¬¬¬¬¬¬Sunday, 4 February 2018
Python Treeview delete rows

https://sharpertradingimage.blogspot.com/2018/02/python-treeview-delete-rows.html

https://youtu.be/ViWXxf8CZd4

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 remove_all(self):
        x = self.tv.get_children()
        print ('get_children values: ', x ,'\n')
        if x != '()': # checks if there is something in the first row
            for child in x:
                self.tv.delete(child)
                
    def search_symbol(self):
        pass

    def add_data(self):
        pass

    def select_item():
        pass

root = Tk()       
app = Application(root)
root.mainloop()

 ¬¬¬¬¬¬¬¬¬¬Sunday, 4 February 2018
Python Button Tkinter passing arguments
Python tkinter button widget passing arguments. 
In these examples I will show you several ways you can pass values, variables, arguments to a function.
You will also learn how to add a right mouse click as well as the left mouse click.

https://sharpertradingimage.blogspot.com/2018/02/python-button-tkinter-passing-arguments.html
https://youtu.be/-qCJIn_Rvis

Here is the code to start the tutorial and follow along

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.grid()
        self.create_widgets()

    def create_widgets(self):
        # create a normal button
        self.button1 = Button(root, font=('', 16, 'bold'), text='.22 Cents', command=self.do_something)
        self.button1.grid(row=0, column=0, pady=5, padx=5)

        # create a text box (Entry box) to hold the value of the click event
        self.tbValue = Entry(root, font=('', 16, 'bold'), textvariable=varEntryValue).grid(row=1, column=2, pady=5, padx=5)

        # create a text box (Entry box) to hold a average price
        self.tbSet = Entry(root, font=('', 16, 'bold'), textvariable=varAvgPrice).grid(row=1, column=1, pady=5, padx=5)
        
    # button 1 example
    def button1_Click(event, arg):
        average_Price = varAvgPrice.get() # gets a value from the first Entry box
        c = float(average_Price) + arg # adds the value from the ttk .22 button to the first entry box value
        c = round(c, 2) # round off c to 2 decimal places
        varEntryValue.set(c) # sets the value in the second Entry box

    def do_something(self):
        varEntryValue.set('Hello, Hola, Bonjour')    

root = Tk()

root.title("Button Examples in Python")
root.geometry("790x850")
root.attributes("-topmost", True)
varEntryValue = StringVar()
varAvgPrice = StringVar(root, value='105.00')

app = Application(root)

root.mainloop()


 ¬¬¬¬¬¬¬¬¬¬Saturday, 3 February 2018
Scrolling 2 text widgets together
I am using the pack() Geometry Manager to place all of the widgets. 
I opted for the pack() Manager because it is ideal for placing widgets side by side or drop down position. 
Fortunately, in a text editor, I have all the widgets Placed next to each other or in descending order. 
It is therefore advantageous to the pack() Manager. We can do the same with the grid() manager also.

# Craig Hammond 2018

import tkinter as tk
from tkinter import *


from tkinter import ttk
import re

class SampleTextApp(Frame):
    def __init__(self, master, **kwargs):# this **kwargs is needed for the scroll bar
        ttk.Frame.__init__(self, master)
        self.file_name = None
        self.grid()
        self.create_widgets()

    def create_widgets(self):

        # font varialble to use with all widgets
        my_font = ('', 18)
        
        # add a text box for the line numbers
        self.line_number_text = Text(self, font=my_font, width=4, padx=3, takefocus=0, border=0, background='yellow', state='disabled', wrap='none')
        self.line_number_text.pack(side='left', fill='y')
        
        # add the main text box widget here
        self.main_text = Text(self, font=my_font, wrap='none')
        self.main_text.bind('<KeyPress>', self.on_text_changed)
        self.main_text.pack(expand='yes', fill='both')
        
        # add a scroll bar for the main text widget
        self.scroll_bar = Scrollbar(self.main_text)
        self.scroll_bar.pack(side='right', fill='y')

        # call the scroll bar functions
        self.scroll_bar['command'] = self.on_scrollbar
        self.line_number_text['yscrollcommand'] = self.on_textscroll
        self.main_text['yscrollcommand'] = self.on_textscroll
# this will update the line numbers any time you
        # press a key on the keyboard
        self.main_text.bind('<Any-KeyPress>', self.on_text_changed)
        self.main_text.focus_set()
   
    def on_scrollbar(self, *args):
        self.line_number_text.yview(*args)
        self.main_text.yview(*args)
        
    def on_textscroll(self, *args):
        # Moves scrollbar and scrolls text widgets when the mouse wheel
        # is moved on the text widget
        self.scroll_bar.set(*args)
        self.on_scrollbar('moveto', args[0])
        
    def on_text_changed(self, event=None):
        self.update_line_numbers()
    
    def get_line_numbers(self):
        output = ''
        row, col = self.main_text.index("end").split('.')
        for i in range(1, int(row)):
            output += str(i) + '\n'
        return output

    def update_line_numbers(self, event=None):
        line_numbers = self.get_line_numbers()
        # disables the text widget so the widget does not scroll
        self.main_text.config(state='disabled')
        self.line_number_text.config(state='normal') 
        self.line_number_text.delete('1.0', 'end')
        self.line_number_text.insert('1.0', line_numbers)
        self.line_number_text.config(state='disabled')
        # returns the text widget back to normal
        self.main_text.config(state='normal')

root = Tk()
PROGRAM_NAME = ' My Text Editor '
root.title(PROGRAM_NAME)
root.geometry("600x300")
app = SampleTextApp(root)
app.pack(fill='both', expand='yes')
app.mainloop()

 ¬¬¬¬¬¬¬¬¬¬Sunday, 10 February 2019
Change color heading of a treeview widget in Python 3

This is the code for changing the color heading in a Treeview Widget

https://sharpertradingimage.blogspot.com/2019/02/change-color-heading-of-treeview-widget.html

        style = ttk.Style()
        style.element_create("Custom.Treeheading.border", "from", "default")
        style.layout("Custom.Treeview.Heading", [
            ("Custom.Treeheading.cell", {'sticky': 'nswe'}),
            ("Custom.Treeheading.border", {'sticky':'nswe', 'children': [
                ("Custom.Treeheading.padding", {'sticky':'nswe', 'children': [
                    ("Custom.Treeheading.image", {'side':'right', 'sticky':''}),
                    ("Custom.Treeheading.text", {'sticky':'we'})
                ]})
            ]}),
        ])
        style.configure("Custom.Treeview.Heading",
            background="green", foreground="white", relief="flat")
        style.map("Custom.Treeview.Heading",
            relief=[('active','groove'),('pressed','sunken')])

        # create Treeview datagridview
        self.tv = ttk.Treeview(self,  height=8, style= "Custom.Treeview")
        #self.tv.grid(row=3, column=0)
        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

 ¬¬¬¬¬¬¬¬¬¬Thursday, 14 July 2016
 Python Code Combo box example
Python Combobox example:
on Enter event, when the enter key is pressed. 
changes text to uppercase. adds item to list if not in the drop down list. 
highlights, selects all text, this allows you to keep typing a new symbol 
without placing your mouse in the box and erasing the previous symbol so you can type a new one.

https://sharpertradingimage.blogspot.com/2018/01/python-code-combo-box-example.html
https://youtu.be/-E7d7Tbszpc

# Craig Hammond 2016
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.grid()  
     self.create_widgets()  
   def create_widgets(self):  
     """ create the window layout. """  
     myFont = ('Lucida Grande', 12)  
     #create Label Symbol  
     self.label2 = Label(self, font=myFont, text="Symbol").grid(row=0, column=0)  
     # create combobox for the symbol  
     self.cbSymbol = ttk.Combobox(self, font=myFont, width=7, 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=0, column =1,sticky = W)  
   def cbSymbol_onEnter(self, event):  
     # changes characters to upper case  
     varSymbol.set(varSymbol.get().upper())  
     # gets the value of the text in the combobox. cbSymbol  
     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)  
     print(mytext)  
     # 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, ))  
     return 'break'   
root = Tk()  
root.title("Combobox")  
root.geometry("600x480")  
varSymbol = StringVar(root, value='NFLX')  
app = Application(root)  
root.mainloop()  

Spinbox Example Link
Learn how to increase the increment value programmatically
use the Control key and mouse click to increase the value by 10 cents and back to 1 cent  

 ¬¬¬¬¬¬¬¬¬¬Sunday, 17 July 2016
Python Spinbox example
Change spinbox increment value programmatically from 10 cents to 1 cent, using control click arrow up or down. 
Format for 8 characters and 2 decimal places, this should be include otherwise you can get different numbers.

https://sharpertradingimage.blogspot.com/2018/01/python-spinbox-example.html

https://youtu.be/flrNuZ57hYI

Please comment below if you have a better way of doing the same basic thing. please see link below for other example using a combobox

 # Craig Hammond  
 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.grid()  
     self.create_widgets()
     self.increment_switch = True  # used as a switch

   def create_widgets(self):  
     """ create the window layout. """  
     myFont = ('Lucida Grande', 12)  
     #create Label Limit Price  
     self.label2 = Label(self, font=myFont, text="Limit Price").grid(row=0, column=0)   
     # create a Spinbox  
     self.spinLimitPrice = Spinbox(self, 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 spinLimitDime()  
     self.spinLimitPrice.bind('<Control-Button-1>', self.spinLimitDime)  
     self.spinLimitPrice.grid(row=2, column=3)

   def spinLimitIncrement(self, event):
       if self.increment_switch == True:
           self.spinLimitPrice.configure(increment=0.10)
           self.increment_switch = False
       else:
           self.spinLimitPrice.configure(increment=0.01)
           self.increment_switch = True 
 root = Tk()  
 root.title("Spinbox")  
 root.geometry("600x480")  
 varLimitPrice = StringVar()  
 app = Application(root)  
 root.mainloop()  

 If you have a better way of doing this, please comment below Python code for combobox link

 ¬¬¬¬¬¬¬¬¬¬Saturday, 8 October 2016
Historical 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

 https://youtu.be/o8zGr6P-x8w

 https://sharpertradingimage.blogspot.com/2018/01/historical-data-examples-stocks-options.html


  ¬¬¬¬¬¬¬¬¬¬Saturday, 8 October 2016
IB TWS Historical Data in Python
https://youtu.be/2Gb1I2m6fno
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 box settingsAPI 2              
http://localhost/Sharper2/wp-content/uploads/2016/06/settingsAPI-2.jpg


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

# make sure this is included in the connect_to_tws function
self.register_callback_functions()


https://youtu.be/5rL1AvcD5RU

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
http://xavierib.github.io/twsapidocs/historical_limitations.html

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


 ¬¬¬¬¬¬¬¬¬¬

 ¬¬¬¬¬¬¬¬¬¬

 ¬¬¬¬¬¬¬¬¬¬