Commit 8ae110d4 authored by Dr.李's avatar Dr.李

added is_tradable flag for rank builder

parent 417f5234
...@@ -99,7 +99,7 @@ def er_portfolio_analysis(er: np.ndarray, ...@@ -99,7 +99,7 @@ def er_portfolio_analysis(er: np.ndarray,
raise ValueError('linear programming optimizer in status: {0}'.format(status)) raise ValueError('linear programming optimizer in status: {0}'.format(status))
elif method == 'rank': elif method == 'rank':
weights = rank_build(er, use_rank=kwargs['use_rank']).flatten() * benchmark.sum() / kwargs['use_rank'] weights = rank_build(er, use_rank=kwargs['use_rank'], masks=is_tradable).flatten() * benchmark.sum() / kwargs['use_rank']
elif method == 'ls' or method == 'long_short': elif method == 'ls' or method == 'long_short':
weights = long_short_build(er).flatten() weights = long_short_build(er).flatten()
elif method == 'mv' or method == 'mean_variance': elif method == 'mv' or method == 'mean_variance':
......
...@@ -12,7 +12,12 @@ from alphamind.utilities import groupby ...@@ -12,7 +12,12 @@ from alphamind.utilities import groupby
from alphamind.utilities import set_value from alphamind.utilities import set_value
def rank_build(er: np.ndarray, use_rank: int, groups: np.ndarray=None) -> np.ndarray: def rank_build(er: np.ndarray, use_rank: int, groups: np.ndarray=None, masks: np.ndarray=None) -> np.ndarray:
er = er.copy()
if masks is not None:
er[~masks] = -np.inf
if er.ndim == 1 or (er.shape[0] == 1 or er.shape[1] == 1): if er.ndim == 1 or (er.shape[0] == 1 or er.shape[1] == 1):
# fast path methods for single column er # fast path methods for single column er
......
...@@ -18,6 +18,7 @@ class TestRankBuild(unittest.TestCase): ...@@ -18,6 +18,7 @@ class TestRankBuild(unittest.TestCase):
self.n_included = 300 self.n_included = 300
self.n_groups = 30 self.n_groups = 30
self.n_portfolio = range(1, 10) self.n_portfolio = range(1, 10)
self.n_mask = 100
def test_rank_build(self): def test_rank_build(self):
for n_portfolio in self.n_portfolio: for n_portfolio in self.n_portfolio:
...@@ -26,10 +27,10 @@ class TestRankBuild(unittest.TestCase): ...@@ -26,10 +27,10 @@ class TestRankBuild(unittest.TestCase):
calc_weights = rank_build(x, self.n_included) calc_weights = rank_build(x, self.n_included)
expected_weights = np.zeros((len(x), n_portfolio)) expected_weights = np.zeros((len(x), n_portfolio))
masks = (-x).argsort(axis=0).argsort(axis=0) < self.n_included chosen = (-x).argsort(axis=0).argsort(axis=0) < self.n_included
for j in range(x.shape[1]): for j in range(x.shape[1]):
expected_weights[masks[:, j], j] = 1. expected_weights[chosen[:, j], j] = 1.
np.testing.assert_array_almost_equal(calc_weights, expected_weights) np.testing.assert_array_almost_equal(calc_weights, expected_weights)
...@@ -45,9 +46,32 @@ class TestRankBuild(unittest.TestCase): ...@@ -45,9 +46,32 @@ class TestRankBuild(unittest.TestCase):
grouped_ordering = pd.DataFrame(-x).groupby(groups).rank() grouped_ordering = pd.DataFrame(-x).groupby(groups).rank()
expected_weights = np.zeros((len(x), n_portfolio)) expected_weights = np.zeros((len(x), n_portfolio))
masks = (grouped_ordering <= n_include).values chosen = (grouped_ordering <= n_include).values
for j in range(x.shape[1]): for j in range(x.shape[1]):
expected_weights[masks[:, j], j] = 1. expected_weights[chosen[:, j], j] = 1.
np.testing.assert_array_almost_equal(calc_weights, expected_weights)
def test_rank_build_with_masks(self):
for n_portfolio in self.n_portfolio:
x = np.random.randn(self.n_samples, n_portfolio)
choices = np.random.choice(self.n_samples, self.n_mask, replace=False)
masks = np.full(self.n_samples, True, dtype=bool)
masks[choices] = False
calc_weights = rank_build(x, self.n_included, masks=masks)
expected_weights = np.zeros((len(x), n_portfolio))
filtered_index = np.arange(len(x))[masks]
filtered_x = x[masks]
big_boolen = np.full(x.shape, False, dtype=bool)
chosen = (-filtered_x).argsort(axis=0).argsort(axis=0) < self.n_included
big_boolen[filtered_index] = chosen
for j in range(x.shape[1]):
expected_weights[big_boolen[:, j], j] = 1.
np.testing.assert_array_almost_equal(calc_weights, expected_weights) np.testing.assert_array_almost_equal(calc_weights, expected_weights)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment