Milestone I: Data Preparation

Part 1: Read In The Stock Data

One of the first goals for the project will be to import the financial data you were given into your program, provided to you as a CSV formatted text file. Get started by downloading both stock data for Apple, and stock data for Microsoft as this is the data you will use for testing.

The data provided has the following columns, click on the links for their full definitions: Date, Open (2), Close, High, Low, Volume, and Adj Close.

CSV files are a relatively simple text file format. Try to inspect the data to become familiar with what it contains (you can inspect the data by opening it in your favorite text editor, like TextEdit, Notepad, Vim, Sublime Text, etc.

The data you will read in is linear by date (but, non-contiguous due to holidays and weekends,) reflecting a timeline of stock performance in reverse chronological order; however your program should run through the days in the data from the earliest date to the most recent.

Now, ask yourself: is the data arranged how you would like it?

You can write whatever code you need to get the job done. The only strictly defined and required function is one named test_data(), and it should be a simple function, relying on calling other functions you have written. It should have the following characteristics, to be filled in by you (along with the docstring):

def test_data(filename, col, day):
    """A test function to query the data you loaded into your program.

    Args:
        filename: A string for the filename containing the stock data,
                  in CSV format.

        col: A string of either "date", "open", "high", "low", "close",
             "volume", or "adj_close" for the column of stock market data to
             look into.

             The string arguments MUST be LOWERCASE!

        day: An integer reflecting the absolute number of the day in the
             data to look up, e.g. day 1, 15, or 1200 is row 1, 15, or 1200
             in the file.

    Returns:
        A value selected for the stock on some particular day, in some
        column col. The returned value *must* be of the appropriate type,
        such as float, int or str.
    """

This function is used primarily for me to test your code for grading. It is not intended to be used in later Milestones, and it will be problematic if you do attempt to use it in later Milestones. Future Milestones will rely on other functions that you hopefully will write to support your test_data() function.

This is how I will test your code, in the file project.py (where 1 is the 1st day, and 25 is 25th day of data), for example, using the Apple stock data:

>>> val = test_data("AAPL.csv", "close", 25)
>>> val
165.259995
>>> type(val)
<class 'float'>
>>>

or, using the Microsoft stock data:

>>> val = test_data("MSFT.csv", "close", 25)
>>> val
93.519997
>>> type(val)
<class 'float'>
>>>

You should write a main() function, but it shouldn’t do anything yet. Feel free to write main() like this:

def main():
    pass  # Do nothing, just passing through!

Part 2: Stock Bookkeeping

Write the function transact() as defined below, along with the docstring. This function should operate as the docstring describes. Please note, you need to lookup pricing of a current day and column. Please choose any column you wish inside this function (e.g. “close”). You must not use test_data() to lookup pricing for the current day. This means transact() and test_data() must use a common function that looks up your stock pricing data after it has been loaded, and processed into memory.

def transact(funds, stocks, qty, day, buy=False, sell=False):
    """A bookkeeping function to help make stock transactions.

    Args:
        funds: An account balance, a float; it is a value of how much money you have,
               currently.

        stocks: An int, representing the number of stock you currently own.

        qty: An int, representing how many stock you wish to buy or sell.

        day: An integer reflecting the absolute number of the day in the
             data to look up, e.g. day 1, 15, or 1200 is row 1, 15, or 1200
             in the file.

        buy: This option parameter, if set to true, will initiate a buy.

        sell: This option parameter, if set to true, will initiate a sell.

    Returns:
        Two values *must* be returned. The first (a float) is the new
        account balance (funds) as the transaction is completed. The second
        is the number of stock now owned (an int) after the transaction is
        complete.

        Error condition #1: If the `buy` and `sell` keyword parameters are both set to true,
        or both false. You *must* print an error message, and then return
        the `funds` and `stocks` parameters unaltered. This is an ambiguous
        transaction request!

        Error condition #2: If you buy, or sell without enough funds or
        stocks to sell, respectively.  You *must* print an error message,
        and then return the `funds` and `stocks` parameters unaltered. This
        is an ambiguous transaction request!
    """
>>> cash_balance = 1000
>>> stocks_owned = 25
>>> day = 10
>>>
>>> cash_balance, stocks_owned = transact(cash_balance, stocks_owned, 3, 25)
Ambigious transaction! No action performed.
>>> print(cash_balance, stocks_owned)
1000 25
>>>
>>> cash_balance, stocks_owned = transact(cash_balance, stocks_owned, 3, 25, buy=True, sell=True)
Ambigious transaction! No action performed.
>>> print(cash_balance, stocks_owned)
1000 25
>>>
>>> cash_balance, stocks_owned = transact(cash_balance, stocks_owned, 3, 25, buy=True)
>>> print(cash_balance, stocks_owned)
-3131.4998750000004 50
>>>
>>> cash_balance, stocks_owned = transact(cash_balance, stocks_owned, 3, 25, sell=True)
>>> print(cash_balance, stocks_owned)
5131.499875 0
>>>

Helpful Hints

  1. It would be good form to have separate functions to open, read, and parse the CSV file all to be called inside test_data().
  2. Do not ask the user for a filename. Unit test your function by calling it inside the interpreter with the filename for your data you want to use.
  3. Lists are virtually required here, so make sure you call help(list) in the Python interpreter to know what a list can do for you!
  4. You will not be allowed to edit the CSV file directly. You can only change the data after you read it in using your Python program.
  5. The stock data isn’t contiguous in its dates listed. You will have gaps that correspond to weekends or market holidays. Do not count those missing dates as part of your day number counting.
  6. Don’t trust Excel to give you the true view of the CSV data, use a text editor.