Skip to main content

Open in Codespaces

Stock Portfolio Report

This assignment will test the following skills:

  • Reading and writing to the file system
  • Making HTTP requests
  • Testing read & write operations to the disk
  • Testing HTTP requests using a mock library
  • Packaging the script using setup.py

Description

Write a program which will generate up-to-date performance reports for a given stock portfolio. The program will accept two arguments: an input CSV file which contains the holdings information, and, a path to output the CSV report.

We will use the IEX Trading API, as the market data source – it is a free API for learning procedure.

you need to register using this link https://iexcloud.io/cloud-login#/register and generate your API key.

Make sure you don't share your API key with your friends.

Requirements

The program will read a CSV file containing our portfolio data. Based on this data, a new CSV report will be generated using live market value to indicate our current holding performance using the IEX API.

The program will be installable using pip, and requires a setup.py file. When installed, a binary will be added to the Python path which can be invoked from anywhere on the filesystem.

An example interaction with the script looks like this:

$ portfolio_report --source portfolio.csv --target report1.csv

Input file

The input CSV will have 3 columns (example provided).

  • symbol: the ticker symbol (e.g. AAPL is Apple)
  • units: the quantity of shares held
  • cost: the original / average purchase price of the holding

Example:

symbol units cost
AAPL 1000 123.56
AMZN 20 2001.1

Using the list of symbols from the input CSV, get quotes from IEX to fetch the latest price. This can be done in a batch request – meaning, multiple quotes can be requested in a single HTTP request. See:

Docs: IEX trading API

Example request & response

Example request: GET the latest quotes for Apple, Facebook & Snapchat:

replace your API key with "pasteyourapihere" in url below. 

https://cloud.iexapis.com/stable/tops?token="pasteyourapihere"&symbols=SNAP,AMZN,AAPL

you can refer to screenshot below for your API key

Returned Data:

[{
    "symbol": "AAPL",
        "price": 204.29,
        "size": 100,
        "time": 1563307196175
}, {
    "symbol": "AMZN",
        "price": 2008.395,
        "size": 1,
        "time": 1563307196058
}, {
    "symbol": "SNAP",
        "price": 15,
        "size": 100,
        "time": 1563307196047
}]

Once the latest price is obtained, a series of calculations are made to establish the current performance of the portfolio: what the current market value is, the gain and loss for each holding and a percentage of change.

If a symbol listed in the input CSV is not found on the exchange, the IEX API ignores it. Your script should account for this situation by warning the user that the symbol was not found, but continue to process the rest of the valid symbols.

Output file

The expected CSV report will have the following columns

  • symbol: The stock ticker symbol (i.e. AAPL)
  • units: The amount of shares held
  • cost: The original cost per share
  • latest_price: The latest market price per share
  • book_value: The value of the shares at time of purchase
  • market_value: The value of the shares based on the latest market value
  • gain_loss: The dollar amount either gained or lost
  • change: A percentage (decimal) of the gain/loss
Sample output CSV
symbol units cost latest_price book_value market_value gain_loss change
AAPL 1000 123.56 156.23 12356 15623 3267 0.264
AMZN 20 2001.1 1478.19 40022 29563 -10459 -0.261

Getting started

Take a modular approach to completing this assignment and build each functional component in isolation, accompanied by appropriate tests.

Here is a breakdown of isolated functional units:

  • Given a filename, read a CSV and convert it to a Python data structure
  • Build a method which returns the latest market price for holdings
  • Build methods which calculate the book value, market value
  • Build a method to convert the holding into CSV
  • Build a method that writes to the output filename.

Testing

Testing against third-party services can be challenging as they are out of our control. As developers, we must build our application with the expectation of specific behaviours from these services. Mocks (faking) are a handy way to isolate the dependency and replace it with a constant to which we can build tests. For this, we will use the requests-mock library to stub out HTTP requests.

https://requests-mock.readthedocs.io/en/latest/pytest.html

Install using pip install requests-mock.

