In [1]:
import sys # for gioia to load aiohttp
sys.path.append('/Users/maggiori/anaconda/envs/py35/lib/python3.5/site-packages')

In [2]:
# to import modules locally even if the package hasn't been installed
# http://stackoverflow.com/questions/714063/importing-modules-from-parent-folder
import os, sys, inspect
currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
parentdir = os.path.dirname(currentdir)
sys.path.insert(0, parentdir)

In [3]:
import time
import signal
import subprocess
import numpy as np
from scipy.stats import norm
import json
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns
sns.set_style('white')
sns.set_context('notebook')

In [4]:
from timeseries import *


Generating LALR tables

Stock Market Similarity Searches: Daily Returns

We have provided a year of daily returns for 379 S&P 500 stocks. We have explicitly excluded stocks with incomplete or missing data. We have pre-loaded 350 stocks in the database, and have excluded 29 stocks for later use in similarity searches.

Data source: www.stockwiz.com


In [5]:
# load data
with open('data/returns_include.json') as f:    
    stock_data_include = json.load(f)
with open('data/returns_exclude.json') as f:    
    stock_data_exclude = json.load(f)

# keep track of which stocks are included/excluded from the database
stocks_include = list(stock_data_include.keys())
stocks_exclude = list(stock_data_exclude.keys())
    
# check the number of market days in the year
num_days = len(stock_data_include[stocks_include[0]])
num_days


Out[5]:
244

Database Initialization

Let's start by initializing all the database components.


In [6]:
# 1. load the database server

# when running from the terminal
# python go_server_persistent.py --ts_length 244 --db_name 'stock_prices'

# here we load the server as a subprocess for demonstration purposes
server = subprocess.Popen(['python', '../go_server_persistent.py',
                           '--ts_length', str(num_days), '--data_dir', '../db_files', '--db_name', 'stock_returns'])
time.sleep(5)  # make sure it loads completely

# 2. load the database webserver

# when running from the terminal
# python go_webserver.py

# here we load the server as a subprocess for demonstration purposes
webserver = subprocess.Popen(['python', '../go_webserver.py'])
time.sleep(5)  # make sure it loads completely

# 3. import the web interface and initialize it

from webserver import *
web_interface = WebInterface()

Stock Data Initialization

The database is now up and running. We have pre-loaded the data for you, but you can always unquote the code below to re-load the data if you accidentally delete it.


In [7]:
# # insert into database
# for stock in stocks_include:
#     web_interface.insert_ts(pk=stock, ts=TimeSeries(range(num_days), stock_data_include[stock]))

Let's check how many stocks are currently in the database (should be 350).


In [8]:
len(web_interface.select())


Out[8]:
350

Let's look at the first 10 stocks, to check that the data has been loaded correctly.


In [9]:
# let's look at the first 10 stocks
web_interface.select(fields=['ts'], additional={'sort_by': '+pk', 'limit': 10})


Out[9]:
OrderedDict([('A',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [-0.00195694716242667, ..., 0.0007007708479327412]))])),
             ('AA',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [-0.011146496815286677, ..., -0.008442776735459678]))])),
             ('ABC',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [-0.01187648456057011, ..., -0.008570449091532373]))])),
             ('ABT',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [0.01520158625247836, ..., 0.00040551500405516805]))])),
             ('ADI',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [-0.006333567909922677, ..., -0.001685203909673083]))])),
             ('ADM',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [-0.009766306243460088, ..., 0.009593119417796947]))])),
             ('AEE',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [0.005545286506469349, ..., 0.0011066027296200431]))])),
             ('AEP',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [0.0015878056525882034, ..., -0.0005740528128588274]))])),
             ('AES',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [0.011220196353436185, ..., -0.017013232514177634]))])),
             ('AET',
              OrderedDict([('ts',
                            TimeSeries(Length: 244 [0.00979068197164068, ..., -0.005137614678899061]))]))])

We need to initialize vantage points in order to carry out a vantage point search. Again, this has already been done for you, but you can re-create the results by running the following code.


In [10]:
# # randomly pick vantage points
# # note: this can be time-intensive for a large number of vantage points
# num_vps = 10
# random_vps = np.random.choice(len(stocks_include), size=num_vps, replace=False)
# vpkeys = [stocks_include[s] for s in random_vps]

# # mark in database
# for vp in vpkeys:
#     web_interface.insert_vp(vp)

Let's pick one of our excluded stocks and carry out a vantage point similarity search.


In [11]:
# pick the stock
stock = np.random.choice(stocks_exclude)
print('Stock:', stock)

# run the vantage point similarity search
result = web_interface.vp_similarity_search(TimeSeries(range(num_days), stock_data_exclude[stock]), 1)
stock_match = list(result)[0]
stock_ts = web_interface.select(fields=['ts'], md={'pk': stock_match})[stock_match]['ts']
print('Most similar stock:', stock_match)

# visualize similarity
plt.plot(stock_data_exclude[stock], label='Query:' + stock)
plt.plot(stock_ts.values(), label='Result:' + stock_match)
plt.xticks([])
plt.legend(loc='best')
plt.title('Daily Stock Return Similarity')
plt.show()


Stock: HST
Most similar stock: BXP

Let's pick another one of our excluded stocks and carry out an iSAX tree similarity search. Note that this is an approximate search technique, so it will not always be able to find a similar stock.


In [12]:
# pick the stock
stock = np.random.choice(stocks_exclude)
print('Stock:', stock)

# run the isax tree similarity search
result = web_interface.isax_similarity_search(TimeSeries(range(num_days), stock_data_exclude[stock]))

# could not find a match
if result == 'ERROR: NO_MATCH':
    print('Could not find a similar stock.')

# found a match
else:
    # closest time series
    stock_match = list(result)[0]
    stock_ts = web_interface.select(fields=['ts'], md={'pk': stock_match})[stock_match]['ts']
    print('Most similar stock:', stock_match)
    
    # visualize similarity
    plt.plot(stock_data_exclude[stock], label='Query:' + stock)
    plt.plot(stock_ts.values(), label='Result:' + stock_match)
    plt.xticks([])
    plt.legend(loc='best')
    plt.title('Daily Stock Return Similarity')
    plt.show()


Stock: TMK
Most similar stock: PRU

Comparing Similarity Searches

Now, let's pick one more random stock, carry out both types of similarity searches, and compare the results.


In [13]:
# pick the stock
stock = np.random.choice(stocks_exclude)
print('Stock:', stock)

# run the vantage point similarity search
result = web_interface.vp_similarity_search(TimeSeries(range(num_days), stock_data_exclude[stock]), 1)
match_vp = list(result)[0]
ts_vp = web_interface.select(fields=['ts'], md={'pk': match_vp})[match_vp]['ts']
print('VP search result:', match_vp)

# run the isax similarity search
result = web_interface.isax_similarity_search(TimeSeries(range(num_days), stock_data_exclude[stock]))

# could not find an isax match
if result == 'ERROR: NO_MATCH':
    print('iSAX search result: Could not find a similar stock.')

# found a match
else:
    # closest time series
    match_isax = list(result)[0]
    ts_isax = web_interface.select(fields=['ts'], md={'pk': match_isax})[match_isax]['ts']
    print('iSAX search result:', match_isax)
    
    # visualize similarity
    plt.plot(stock_data_exclude[stock], label='Query:' + stock)
    plt.plot(ts_vp.values(), label='Result:' + match_vp)
    plt.plot(ts_isax.values(), label='Result:' + match_isax)
    plt.xticks([])
    plt.legend(loc='best')
    plt.title('Daily Stock Return Similarity')
    plt.show()


Stock: TSN
VP search result: HES
iSAX search result: DRI

iSAX Tree Representation

Finally, let's visualize the iSAX tree. The clusters represent groups of "similar" stocks.


In [14]:
print(web_interface.isax_tree())


