Skip to content

Commit

Permalink
TST: added test cases for holidays detection
Browse files Browse the repository at this point in the history
  • Loading branch information
luca-s committed Apr 24, 2018
1 parent 417621b commit 6016e86
Showing 1 changed file with 161 additions and 12 deletions.
173 changes: 161 additions & 12 deletions alphalens/tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
date_range,
MultiIndex,
Timedelta,
Timestamp,
concat,
)
from pandas.util.testing import (assert_frame_equal,
Expand Down Expand Up @@ -128,17 +129,21 @@ def test_get_clean_factor_and_forward_returns_1(self):
factor_groups = {'A': 1, 'B': 2, 'C': 1, 'D': 2, 'E': 1, 'F': 2}

price_data = [[1.10**i, 0.50**i, 3.00**i, 0.90**i, 0.50**i, 1.00**i]
for i in range(1, 7)]
for i in range(1, 7)] # 6 days = 3 + 3 fwd returns

factor_data = [[3, 4, 2, 1, nan, nan],
[3, nan, nan, 1, 4, 2],
[3, 4, 2, 1, nan, nan]]
[3, 4, 2, 1, nan, nan]] # 3 days

price_index = date_range(start='2015-1-11', end='2015-1-16')
start = '2015-1-11'
factor_end = '2015-1-13'
price_end = '2015-1-16' # 3D fwd returns

price_index = date_range(start=start, end=price_end)
price_index.name = 'date'
prices = DataFrame(index=price_index, columns=tickers, data=price_data)

factor_index = date_range(start='2015-1-11', end='2015-1-13')
factor_index = date_range(start=start, end=factor_end)
factor_index.name = 'date'
factor = DataFrame(index=factor_index, columns=tickers,
data=factor_data).stack()
Expand Down Expand Up @@ -180,17 +185,21 @@ def test_get_clean_factor_and_forward_returns_2(self):
factor_groups = {'A': 1, 'B': 2, 'C': 1, 'D': 2, 'E': 1, 'F': 2}

price_data = [[1.10**i, 0.50**i, 3.00**i, 0.90**i, 0.50**i, 1.00**i]
for i in range(1, 7)]
for i in range(1, 7)] # 6 days = 3 + 3 fwd returns

factor_data = [[3, 4, 2, 1, nan, nan],
[3, nan, nan, 1, 4, 2],
[3, 4, 2, 1, nan, nan]]
[3, 4, 2, 1, nan, nan]] # 3 days

start = '2017-1-12'
factor_end = '2017-1-16'
price_end = '2017-1-19' # 3D fwd returns

price_index = date_range(start='2017-1-12', end='2017-1-19', freq='B')
price_index = date_range(start=start, end=price_end, freq='B')
price_index.name = 'date'
prices = DataFrame(index=price_index, columns=tickers, data=price_data)

factor_index = date_range(start='2017-1-12', end='2017-1-16', freq='B')
factor_index = date_range(start=start, end=factor_end, freq='B')
factor_index.name = 'date'
factor = DataFrame(index=factor_index, columns=tickers,
data=factor_data).stack()
Expand Down Expand Up @@ -231,13 +240,17 @@ def test_get_clean_factor_and_forward_returns_3(self):
factor_groups = {'A': 1, 'B': 2, 'C': 1, 'D': 2, 'E': 1, 'F': 2}

price_data = [[1.10**i, 0.50**i, 3.00**i, 0.90**i, 0.50**i, 1.00**i]
for i in range(1, 7)]
for i in range(1, 5)] # 4 days = 3 + 1 fwd returns

factor_data = [[3, 4, 2, 1, nan, nan],
[3, nan, nan, 1, 4, 2],
[3, 4, 2, 1, nan, nan]]
[3, 4, 2, 1, nan, nan]] # 3 days

price_index = date_range(start='2017-1-12', end='2017-1-19', freq='B')
start = '2017-1-12'
factor_end = '2017-1-16'
price_end = '2017-1-17' # 1D fwd returns

price_index = date_range(start=start, end=price_end, freq='B')
price_index.name = 'date'
today_open = DataFrame(index=price_index + Timedelta('9h30m'),
columns=tickers, data=price_data)
Expand All @@ -250,7 +263,7 @@ def test_get_clean_factor_and_forward_returns_3(self):
prices = concat([today_open, today_open_1h, today_open_3h]) \
.sort_index()

factor_index = date_range(start='2017-1-12', end='2017-1-16', freq='B')
factor_index = date_range(start=start, end=factor_end, freq='B')
factor_index.name = 'date'
factor = DataFrame(index=factor_index + Timedelta('9h30m'),
columns=tickers, data=factor_data).stack()
Expand Down Expand Up @@ -330,3 +343,139 @@ def test_get_clean_factor_and_forward_returns_4(self):
expected['group'] = expected['group'].astype('category')

assert_frame_equal(factor_data, expected)

def test_get_clean_factor_and_forward_returns_5(self):
"""
Test get_clean_factor_and_forward_returns with and intraday factor
and holidays
"""
tickers = ['A', 'B', 'C', 'D', 'E', 'F']

factor_groups = {'A': 1, 'B': 2, 'C': 1, 'D': 2, 'E': 1, 'F': 2}

price_data = [[1.10**i, 0.50**i, 3.00**i, 0.90**i, 0.50**i, 1.00**i]
for i in range(1, 20)] # 19 days = 18 + 1 fwd returns

factor_data = [[3, 4, 2, 1, nan, nan],
[3, nan, nan, 1, 4, 2],
[3, 4, 2, 1, nan, nan]] * 6 # 18 days

