Version: Wednesday, May 23, 2018 (PDT) 17:30
- Stock Investing
- Investigation of WIKI API
- Development
- Application
Retrieves Stocks pricing data from the Quandl WIKI Stock Price API for a given set of securities and date range
The documentation of the API can be found here.
Securities to use are: COF, GOOGL, and MSFT.
Perform this analysis for Jan - June of 2017
--avg-monthly-open-close
: Average Monthly Open and Close prices for each security for each month of data in the data set..--max-daily-profit
: We’d like to know which day in our data set would provide the highest amount of profit for each security if purchased at the day’s low and sold at the day’s high. Please display the ticker symbol, date, and the amount of profit.--busy-day
: We’d like to know which days generated unusually high activity for our securities. Please display the ticker symbol, date, and volume for each day where the volume was more than 10% higher than the security’s average volume (Note: You’ll need to calculate the average volume, and should display that somewhere too).--biggest-loser
: Which security had the most days where the closing price was lower than the opening price. Please display the ticker symbol and the number of days that security’s closing price was lower than that day’s opening price.
Output the data in the below format, or optionally in a prettier format if you see fit.
{"GOOGL": {"month":"2017-01", "average_open": "815.43", "average_close": "$818.34"},
{"month":"2017-02", "average_open": "825.87", "average_close": "$822.73"},
...
{"month":"2017-05", "average_open": "945.24", "average_close": "$951.52"},
{"month":"2017-06", "average_open": "975.37", "average_close": "$977.11"}}
Read the documentation of the API can be found here.
And created a bash script for investigating this API.
$ cd scripts
$cd ./stock_investing.sh \
--stock GOOGL \
--api-key [REDACTED] \
--start-date 2017-01-01 \
--end-date 2017-06-30 \
--limit 5 \
--column-index 5
{
"dataset_data": {
"limit": 5,
"transform": null,
"column_index": 5,
"column_names": [
"Date",
"Volume"
],
"start_date": "2004-08-19",
"end_date": "2018-03-27",
"frequency": "daily",
"data": [
[
"2018-03-27",
2940957
],
[
"2018-03-26",
3272409
],
[
"2018-03-23",
2413517
],
[
"2018-03-22",
3418154
],
[
"2018-03-21",
1990515
]
],
"collapse": null,
"order": null
}
}
This application was built within my Python environment version 3.5.4:
$ python3 --version
Python 3.5.4
Two Python projects that I have on PyPi and currently actively developing, however, I have not made sources public yet, where used with this coding challenge:
- pyfortified-cache: https://pypi.org/project/pyfortified-cache
- pyfortified-logging: https://pypi.org/project/pyfortified-logging
- pyfortified-requests: https://pypi.org/project/pyfortified-requests
This challenge is using concurrent.futures module provides a high-level interface for asynchronously executing callables, which is native to Python 3.x.
By using memcached, for this exercise, data will be pulled once from WIKI API.
Using cached data, Python Pandas dataframes will be pull from this data and provide requested results.
Extension of Python native logging is used for ease of verbose tracking:
Extension of Python project requests is used for more robust HTTP remote calls:
Caching factor with common abstract interface for handling caching fetch/hit/put and cache key generation:
Install memcached
before before using this application.
$ memcached
$ echo 'flush_all' | nc localhost 11211
OK
- More comments in the code
- CI Test
- Bug:Fix overlapping of Cached Date Ranges.
- Install Python 3.5+
- Install memcached and start it
- Use Makefile to install Python requirements
$ make install
To run application using Makefile, perform the following and add API Key to environment:
$ export QUANDL_WIKI_API_KEY=[REDACTED]
$ python3 stock_investing/worker.py --help
Usage: stock_investing/worker.py
[-v | --verbose]
[-h | --help]
--api-key='API-KEY'
[--stocks=Stock,Stock,Stock]
[--start-date='YYYY-MM-DD']
[--end-date='YYYY-MM-DD']
[--help | --avg-monthly-open-close | --max-daily-profit | --busy-day | --biggest-loser]
-v | --verbose: Provide verbose details
-h | --help: Usage
--api-key: Quandl WIKI API Key [Required]
--start-date: 'YYYY-MM-DD' Default: '2018-05-13'
--end-date: 'YYYY-MM-DD' Default: '2018-05-13'
--stocks: List of WIKI Stock Symbols [Required] Default: ['COF', 'GOOGL', 'MSFT']
--avg-monthly-open-close: Average Monthly Open and Close prices for each stock. Default.
--max-daily-profit: Which day provided the highest amount of profit for each stock.
--busy-day: Which days generated unusually high activity for each stock.
--biggest-loser: Which stock had the most days where the closing price was lower than the opening price.
python3 stock_investing/worker.py \
--api-key '[REDACTED]' \
--start-date '2017-01-01' \
--end-date '2017-06-30' \
--avg-monthly-open-close
$ make run-example-avg-monthly-open-close
{
'COF': [
{'average_close': 88.26, 'average_open': 88.3, 'month': '2017-01'},
{'average_close': 90.2, 'average_open': 89.85, 'month': '2017-02'},
{'average_close': 88.93, 'average_open': 89.27, 'month': '2017-03'},
{'average_close': 83.24, 'average_open': 83.41, 'month': '2017-04'},
{'average_close': 80.51, 'average_open': 80.65, 'month': '2017-05'},
{'average_close': 80.33, 'average_open': 80.1, 'month': '2017-06'},
],
'GOOGL': [
{'average_close': 830.25, 'average_open': 829.85, 'month': '2017-01'},
{'average_close': 836.75, 'average_open': 836.15, 'month': '2017-02'},
{'average_close': 853.79, 'average_open': 853.86, 'month': '2017-03'},
{'average_close': 861.38, 'average_open': 860.08, 'month': '2017-04'},
{'average_close': 961.65, 'average_open': 959.6, 'month': '2017-05'},
{'average_close': 973.37, 'average_open': 975.78, 'month': '2017-06'},
],
'MSFT': [
{'average_close': 63.19, 'average_open': 63.19, 'month': '2017-01'},
{'average_close': 64.11, 'average_open': 64.13, 'month': '2017-02'},
{'average_close': 64.84, 'average_open': 64.76, 'month': '2017-03'},
{'average_close': 66.17, 'average_open': 66.24, 'month': '2017-04'},
{'average_close': 68.92, 'average_open': 68.83, 'month': '2017-05'},
{'average_close': 70.52, 'average_open': 70.56, 'month': '2017-06'},
],
}
python3 stock_investing/worker.py \
--api-key '[REDACTED]' \
--start-date '2017-01-01' \
--end-date '2017-06-30' \
--max-daily-profit
$ make run-example-max-daily-profit
{
'COF': {'Date': '2017-03-21', 'Profit': 3.76},
'GOOGL': {'Date': '2017-06-09', 'Profit': 52.13},
'MSFT': {'Date': '2017-06-09', 'Profit': 3.49},
}
Which security had the most days where the closing price was lower than the opening price. Please display the ticker symbol and the number of days that security’s closing price was lower than that day’s opening price.
$ python3 stock_investing/worker.py \
--api-key '[REDACTED]' \
--start-date '2017-01-01' \
--end-date '2017-06-30' \
--biggest-loser
$ make run-example-biggest-loser
{'COF': 62}
We’d like to know which days generated unusually high activity for our securities. Please display the ticker symbol, date, and volume for each day where the volume was more than 10% higher than the security’s average volume (Note: You’ll need to calculate the average volume, and should display that somewhere too).
python3 stock_investing/worker.py \
--api-key '[REDACTED]' \
--start-date '2017-01-01' \
--end-date '2017-06-30' \
--busy-day
$ make run-example-busy-day
{
'COF': [
{'date': '2017-05-12', 'volume': 3931119, 'volume_mean': 2757167},
{'date': '2017-06-19', 'volume': 3225890, 'volume_mean': 2757167},
{'date': '2017-03-22', 'volume': 3133651, 'volume_mean': 2757167},
{'date': '2017-03-17', 'volume': 3388267, 'volume_mean': 2757167},
{'date': '2017-04-25', 'volume': 3080861, 'volume_mean': 2757167},
{'date': '2017-01-25', 'volume': 5304078, 'volume_mean': 2757167},
{'date': '2017-02-07', 'volume': 3514042, 'volume_mean': 2757167},
{'date': '2017-04-13', 'volume': 3400095, 'volume_mean': 2757167},
{'date': '2017-03-15', 'volume': 3178963, 'volume_mean': 2757167},
{'date': '2017-06-01', 'volume': 3295232, 'volume_mean': 2757167},
{'date': '2017-01-03', 'volume': 3441067, 'volume_mean': 2757167},
{'date': '2017-05-18', 'volume': 4884650, 'volume_mean': 2757167},
{'date': '2017-06-15', 'volume': 3854218, 'volume_mean': 2757167},
{'date': '2017-04-03', 'volume': 3158771, 'volume_mean': 2757167},
{'date': '2017-04-26', 'volume': 7386158, 'volume_mean': 2757167},
{'date': '2017-05-04', 'volume': 3154418, 'volume_mean': 2757167},
{'date': '2017-04-06', 'volume': 4378949, 'volume_mean': 2757167},
{'date': '2017-05-31', 'volume': 4205013, 'volume_mean': 2757167},
{'date': '2017-03-30', 'volume': 4081656, 'volume_mean': 2757167},
{'date': '2017-04-17', 'volume': 3759420, 'volume_mean': 2757167},
{'date': '2017-03-01', 'volume': 3387946, 'volume_mean': 2757167},
{'date': '2017-01-10', 'volume': 3141198, 'volume_mean': 2757167},
{'date': '2017-03-27', 'volume': 4282097, 'volume_mean': 2757167},
{'date': '2017-05-01', 'volume': 3543401, 'volume_mean': 2757167},
{'date': '2017-06-29', 'volume': 6009615, 'volume_mean': 2757167},
{'date': '2017-05-17', 'volume': 3145845, 'volume_mean': 2757167},
{'date': '2017-04-28', 'volume': 6133211, 'volume_mean': 2757167},
{'date': '2017-03-21', 'volume': 4559025, 'volume_mean': 2757167},
{'date': '2017-06-16', 'volume': 3255538, 'volume_mean': 2757167},
{'date': '2017-02-28', 'volume': 3122357, 'volume_mean': 2757167},
{'date': '2017-04-18', 'volume': 3119402, 'volume_mean': 2757167},
{'date': '2017-05-11', 'volume': 3741154, 'volume_mean': 2757167},
{'date': '2017-04-27', 'volume': 3604560, 'volume_mean': 2757167},
{'date': '2017-01-30', 'volume': 3550371, 'volume_mean': 2757167},
{'date': '2017-06-09', 'volume': 3476989, 'volume_mean': 2757167},
{'date': '2017-06-28', 'volume': 3773097, 'volume_mean': 2757167},
{'date': '2017-03-28', 'volume': 3784720, 'volume_mean': 2757167},
{'date': '2017-02-21', 'volume': 3825225, 'volume_mean': 2757167},
{'date': '2017-02-17', 'volume': 4044661, 'volume_mean': 2757167},
],
'GOOGL': [
{'date': '2017-01-27', 'volume': 3752497, 'volume_mean': 1632363},
{'date': '2017-05-01', 'volume': 2294856, 'volume_mean': 1632363},
{'date': '2017-03-17', 'volume': 1868252, 'volume_mean': 1632363},
{'date': '2017-06-12', 'volume': 4167184, 'volume_mean': 1632363},
{'date': '2017-02-01', 'volume': 2251047, 'volume_mean': 1632363},
{'date': '2017-03-23', 'volume': 3287669, 'volume_mean': 1632363},
{'date': '2017-03-27', 'volume': 1935211, 'volume_mean': 1632363},
{'date': '2017-06-16', 'volume': 2484914, 'volume_mean': 1632363},
{'date': '2017-06-29', 'volume': 3182331, 'volume_mean': 1632363},
{'date': '2017-06-28', 'volume': 2713366, 'volume_mean': 1632363},
{'date': '2017-01-03', 'volume': 1959033, 'volume_mean': 1632363},
{'date': '2017-06-15', 'volume': 2349212, 'volume_mean': 1632363},
{'date': '2017-04-03', 'volume': 1969402, 'volume_mean': 1632363},
{'date': '2017-04-05', 'volume': 1855153, 'volume_mean': 1632363},
{'date': '2017-05-04', 'volume': 1934652, 'volume_mean': 1632363},
{'date': '2017-04-25', 'volume': 2020460, 'volume_mean': 1632363},
{'date': '2017-05-17', 'volume': 2414323, 'volume_mean': 1632363},
{'date': '2017-01-06', 'volume': 2017097, 'volume_mean': 1632363},
{'date': '2017-05-08', 'volume': 1863198, 'volume_mean': 1632363},
{'date': '2017-03-01', 'volume': 1818671, 'volume_mean': 1632363},
{'date': '2017-06-13', 'volume': 1992456, 'volume_mean': 1632363},
{'date': '2017-01-23', 'volume': 2457377, 'volume_mean': 1632363},
{'date': '2017-01-26', 'volume': 3493251, 'volume_mean': 1632363},
{'date': '2017-04-28', 'volume': 3753169, 'volume_mean': 1632363},
{'date': '2017-03-21', 'volume': 2537978, 'volume_mean': 1632363},
{'date': '2017-01-31', 'volume': 2020180, 'volume_mean': 1632363},
{'date': '2017-05-25', 'volume': 1951402, 'volume_mean': 1632363},
{'date': '2017-04-27', 'volume': 1817740, 'volume_mean': 1632363},
{'date': '2017-01-30', 'volume': 3516933, 'volume_mean': 1632363},
{'date': '2017-06-09', 'volume': 3613964, 'volume_mean': 1632363},
{'date': '2017-06-30', 'volume': 2185444, 'volume_mean': 1632363},
{'date': '2017-06-27', 'volume': 2428048, 'volume_mean': 1632363},
{'date': '2017-03-24', 'volume': 2105682, 'volume_mean': 1632363},
],
'MSFT': [
{'date': '2017-01-20', 'volume': 30213462, 'volume_mean': 23748646},
{'date': '2017-01-27', 'volume': 44817972, 'volume_mean': 23748646},
{'date': '2017-05-01', 'volume': 31304672, 'volume_mean': 23748646},
{'date': '2017-03-17', 'volume': 49219686, 'volume_mean': 23748646},
{'date': '2017-05-15', 'volume': 30705323, 'volume_mean': 23748646},
{'date': '2017-02-01', 'volume': 39671528, 'volume_mean': 23748646},
{'date': '2017-06-16', 'volume': 46911637, 'volume_mean': 23748646},
{'date': '2017-05-16', 'volume': 33250702, 'volume_mean': 23748646},
{'date': '2017-06-12', 'volume': 47363986, 'volume_mean': 23748646},
{'date': '2017-05-11', 'volume': 27985424, 'volume_mean': 23748646},
{'date': '2017-06-06', 'volume': 31220057, 'volume_mean': 23748646},
{'date': '2017-04-25', 'volume': 29983174, 'volume_mean': 23748646},
{'date': '2017-05-31', 'volume': 29538356, 'volume_mean': 23748646},
{'date': '2017-04-19', 'volume': 26992771, 'volume_mean': 23748646},
{'date': '2017-05-17', 'volume': 29964198, 'volume_mean': 23748646},
{'date': '2017-06-05', 'volume': 29507429, 'volume_mean': 23748646},
{'date': '2017-03-01', 'volume': 26937459, 'volume_mean': 23748646},
{'date': '2017-02-03', 'volume': 30301759, 'volume_mean': 23748646},
{'date': '2017-04-24', 'volume': 29721254, 'volume_mean': 23748646},
{'date': '2017-06-02', 'volume': 34586054, 'volume_mean': 23748646},
{'date': '2017-01-26', 'volume': 43554645, 'volume_mean': 23748646},
{'date': '2017-04-28', 'volume': 38940853, 'volume_mean': 23748646},
{'date': '2017-03-21', 'volume': 26640480, 'volume_mean': 23748646},
{'date': '2017-02-02', 'volume': 45827013, 'volume_mean': 23748646},
{'date': '2017-06-29', 'volume': 28231562, 'volume_mean': 23748646},
{'date': '2017-04-21', 'volume': 32522645, 'volume_mean': 23748646},
{'date': '2017-01-30', 'volume': 31651445, 'volume_mean': 23748646},
{'date': '2017-06-09', 'volume': 48619420, 'volume_mean': 23748646},
{'date': '2017-05-19', 'volume': 26496478, 'volume_mean': 23748646},
{'date': '2017-04-27', 'volume': 32219234, 'volume_mean': 23748646},
{'date': '2017-05-03', 'volume': 28725646, 'volume_mean': 23748646},
],
}