root
--->['10', '01', '10', '01']: 0 []
------>['100', '011', '100', '011']: 0 []
--------->['1000', '0111', '1000', '0111']: 0 []
------------>['10001', '01110', '10000', '01111']: 2 ['GPC', 'STT']
------------>['10000', '01110', '10000', '01111']: 2 ['CCE', 'LUK']
------------>['10000', '01111', '10000', '01110']: 1 ['NU']
------------>['10000', '01111', '10000', '01111']: 3 ['BSX', 'NSM', 'UNP']
------------>['10001', '01111', '10001', '01110']: 2 ['AYE', 'WEC']
------------>['10000', '01110', '10001', '01111']: 2 ['MCO', 'X']
------------>['10000', '01111', '10001', '01110']: 5 ['AEP', 'CMS', 'CNP', 'HRL', 'MMC']
--------->['1000', '0111', '1000', '0110']: 1 ['BLL']
--->['01', '10', '10', '10']: 0 []
------>['011', '100', '100', '100']: 0 []
--------->['0111', '1000', '1000', '1000']: 0 []
------------>['01111', '10000', '10000', '10000']: 0 []
--------------->['011110', '100000', '100000', '100001']: 1 ['TDC']
--------------->['011110', '100000', '100000', '100000']: 3 ['EMC', 'MMM', 'TWC']
--------------->['011110', '100001', '100000', '100000']: 1 ['IFF']
--------------->['011110', '100000', '100001', '100000']: 1 ['CI']
------------>['01110', '10000', '10000', '10000']: 0 []
--------------->['011101', '100001', '100001', '100000']: 3 ['IP', 'MA', 'SLB']
--------------->['011100', '100001', '100001', '100001']: 1 ['APH']
--------------->['011101', '100000', '100001', '100000']: 2 ['DOV', 'PCP']
--------------->['011101', '100001', '100000', '100000']: 3 ['ETN', 'OXY', 'PEP']
--------------->['011100', '100000', '100001', '100001']: 2 ['DOW', 'PLD']
--------------->['011101', '100000', '100000', '100001']: 2 ['EOG', 'GE']
--------------->['011100', '100001', '100001', '100000']: 1 ['FDX']
--------------->['011101', '100000', '100000', '100000']: 1 ['DIS']
--------------->['011101', '100001', '100000', '100001']: 1 ['CBS']
--------------->['011100', '100000', '100000', '100001']: 1 ['COH']
------------>['01110', '10000', '10000', '10001']: 2 ['HIG', 'HRS']
------------>['01110', '10000', '10001', '10000']: 1 ['WMT']
------------>['01110', '10001', '10000', '10000']: 1 ['AXP']
--------->['0110', '1000', '1000', '1000']: 0 []
------------>['01101', '10000', '10001', '10000']: 3 ['CL', 'DO', 'TIF']
------------>['01101', '10000', '10000', '10001']: 4 ['CSC', 'SLE', 'WAG', 'ZMH']
------------>['01101', '10000', '10001', '10001']: 1 ['PG']
------------>['01101', '10001', '10000', '10000']: 1 ['MWV']
------------>['01101', '10001', '10000', '10001']: 1 ['HRB']
--------->['0110', '1000', '1000', '1001']: 1 ['AMD']
--->['10', '01', '01', '10']: 0 []
------>['100', '011', '011', '100']: 0 []
--------->['1000', '0111', '0111', '1000']: 0 []
------------>['10001', '01110', '01111', '10000']: 3 ['IRM', 'JEC', 'MI']
------------>['10000', '01111', '01111', '10000']: 0 []
--------------->['100000', '011110', '011111', '100001']: 3 ['AIV', 'FO', 'LNC']
--------------->['100000', '011111', '011111', '100000']: 1 ['HOT']
--------------->['100001', '011111', '011110', '100000']: 1 ['MET']
--------------->['100000', '011111', '011110', '100000']: 1 ['NUE']
--------------->['100001', '011110', '011111', '100000']: 1 ['VLO']
--------------->['100001', '011110', '011110', '100001']: 1 ['UNM']
------------>['10000', '01110', '01111', '10001']: 2 ['CVS', 'LEN']
------------>['10000', '01110', '01111', '10000']: 2 ['BAC', 'DHI']
------------>['10001', '01111', '01110', '10000']: 2 ['DNR', 'PWR']
------------>['10001', '01111', '01111', '10000']: 1 ['KEY']
------------>['10001', '01110', '01111', '10001']: 1 ['PHM']
--------->['1000', '0111', '0110', '1000']: 1 ['SHW']
--------->['1000', '0111', '0111', '1001']: 1 ['BBT']
--------->['1001', '0111', '0111', '1000']: 1 ['HSY']
--------->['1000', '0111', '0110', '1001']: 1 ['WPO']
--->['01', '10', '01', '10']: 0 []
------>['011', '100', '011', '100']: 0 []
--------->['0111', '1000', '0111', '1000']: 0 []
------------>['01111', '10000', '01110', '10000']: 1 ['PFG']
------------>['01110', '10000', '01111', '10000']: 2 ['NKE', 'RL']
------------>['01111', '10000', '01111', '10001']: 3 ['JCP', 'LMT', 'MAS']
------------>['01111', '10000', '01111', '10000']: 0 []
--------------->['011110', '100000', '011111', '100001']: 2 ['HON', 'PBI']
--------------->['011111', '100000', '011111', '100000']: 3 ['CSX', 'GR', 'OMC']
--------------->['011110', '100000', '011111', '100000']: 1 ['NSC']
--------------->['011110', '100001', '011111', '100000']: 1 ['LH']
--------------->['011111', '100000', '011110', '100000']: 1 ['TIE']
------------>['01110', '10000', '01111', '10001']: 4 ['ICE', 'K', 'PXD', 'WAT']
------------>['01111', '10001', '01110', '10000']: 2 ['LM', 'NWL']
------------>['01111', '10001', '01111', '10000']: 1 ['AIG']
------------>['01110', '10001', '01110', '10001']: 2 ['HOG', 'MCK']
------------>['01111', '10000', '01110', '10001']: 3 ['IGT', 'LEG', 'VMC']
------------>['01110', '10001', '01111', '10000']: 1 ['ITW']
--------->['0111', '1000', '0110', '1000']: 1 ['R']
--------->['0110', '1001', '0111', '1000']: 1 ['AVY']
--------->['0111', '1001', '0111', '1000']: 3 ['CPB', 'DNB', 'STZ']
--------->['0111', '1001', '0110', '1000']: 1 ['GME']
--------->['0111', '1000', '0111', '1001']: 2 ['BBY', 'GPS']
--------->['0110', '1000', '0111', '1000']: 1 ['PNC']
--->['10', '01', '01', '01']: 0 []
------>['100', '011', '011', '011']: 0 []
--------->['1000', '0111', '0111', '0111']: 0 []
------------>['10001', '01111', '01111', '01111']: 2 ['FLR', 'WFR']
------------>['10000', '01111', '01111', '01111']: 5 ['AVB', 'CBG', 'GT', 'NYX', 'Q']
------------>['10001', '01111', '01111', '01110']: 1 ['AZO']
------------>['10001', '01110', '01111', '01111']: 1 ['KFT']
--->['01', '10', '10', '01']: 0 []
------>['011', '100', '100', '011']: 0 []
--------->['0111', '1000', '1001', '0111']: 0 []
------------>['01110', '10000', '10010', '01111']: 2 ['MRK', 'PFE']
------------>['01110', '10000', '10010', '01110']: 3 ['AMT', 'BTU', 'KG']
------------>['01111', '10000', '10010', '01110']: 2 ['L', 'MON']
--------->['0111', '1000', '1000', '0111']: 0 []
------------>['01110', '10001', '10000', '01111']: 0 []
--------------->['011100', '100011', '100001', '011110']: 1 ['LLY']
--------------->['011101', '100010', '100000', '011110']: 2 ['CAT', 'DFS']
--------------->['011100', '100010', '100000', '011111']: 1 ['BEN']
--------------->['011100', '100011', '100000', '011111']: 4 ['COP', 'CVX', 'NEM', 'SEE']
--------------->['011101', '100010', '100000', '011111']: 2 ['ANF', 'MCD']
------------>['01110', '10000', '10000', '01111']: 0 []
--------------->['011101', '100000', '100001', '011111']: 3 ['DVA', 'KR', 'XL']
--------------->['011101', '100001', '100000', '011111']: 3 ['FLS', 'IVZ', 'MKC']
--------------->['011101', '100001', '100001', '011111']: 4 ['RHT', 'SLM', 'VAR', 'WM']
------------>['01111', '10000', '10000', '01110']: 3 ['ED', 'EIX', 'FE']
------------>['01110', '10000', '10001', '01110']: 1 ['PPL']
------------>['01110', '10000', '10001', '01111']: 0 []
--------------->['011101', '100000', '100010', '011110']: 2 ['HAL', 'NOV']
--------------->['011101', '100000', '100011', '011111']: 1 ['TRV']
--------------->['011101', '100000', '100011', '011110']: 1 ['SJM']
--------------->['011101', '100000', '100010', '011111']: 2 ['AMP', 'HES']
--------------->['011101', '100001', '100010', '011110']: 2 ['DUK', 'FRX']
------------>['01111', '10000', '10000', '01111']: 0 []
--------------->['011111', '100000', '100001', '011110']: 3 ['D', 'VTR', 'XEL']
--------------->['011111', '100000', '100001', '011111']: 1 ['ADI']
--------------->['011110', '100000', '100000', '011111']: 2 ['FTI', 'PPG']
--------------->['011110', '100000', '100001', '011110']: 1 ['TE']
--------------->['011111', '100001', '100000', '011110']: 1 ['HCN']
--------------->['011110', '100000', '100001', '011111']: 1 ['BMS']
--------------->['011110', '100001', '100001', '011111']: 1 ['BF.B']
--------------->['011110', '100001', '100000', '011111']: 2 ['EMN', 'MS']
--------------->['011111', '100000', '100000', '011111']: 3 ['JNS', 'TSO', 'TXN']
--------------->['011110', '100001', '100001', '011110']: 1 ['RSG']
--------------->['011111', '100001', '100001', '011110']: 1 ['AGN']
--------------->['011111', '100001', '100000', '011111']: 1 ['PSA']
------------>['01111', '10000', '10001', '01111']: 4 ['DE', 'POM', 'RAI', 'RDC']
------------>['01111', '10000', '10001', '01110']: 4 ['AES', 'EXC', 'GS', 'NI']
------------>['01110', '10001', '10001', '01110']: 2 ['AVP', 'BMY']
------------>['01111', '10001', '10000', '01110']: 3 ['PCG', 'T', 'VZ']
------------>['01110', '10001', '10001', '01111']: 1 ['CTL']
------------>['01111', '10001', '10000', '01111']: 1 ['MOT']
------------>['01111', '10001', '10001', '01110']: 1 ['SRE']
--------->['0110', '1000', '1001', '0111']: 1 ['ABT']
--------->['0110', '1001', '1000', '0111']: 2 ['KO', 'XOM']
--------->['0111', '1001', '1000', '0111']: 2 ['APD', 'KMB']
--------->['0111', '1000', '1001', '0110']: 1 ['ADM']
--------->['0111', '1001', '1000', '0110']: 1 ['PX']
--------->['0110', '1000', '1000', '0111']: 1 ['FCX']
--->['10', '01', '10', '10']: 0 []
------>['100', '011', '100', '100']: 0 []
--------->['1000', '0110', '1000', '1000']: 4 ['DRI', 'LUV', 'RHI', 'SII']
--------->['1000', '0111', '1000', '1000']: 0 []
------------>['10000', '01111', '10000', '10000']: 3 ['HAS', 'KIM', 'STJ']
------------>['10000', '01110', '10000', '10001']: 1 ['CMA']
------------>['10000', '01110', '10000', '10000']: 3 ['BK', 'SNA', 'XRX']
--->['01', '01', '01', '10']: 0 []
------>['011', '011', '011', '100']: 0 []
--------->['0111', '0111', '0111', '1000']: 0 []
------------>['01110', '01111', '01111', '10001']: 1 ['ABC']
------------>['01111', '01111', '01111', '10000']: 4 ['EQR', 'M', 'PRU', 'WPI']
------------>['01111', '01111', '01111', '10001']: 0 []
--------------->['011110', '011111', '011110', '100011']: 1 ['TMO']
--------------->['011111', '011111', '011111', '100010']: 2 ['TER', 'TGT']
--------------->['011110', '011111', '011111', '100010']: 2 ['FHN', 'TJX']
--------------->['011111', '011111', '011110', '100010']: 1 ['WFC']
--------------->['011110', '011110', '011111', '100010']: 1 ['ATI']
--------------->['011110', '011111', '011110', '100010']: 1 ['THC']
--------->['0111', '0111', '0111', '1001']: 0 []
------------>['01111', '01110', '01111', '10010']: 1 ['HD']
------------>['01110', '01111', '01111', '10010']: 2 ['DHR', 'GIS']
------------>['01111', '01111', '01111', '10010']: 2 ['WHR', 'WY']
------------>['01111', '01110', '01111', '10011']: 1 ['DV']
--->['01', '01', '10', '10']: 0 []
------>['011', '011', '100', '100']: 0 []
--------->['0111', '0111', '1000', '1000']: 0 []
------------>['01111', '01110', '10000', '10000']: 4 ['PKI', 'ROK', 'RRC', 'TEG']
------------>['01111', '01111', '10000', '10000']: 0 []
--------------->['011110', '011111', '100000', '100001']: 3 ['ITT', 'USB', 'VFC']
--------------->['011111', '011111', '100000', '100000']: 2 ['AET', 'GLW']
--------------->['011111', '011110', '100001', '100001']: 1 ['ALL']
--------------->['011110', '011110', '100001', '100001']: 2 ['BA', 'SYY']
--------------->['011111', '011111', '100001', '100000']: 1 ['FII']
--------------->['011111', '011110', '100000', '100001']: 1 ['LTD']
--------------->['011111', '011110', '100001', '100000']: 2 ['CA', 'WYN']
------------>['01111', '01110', '10001', '10000']: 0 []
--------------->['011110', '011101', '100010', '100000']: 3 ['BHI', 'EFX', 'EQT']
--------------->['011111', '011101', '100010', '100000']: 1 ['F']
--------------->['011110', '011101', '100010', '100001']: 1 ['NYT']
--------------->['011111', '011101', '100011', '100000']: 1 ['WLP']
------------>['01111', '01111', '10000', '10001']: 2 ['CCL', 'LSI']
------------>['01110', '01111', '10000', '10001']: 3 ['A', 'DGX', 'NOC']
------------>['01110', '01111', '10001', '10000']: 5 ['EMR', 'HAR', 'HSP', 'SWN', 'WMB']
------------>['01110', '01111', '10000', '10000']: 0 []
--------------->['011101', '011111', '100001', '100001']: 4 ['BCR', 'DTE', 'JNJ', 'SWK']
--------------->['011101', '011111', '100001', '100000']: 1 ['HNZ']
--------------->['011101', '011111', '100000', '100001']: 1 ['KSS']
------------>['01110', '01111', '10001', '10001']: 5 ['GD', 'HPQ', 'JBL', 'LXK', 'SWY']
------------>['01111', '01111', '10001', '10000']: 2 ['AA', 'JCI']
------------>['01111', '01110', '10000', '10001']: 1 ['EK']
------------>['01110', '01110', '10000', '10001']: 1 ['SVU']
------------>['01110', '01110', '10001', '10001']: 3 ['EL', 'GCI', 'GNW']
--------->['0111', '0111', '1000', '1001']: 3 ['CAG', 'RTN', 'WDC']
--------->['0110', '0111', '1000', '1001']: 2 ['MHS', 'SYK']
--------->['0111', '0111', '1001', '1000']: 1 ['BDX']
--------->['0111', '0110', '1000', '1001']: 1 ['LLL']
--------->['0110', '0111', '1000', '1000']: 1 ['MDT']
--->['10', '10', '01', '01']: 0 []
------>['100', '100', '011', '011']: 0 []
--------->['1000', '1000', '0111', '0111']: 0 []
------------>['10001', '10000', '01110', '01111']: 2 ['PCS', 'PTV']
------------>['10000', '10000', '01111', '01111']: 1 ['IPG']
------------>['10000', '10001', '01110', '01111']: 2 ['C', 'YUM']
------------>['10000', '10000', '01111', '01110']: 2 ['PEG', 'SO']
------------>['10000', '10001', '01111', '01110']: 1 ['TAP']
--->['01', '01', '10', '01']: 0 []
------>['011', '011', '100', '011']: 0 []
--------->['0111', '0111', '1001', '0111']: 5 ['AKS', 'BAX', 'CNX', 'NBL', 'PLL']
--------->['0111', '0111', '1000', '0111']: 0 []
------------>['01111', '01111', '10001', '01111']: 0 []
--------------->['011110', '011111', '100011', '011111']: 1 ['APA']
--------------->['011110', '011110', '100011', '011111']: 3 ['CHK', 'COG', 'MHP']
--------------->['011110', '011111', '100010', '011111']: 2 ['DVN', 'HUM']
--------------->['011111', '011111', '100010', '011110']: 1 ['CAM']
--------------->['011111', '011111', '100011', '011110']: 1 ['AFL']
------------>['01111', '01110', '10001', '01111']: 2 ['SE', 'UNH']
------------>['01111', '01111', '10001', '01110']: 1 ['PNW']
------------>['01111', '01111', '10000', '01111']: 5 ['CVH', 'GAS', 'JPM', 'MO', 'PH']
------------>['01110', '01111', '10001', '01111']: 2 ['MEE', 'NBR']
--------->['0111', '0111', '1001', '0110']: 1 ['CF']
--->['01', '10', '01', '01']: 0 []
------>['011', '100', '011', '011']: 0 []
--------->['0111', '1000', '0111', '0111']: 0 []
------------>['01111', '10001', '01111', '01111']: 2 ['DD', 'WU']
------------>['01111', '10001', '01111', '01110']: 2 ['CRM', 'MUR']
------------>['01111', '10000', '01111', '01111']: 5 ['AIZ', 'BXP', 'CLX', 'UPS', 'VNO']
------------>['01111', '10001', '01110', '01111']: 1 ['MRO']
------------>['01110', '10001', '01111', '01111']: 1 ['TWX']
--------->['0111', '1001', '0111', '0111']: 1 ['TSS']
--->['10', '10', '01', '10']: 0 []
------>['100', '100', '011', '100']: 0 []
--------->['1000', '1000', '0111', '1000']: 0 []
------------>['10000', '10000', '01111', '10000']: 1 ['OI']
------------>['10001', '10000', '01110', '10000']: 1 ['FIS']
------------>['10000', '10000', '01110', '10000']: 4 ['FDO', 'MAR', 'PGR', 'S']
--->['10', '10', '10', '01']: 0 []
------>['100', '100', '100', '011']: 0 []
--------->['1000', '1000', '1000', '0111']: 5 ['AN', 'EP', 'PGN', 'SCG', 'SUN']
--------->['1000', '1000', '1000', '0110']: 2 ['AEE', 'MFE']

Termination

Always remember to terminate any outstanding processes!


In [15]:
# terminate processes before exiting
os.kill(server.pid, signal.SIGINT)
time.sleep(5)  # give it time to terminate
web_interface = None
webserver.terminate()