start = '2017-1-12'
factor_end = '2017-2-10'
price_end = '2017-2-13' # 1D (business day) fwd returns
holidays = ['2017-1-13', '2017-1-18', '2017-1-30', '2017-2-7']
holidays = [Timestamp(d) for d in holidays]

price_index = date_range(start=start, end=price_end, freq='B')
price_index.name = 'date'
price_index = price_index.drop(holidays)

today_open = DataFrame(index=price_index + Timedelta('9h30m'),
columns=tickers, data=price_data)
today_open_1h = DataFrame(index=price_index + Timedelta('10h30m'),
columns=tickers, data=price_data)
today_open_1h += today_open_1h * 0.001
today_open_3h = DataFrame(index=price_index + Timedelta('12h30m'),
columns=tickers, data=price_data)
today_open_3h -= today_open_3h * 0.002
prices = concat([today_open, today_open_1h, today_open_3h]) \
.sort_index()

factor_index = date_range(start=start, end=factor_end, freq='B')
factor_index.name = 'date'
factor_index = factor_index.drop(holidays)
factor = DataFrame(index=factor_index + Timedelta('9h30m'),
columns=tickers, data=factor_data).stack()

factor_data = get_clean_factor_and_forward_returns(
factor, prices,
groupby=factor_groups,
quantiles=4,
periods=(1, 2, 3))

expected_idx = factor.index.rename(['date', 'asset'])
expected_cols = ['1h', '3h', '1D',
'factor', 'group', 'factor_quantile']
expected_data = [[0.001, -0.002, 0.1, 3.0, 1, 3],
[0.001, -0.002, -0.5, 4.0, 2, 4],
[0.001, -0.002, 2.0, 2.0, 1, 2],
[0.001, -0.002, -0.1, 1.0, 2, 1],
[0.001, -0.002, 0.1, 3.0, 1, 3],
[0.001, -0.002, -0.1, 1.0, 2, 1],
[0.001, -0.002, -0.5, 4.0, 1, 4],
[0.001, -0.002, 0.0, 2.0, 2, 2],
[0.001, -0.002, 0.1, 3.0, 1, 3],
[0.001, -0.002, -0.5, 4.0, 2, 4],
[0.001, -0.002, 2.0, 2.0, 1, 2],
[0.001, -0.002, -0.1, 1.0, 2, 1]] * 6 # 18 days
expected = DataFrame(index=expected_idx,
columns=expected_cols, data=expected_data)
expected['group'] = expected['group'].astype('category')

assert_frame_equal(factor_data, expected)

inferred_holidays = factor_data.index.levels[0].freq.holidays
assert sorted(holidays) == sorted(inferred_holidays)

def test_get_clean_factor_and_forward_returns_6(self):
"""
Test get_clean_factor_and_forward_returns with a daily factor
on a business day calendar and holidays
"""
tickers = ['A', 'B', 'C', 'D', 'E', 'F']

factor_groups = {'A': 1, 'B': 2, 'C': 1, 'D': 2, 'E': 1, 'F': 2}

price_data = [[1.10**i, 0.50**i, 3.00**i, 0.90**i, 0.50**i, 1.00**i]
for i in range(1, 22)] # 21 days = 18 + 3 fwd returns

factor_data = [[3, 4, 2, 1, nan, nan],
[3, nan, nan, 1, 4, 2],
[3, 4, 2, 1, nan, nan]] * 6 # 18 days

start = '2017-1-12'
factor_end = '2017-2-10'
price_end = '2017-2-15' # 3D (business day) fwd returns
holidays = ['2017-1-13', '2017-1-18', '2017-1-30', '2017-2-7']
holidays = [Timestamp(d) for d in holidays]

price_index = date_range(start=start, end=price_end, freq='B')
price_index.name = 'date'
price_index = price_index.drop(holidays)
prices = DataFrame(index=price_index, columns=tickers, data=price_data)

factor_index = date_range(start=start, end=factor_end, freq='B')
factor_index.name = 'date'
factor_index = factor_index.drop(holidays)
factor = DataFrame(index=factor_index, columns=tickers,
data=factor_data).stack()

factor_data = get_clean_factor_and_forward_returns(
factor, prices,
groupby=factor_groups,
quantiles=4,
periods=(1, 2, 3))

expected_idx = factor.index.rename(['date', 'asset'])
expected_cols = ['1D', '2D', '3D',
'factor', 'group', 'factor_quantile']
expected_data = [[0.1, 0.21, 0.331, 3.0, 1, 3],
[-0.5, -0.75, -0.875, 4.0, 2, 4],
[2.0, 8.00, 26.000, 2.0, 1, 2],
[-0.1, -0.19, -0.271, 1.0, 2, 1],
[0.1, 0.21, 0.331, 3.0, 1, 3],
[-0.1, -0.19, -0.271, 1.0, 2, 1],
[-0.5, -0.75, -0.875, 4.0, 1, 4],
[0.0, 0.00, 0.000, 2.0, 2, 2],
[0.1, 0.21, 0.331, 3.0, 1, 3],
[-0.5, -0.75, -0.875, 4.0, 2, 4],
[2.0, 8.00, 26.000, 2.0, 1, 2],
[-0.1, -0.19, -0.271, 1.0, 2, 1]] * 6 # 18 days
expected = DataFrame(index=expected_idx,
columns=expected_cols, data=expected_data)
expected['group'] = expected['group'].astype('category')

assert_frame_equal(factor_data, expected)

inferred_holidays = factor_data.index.levels[0].freq.holidays
assert sorted(holidays) == sorted(inferred_holidays)

0 comments on commit 6016e86

Please sign in to comment.