Advertisement
Guest User

DAS Program Trading Model

a guest
Mar 31st, 2017
133
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 69.15 KB | None | 0 0
  1. # trading model for use with the DAS Program artificial financial market environment
  2. # this code should be used with the Stock Exchange API service
  3. # written by Gregory Cave on the 25th of January 2017
  4. # last updated on the 15th of March 2017
  5. # developed in a Python 3 programming environment
  6.  
  7. # ====================================================================================
  8.  
  9. # import the main modules
  10.  
  11. import json
  12. import math
  13. import os
  14. import pickle
  15. import random
  16. import sys
  17. import time
  18. import urllib
  19.  
  20. # ====================================================================================
  21.  
  22. # import the tkinter modules
  23.  
  24. from tkinter import *
  25. from tkinter import ttk
  26. from tkinter.font import Font
  27. from tkinter.messagebox import *
  28.  
  29. # ====================================================================================
  30.  
  31. # append the filepath to import models
  32.  
  33. sys.path.append('models')
  34.  
  35. # import stock models
  36.  
  37. import news
  38. import notification
  39. import order
  40. import stock
  41. import stock_history
  42. import transaction
  43. import user
  44. import user_stocks
  45.  
  46. # ====================================================================================
  47.  
  48. # class for main application
  49.  
  50. class App(ttk.Frame):
  51.    
  52.     # class variable to track direction of column
  53.     # header sort
  54.     SortDir = True     # descending
  55.  
  56.     # ================================================================================
  57.     # init for app class
  58.     # ================================================================================
  59.    
  60.     def __init__(self, isapp=True, name='model'):
  61.         ttk.Frame.__init__(self, name=name) # app frame for init
  62.         self.pack(expand=Y, fill=BOTH) # app screen properties (pack) for init
  63.         self.master.title('DAS Program Trading Model') # app title for init
  64.         self.master.wm_state('zoomed')
  65.         #self.master.resizable(width=False, height=False) # uncomment for disable resizing
  66.         self.width=self.master.winfo_screenwidth()
  67.         self.height=self.master.winfo_screenheight()
  68.         self.isapp = isapp # isapp for init
  69.         self.__vars = {} # menu vars for init
  70.         self.logged_in=False
  71.         self._create_panel()
  72.  
  73.     # ================================================================================
  74.     # load stock data function (with API)
  75.     # ================================================================================
  76.        
  77.     def _load_stock_data(self):
  78.         self.data = [
  79.             ('DAAS', '74.74', '73.52', '75.92', '76.91', '68.22', '75.51', '187', '-1'),
  80.             ('KAYT', '69.22', '67.33', '78.13', '77.29', '65.65', '73.25', '643', '-1'),
  81.             ('EQNX', '63.57', '62.29', '65.44', '67.55', '58.92', '64.00', '266', '-1')]
  82.                  
  83.         # configure column headings
  84.         for c in self.dataCols:
  85.             self.tree.heading(c, text=c.title(),
  86.                                 command=lambda c=c: self._column_sort(c, App.SortDir))          
  87.             self.tree.column(c, width=Font().measure(c.title()))
  88.              
  89.         # add data to the tree
  90.         for item in self.data:
  91.             self.tree.insert('', 'end', values=item)
  92.              
  93.             # and adjust column widths if necessary
  94.             for idx, val in enumerate(item):
  95.                 iwidth = Font().measure(val)
  96.                 if self.tree.column(self.dataCols[idx], 'width') < iwidth:
  97.                     self.tree.column(self.dataCols[idx], width = iwidth)
  98.  
  99.     # ================================================================================
  100.     # load news data function (with API)
  101.     # ================================================================================
  102.        
  103.     def _load_news_data(self):
  104.         id=1
  105.         user_id=1
  106.        
  107.         if user_id == 1:
  108.             author='Gregory Cave'
  109.            
  110.         stock_id=()
  111.         title='Debt Advice Specialist (DAS) Program for Investors'
  112.         intro='DAS Program Remains Popular with the Shareholders of AMP'
  113.         created_at='FEB 20 AT 21:36'
  114.        
  115.         body = ["The Debt Advice Specialist (DAAS) stock took a steep dive today ",
  116.          "after certain individuals decided they would sell their $371.32 shares ",
  117.          "for a mere $5! The result is shown in the graph below, ",
  118.          "where the stock peaked at $371 ",
  119.          "and dipped down to $5 where it stuck for a while. "]
  120.        
  121.         self.news = [id, author, stock_id, title, intro, body, created_at]
  122.  
  123.     # ================================================================================
  124.     # load users data function (with API)
  125.     # ================================================================================
  126.        
  127.     def _load_user_data(self):
  128.  
  129.         users=open(user_file, 'rb')
  130.        
  131.         self.data = []
  132.  
  133.         end_of_file=False
  134.    
  135.         while not end_of_file:
  136.          
  137.             try:
  138.                 # Unpickle the next object.
  139.                 user = pickle.load(users)
  140.  
  141.                 user_id = user.get_id()
  142.                 first_name = user.get_first_name()
  143.                 last_name = user.get_last_name()
  144.                 cash=user.get_cash()
  145.                 account_value=user.get_account_value(user_id, cash, stocks_file, user_stocks_file)
  146.                 name= first_name + " " + last_name
  147.  
  148.                 # Add the user to self.data
  149.                 self.data.append(['1st', name, account_value, cash])
  150.                
  151.             except EOFError:
  152.                 # Set the flag to indicate the end
  153.                 # of the file has been reached
  154.                 end_of_file = True
  155.  
  156.         # Close the file
  157.         users.close()
  158.                  
  159.         # configure column headings
  160.         for c in self.dataCols:
  161.             self.tree.heading(c, text=c.title(),
  162.                                 command=lambda c=c: self._column_sort(c, App.SortDir))          
  163.             self.tree.column(c, width=Font().measure(c.title()))
  164.              
  165.         # add data to the tree
  166.         for item in self.data:
  167.             self.tree.insert('', 'end', values=item)
  168.              
  169.             # and adjust column widths if necessary
  170.             for idx, val in enumerate(item):
  171.                 iwidth = Font().measure(val)
  172.                 if self.tree.column(self.dataCols[idx], 'width') < iwidth:
  173.                     self.tree.column(self.dataCols[idx], width = iwidth)
  174.  
  175.     # ================================================================================
  176.     # column sort function for market data feed
  177.     # ================================================================================
  178.  
  179.     def _column_sort(self, col, descending=False):
  180.          
  181.         # grab values to sort as a list of tuples (column value, column id)
  182.         data = [(self.tree.set(child, col), child) for child in self.tree.get_children('')]
  183.          
  184.         # reorder data
  185.         # tkinter looks after moving other items in
  186.         # the same row
  187.         data.sort(reverse=descending)
  188.         for indx, item in enumerate(data):
  189.             self.tree.move(item[1], '', indx)   # item[1] = item Identifier
  190.          
  191.         # reverse sort direction for next sort operation
  192.         App.SortDir = not descending
  193.  
  194.     # ================================================================================
  195.     # configure text styles function (for user interface)
  196.     # ================================================================================
  197.  
  198.     def _create_styles(self):
  199.         # font styles
  200.         family = 'Courier'      # font family
  201.          
  202.         self.text.tag_configure('bold', font=(family, 12, 'bold', 'italic'))
  203.         self.text.tag_configure('big', font=(family, 14, 'bold'))
  204.         self.text.tag_configure('verybig', font=('Helvetica', 24, 'bold'))
  205.         self.text.tag_configure('tiny', font=('Times', 8, 'bold'))
  206.         self.text.tag_configure('underline', underline='on')
  207.         self.text.tag_configure('overstrike', overstrike='on')
  208.         self.text.tag_configure('super', offset='4p', font=(family, 10))
  209.         self.text.tag_configure('sub', offset='-2p', font=(family, 10))
  210.          
  211.         # foreground/background styles
  212.         self.text.tag_configure('bgstipple', background='black',
  213.                            borderwidth=0, bgstipple='gray12')
  214.                            
  215.         self.text.tag_configure('fgstipple', foreground='blue', fgstipple='gray50')
  216.         self.text.tag_configure('color1', background='#a0b7ce')
  217.         self.text.tag_configure('color2', foreground='red')
  218.         self.text.tag_configure('raised', relief=RAISED, borderwidth=1)
  219.         self.text.tag_configure('sunken', relief=SUNKEN, borderwidth=1)
  220.          
  221.         # margins, spacing, and alignment
  222.         self.text.tag_configure('right', justify='right')
  223.         self.text.tag_configure('center', justify='center')
  224.         self.text.tag_configure('margins', lmargin1='12m', lmargin2='6m',
  225.                            rmargin='10m')
  226.                            
  227.         self.text.tag_configure('spacing', spacing1='10p', spacing2='2p',
  228.                            lmargin1='12m', lmargin2='6m', rmargin='10m')
  229.        
  230.     # ================================================================================
  231.     # create panel function (for user interface)
  232.     # ================================================================================
  233.    
  234.     def _create_panel(self):
  235.         # create Panel
  236.         self.panel = Frame(self, name='model')
  237.         self.panel.pack(side=TOP, fill=BOTH, expand=Y)
  238.        
  239.         # create statusbar
  240.         statusBar = ttk.Frame()
  241.         self.__status = ttk.Label(self.master, text=' ', relief=SUNKEN, borderwidth=1,
  242.                               font=('Helv 10'), anchor=W, name='status')
  243.        
  244.         # pack statusbar
  245.         self.__status.pack(side=LEFT, padx=2, expand=Y, fill=BOTH)
  246.         statusBar.pack(side=BOTTOM, fill=X, pady=2)
  247.                  
  248.         self._create_submenus()
  249.  
  250.        
  251.         # create structure and windows
  252.         self._create_window()
  253.         self._stock_pane()
  254.         self._home()
  255.  
  256.     # ================================================================================
  257.     # create window structure function (for user interface)
  258.     # ================================================================================
  259.  
  260.     def _create_window(self):
  261.         self.outer = ttk.PanedWindow(self.panel, orient=HORIZONTAL, name='outer')
  262.         self.outer.pack(expand=Y, fill=BOTH, padx=10, pady=(6,10))
  263.        
  264.         self.left = ttk.PanedWindow(self.outer, orient=VERTICAL, name='left')
  265.         self.right = ttk.PanedWindow(self.outer, orient=VERTICAL, name='right')
  266.         self.outer.add(self.left)
  267.         self.outer.add(self.right)
  268.          
  269.         ltop = ttk.LabelFrame(self.left, text='Stocks', padding=3, name='ltop')
  270.         self.left.add(ltop)
  271.        
  272.         rtop = ttk.LabelFrame(self.right, padding=3, name='rtop')
  273.         self.right.add(rtop)
  274.  
  275.     # ================================================================================
  276.     # create submenus function (for user interface)
  277.     # ================================================================================
  278.  
  279.     def _create_submenus(self):
  280.         # create the submenus
  281.         # the routines are essentially the same:
  282.         #    1. create the submenu, passing the main menu as parent
  283.         #    2. add the submenu to the main menu as a 'cascade'
  284.         #    3. add the submenu's individual items
  285.  
  286.         # try and except to destroy the menu if it already exists e.g. for user login        
  287.         try:
  288.             self._menu.destroy()
  289.         except:
  290.             pass
  291.  
  292.         # create the main menu (only displays if child of the 'root' window)
  293.         self.master.option_add('*tearOff', False)  # disable all tearoff's
  294.         self._menu = Menu(self.master, name='menu')
  295.        
  296.         self._create_home_menu()
  297.         self._create_stocks_menu()
  298.         self._create_news_menu()
  299.         self._create_users_menu()
  300.         self._create_support_menu()
  301.  
  302.         self.master.config(menu=self._menu)
  303.          
  304.         # set up standard bindings for the Menu class
  305.         # (essentially to capture mouse enter/leave events)
  306.         self._menu.bind_class('Menu', '<<MenuSelect>>', self._update_command)
  307.        
  308.     # ================================================================================
  309.     # create home menu function (for user interface)
  310.     # ================================================================================
  311.    
  312.     def _create_home_menu(self):
  313.         self.home_menu = Menu(self._menu, name='home_menu')
  314.         self._menu.add_cascade(label='Home', menu=self.home_menu, underline=0)
  315.  
  316.         # if the user is logged in, show the user's cash and name
  317.         if self.logged_in == True:
  318.             self.home_menu.add_command(label=self.cash, state='disabled')
  319.             self.home_menu.add_command(label=self.name, state='disabled')
  320.         self.home_menu.add_command(label='Home', underline=6,
  321.                             command=lambda: self._home())
  322.        
  323.         if self.logged_in == True:
  324.             # if the user is an admin, show the admin panel
  325.             if self.admin == True:
  326.                 self.home_menu.add_command(label='Admin', underline=6,
  327.                     command=lambda: self._admin())
  328.             else:
  329.                 self.home_menu.add_command(label='Admin', underline=6, state='disabled',
  330.                     command=lambda: self._admin())
  331.             self.home_menu.add_command(label='Profile', underline=6,
  332.                 command=lambda: self._profile())
  333.             self.home_menu.add_command(label='Logout', underline=6,
  334.                 command=lambda: self._logout())
  335.            
  336.         else:
  337.             self.home_menu.add_command(label='Register', underline=6,
  338.                 command=lambda: self._registration())
  339.             self.home_menu.add_command(label='Login', underline=6,
  340.                 command=lambda: self._login())
  341.            
  342.         self.home_menu.add_separator()
  343.         self.home_menu.add_command(label='Exit',
  344.                           command=lambda: self.master.destroy()) # kill toplevel window
  345.          
  346.     # ================================================================================
  347.     # create stocks menu function (for user interface)
  348.     # ================================================================================
  349.    
  350.     def _create_stocks_menu(self):
  351.        
  352.         self.stocks_menu = Menu(self._menu, name='stocks_menu')
  353.         self._menu.add_cascade(menu=self.stocks_menu, label='Stocks', underline=0)
  354.  
  355.         #_____________________________________________________________________________
  356.        
  357.         def create_order_menu(self, cascades):
  358.             # build Cascades->Radio Buttuns subment
  359.             submenu = Menu(cascades)
  360.             cascades.add_cascade(label='Create Order', underline=0,
  361.                                    menu=submenu)
  362.          
  363.             self.__vars['size'] = StringVar()
  364.             self.__vars['font'] = StringVar()
  365.          
  366.             for item in ('Buy Order', 'Sell Order'):
  367.                submenu.add_radiobutton(label='{}'.format(item),
  368.                                     variable=self.__vars['size'])
  369.  
  370.         create_order_menu(self, self.stocks_menu)
  371.  
  372.         self.stocks_menu.add_command(label='Stock Data', underline=6,
  373.             command=lambda: self._stock_data())
  374.  
  375.     # ================================================================================
  376.     # create news menu function (for user interface)
  377.     # ================================================================================
  378.    
  379.     def _create_news_menu(self):
  380.        
  381.         self._menu.add_command(label='News', underline=0, command=lambda: self._news())
  382.  
  383.     # ================================================================================
  384.     # create users menu function (for user interface)
  385.     # ================================================================================
  386.    
  387.     def _create_users_menu(self):
  388.        
  389.         self._menu.add_command(label='Users', underline=0, command=lambda: self._users())
  390.  
  391.     # ================================================================================
  392.     # create help & support menu function (for user interface)
  393.     # ================================================================================
  394.    
  395.     def _create_support_menu(self):
  396.        
  397.         self._menu.add_command(label='Help & Support', underline=0, command=lambda: self._support())
  398.  
  399.     # ================================================================================
  400.     # Bound and Command methods
  401.     # ================================================================================
  402.    
  403.     def _print_command(self, e, txt):
  404.        
  405.         # triggered by multiple menu items that print letters or greetings
  406.         # or by an accelerator keypress (CTRL+A, CTRL+B, etc).
  407.         print(txt)
  408.  
  409.     #_________________________________________________________________________________
  410.    
  411.     def _update_command(self, evt):
  412.        
  413.         # triggered on mouse entry if a menu item has focus
  414.         # (focus occurs when user clicks on a top level menu item)
  415.         try:
  416.             item = self.tk.eval('%s entrycget active -label' % evt.widget )
  417.             self.__status.configure(background='gray90', foreground='black',
  418.                                     text=item)
  419.         except TclError:
  420.             # no label available, ignore
  421.             pass
  422.        
  423.     # ================================================================================
  424.     # frame construction method(s)
  425.     # ================================================================================
  426.  
  427.     def _create_rtop(self, current_tab):
  428.  
  429.         # create the top right position for use in the frame
  430.         rtop = ttk.LabelFrame(self.right, text=current_tab, padding=3, name='rtop')
  431.         return rtop
  432.  
  433.     #_________________________________________________________________________________
  434.  
  435.     def _create_frame(self, rtop):
  436.  
  437.         # try and except to destroy the frame if it exists
  438.         # so that a new frame can be created
  439.         try:
  440.             self.frame.destroy()
  441.         except:
  442.             pass
  443.  
  444.         # create the new frame using the top right position variable (rtop)
  445.         self.frame = ttk.Frame(rtop)
  446.        
  447.         # set frame resize priorities
  448.         self.frame.rowconfigure(1, weight=1)
  449.         self.frame.columnconfigure((0,1), weight=1, uniform=1)
  450.  
  451.         # pack the frame
  452.         self.frame.pack(expand=Y, fill=BOTH)
  453.  
  454.     # ================================================================================
  455.     # canvas construction method
  456.     # ================================================================================
  457.  
  458.     def _create_canvas(self, current_tab):
  459.  
  460.         # create and add the submenus
  461.         self._create_submenus()
  462.        
  463.         # create and add frame widget
  464.         rtop = self._create_rtop(current_tab)
  465.         self.right.add(rtop)
  466.         self._create_frame(rtop)
  467.  
  468.     # ================================================================================
  469.     # notebook construction method
  470.     # ================================================================================
  471.  
  472.     def _create_notebook(self, name):
  473.        
  474.         self.nb = ttk.Notebook(self.frame, name=name)
  475.  
  476.         # extend bindings to top level window allowing
  477.         #   CTRL+TAB - cycles through tabs
  478.         #   SHIFT+CTRL+TAB - previous tab
  479.         #   ALT+K - select tab using mnemonic (K = underlined letter)
  480.         self.nb.enable_traversal()
  481.  
  482.         self.nb.pack(fill=BOTH, expand=Y, padx=2, pady=3)
  483.  
  484.     # ================================================================================
  485.     # label construction method
  486.     # ================================================================================
  487.  
  488.     def _create_label(self, frame):
  489.  
  490.         # create and add label
  491.         self.label = ttk.Label(frame, justify=LEFT, anchor=N)
  492.              
  493.         # position and set resize behaviour
  494.         self.label.grid(row=0, column=0, columnspan=2, sticky='new', pady=5)
  495.  
  496.     # ================================================================================
  497.     # text construction method
  498.     # ================================================================================
  499.  
  500.     def _create_text(self):
  501.  
  502.         # create text styles
  503.         self.text = Text(self.label, height=self.height, width=self.width, setgrid=True, wrap=WORD,
  504.                     undo=True, pady=2, padx=3)
  505.  
  506.         self._create_styles()
  507.  
  508.     # ================================================================================
  509.     # seperator construction method
  510.     # ================================================================================
  511.  
  512.     def _create_seperator(self):
  513.  
  514.         self.text.insert(END, '\n\n')
  515.        
  516.         for each in range (0, 110):
  517.             self.text.insert(END, '_')
  518.  
  519.         self.text.insert(END, '\n\n')
  520.  
  521.     # ================================================================================
  522.     # home section function
  523.     # ================================================================================
  524.            
  525.     def _home(self):
  526.         self._create_canvas('Home')
  527.  
  528.     # ================================================================================
  529.     # stocks function (using data from self._load_data())
  530.     # ================================================================================
  531.            
  532.     def _stock_data(self):
  533.         self._create_canvas('Market Data')
  534.  
  535.         #_____________________________________________________________________________
  536.        
  537.         def create_header(self):
  538.             self.text = Text(self.frame, height=6, width=self.width, setgrid=True, wrap=WORD,
  539.                         undo=True, pady=2, padx=3)
  540.  
  541.             self._create_styles()
  542.  
  543.             self.text.insert(END, "\nStocks", 'big')
  544.             self.text.insert(END, "\n\nBrowse the stocks available that are currently trading. You must be logged in to trade stocks.", 'bold')
  545.  
  546.             # position in frame and set resize constraints
  547.             self.text.grid(row=0, columnspan=2)
  548.            
  549.             # set text state to disabled
  550.             self.text.config(state=DISABLED)
  551.  
  552.         #_____________________________________________________________________________
  553.  
  554.         def create_table(self):
  555.            
  556.             # create the tree
  557.             self.dataCols = ('Stock', 'Price ($)', 'Bid ($)', 'Offer ($)', 'High ($)', 'Low ($)', 'Last Close ($)', 'Volume', 'Change (%)')      
  558.             self.tree = ttk.Treeview(columns=self.dataCols,
  559.                                              show = 'headings')
  560.             # add tree to frame
  561.             self.tree.grid(in_=self.frame, row=1, column=0, columnspan=4, sticky="nsew")
  562.  
  563.             self._load_stock_data()
  564.  
  565.         #_____________________________________________________________________________
  566.  
  567.         create_header(self)
  568.         create_table(self)
  569.  
  570.     # ================================================================================
  571.     # account registration function
  572.     # ================================================================================
  573.  
  574.     def _registration(self):
  575.         self._create_canvas('Register')
  576.  
  577.     # ================================================================================
  578.     # account login function
  579.     # ================================================================================
  580.  
  581.     def _login(self):
  582.  
  583.         self._create_canvas('Login')
  584.  
  585.         #_____________________________________________________________________________
  586.  
  587.         def create_login():
  588.             demoPanel = Frame(self.frame)
  589.             demoPanel.pack(side=TOP, fill=X)
  590.              
  591.             self.flds = []  # entry fields
  592.             lbls = ['Email Address:','Password:']
  593.          
  594.             for i in range(2):
  595.                 f = ttk.Frame()
  596.                 f.pack(in_=demoPanel, side=TOP, fill=X, padx=10)
  597.                  
  598.                 lbl = ttk.Label(text=lbls[i], width=15)
  599.                 e = ttk.Entry(width=20)
  600.                 self.flds.append(e) # save reference to field
  601.                  
  602.                 # on resize, expand entry but not label
  603.                 lbl.pack(in_=f, side=LEFT)
  604.                 e.pack(in_=f, side=LEFT, expand=Y, fill=X)
  605.                  
  606.             self.flds[0].focus_set()
  607.  
  608.         #_____________________________________________________________________________
  609.        
  610.         def do_login():
  611.  
  612.             users=open(user_file, 'rb')
  613.            
  614.             self.data = []
  615.  
  616.             end_of_file=False
  617.        
  618.             while not end_of_file:
  619.              
  620.                 try:
  621.                     # Unpickle the next object.
  622.                     user = pickle.load(users)
  623.  
  624.                     first_name = user.get_first_name()
  625.                     last_name = user.get_last_name()
  626.                    
  627.                     if user.get_id() == 1:
  628.                        
  629.                         self.logged_in=True
  630.                         self.name= first_name + " " + last_name
  631.                         self.admin = user.get_admin()
  632.                         self.cash=user.get_cash()
  633.                    
  634.                 except EOFError:
  635.                     # Set the flag to indicate the end
  636.                     # of the file has been reached
  637.                     end_of_file = True
  638.  
  639.             # Close the file
  640.             srchStr = StringVar()
  641.             e = ttk.Entry(width=40, textvariable=srchStr)
  642.             e.pack(in_=self.frame, side=LEFT)
  643.  
  644.             btn = ttk.Button(text='Search',
  645.                              command=lambda ss=srchStr: search_text(self, ss.get()))
  646.             btn.pack(in_=self.frame, side=LEFT, padx=10, pady=5)
  647.  
  648.             # 'Return' triggers button routine
  649.             e.bind('<Return>', lambda evt, btn=btn: btn.invoke())
  650.  
  651.             self.frame.grid(row=0, column=0, sticky="nsew")
  652.             self._home()
  653.  
  654.         #_____________________________________________________________________________
  655.  
  656.         create_login()
  657.         #do_login()
  658.  
  659.     # ================================================================================
  660.     # profile section function
  661.     # ================================================================================
  662.  
  663.     def _profile(self):
  664.         self._create_canvas('Profile')
  665.  
  666.     # ================================================================================
  667.     # orders function
  668.     # ================================================================================
  669.  
  670.     def _orders(self):
  671.         self._create_canvas('Create Order')
  672.  
  673.     # ================================================================================
  674.     # news function
  675.     # ================================================================================
  676.  
  677.     def _news(self):
  678.         self._create_canvas('News')
  679.  
  680.         #_____________________________________________________________________________
  681.        
  682.         def search_text(self, srchString):
  683.             # remove previous search results
  684.             self.text.tag_remove('search', 0.0, END)
  685.              
  686.             # empty search string?
  687.             if not srchString:
  688.                 return 'break'  # don't propagate event
  689.            
  690.             cur = 1.0         # current position
  691.             length = IntVar() # num of matched chars
  692.             while True:
  693.                 cur = self.text.search(srchString,
  694.                                        cur, END,
  695.                                        count=length)
  696.                 if not cur:
  697.                     return 'break'
  698.                  
  699.                 # 'end' position of matched characters
  700.                 matchEnd = '{0}+{1}c'.format(cur, length.get())
  701.                  
  702.                 self.text.tag_add('search', cur, matchEnd)
  703.                 cur = self.text.index(matchEnd)
  704.                
  705.         #_____________________________________________________________________________
  706.  
  707.         def create_search_panel(self):
  708.            
  709.             self.label=ttk.Label(text='Search News: ',
  710.                     width=13, anchor=W).pack(in_=self.frame, side=LEFT)
  711.  
  712.             srchStr = StringVar()
  713.             e = ttk.Entry(width=40, textvariable=srchStr)
  714.             e.pack(in_=self.frame, side=LEFT)
  715.  
  716.             btn = ttk.Button(text='Search',
  717.                              command=lambda ss=srchStr: search_text(self, ss.get()))
  718.             btn.pack(in_=self.frame, side=LEFT, padx=10, pady=5)
  719.  
  720.             # 'Return' triggers button routine
  721.             e.bind('<Return>', lambda evt, btn=btn: btn.invoke())
  722.  
  723.             self.frame.grid(row=0, column=0, sticky="nsew")
  724.  
  725.         #_____________________________________________________________________________
  726.  
  727.         def create_text_panel(self):
  728.        
  729.             # create scrolled text widget
  730.  
  731.             rtop = self.nametowidget('model.outer.right.rtop')
  732.            
  733.             txtFrame = ttk.Frame(rtop)
  734.             txtFrame.grid(row=1, column=0, sticky="nsew")
  735.              
  736.             self.text = Text(txtFrame, height=20, setgrid=True, wrap=WORD,
  737.                         undo=True, pady=2, padx=3)
  738.  
  739.             self._create_styles()
  740.            
  741.             xscroll = ttk.Scrollbar(txtFrame, command=self.text.xview,
  742.                                     orient=HORIZONTAL)
  743.            
  744.             yscroll = ttk.Scrollbar(txtFrame, command=self.text.yview,
  745.                                     orient=VERTICAL)
  746.            
  747.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  748.              
  749.             # configure 'search' style tag
  750.             self.text.tag_configure('search', background='yellow')
  751.              
  752.             # position in frame and set resize constraints
  753.             self.text.grid(row=0, columnspan=2)
  754.             yscroll.grid(row=0, column=1, sticky=NSEW)
  755.             txtFrame.rowconfigure(0, weight=1)
  756.             txtFrame.columnconfigure(0, weight=1)
  757.              
  758.             # add text to scrolled text widget
  759.             txt = ["The Debt Advice Specialist (DAAS) stock took a steep dive today ",
  760.                    "after certain individuals decided they would sell their $371.32 shares ",
  761.                    "for a mere $5! The result is shown in the graph below, ",
  762.                    "where the stock peaked at $371 ",
  763.                    "and dipped down to $5 where it stuck for a while. "]
  764.      
  765.             self.text.insert(END, ''.join(txt))
  766.        
  767.         #_____________________________________________________________________________
  768.  
  769.         create_search_panel(self)
  770.         create_text_panel(self)
  771.            
  772.     # ================================================================================
  773.     # users function
  774.     # ================================================================================
  775.  
  776.     def _users(self):
  777.         self._create_canvas('Users')
  778.  
  779.         #_____________________________________________________________________________
  780.    
  781.         def create_header(self):
  782.             self.text = Text(self.frame, height=6, width=self.width, setgrid=True, wrap=WORD,
  783.                         undo=True, pady=2, padx=3)
  784.  
  785.             self._create_styles()
  786.  
  787.             self.text.insert(END, "\nUsers", 'big')
  788.             self.text.insert(END, "\n\nValues shown here do NOT include stocks managed by the user.", 'bold')
  789.  
  790.             # position in frame and set resize constraints
  791.             self.text.grid(row=0, columnspan=2)
  792.            
  793.             # set text state to disabled
  794.             self.text.config(state=DISABLED)
  795.  
  796.         #_____________________________________________________________________________
  797.        
  798.         def create_table(self):
  799.             # create the tree
  800.             self.dataCols = ('Rank', 'User', 'Account Value ($)', 'Cash ($)')      
  801.             self.tree = ttk.Treeview(columns=self.dataCols,
  802.                                              show = 'headings')
  803.             # add tree to frame
  804.             self.tree.grid(in_=self.frame, row=1, column=0, columnspan=4, sticky="nsew")
  805.  
  806.             self._load_user_data()
  807.  
  808.         #_____________________________________________________________________________
  809.    
  810.         create_header(self)
  811.         create_table(self)
  812.  
  813.     # ================================================================================
  814.     # help & support section function
  815.     # ================================================================================
  816.  
  817.     def _support(self):
  818.        
  819.         self._create_canvas('Help & Support')
  820.    
  821.         # create and add notebook
  822.         name='support'
  823.         self._create_notebook(name)
  824.  
  825.         #_____________________________________________________________________________
  826.        
  827.         def create_support_getting_started(self):
  828.             frame = ttk.Frame(self.nb, name='getting_started')
  829.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  830.  
  831.             # create and add label
  832.             self._create_label(frame)
  833.  
  834.             # create and add text
  835.             self._create_text()
  836.      
  837.             # Header
  838.             self.text.insert(END, "\nGetting Started", 'big')
  839.             self.text.insert(END, "\n\nWelcome to the help and support section.")
  840.             self.text.insert(END, "\n\nThis is your resource for learning about how the stock exchange works, ")
  841.             self.text.insert(END, "as well as stock trading in general.")
  842.                            
  843.             # Seperator
  844.             self._create_seperator()
  845.  
  846.             #Body
  847.             self.text.insert(END, "How to Start Trading", 'big')
  848.             self.text.insert(END, "\n\nYou can start by buying, and selling stocks.")
  849.             self.text.insert(END, " You were given ")
  850.             self.text.insert(END, "$20000", 'bold')
  851.             self.text.insert(END, " when you first joined to help you get started. ")
  852.             self.text.insert(END, "\n\nFollow the few steps below to make your first trade.")
  853.             self.text.insert(END, "\n\n1.", 'bold')
  854.             self.text.insert(END, " Take a look at the ")
  855.             self.text.insert(END, "Debt Advice Specialist Program (DAAS)", 'bold')
  856.             self.text.insert(END, " stock and click on the ")
  857.             self.text.insert(END, "Buy" , 'bold')
  858.             self.text.insert(END, " tab.")
  859.             self.text.insert(END, "\n2.", 'bold')
  860.             self.text.insert(END, " Choose the ")
  861.             self.text.insert(END, "Market", 'bold')
  862.             self.text.insert(END, " type, leave the Quantity as 1, and set the ")
  863.             self.text.insert(END, "Expiry", 'bold')
  864.             self.text.insert(END, " to ")
  865.             self.text.insert(END, "End of Day.", 'bold')
  866.             self.text.insert(END, "\n3.", 'bold')
  867.             self.text.insert(END, " Press the ")
  868.             self.text.insert(END, "Place Bid", 'bold')
  869.             self.text.insert(END, " button.")
  870.             self.text.insert(END, "\n\nThat's all!", 'bold')
  871.             self.text.insert(END, " Within the next 5 minutes you'll ")
  872.             self.text.insert(END, "own your very own stock.", 'bold')
  873.             self.text.insert(END, "\n\nYou can then either sell the stock straight away (look out for those fees!),")
  874.             self.text.insert(END, " or keep them until the value increases and make your fortune!")
  875.  
  876.             # Seperator
  877.             self._create_seperator()
  878.  
  879.             self.text.insert(END, "What next?", 'big')
  880.             self.text.insert(END, "\n\nHead on over to the ")
  881.             self.text.insert(END, "Stocks", 'bold')
  882.             self.text.insert(END, " page and browse the other stocks available to trade.")
  883.             self.text.insert(END, "\n\nYou can also take a look at your ")
  884.             self.text.insert(END, "Portfolio", 'bold')
  885.             self.text.insert(END, " to see how your stocks are doing and look at previous orders you've placed.")
  886.  
  887.             # set text state to disabled
  888.             self.text.config(state=DISABLED)
  889.  
  890.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  891.                                 orient=HORIZONTAL)
  892.            
  893.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  894.                                 orient=VERTICAL)
  895.            
  896.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  897.  
  898.             # position in frame and set resize constraints
  899.             self.text.grid(row=0, column=0, sticky=NSEW)
  900.             yscroll.grid(row=0, column=1, sticky=NSEW)
  901.             frame.rowconfigure(0, weight=1)
  902.             frame.columnconfigure(0, weight=1)
  903.  
  904.             # pack text into notebook
  905.             self.text.pack()
  906.            
  907.             # add to notebook (underline = index for short-cut character)
  908.             self.nb.add(frame, text='Getting Started', underline=0, padding=2)
  909.  
  910.         #_____________________________________________________________________________
  911.  
  912.         def create_support_stocks(self):
  913.             frame = ttk.Frame(self.nb, name='stocks')
  914.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  915.            
  916.             # create and add label
  917.             self._create_label(frame)
  918.  
  919.             # create and add text
  920.             self._create_text()
  921.  
  922.             # Header
  923.             self.text.insert(END, "\nStocks", 'big')
  924.             self.text.insert(END, "\n\nStocks, are a virtual unit of investment in a company.")
  925.             self.text.insert(END, "\n\nThis is your resource for learning about how the stock exchange works, as well as stock trading in general.")
  926.  
  927.             # Seperator
  928.             self._create_seperator()
  929.  
  930.             # Body
  931.             self.text.insert(END, "Buying and Selling Stocks", 'big')
  932.             self.text.insert(END, "\n\nBuying and selling stocks is an investment.")
  933.             self.text.insert(END, "\n\nOver time, stocks can gain or lose value depending on multiple factors.")
  934.             self.text.insert(END, "\n\nThe value of a stock will also depend on whether a stocks price moves up or down and when you buy and sell.")
  935.             self.text.insert(END, "\n\nYou should expect to make both gains and losses.")
  936.  
  937.             # Seperator
  938.             self._create_seperator()
  939.  
  940.             #Footer
  941.             self.text.insert(END, "Stock Types", 'big')
  942.             self.text.insert(END, "\n\nThere are currently 3 different types of stock trading on the  exchange:")
  943.             self.text.insert(END, "\n\n • Company Stocks")
  944.             self.text.insert(END, "\n\n • Community Stocks")
  945.             self.text.insert(END, "\n\n • Server Stocks")
  946.            
  947.             # set text state to disabled
  948.             self.text.config(state=DISABLED)
  949.  
  950.             # create scrolled text widget
  951.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  952.                                 orient=HORIZONTAL)
  953.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  954.                                 orient=VERTICAL)
  955.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  956.  
  957.             # position in frame and set resize constraints
  958.             self.text.grid(row=0, column=0, sticky=NSEW)
  959.             yscroll.grid(row=0, column=1, sticky=NSEW)
  960.             frame.rowconfigure(0, weight=1)
  961.             frame.columnconfigure(0, weight=1)
  962.  
  963.             # pack text into notebook
  964.             self.text.pack()
  965.            
  966.             # add to notebook (underline = index for short-cut character)
  967.             self.nb.add(frame, text='Stocks', underline=0, padding=2)
  968.  
  969.         #_____________________________________________________________________________
  970.  
  971.         def create_support_buying_stocks(self):
  972.             frame = ttk.Frame(self.nb, name='buying_stocks')
  973.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  974.            
  975.             # create and add label
  976.             self._create_label(frame)
  977.  
  978.             # create and add text
  979.             self._create_text()
  980.  
  981.             # Header
  982.             self.text.insert(END, "\nBuying Stocks", 'big')
  983.             self.text.insert(END, "\n\nBuying stocks allows you to own an investment in a company, community or server.")
  984.             self.text.insert(END, "\n\nWhen buying stocks, you are not buying them directly from the exchange, but from another user.")
  985.             self.text.insert(END, "\n\nTo buy stocks, another user must have those stocks for sale.")
  986.  
  987.             # Seperator
  988.             self._create_seperator()
  989.  
  990.             # Body
  991.  
  992.             self.text.insert(END, "Buy Orders", 'big')
  993.             self.text.insert(END, "\n\nTo buy a stock, you must place a buy order which you can do from the stock's page.")
  994.             self.text.insert(END, "\n\nThere are two types of buy orders you can choose from.")
  995.             self.text.insert(END, "\n\nOrder Types", 'big')
  996.             self.text.insert(END, "\n\nA ")
  997.             self.text.insert(END, "Market Buy Order", 'bold')
  998.             self.text.insert(END, " is one that will be fulfilled at the 'current' market price.")
  999.             self.text.insert(END, "\nThe 'current' price is the price of the stock at the time the order is processed, before any transaction fees.")
  1000.             self.text.insert(END, "\n\nA ")
  1001.             self.text.insert(END, "Limit Buy Order", 'bold')
  1002.             self.text.insert(END, " is one that will be fulfilled at a maximum of the limit you set when placing the order, before any fees.")
  1003.  
  1004.             #Footer
  1005.             self.text.insert(END, "\n\nOrder Expiry", 'big')
  1006.             self.text.insert(END, "\n\nYou can set your orders to expire either at End Of Day ")
  1007.             self.text.insert(END, "(EOD)", 'bold')
  1008.             self.text.insert(END, " or Good 'Til Cancelled ")
  1009.             self.text.insert(END, "(GTC).", 'bold')
  1010.             self.text.insert(END, "\n\nEOD orders will expire at the end of the trading day (23:59:59 UTC) if they are not fulfilled, whereas GTC orders will not expire.")
  1011.            
  1012.             # set text state to disabled
  1013.             self.text.config(state=DISABLED)
  1014.  
  1015.             # create scrolled text widget
  1016.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  1017.                                 orient=HORIZONTAL)
  1018.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  1019.                                 orient=VERTICAL)
  1020.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  1021.  
  1022.             # position in frame and set resize constraints
  1023.             self.text.grid(row=0, column=0, sticky=NSEW)
  1024.             yscroll.grid(row=0, column=1, sticky=NSEW)
  1025.             frame.rowconfigure(0, weight=1)
  1026.             frame.columnconfigure(0, weight=1)
  1027.  
  1028.             # pack text into notebook
  1029.             self.text.pack()
  1030.            
  1031.             # add to notebook (underline = index for short-cut character)
  1032.             self.nb.add(frame, text='Buying Stocks', underline=0, padding=2)
  1033.  
  1034.         #_____________________________________________________________________________
  1035.  
  1036.         def create_support_selling_stocks(self):
  1037.             frame = ttk.Frame(self.nb, name='selling_stocks')
  1038.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1039.            
  1040.             # create and add label
  1041.             self._create_label(frame)
  1042.  
  1043.             # create and add text
  1044.             self._create_text()
  1045.  
  1046.             # Header
  1047.             self.text.insert(END, "\nSelling Stocks", 'big')
  1048.             self.text.insert(END, "\n\nSelling stocks allows you to sell your investment in a company, community or server.")
  1049.             self.text.insert(END, "\n\nWhen selling stocks, you are not selling them directly to the exchange, but to another user.")
  1050.             self.text.insert(END, "\n\nTo sell stocks, another user must want to buy those stocks.")
  1051.  
  1052.             # Seperator
  1053.             self._create_seperator()
  1054.  
  1055.             # Body
  1056.  
  1057.             self.text.insert(END, "Sell Orders", 'big')
  1058.             self.text.insert(END, "\n\nTo sell a stock, you must place a sell order which you can do from the stock's page.")
  1059.             self.text.insert(END, "\n\nThere are two types of sell orders you can choose from.")
  1060.             self.text.insert(END, "\n\nOrder Types", 'big')
  1061.             self.text.insert(END, "\n\nA ")
  1062.             self.text.insert(END, "Market Sell Order", 'bold')
  1063.             self.text.insert(END, " is one that will be fulfilled at the 'current' market price.")
  1064.             self.text.insert(END, "\nThe 'current' price is the price of the stock at the time the order is processed, before any transaction fees.")
  1065.             self.text.insert(END, "\n\nA ")
  1066.             self.text.insert(END, "Limit Sell Order", 'bold')
  1067.             self.text.insert(END, " is one that will be fulfilled at a minimum of the limit you set when placing the order, before any fees.")
  1068.  
  1069.             #Footer
  1070.             self.text.insert(END, "\n\nOrder Expiry", 'big')
  1071.             self.text.insert(END, "\n\nYou can set your orders to expire either at End Of Day ")
  1072.             self.text.insert(END, "(EOD)", 'bold')
  1073.             self.text.insert(END, " or Good 'Til Cancelled ")
  1074.             self.text.insert(END, "(GTC).", 'bold')
  1075.             self.text.insert(END, "\n\nEOD orders will expire at the end of the trading day (23:59:59 UTC) if they are not fulfilled, whereas GTC orders will not expire.")
  1076.            
  1077.             # set text state to disabled
  1078.             self.text.config(state=DISABLED)
  1079.  
  1080.             # create scrolled text widget
  1081.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  1082.                                 orient=HORIZONTAL)
  1083.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  1084.                                 orient=VERTICAL)
  1085.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  1086.  
  1087.             # position in frame and set resize constraints
  1088.             self.text.grid(row=0, column=0, sticky=NSEW)
  1089.             yscroll.grid(row=0, column=1, sticky=NSEW)
  1090.             frame.rowconfigure(0, weight=1)
  1091.             frame.columnconfigure(0, weight=1)
  1092.  
  1093.             # pack text into notebook
  1094.             self.text.pack()
  1095.            
  1096.             # add to notebook (underline = index for short-cut character)
  1097.             self.nb.add(frame, text='Selling Stocks', underline=0, padding=2)
  1098.  
  1099.         #_____________________________________________________________________________
  1100.  
  1101.         def create_support_order_fees(self):
  1102.             frame = ttk.Frame(self.nb, name='order_fees')
  1103.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1104.            
  1105.             # create and add label
  1106.             self._create_label(frame)
  1107.  
  1108.             # create and add text
  1109.             self._create_text()
  1110.  
  1111.             # Header
  1112.             self.text.insert(END, "\nOrder Fees", 'big')
  1113.             self.text.insert(END, "\n\nJust like most stock exchanges, there are commission fees placed on orders we fulfill for you.")
  1114.  
  1115.             # Seperator
  1116.             self._create_seperator()
  1117.  
  1118.             # Body
  1119.             self.text.insert(END, "For  ")
  1120.             self.text.insert(END, "Market Orders", 'bold')
  1121.             self.text.insert(END, ", there is a fee of $20.00.")
  1122.             self.text.insert(END, "\n\nFor  ")
  1123.             self.text.insert(END, "Limit Orders", 'bold')
  1124.             self.text.insert(END, ", there is a fee of $30.00.")
  1125.            
  1126.             # set text state to disabled
  1127.             self.text.config(state=DISABLED)
  1128.  
  1129.             # create scrolled text widget
  1130.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  1131.                                 orient=HORIZONTAL)
  1132.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  1133.                                 orient=VERTICAL)
  1134.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  1135.  
  1136.             # position in frame and set resize constraints
  1137.             self.text.grid(row=0, column=0, sticky=NSEW)
  1138.             yscroll.grid(row=0, column=1, sticky=NSEW)
  1139.             frame.rowconfigure(0, weight=1)
  1140.             frame.columnconfigure(0, weight=1)
  1141.  
  1142.             # pack text into notebook
  1143.             self.text.pack()
  1144.            
  1145.             # add to notebook (underline = index for short-cut character)
  1146.             self.nb.add(frame, text='Order Fees', underline=0, padding=2)
  1147.  
  1148.         #_____________________________________________________________________________
  1149.        
  1150.         def create_support_order_matching(self):
  1151.             frame = ttk.Frame(self.nb, name='order_matching')
  1152.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1153.            
  1154.             # create and add label
  1155.             self._create_label(frame)
  1156.  
  1157.             # create and add text
  1158.             self._create_text()
  1159.  
  1160.             # Header
  1161.             self.text.insert(END, "\nOrder Matching", 'big')
  1162.             self.text.insert(END, "\n\nOrders are matched in a certain order, according to a set of rules.")
  1163.             self.text.insert(END, "\n\nThis exchange is using a Price-time Priority matching algorithm..")
  1164.  
  1165.             # Seperator
  1166.             self._create_seperator()
  1167.  
  1168.             # Body
  1169.             self.text.insert(END, "Orders are executed in an order determined by following the rules below. ")
  1170.             self.text.insert(END, "\n\n • Buy Orders", 'bold')
  1171.             self.text.insert(END, ": Market orders are executed first (from the oldest to the newest), and then limit orders (from the highest to the lowest).")
  1172.             self.text.insert(END, "\n\n • Sell Orders", 'bold')
  1173.             self.text.insert(END, ": Market orders are executed first (from the oldest to the newest), and then limit orders (from the lowest to the highest).")
  1174.             self.text.insert(END, "\n\nOrders placed at the same price are executed in time-priority order (from oldest to newest).")
  1175.            
  1176.             # set text state to disabled
  1177.             self.text.config(state=DISABLED)
  1178.  
  1179.             # create scrolled text widget
  1180.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  1181.                                 orient=HORIZONTAL)
  1182.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  1183.                                 orient=VERTICAL)
  1184.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  1185.  
  1186.             # position in frame and set resize constraints
  1187.             self.text.grid(row=0, column=0, sticky=NSEW)
  1188.             yscroll.grid(row=0, column=1, sticky=NSEW)
  1189.             frame.rowconfigure(0, weight=1)
  1190.             frame.columnconfigure(0, weight=1)
  1191.  
  1192.             # pack text into notebook
  1193.             self.text.pack()
  1194.            
  1195.             # add to notebook (underline = index for short-cut character)
  1196.             self.nb.add(frame, text='Order Matching', underline=0, padding=2)
  1197.  
  1198.         #_____________________________________________________________________________
  1199.  
  1200.         def create_support_dividends(self):
  1201.             frame = ttk.Frame(self.nb, name='dividends')
  1202.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1203.            
  1204.             # create and add label
  1205.             self._create_label(frame)
  1206.  
  1207.             # create and add text
  1208.             self._create_text()
  1209.  
  1210.             # Header
  1211.             self.text.insert(END, "\nDividends", 'big')
  1212.             self.text.insert(END, "\n\nDividends are paid out daily for certain stocks.")
  1213.  
  1214.             # Seperator
  1215.             self._create_seperator()
  1216.  
  1217.             # Body
  1218.             self.text.insert(END, "Each day, any stocks with a price of ")
  1219.             self.text.insert(END, "$30.00", 'bold')
  1220.             self.text.insert(END, " or more will pay out a ")
  1221.             self.text.insert(END, "1%", 'bold')
  1222.             self.text.insert(END, " dividend for each stock to shareholders in that stock.")
  1223.             self.text.insert(END, "\n\nFor example, if a certain stock is worth ")
  1224.             self.text.insert(END, "$50", 'bold')
  1225.             self.text.insert(END, " and you own ")
  1226.             self.text.insert(END, "200", 'bold')
  1227.             self.text.insert(END, " stocks, you will be paid out ")
  1228.             self.text.insert(END, "$100", 'bold')
  1229.             self.text.insert(END, " each day for owning that stock!")
  1230.            
  1231.             # set text state to disabled
  1232.             self.text.config(state=DISABLED)
  1233.  
  1234.             # create scrolled text widget
  1235.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  1236.                                 orient=HORIZONTAL)
  1237.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  1238.                                 orient=VERTICAL)
  1239.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  1240.  
  1241.             # position in frame and set resize constraints
  1242.             self.text.grid(row=0, column=0, sticky=NSEW)
  1243.             yscroll.grid(row=0, column=1, sticky=NSEW)
  1244.             frame.rowconfigure(0, weight=1)
  1245.             frame.columnconfigure(0, weight=1)
  1246.  
  1247.             # pack text into notebook
  1248.             self.text.pack()
  1249.            
  1250.             # add to notebook (underline = index for short-cut character)
  1251.             self.nb.add(frame, text='Dividends', underline=0, padding=2)
  1252.  
  1253.         #_____________________________________________________________________________
  1254.  
  1255.         def create_support_definitions(self):
  1256.             frame = ttk.Frame(self.nb, name='definitions')
  1257.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1258.            
  1259.             # create and add label
  1260.             self._create_label(frame)
  1261.  
  1262.             # create and add text
  1263.             self._create_text()
  1264.  
  1265.             # Header
  1266.             self.text.insert(END, "\nDefinitions", 'big')
  1267.             self.text.insert(END, "\n\nA quick rundown of the definitions used on the site and stock trading in general.")
  1268.  
  1269.             # Seperator
  1270.             self._create_seperator()
  1271.  
  1272.             # Body
  1273.             self.text.insert(END, "GTC", 'big')
  1274.             self.text.insert(END, "\nGood 'Til Cancelled - ", 'bold')
  1275.             self.text.insert(END, "This is where a buy or sell order will not expire at the end of the trading day.")
  1276.             self.text.insert(END, "\n\nEOD", 'big')
  1277.             self.text.insert(END, "\nEnd of Day - ", 'bold')
  1278.             self.text.insert(END, "This is where a buy or sell order will expire at the end of the trading day.")
  1279.            
  1280.             # set text state to disabled
  1281.             self.text.config(state=DISABLED)
  1282.  
  1283.             # create scrolled text widget
  1284.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  1285.                                 orient=HORIZONTAL)
  1286.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  1287.                                 orient=VERTICAL)
  1288.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  1289.  
  1290.             # position in frame and set resize constraints
  1291.             self.text.grid(row=0, column=0, sticky=NSEW)
  1292.             yscroll.grid(row=0, column=1, sticky=NSEW)
  1293.             frame.rowconfigure(0, weight=1)
  1294.             frame.columnconfigure(0, weight=1)
  1295.  
  1296.             # pack text into notebook
  1297.             self.text.pack()
  1298.            
  1299.             # add to notebook (underline = index for short-cut character)
  1300.             self.nb.add(frame, text='Definitions', underline=0, padding=2)
  1301.  
  1302.         #_____________________________________________________________________________
  1303.  
  1304.         def create_support_rules(self):
  1305.             frame = ttk.Frame(self.nb, name='rules')
  1306.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1307.            
  1308.             # create and add label
  1309.             self._create_label(frame)
  1310.  
  1311.             # create and add text
  1312.             self._create_text()
  1313.  
  1314.             # Header
  1315.             self.text.insert(END, "\nRules", 'big')
  1316.             self.text.insert(END, "\n\nThese rules apply to the exchange and are enforced automatically.")
  1317.  
  1318.             # Seperator
  1319.             self._create_seperator()
  1320.  
  1321.             # Body
  1322.             self.text.insert(END, "1. You cannot own more than ")
  1323.             self.text.insert(END, "100%", 'bold')
  1324.             self.text.insert(END, " of a stock at any one time.")
  1325.            
  1326.             self.text.insert(END, "\n\n2. You cannot place a limit buy or sell order more than ")
  1327.             self.text.insert(END, "10%", 'bold')
  1328.             self.text.insert(END, " away from the current market price of a stock.")
  1329.             self.text.insert(END, "\nFor example, if a stock price is ")
  1330.             self.text.insert(END, "$100", 'bold')
  1331.             self.text.insert(END, ", you cannot place a limit sell order for less than ")
  1332.             self.text.insert(END, "$90", 'bold')            
  1333.             self.text.insert(END, ", or more than ")
  1334.             self.text.insert(END, "$110.", 'bold')    
  1335.  
  1336.             self.text.insert(END, "\n\n3. Stocks with a value over ")
  1337.             self.text.insert(END, "$50", 'bold')
  1338.             self.text.insert(END, " that changes by ")
  1339.             self.text.insert(END, "10%", 'bold')
  1340.             self.text.insert(END, " or more on a single day will halt trading until the end of the day.")
  1341.            
  1342.             # set text state to disabled
  1343.             self.text.config(state=DISABLED)
  1344.  
  1345.             # create scrolled text widget
  1346.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  1347.                                 orient=HORIZONTAL)
  1348.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  1349.                                 orient=VERTICAL)
  1350.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  1351.  
  1352.             # position in frame and set resize constraints
  1353.             self.text.grid(row=0, column=0, sticky=NSEW)
  1354.             yscroll.grid(row=0, column=1, sticky=NSEW)
  1355.             frame.rowconfigure(0, weight=1)
  1356.             frame.columnconfigure(0, weight=1)
  1357.  
  1358.             # pack text into notebook
  1359.             self.text.pack()
  1360.            
  1361.             # add to notebook (underline = index for short-cut character)
  1362.             self.nb.add(frame, text='Rules', underline=0, padding=2)
  1363.  
  1364.         #_____________________________________________________________________________
  1365.  
  1366.         def create_support_faq(self):
  1367.             frame = ttk.Frame(self.nb, name='faq')
  1368.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1369.  
  1370.             # create and add label
  1371.             self._create_label(frame)
  1372.  
  1373.             # create and add text
  1374.             self._create_text()
  1375.  
  1376.             # Header
  1377.             self.text.insert(END, "\nFrequently Asked Questions", 'big')
  1378.             self.text.insert(END, "\n\nHere, you can find the answers to some of the most frequently asked questions.")
  1379.  
  1380.             # Seperator
  1381.             self._create_seperator()
  1382.  
  1383.             # Body
  1384.             self.text.insert(END, "Q: What is stock trading all about?", 'big')
  1385.             self.text.insert(END, "\n\nA: ", 'bold')
  1386.             self.text.insert(END, "Stock trading is all about return on investment.")
  1387.             self.text.insert(END, "\nWe start you off with some virtual cash to buy your initial stocks, but from there on out you'll need to manage your own portfolio.")
  1388.  
  1389.             self.text.insert(END, "\n\nQ. Can I use real money?", 'big')
  1390.             self.text.insert(END, "\n\nA: ", 'bold')
  1391.             self.text.insert(END, "No, only virtual money is used here. More money cannot be given or bought.")
  1392.  
  1393.             self.text.insert(END, "\n\nQ. Can I make my own stock?", 'big')
  1394.             self.text.insert(END, "\n\nA: ", 'bold')
  1395.             self.text.insert(END, "You can apply to have stock added. You must have at least $5,000.00 cash to apply.")
  1396.  
  1397.             self.text.insert(END, "\n\nQ. I've made my own stock, how do other people buy it?", 'big')
  1398.             self.text.insert(END, "\n\nA: ", 'bold')
  1399.             self.text.insert(END, "You must create a sell order to sell the stock that was given to you, so others can then buy it.")
  1400.            
  1401.             # set text state to disabled
  1402.             self.text.config(state=DISABLED)
  1403.  
  1404.             # create scrolled text widget
  1405.             xscroll = ttk.Scrollbar(frame, command=self.text.xview,
  1406.                                 orient=HORIZONTAL)
  1407.             yscroll = ttk.Scrollbar(frame, command=self.text.yview,
  1408.                                 orient=VERTICAL)
  1409.             self.text.configure(xscrollcommand=xscroll.set, yscrollcommand=yscroll.set)
  1410.  
  1411.             # position in frame and set resize constraints
  1412.             self.text.grid(row=0, column=0, sticky=NSEW)
  1413.             yscroll.grid(row=0, column=1, sticky=NSEW)
  1414.             frame.rowconfigure(0, weight=1)
  1415.             frame.columnconfigure(0, weight=1)
  1416.  
  1417.             # pack text into notebook
  1418.             self.text.pack()
  1419.            
  1420.             # add to notebook (underline = index for short-cut character)
  1421.             self.nb.add(frame, text='FAQ', underline=0, padding=2)
  1422.  
  1423.         #_____________________________________________________________________________
  1424.            
  1425.         create_support_getting_started(self)
  1426.         create_support_stocks(self)
  1427.         create_support_buying_stocks(self)
  1428.         create_support_selling_stocks(self)
  1429.         create_support_order_fees(self)
  1430.         create_support_order_matching(self)
  1431.         create_support_dividends(self)
  1432.         create_support_definitions(self)
  1433.         create_support_rules(self)
  1434.         create_support_faq(self)
  1435.  
  1436.     # ================================================================================
  1437.     # admin section function
  1438.     # ================================================================================
  1439.  
  1440.     def _admin(self):
  1441.        
  1442.         self._create_canvas('Admin')
  1443.    
  1444.         # create the notebook
  1445.         name='admin'
  1446.         self._create_notebook(name)
  1447.        
  1448.         def create_admin_dashboard(self):
  1449.             frame = ttk.Frame(self.nb, name='dashboard')
  1450.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1451.  
  1452.             msg = ["Ttk is the new Tk themed widget set. One of the widgets ",
  1453.                    "it includes is the notebook widget, which provides a set ",
  1454.                    "of tabs that allow the selection of a group of panels, ",
  1455.                    "each with distinct content. They are a feature of many ",
  1456.                    "modern user interfaces. Not only can the tabs be selected ",
  1457.                    "with the mouse, but they can also be switched between ",
  1458.                    "using Ctrl+Tab when the notebook page heading itself is ",
  1459.                    "selected. Note that the second tab is disabled, and cannot "
  1460.                    "be selected."]
  1461.              
  1462.             lbl = ttk.Label(frame, wraplength='7i', justify=LEFT, anchor=N,
  1463.                             text=''.join(msg))
  1464.              
  1465.             # position and set resize behaviour
  1466.             lbl.grid(row=0, column=0, columnspan=2, sticky='new', pady=5)
  1467.            
  1468.             # add to notebook (underline = index for short-cut character)
  1469.             self.nb.add(frame, text='Dashboard', underline=0, padding=2)
  1470.  
  1471.         def create_admin_stocks(self):
  1472.             frame = ttk.Frame(self.nb, name='stocks')
  1473.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1474.            
  1475.             # add to notebook (underline = index for short-cut character)
  1476.             self.nb.add(frame, text='Stocks', underline=0, padding=2)
  1477.  
  1478.         def create_admin_buy_orders(self):
  1479.             frame = ttk.Frame(self.nb, name='buy_orders')
  1480.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1481.            
  1482.             # add to notebook (underline = index for short-cut character)
  1483.             self.nb.add(frame, text='Buy Orders', underline=0, padding=2)
  1484.  
  1485.         def create_admin_sell_orders(self):
  1486.             frame = ttk.Frame(self.nb, name='sell_orders')
  1487.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1488.            
  1489.             # add to notebook (underline = index for short-cut character)
  1490.             self.nb.add(frame, text='Sell Orders', underline=0, padding=2)
  1491.  
  1492.         def create_admin_news(self):
  1493.             frame = ttk.Frame(self.nb, name='news')
  1494.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1495.            
  1496.             # add to notebook (underline = index for short-cut character)
  1497.             self.nb.add(frame, text='News', underline=0, padding=2)
  1498.  
  1499.         def create_admin_users(self):
  1500.             frame = ttk.Frame(self.nb, name='users')
  1501.             frame.pack(side=TOP, fill=BOTH, expand=Y)
  1502.            
  1503.             # add to notebook (underline = index for short-cut character)
  1504.             self.nb.add(frame, text='Users', underline=0, padding=2)
  1505.  
  1506.         create_admin_dashboard(self)
  1507.         create_admin_stocks(self)
  1508.         create_admin_buy_orders(self)
  1509.         create_admin_sell_orders(self)
  1510.         create_admin_news(self)
  1511.         create_admin_users(self)
  1512.  
  1513.     # ================================================================================
  1514.     # fill stock pane function (with API)
  1515.     # ================================================================================
  1516.                                                                        
  1517.     def _stock_pane(self):
  1518.         # create and add stock labels
  1519.         stocks = ('AVLN',
  1520.                  'ASTR',
  1521.                  'BETA',
  1522.                  'DAAS',
  1523.                  'EQNX',
  1524.                  'KAYT',
  1525.                  'RFRD')
  1526.  
  1527.         ltop = self.nametowidget('model.outer.left.ltop')          
  1528.         for each in stocks:
  1529.             # extract and format stock identifier
  1530.             identifier = each.split('/')[-1]
  1531.             identifier = [c if c != '_' else ' ' for c in identifier]
  1532.              
  1533.             # create two labels for each stock; one with the identifier
  1534.             # the other to hold the stock price
  1535.             lbl = ttk.Label(ltop, text=''.join(identifier), anchor=W)
  1536.             price = ttk.Label(ltop,  textvariable=StringVar(), anchor=W)
  1537.             lbl.pack(fill=X)
  1538.             price.pack(fill=X)
  1539.             ttk.Separator(ltop).pack(fill=X)
  1540.  
  1541.             # set the current price for the indicated stock      
  1542.             self._update_stock_price(price, each)
  1543.  
  1544.     # ================================================================================
  1545.     # update stock pane function (with API)
  1546.     # ================================================================================
  1547.              
  1548.     def _update_stock_price(self, price, identifier):
  1549.             # stock label helper function
  1550.             # sets the price immediately and updates it every 1000ms
  1551.             #
  1552.             # price - one of the 'stock' labels
  1553.             # stock - the associated stock identifier
  1554.  
  1555.             stocks=open(stocks_file, 'rb')
  1556.             stock_data = []
  1557.             end_of_file=False
  1558.            
  1559.             while not end_of_file:
  1560.               try:
  1561.                 # Unpickle the next object.
  1562.                 stock = pickle.load(stocks)
  1563.  
  1564.                 # Store the next object
  1565.                 stock_data.append([stock.get_identifier(), stock.get_price()])
  1566.                  
  1567.               except EOFError:
  1568.                         # Set the flag to indicate the end
  1569.                         # of the file has been reached
  1570.                         end_of_file = True
  1571.  
  1572.             # Close the file
  1573.             stocks.close()
  1574.  
  1575.             for each in stock_data:
  1576.                 if each[0] == identifier:
  1577.                     c=each[1]
  1578.  
  1579.             varname = price.cget('textvariable')
  1580.             price.setvar(varname, c)
  1581.              
  1582.             self.after(1000, self._update_stock_price, *(price, identifier))
  1583.            
  1584.     # ================================================================================
  1585.     # logout function
  1586.     # ================================================================================
  1587.  
  1588.     def _logout(self):
  1589.         self.logged_in=False
  1590.         self._home()
  1591.  
  1592. # ===================================================================================
  1593.  
  1594. # function for the main program
  1595.  
  1596. if __name__ == '__main__':
  1597.  
  1598.     #_________________________________________________________________________________
  1599.  
  1600.     # global variable to store current directory
  1601.  
  1602.     cwd = os.getcwd()
  1603.     new_cwd = ""
  1604.  
  1605.     for each in cwd:
  1606.        
  1607.         if each == '\\':
  1608.             each = '/'
  1609.            
  1610.         new_cwd+=each
  1611.  
  1612.     cwd=new_cwd
  1613.  
  1614.     #_________________________________________________________________________________
  1615.  
  1616.     # global variables to store filepaths for static data
  1617.     stocks_file = (cwd + '/data/stocks.dat') # Stock Data
  1618.     transaction_file = (cwd + '/data/transactions.dat') # Transaction Data
  1619.     user_file = (cwd + '/data/users.dat') # User Data
  1620.     user_stocks_file = (cwd + '/data/user_stocks.dat') # User Stocks Data
  1621.    
  1622.     #_________________________________________________________________________________
  1623.  
  1624.     # global variables to store filepaths for data feeds
  1625.     news_file = (cwd + '/feeds/news.dat') # News Feeds
  1626.     notification_file = (cwd + '/feeds/notifications.dat') # Notification Feeds
  1627.     stock_history_file = (cwd + '/feeds/stock_history.dat') # Market Feeds
  1628.  
  1629.  
  1630.     #_________________________________________________________________________________
  1631.  
  1632.     # global variables to store filepaths for orders
  1633.     buy_orders_file = (cwd + '/orders/buy_orders.dat') # Buy Orders
  1634.     sell_orders_file = (cwd + '/orders/sell_orders.dat') # Sell Orders
  1635.  
  1636.     #_________________________________________________________________________________
  1637.  
  1638.     # call the main program
  1639.  
  1640.     App().mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement