Demo entry 6741397

asdfgfhhsdf

   

Submitted by anonymous on May 15, 2018 at 11:29
Language: Python 3. Code size: 4.0 kB.

import asyncio
import json
import requests
import pickle

from concurrent.futures import ThreadPoolExecutor
from copy import copy
from pprint import pformat
from threading import RLock

import click
import matplotlib.pyplot as plt
import pandas as pd

base_url = 'https://api.iextrading.com/1.0/stock/{}/chart'


class DataContainer:
    def __init__(self, load=False, path=None):
        self._store = dict()
        self._lock = RLock()

        if path:
            self.load(path)
        elif load:
            self.load()

    @staticmethod
    def _munge(df):
        df['date'] = pd.to_datetime(df['date'])
        df = df.sort_values('date')
        return df

    def add(self, response):
        # check if the response was positive
        assert response.status_code == 200,\
            f'Response wasn\' positive, {response.status_code}'
        # determin the spliting pattern
        front, back = base_url.split('{}')
        # extract symbol from responses url
        key = response.url.partition(front)[2].partition(back)[0]
        # convert responses data to pandas df
        df = pd.read_json(response.text)
        # munge the data
        df = self._munge(df)

        # actually store the df
        with self._lock:
            self._store[key] = df

    def __getitem__(self, key):
        with self._lock:
            df = copy(self._store[key])
        return df

    def save(self, path='data.p'):
        if path.endswith('.p'):
            with self._lock, open(path, 'wb') as f:
                pickle.dump(self._store, f, protocol=pickle.HIGHEST_PROTOCOL)
        elif path.endswith('.json'):
            with self._lock, open(path, 'w') as f:
                json.dump(
                    {
                        key: json.loads(df.to_json())
                        for key, df in self._store.items()
                    },
                    f
                )

    def load(self, path='data.p'):
        if path.endswith('.p'):
            with open(path, 'rb') as f:
                new_store = pickle.load(f)
        elif path.endswith('.json'):
            with open(path, 'r') as f:
                loaded = json.load(f)
            new_store = {key: self._munge(pd.DataFrame(dic)) for key, dic in loaded.items()}
        with self._lock:
            self._store = new_store

    def __repr__(self):
        return pformat(self._store)

    def plot(self):
        with self._lock:
            for symbol, df in self._store.items():
                plt.plot(df['date'], df['volume'], label=symbol)
        plt.xticks(rotation='vertical')
        plt.legend(
            bbox_to_anchor=(0., 1.02, 1., .102),
            loc=3,
            ncol=2,
            mode="expand",
            borderaxespad=0.
        )
        plt.show()


async def get_data(symbols, path='data.p'):
    store = DataContainer()
    with ThreadPoolExecutor(max_workers=20) as executor:
        loop = asyncio.get_event_loop()
        # run all of the request asyncronosly
        request_futures = [
            loop.run_in_executor(
                executor,
                requests.get,
                base_url.format(symbol)
            )
            for symbol in symbols
        ]
        # run all of the store/munging operations asyncronosly
        store_futures = [
            loop.run_in_executor(
                executor,
                lambda: store.add(response)
            )
            for response in await asyncio.gather(*request_futures)
        ]
        # wait for all the storing to complete
        for done in await asyncio.gather(*store_futures):
            pass
        # save the results to a pickle
        store.save(path=path)

@click.command()
@click.option('--symbols', prompt=True)
def main(symbols):
    symbols = ''.join(symbols.lower()).split()
    loop = asyncio.get_event_loop()
    loop.run_until_complete(get_data(symbols))
    store = DataContainer(load=True)
    store.plot()


if __name__ == '__main__':
    main()

This snippet took 0.01 seconds to highlight.

Back to the Entry List or Home.

Delete this entry (admin only).