Python Bibliotheca
Python resources for teachers and students.

Portfolio Tracker

Description

In the financial world a portfolio is a collection of investments. Many investors have a portfolio of stocks or mutual funds. For this assignment, you will write a program for keeping track of the value of a group of stocks.

Data structure

You should store your data in a list of lists. A sample portfolio might look like this:

[['MMM', '3M', '100', '74.00', '118.30'],
 ['MDT', 'Medtronic', '50', '56.10', '48.00'],
 ['NWAC', 'Northwest Airlines', '100', '67.50', '18.04'],
 ['SGI', 'Silicon Graphics', '100', '22.25', '2.25']]

Note: Storing the prices in cents may make rounding easier in the long run. A lot of financial software uses this strategy.

This is the most complex program we have written so far. You will team up in groups of four and divide some of the tasks between pairs of programmers. For example, one pair could work on the user interface while another writes the code to update share prices. You will meet daily with your entire team of four to update one another on your progress and troubleshoot problems.

Input

This program will be menu-driven. When you are done you will be able to open a file containing your portfolio data, save the file back to disk, display a portfolio summary (sorted in several different ways), add a new stock to your portfolio, delete a stock from your portfolio, and update the prices of the stocks in your portfolio. In order to accomplish this, you will need to take advantage of a number of the Python features we have studied lately.

See also: Using dictionaries for program menus

You can build whatever kind of user interface you would like. Make sure you pay attention to designing something that is clear and easy to use.

Output

When you sort the portfolio for display, you should create a dictionary with the sort category as the key and the list as the value. Then you can iterate through the keys and display the table of stocks. Such a dictionary might look like:

{'3M': ['MMM', '3M', '100', '74.00', '118.30'],
 'Medtronic': ['MDT', 'Medtronic', '50', '56.10', '48.00'],
 'Northwest Airlines': ['NWAC', 'Northwest Airlines', '100', '67.50', '18.04'],
 'Silicon Graphics': ['SGI', 'Silicon Graphics', '100', '22.25', '2.25']}

Instead of using tab characters to align the fields for displaying, try using the string formatting codes we've used previously in class.

See also: String formatting codes

Sample run

(A)dd/(D)elete stocks, (L)oad file, (U)pdate prices, (R)eport, or (Q)uit? l
Load file: portfolio.dat

(A)dd/(D)elete stocks, (L)oad file, (U)pdate prices, (R)eport, or (Q)uit? r
Sort output on (N)ame, or (V)alue? n

Company                   Shares   Pur.  Latest   Value     G/L
=================================================================
3M (MMM)                    100   74.00  118.30   11830    59.9%
Medtronic (MDT)              50   56.10   48.00    2400   -14.4%
Northwest Airlines (NWAC)   100   67.50   18.04    1804   -73.3%
Silicon Graphics (SGI)      100   22.25    2.25     225   -89.9%
                                                  ---------------
                                                  16259   -15.2%
                                                  ===============

(A)dd/(D)elete stocks, (L)oad file, (U)pdate prices, (R)eport, or (Q)uit? a
Add a stock to your portfolio...

Ticker: RHAT
Company name: RedHat
Number of shares: 75
Purchase price per share: $3.5

(A)dd/(D)elete stocks, (L)oad file, (U)pdate prices, (R)eport, or (Q)uit? r

Sort output on (N)ame, or (V)alue? v

Company                   Shares   Pur.  Latest   Value     G/L
=================================================================
Silicon Graphics (SGI)      100   22.25    2.25     225   -89.9%
RedHat (RHAT)                75    3.50    3.50     262     0.0%
Northwest Airlines (NWAC)   100   67.50   18.04    1804   -73.3%
Medtronic (MDT)              50   56.10   48.00    2400   -14.4%
3M (MMM)                    100   74.00  118.30   11830    59.9%
                                                  ---------------
                                                  16522   -15.0%
                                                  ===============

(A)dd/(D)elete stocks, (L)oad file, (U)pdate prices, (R)eport, or (Q)uit? d
Enter the ticker symbol of the stock to remove: nwac
 
(A)dd/(D)elete stocks, (L)oad file, (U)pdate prices, (R)eport, or (Q)uit? u
Update stock prices (<Return> to keep current value)...
 
MMM: 112

MDT: 47.89
SGI: 4.98
RHAT: 4.25
 
(A)dd/(D)elete stocks, (L)oad file, (U)pdate prices, (R)eport, or (Q)uit? r
Sort output on (N)ame, or (V)alue?
 
Company                   Shares   Pur.  Latest   Value     G/L
=================================================================
3M (MMM)                    100   74.00  112.00   11200    51.4%
Medtronic (MDT)              50   56.10   47.89    2394   -14.6%
RedHat (RHAT)                75    3.50    4.25     319    21.4%
Silicon Graphics (SGI)      100   22.25    4.98     498   -77.6%
                                                  ---------------
                                                  14411    13.5%
                                                  ===============

(A)dd/(D)elete stocks, (L)oad file, (U)pdate prices, (R)eport, or (Q)uit? q
Save portfolio.dat (y/n)? y

Bye.

Going further

  1. Use urllib2 to automatically update stock prices from finance.yahoo.com. Raw price data is available at a URL of the form http://finance.yahoo.com/d/quotes.csv?s=MMM&f=sl1d1t1c1ohgv&e=.csv where 'MMM' (in the middle of the URL) is the ticker symbol for the stock you'd like to retrieve. To retrieve more than one report simultaneously, use a + symbol between each ticker symbol. For example, you would use 'MMM+MDT' to get 3M and Medtronic in a single request.
  2. Use the pickle module to save your list to disk directly.
  3. Modify your program to handle different lots of the same stock.
  4. Expand the data that is stored to include the date of purchase and calculate the annual rate of return.

[ Copyright 2003, Tim Wilson ]

Comments, questions, or suggestions? Email the webmaster