import json import csv import logging from pathlib import Path import argparse from collections import namedtuple import requests logging.basicConfig(level=logging.INFO) QUANDL_URL = 'https://www.quandl.com/api/v3/datasets/WIKI/{}.json' DATASTORE = Path('/project/stock-price/data') Configuration = namedtuple( 'Configuration', ['stock', 'start_date', 'end_date'] ) def fetch_stock_info(stock, start_date, end_date): response = requests.get( QUANDL_URL.format(stock), params={'start_date': start_date, 'end_date': end_date} ) response.raise_for_status() json = response.json() data = json['dataset']['data'] stock_price = {} for entry in data: date = entry[0] closing = entry[4] stock_price[date] = float(closing) return stock_price def read_current_data(store): stock_prices = {} try: with open(store) as f: reader = csv.reader(f) next(reader) # skip header for row in reader: date, price = row stock_prices[date] = price except FileNotFoundError: return {} return stock_prices def write_data(store, stock_prices): sorted_data = sorted(stock_prices.items(), key=lambda it: it[0]) with open(store, 'w') as f: writer = csv.writer(f) writer.writerow(['date', 'price']) writer.writerows(sorted_data) def store_update(store, new_prices): stock_prices = read_current_data(store) stock_prices.update(new_prices) write_data(store, stock_prices) def fetch_and_update_stocks(stock, start_date, end_date): logging.info( f'Fetching stocks for symbol {stock} ' f'between {start_date} and {end_date}' ) prices = fetch_stock_info(stock, start_date, end_date) logging.info(f'Fetched {len(prices)} stock prices.') store = DATASTORE / f'{stock}.csv' store_update(store, prices) logging.info(f'Written information back to data store {store}.') def parse_command_line(): parser = argparse.ArgumentParser( description='Fetch and store stock information') parser.add_argument('symbol') parser.add_argument( 'start_date', help='start date, in format 2018-01-22' ) parser.add_argument( 'end_date', help='end date, in format 2018-01-29' ) args = parser.parse_args() return Configuration( args.symbol.upper(), args.start_date, args.end_date ) if __name__ == '__main__': configuration = parse_command_line() logging.info(f'Using configuration {configuration}.') fetch_and_update_stocks( configuration.stock, configuration.start_date, configuration.end_date )