As for writing files, use the tmp_path fixture that ships with pytest to write to temporary locations on the disk.

Make sure to update requirements.txt and include any libraries required to build this project (e.g. requests, requests-mock) so they are available to Travis CI.

Packaging

As described above, provide a setup.py configuration to package your application. Ensure that dependencies required to run your script are included (e.g. requests)

Evaluation rubric

Metric 4 3 2 1 0
Meets requirements All requirements are met Almost all requirements are met Most requirements met, some bugs Incorrect results, several bugs Program does not work
Testing Unit tests are present and cover all functionality Most of the script is covered by testing Partial test coverage, some false assertions present Minimal testing, false assertions present, missing main functional coverage. No meaningful tests exist
Packaging & delivery The project is properly packaged, documented and can be installed using pip. The project is packaged, but is missing certain metadata The project is installable, but with some issues. Documentation is incomplete. Documentation is partial, the package does not install No packaging present, little or no documentation
Reusability The code could be reused as a whole and each routine could be reused Most of the code could be reused in other programs Some parts of the code could be reused in other programs A few parts of the code could be reused in other programs The code is not organized for reusability
Readability The code is well organized and very easy to understand The code is pretty well organized and fairly easy to read The code has some organization, is a challenge to read The code is readable only by someone who knows what it is supposed to do The code is poorly organized and very difficult to read

Metadata

Release files for assignment-7-portfolio-generator-burrmit 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for assignment-7-portfolio-generator-burrmit 1.0.0
File Size Uploaded Provenance Actions
assignment-7-portfolio-generator-burrmit-1.0.0.tar.gz 5.3 kB Without provenance Details for assignment-7-portfolio-generator-burrmit-1.0.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for assignment-7-portfolio-generator-burrmit 1.0.0
File Interpreter ABI Platform Actions
assignment_7_portfolio_generator_burrmit-1.0.0-py3.10.egg Legacy Egg format - - Details for assignment_7_portfolio_generator_burrmit-1.0.0-py3.10.egg
assignment_7_portfolio_generator_burrmit-1.0.0-py3-none-any.whl Python 3 none any Details for assignment_7_portfolio_generator_burrmit-1.0.0-py3-none-any.whl

Total release size: 14.8 kB

Release files / assignment-7-portfolio-generator-burrmit-1.0.0.tar.gz

Download URL assignment-7-portfolio-generator-burrmit-1.0.0.tar.gz
Size 5.3 kB
Tags Source
SHA-256 checksum
How to use checksums
200246c6679e33ec63a9daf80b6f67eb868623c07521088361f7799035f2e36d
BLAKE2b-256 checksum
How to use checksums
f9bb1f65b4703ac14dfa728a4c6c83d1f273f646506dbc6f3b26961a34ebac52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.5

Release files / assignment_7_portfolio_generator_burrmit-1.0.0-py3.10.egg

Download URL assignment_7_portfolio_generator_burrmit-1.0.0-py3.10.egg
Size 4.2 kB
Tags Egg
SHA-256 checksum
How to use checksums
b89337f4dccca1cf38998241eb1e9e767d091f4d79b2670ccc11b1b94bd48f12
BLAKE2b-256 checksum
How to use checksums
795991e9b5741b89b6eab28b434164fbb913e12a816f8e1fd828c2c37519e1cb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.5

Release files / assignment_7_portfolio_generator_burrmit-1.0.0-py3-none-any.whl

Download URL assignment_7_portfolio_generator_burrmit-1.0.0-py3-none-any.whl
Size 5.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4e9c129d48c37964665bc0c3aa6cd8fda1432814ea8138e95bdba858290988ff
BLAKE2b-256 checksum
How to use checksums
d43f3bde59505272f31221fe5b8c71f0eb5c736ab00d8727b6e7cb7de8cda7bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/4.0.1 CPython/3.10.5

Security for assignment-7-portfolio-generator-burrmit 1.0.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

1.0.0 This release

3 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page