mirror of
https://github.com/wassname/catalyst.git
synced 2026-06-30 04:34:21 +08:00
5730de25a4
All terms just implement `_compute` now. (We reserve `compute` for the public API of `CustomFactor`.) Also removed `TestingTermMixin` and its subclasses in favor of just using `CustomFactor.`
138 lines
4.9 KiB
Python
138 lines
4.9 KiB
Python
"""
|
|
Tests for Factor terms.
|
|
"""
|
|
from numpy import (
|
|
array,
|
|
ones,
|
|
)
|
|
|
|
from zipline.errors import UnknownRankMethod
|
|
from zipline.modelling.factor import Factor
|
|
from zipline.utils.test_utils import check_arrays
|
|
|
|
from .base import BaseFFCTestCase
|
|
|
|
|
|
class F(Factor):
|
|
inputs = ()
|
|
window_length = 0
|
|
|
|
|
|
class FactorTestCase(BaseFFCTestCase):
|
|
|
|
def setUp(self):
|
|
super(FactorTestCase, self).setUp()
|
|
self.f = F()
|
|
|
|
def test_bad_input(self):
|
|
with self.assertRaises(UnknownRankMethod):
|
|
self.f.rank("not a real rank method")
|
|
|
|
def test_rank_ascending(self):
|
|
|
|
# Generated with:
|
|
# data = arange(25).reshape(5, 5).transpose() % 4
|
|
data = array([[0, 1, 2, 3, 0],
|
|
[1, 2, 3, 0, 1],
|
|
[2, 3, 0, 1, 2],
|
|
[3, 0, 1, 2, 3],
|
|
[0, 1, 2, 3, 0]], dtype=float)
|
|
expected_ranks = {
|
|
'ordinal': array([[1., 3., 4., 5., 2.],
|
|
[2., 4., 5., 1., 3.],
|
|
[3., 5., 1., 2., 4.],
|
|
[4., 1., 2., 3., 5.],
|
|
[1., 3., 4., 5., 2.]]),
|
|
'average': array([[1.5, 3., 4., 5., 1.5],
|
|
[2.5, 4., 5., 1., 2.5],
|
|
[3.5, 5., 1., 2., 3.5],
|
|
[4.5, 1., 2., 3., 4.5],
|
|
[1.5, 3., 4., 5., 1.5]]),
|
|
'min': array([[1., 3., 4., 5., 1.],
|
|
[2., 4., 5., 1., 2.],
|
|
[3., 5., 1., 2., 3.],
|
|
[4., 1., 2., 3., 4.],
|
|
[1., 3., 4., 5., 1.]]),
|
|
'max': array([[2., 3., 4., 5., 2.],
|
|
[3., 4., 5., 1., 3.],
|
|
[4., 5., 1., 2., 4.],
|
|
[5., 1., 2., 3., 5.],
|
|
[2., 3., 4., 5., 2.]]),
|
|
'dense': array([[1., 2., 3., 4., 1.],
|
|
[2., 3., 4., 1., 2.],
|
|
[3., 4., 1., 2., 3.],
|
|
[4., 1., 2., 3., 4.],
|
|
[1., 2., 3., 4., 1.]]),
|
|
}
|
|
|
|
def check(terms):
|
|
results = self.run_terms(
|
|
terms,
|
|
initial_workspace={self.f: data},
|
|
mask=self.build_mask(ones((5, 5))),
|
|
)
|
|
for method in terms:
|
|
check_arrays(results[method], expected_ranks[method])
|
|
|
|
check({meth: self.f.rank(method=meth) for meth in expected_ranks})
|
|
check({
|
|
meth: self.f.rank(method=meth, ascending=True)
|
|
for meth in expected_ranks
|
|
})
|
|
# Not passing a method should default to ordinal.
|
|
check({'ordinal': self.f.rank()})
|
|
check({'ordinal': self.f.rank(ascending=True)})
|
|
|
|
def test_rank_descending(self):
|
|
|
|
# Generated with:
|
|
# data = arange(25).reshape(5, 5).transpose() % 4
|
|
data = array([[0, 1, 2, 3, 0],
|
|
[1, 2, 3, 0, 1],
|
|
[2, 3, 0, 1, 2],
|
|
[3, 0, 1, 2, 3],
|
|
[0, 1, 2, 3, 0]], dtype=float)
|
|
expected_ranks = {
|
|
'ordinal': array([[4., 3., 2., 1., 5.],
|
|
[3., 2., 1., 5., 4.],
|
|
[2., 1., 5., 4., 3.],
|
|
[1., 5., 4., 3., 2.],
|
|
[4., 3., 2., 1., 5.]]),
|
|
'average': array([[4.5, 3., 2., 1., 4.5],
|
|
[3.5, 2., 1., 5., 3.5],
|
|
[2.5, 1., 5., 4., 2.5],
|
|
[1.5, 5., 4., 3., 1.5],
|
|
[4.5, 3., 2., 1., 4.5]]),
|
|
'min': array([[4., 3., 2., 1., 4.],
|
|
[3., 2., 1., 5., 3.],
|
|
[2., 1., 5., 4., 2.],
|
|
[1., 5., 4., 3., 1.],
|
|
[4., 3., 2., 1., 4.]]),
|
|
'max': array([[5., 3., 2., 1., 5.],
|
|
[4., 2., 1., 5., 4.],
|
|
[3., 1., 5., 4., 3.],
|
|
[2., 5., 4., 3., 2.],
|
|
[5., 3., 2., 1., 5.]]),
|
|
'dense': array([[4., 3., 2., 1., 4.],
|
|
[3., 2., 1., 4., 3.],
|
|
[2., 1., 4., 3., 2.],
|
|
[1., 4., 3., 2., 1.],
|
|
[4., 3., 2., 1., 4.]]),
|
|
}
|
|
|
|
def check(terms):
|
|
results = self.run_terms(
|
|
terms,
|
|
initial_workspace={self.f: data},
|
|
mask=self.build_mask(ones((5, 5))),
|
|
)
|
|
for method in terms:
|
|
check_arrays(results[method], expected_ranks[method])
|
|
|
|
check({
|
|
meth: self.f.rank(method=meth, ascending=False)
|
|
for meth in expected_ranks
|
|
})
|
|
# Not passing a method should default to ordinal.
|
|
check({'ordinal': self.f.rank(ascending=False)})
|