class TestFactorContainer(TestCase):
    def test_factor_1(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28', '2014-03-31'], ['001', '002']],
                                           names=['trade_date', 'ticker'])
        data = pd.DataFrame(index=index, data=[1, 2, 3, 4, 5, 6])
        factor = Factor(data=data, name='test', production_data_format=OutputDataFormat.PITVOT_TABLE_DF)

        self.assertEqual(factor.type, FactorType.ALPHA_FACTOR)
        self.assertEqual(factor.trade_date_list, [dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 3, 31)])
        self.assertEqual(factor.production_data_format, OutputDataFormat.PITVOT_TABLE_DF)
        self.assertEqual(factor.freq, FreqType.EOM)

        factor_data_expected = pd.DataFrame({'001': [1, 3, 5], '002': [2, 4, 6]},
                                            index=pd.Index([dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 3, 31)],
                                                           name='trade_date'))
        assert_frame_equal(factor.data, factor_data_expected)

    def test_factor_2(self):
        data = pd.DataFrame({'001': [1, 3, 5], '002': [2, 4, 6]},
                            index=pd.Index([dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 3, 31)],
                                           name='trade_date'))
        property_dict = {'data_format': OutputDataFormat.PITVOT_TABLE_DF}
        factor = Factor(data=data,
                        name='test',
                        property_dict=property_dict,
                        production_data_format=OutputDataFormat.MULTI_INDEX_DF)

        self.assertEqual(factor.type, FactorType.ALPHA_FACTOR)
        self.assertEqual(factor.trade_date_list, [dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 3, 31)])
        self.assertEqual(factor.production_data_format, OutputDataFormat.MULTI_INDEX_DF)
        self.assertEqual(factor.freq, FreqType.EOM)

        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 3, 31)], ['001', '002']],
                                           names=['trade_date', 'ticker'])
        factor_data_expected = pd.DataFrame(index=index, data=[1, 2, 3, 4, 5, 6], columns=['test'])
        assert_frame_equal(factor.data, factor_data_expected)

    def test_factor_3(self):
        """
        test index name validation 
        """
        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 3, 31)], ['001', '002']],
                                           names=['trade_date', 'sec'])
        data = pd.DataFrame(index=index, data=[1, 2, 3, 4, 5, 6])
        factor = Factor(data=data, name='test2')
        index_exp = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 3, 31)], ['001', '002']],
                                               names=['trade_date', 'ticker'])

        expected = pd.DataFrame(index=index_exp, data=[1, 2, 3, 4, 5, 6], columns=['test2'])
        assert_frame_equal(factor.data, expected)

    def test_factor_container_1(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28', '2014-03-31'], ['001', '002']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
        factor_test1 = Factor(data=data1, name='test1')

        data2 = pd.DataFrame(index=index, data=[3.0, 2.0, 3.0, 7.0, 8.0, 9.0])
        factor_test2 = Factor(data=data2, name='test2')

        data3 = pd.DataFrame(index=index, data=[3.0, 4.0, 3.0, 5.0, 6.0, 7.0])
        factor_test3 = Factor(data=data3, name='test3')

        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test1, factor_test2])

        index_exp = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002']],
                                               names=['trade_date', 'ticker'])

        data_exp = pd.DataFrame({'test1': [1.0, 2.0, 3.0, 4.0], 'test2': [3.0, 2.0, 3.0, 7.0]}, index=index_exp)
        assert_frame_equal(fc.data, data_exp)

        fc.add_factor(factor_test3)
        data_exp = pd.DataFrame({'test1': [1.0, 2.0, 3.0, 4.0], 'test2': [3.0, 2.0, 3.0, 7.0],
                                 'test3': [3.0, 4.0, 3.0, 5.0]}, index=index_exp)
        assert_frame_equal(fc.data, data_exp)

        fc.remove_factor(factor_test2)
        data_exp = pd.DataFrame({'test1': [1.0, 2.0, 3.0, 4.0], 'test3': [3.0, 4.0, 3.0, 5.0]}, index=index_exp)
        assert_frame_equal(fc.data, data_exp)

        property_exp = {'test1': {'type': FactorType.ALPHA_FACTOR,
                                  'data_format': OutputDataFormat.MULTI_INDEX_DF,
                                  'norm_type': FactorNormType.Null,
                                  'freq': FreqType.EOM},
                        'test3': {'type': FactorType.ALPHA_FACTOR,
                                  'data_format': OutputDataFormat.MULTI_INDEX_DF,
                                  'norm_type': FactorNormType.Null,
                                  'freq': FreqType.EOM}}
        self.assertEqual(fc.property, property_exp)

        fc.replace_data(np.array([[1.0, 2.0, 3.0, 4.0], [1.0, 2.0, 3.0, 5.0]]).T)
        assert_frame_equal(fc.data,
                           pd.DataFrame({'test1': [1.0, 2.0, 3.0, 4.0], 'test3': [1.0, 2.0, 3.0, 5.0]},
                                        index=index_exp))

        self.assertEqual(list(fc.alpha_factor_col), ['test1', 'test3']) class TestReturnMetrics(TestCase):
    def setUp(self):
        dir_name = os.path.dirname(os.path.abspath(__file__))
        return_data = pd.read_csv(dir_name + '//data//performance.csv')
        return_data.columns = ['trade_date', 'benchmark', 'strategy']
        return_data['trade_date'] = pd.to_datetime(return_data['trade_date'], format='%Y/%m/%d')
        return_data.set_index('trade_date', inplace=True)

        self.strategy = RETURN(data=return_data['strategy'], type=ReturnType.Cumul)
        self.benchmark = RETURN(data=return_data['benchmark'], type=ReturnType.Cumul)

        result = pd.read_csv(dir_name + "//data//result.csv")
        result.columns = ['trade_date', 'result1', 'result2', 'result3']
        result['trade_date'] = pd.to_datetime(result['trade_date'], format='%Y/%m/%d')
        result.set_index('trade_date', inplace=True)
        self.result = result

    def test_calc_ptf_return(self):
        index = pd.MultiIndex.from_product([['2014-02-27', '2014-02-28'], ['001', '002']],
                                           names=['trade_date', 'ticker'])
        ticker_return = pd.Series([0.05, 0.06, 0.08, 0.08], index=index, name='return')

        calculated = calc_ptf_return(ticker_return=ticker_return)
        expected = pd.DataFrame({'return': [1.055, 1.1394]},
                                index=pd.Index(['2014-02-27', '2014-02-28'], name='trade_date'))
        assert_frame_equal(calculated, expected)

    def test_calc_alpha_return(self):
        calculated = calc_alpha_return(unhedged_return=self.strategy,
                                       benchmark_return=self.benchmark,
                                       rebalance_freq=FreqType.EOM)
        expected = self.result['result1']
        expected.name = INDEX_RETURN.hedged_return
        assert_series_equal(calculated, expected)

    def test_group_perf_stat(self):
        calculated = group_perf_stat(self.strategy, risk_free=0.02, freq=FreqType.EOQ)
        expected = pd.DataFrame(
            data=[[-0.194346, -0.391711, 0.439566, -0.126527], [-1.313148, -2.160582, 3.146201, -1.187699],
                  [-0.148000, -0.181299, -0.139713, -0.106531], [-24.203418, -18.283650, -16.019707, -25.555582]],
            index=['annual_return', 'calmar_ratio', 'max_drawdown', 'sharpe_ratio'],
            columns=pd.DatetimeIndex(['2005-03-31', '2005-06-30', '2005-09-30', '2005-12-31'], dtype='datetime64[ns]',
                                     freq=None))
        assert_frame_equal(calculated, expected)
        calculated = group_perf_stat(self.strategy, risk_free=0.04, freq=FreqType.EOY)
        expected = pd.DataFrame(data=[-0.101456, -0.295517, -0.343317, -39.591727],
                                index=['annual_return', 'calmar_ratio', 'max_drawdown', 'sharpe_ratio'],
                                columns=pd.DatetimeIndex(['2005-12-31'], dtype='datetime64[ns]', freq=None))
        assert_frame_equal(calculated, expected) class TestPipeline(TestCase):
    def setUp(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28'], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 1.0, 1.2, 2.0, 0.9, 5.0, 5.0, 5.1])
        factor_test1 = Factor(data=data1, name='test1',
                              property_dict={'norm_type': FactorNormType.Industry_Cap_Neutral})

        data2 = pd.DataFrame(index=index, data=[2.6, 2.5, 2.8, 2.9, 2.7, 1.9, 5.0, 2.1])
        factor_test2 = Factor(data=data2, name='test2', property_dict={'type': FactorType.ALPHA_FACTOR_MV})

        data3 = pd.DataFrame(index=index, data=['a', 'b', 'a', 'a', 'a', 'b', 'c', 'b'])
        factor_test3 = Factor(data=data3, name='test3', property_dict={'type': FactorType.INDUSTY_CODE})

        data4 = pd.DataFrame(index=index, data=[1.0, 1.0, 1.2, 2.0, 0.9, 5.0, 5.0, 5.1])
        factor_test4 = Factor(data=data4, name='test4', property_dict={'norm_type': FactorNormType.Industry_Neutral})

        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test1, factor_test2, factor_test3, factor_test4])

        self.factor_container = fc

    def test_error_raise(self):
        with self.assertRaises(TypeError):
            AlphaPipeline([('no_transform', NoTransformT()),
                           ('no_fit', NoFitT())])

        with self.assertRaises(TypeError):
            AlphaPipeline([('no_fit', NoFitT())])

    def test_factor_tranformer(self):
        pipeline = AlphaPipeline([('multi', TransMulti2()),
                                  ('div', TransDiv4())])
        calculated = pipeline.fit_transform(self.factor_container)
        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        expected = pd.DataFrame({'test1': [0.5, 0.5, 0.6, 1, 0.45, 2.5, 2.5, 2.55],
                                 'test2': [2.6, 2.5, 2.8, 2.9, 2.7, 1.9, 5.0, 2.1],
                                 'test3': ['a', 'b', 'a', 'a', 'a', 'b', 'c', 'b'],
                                 'test4': [0.5, 0.5, 0.6, 1, 0.45, 2.5, 2.5, 2.55]},
                                index=index,
                                dtype=object)
        assert_frame_equal(calculated, expected)

    def test_factor_tranformer_2(self):
        pipeline = AlphaPipeline([('multi', TransMulti2()),
                                  ('div', TransDiv4())])
        pipeline.set_params(multi__out_container=True)
        calculated = pipeline.fit_transform(self.factor_container)
        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        expected = pd.DataFrame({'test1': [0.5, 0.5, 0.6, 1, 0.45, 2.5, 2.5, 2.55],
                                 'test2': [2.6, 2.5, 2.8, 2.9, 2.7, 1.9, 5.0, 2.1],
                                 'test3': ['a', 'b', 'a', 'a', 'a', 'b', 'c', 'b'],
                                 'test4': [0.5, 0.5, 0.6, 1, 0.45, 2.5, 2.5, 2.55]},
                                index=index)
        assert_frame_equal(calculated, expected)

    def test_factor_tranformer_3(self):
        pipeline = AlphaPipeline([('multi', TransMulti2()),
                                  ('div', TransDiv4()),
                                  ('pred', PredMean())])
        pipeline.set_params(multi__out_container=True)
        calculated = pipeline.predict(self.factor_container)
        expected = pd.Series([1.3250, 2.8125, 1.3250], index=['test1', 'test2', 'test4'])
        assert_series_equal(calculated, expected)

    def test_make_alpha_pipeline(self):
        pipeline = make_alpha_pipeline(TransMulti2(), TransDiv4())
        pipeline.set_params(transmulti2__out_container=True)
        calculated = pipeline.fit_transform(self.factor_container)
        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        expected = pd.DataFrame({'test1': [0.5, 0.5, 0.6, 1, 0.45, 2.5, 2.5, 2.55],
                                 'test2': [2.6, 2.5, 2.8, 2.9, 2.7, 1.9, 5.0, 2.1],
                                 'test3': ['a', 'b', 'a', 'a', 'a', 'b', 'c', 'b'],
                                 'test4': [0.5, 0.5, 0.6, 1, 0.45, 2.5, 2.5, 2.55]},
                                index=index)
        assert_frame_equal(calculated, expected) class TestBenchmark(TestCase):
    def test_benchmark(self):
        index_industry = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28', '2014-03-31'], ['a', 'b']],
                                                    names=['trade_date', 'ticker'])
        industry_weight = pd.DataFrame(index=index_industry, data=[0.1, 0.2, 0.3, 0.2, 0.3, 0.3])

        index_return = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28', '2014-03-31'], ['001', '002']],
                                                  names=['trade_date', 'ticker'])
        hist_return = pd.DataFrame(index=index_return, data=[0.1, 0.05, 0.05, -0.05, 0.05, 0.06])
        benchmark = Benchmark(name='test', industry_weight=industry_weight, hist_return=hist_return)

        calculated = benchmark.get_industry_weight_on_date('2014-01-30')
        expected = pd.Series([0.1, 0.2, 99.7], index=pd.Index(['a', 'b', 'other'], name='industry_code'), name='weight')
        assert_series_equal(calculated, expected) class TestFactorImputer(TestCase):
    def test_imputer_1(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28'], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 3.0, 3.0, np.nan, 5.0, 5.0, 6.0, 8.0])
        factor_test1 = Factor(data=data1, name='test1')

        data2 = pd.DataFrame(index=index, data=[3.0, 2.0, 3.0, 7.0, 7.0, np.nan, 6.0, 6.0])
        factor_test2 = Factor(data=data2, name='test2')

        data3 = pd.DataFrame(index=index, data=[3.0, 3.0, np.nan, 5.0, 6.0, 7.0, 6.0, 6.0])
        factor_test3 = Factor(data=data3, name='test3')

        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test1, factor_test2, factor_test3])

        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        calculated = FactorImputer(numerical_strategy=NAStrategy.MOST_FREQ).fit_transform(fc)
        expected = pd.DataFrame({'test1': [1.0, 3.0, 3.0, 3.0, 5.0, 5.0, 6.0, 8.0],
                                 'test2': [3.0, 2.0, 3.0, 7.0, 7.0, 6.0, 6.0, 6.0],
                                 'test3': [3.0, 3.0, 3.0, 5.0, 6.0, 7.0, 6.0, 6.0]},
                                index=index)
        assert_frame_equal(calculated, expected)

        calculated = FactorImputer(numerical_strategy=NAStrategy.MEDIAN).fit_transform(fc)
        expected = pd.DataFrame({'test1': [1.0, 3.0, 3.0, 3.0, 5.0, 5.0, 6.0, 8.0],
                                 'test2': [3.0, 2.0, 3.0, 7.0, 7.0, 6.0, 6.0, 6.0],
                                 'test3': [3.0, 3.0, 3.0, 5.0, 6.0, 7.0, 6.0, 6.0]},
                                index=index)
        assert_frame_equal(calculated, expected)

        industry = pd.DataFrame(index=index, data=['a', 'a', 'a', 'a', 'a', 'a', np.nan, 'a'])
        factor_industry = Factor(data=industry, name='industry', property_dict={'type': FactorType.INDUSTY_CODE})
        fc.add_factor(factor=factor_industry)
        calculated = FactorImputer(numerical_strategy=NAStrategy.MEDIAN,
                                   categorical_strategy=NAStrategy.CUSTOM,
                                   custom_value='other').fit_transform(fc)
        calculated.sort_index(axis=1, inplace=True)
        expected = pd.DataFrame({'test1': [1.0, 3.0, 3.0, 3.0, 5.0, 5.0, 6.0, 8.0],
                                 'test2': [3.0, 2.0, 3.0, 7.0, 7.0, 6.0, 6.0, 6.0],
                                 'test3': [3.0, 3.0, 3.0, 5.0, 6.0, 7.0, 6.0, 6.0],
                                 'industry': ['a', 'a', 'a', 'a', 'a', 'a', 'other', 'a']},
                                index=index,
                                dtype=object)
        assert_frame_equal(calculated, expected)

    def test_imputer_2(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28'], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        data = pd.DataFrame(index=index, data=[1.0, 3.0, 3.0, np.nan, 5.0, 5.0, 6.0, 8.0])
        factor_test = Factor(data=data, name='test1')

        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        fi = FactorImputer(numerical_strategy=NAStrategy.MEAN)
        calculated = fi.fit_transform(factor_test)
        expected = pd.DataFrame({'test1': [1.0, 3.0, 3.0, 2.33333333333, 5.0, 5.0, 6.0, 8.0]}, index=index)
        assert_frame_equal(calculated, expected)

        fi.set_out_container(True)
        calculated = fi.fit_transform(factor_test)
        expected = FactorContainer(start_date='2014-01-30',
                                   end_date='2014-02-28')
        factor = Factor(data=pd.DataFrame({'test1': [1.0, 3.0, 3.0, 2.33333333333, 5.0, 5.0, 6.0, 8.0]}, index=index),
                        name='test1')
        expected.add_factor(factor)

        assert (isinstance(calculated, FactorContainer))
        self.assertEqual(calculated.property, expected.property)
        assert_frame_equal(calculated.data, expected.data) class TestExtCategoricalImputer(TestCase):
    def test_default(self):
        calculated = ExtCategoricalImputer().fit_transform(np.array(['a', 'b', 'b', None, 'c']))
        expected = np.array(['a', 'b', 'b', 'b', 'c'], dtype=object)
        assert_array_equal(calculated, expected)

        calculated = ExtCategoricalImputer().fit_transform(pd.Series(['a', 'b', 'b', np.nan, 'c']))
        expected = np.array(['a', 'b', 'b', 'b', 'c'], dtype=object)
        assert_array_equal(calculated, expected)

    def test_ext(self):
        calculated = ExtCategoricalImputer(strategy=NAStrategy.CUSTOM, custom_value='d') \
            .fit_transform(np.array(['a', 'b', 'b', None, 'c', 'd']))
        expected = np.array(['a', 'b', 'b', 'd', 'c', 'd'], dtype=object)
        assert_array_equal(calculated, expected)

        calculated = ExtCategoricalImputer(strategy=NAStrategy.CUSTOM, custom_value='x') \
            .fit_transform(pd.Series(['a', 'b', 'b', np.nan, 'c', 'd']))
        expected = np.array(['a', 'b', 'b', 'x', 'c', 'd'], dtype=object)
        assert_array_equal(calculated, expected) class TestNeutralizer(TestCase):
    def setUp(self):
        index = ['001', '002', '003', '004', '005', '006', '007', '008', '009', '010']
        factor = [24, 1.0, 1.1, 0.8, 0.5, 1.2, -1.0, -2, 1.0, 0.5]
        industry = ['a', 'a', 'b', 'c', 'b', 'b', 'b', 'b', 'c', 'c']
        cap = [2.0, 2.0, 1.0, 3.0, 5.0, 1.0, 1.0, 1.0, 1.0, 2.0]
        pd_factor = pd.Series(factor, index=index, name='factor')
        pd_industry = pd.Series(industry, index=index)
        pd_cap = pd.Series(cap, index=index)

        self.data = {'factor': pd_factor,
                     'industry': pd_industry,
                     'cap': pd_cap,
                     'np_factor': np.array(factor),
                     'np_industry': np.array(industry),
                     'np_cap': np.array(cap)}

    def test_get_indicator_matrix(self):
        industry = self.data['industry']
        calculated = get_indicator_matrix(industry)
        expected = np.array([[1.0, 0.0, 0.0],
                             [1.0, 0.0, 0.0],
                             [0.0, 1.0, 0.0],
                             [0.0, 0.0, 1.0],
                             [0.0, 1.0, 0.0],
                             [0.0, 1.0, 0.0],
                             [0.0, 1.0, 0.0],
                             [0.0, 1.0, 0.0],
                             [0.0, 0.0, 1.0],
                             [0.0, 0.0, 1.0]])
        assert_array_equal(calculated, expected)

        industry = self.data['industry']
        cap = self.data['cap']
        calculated = get_indicator_matrix(industry, cap)
        expected = np.array([[1.0, 0.0, 0.0, 2.0],
                             [1.0, 0.0, 0.0, 2.0],
                             [0.0, 1.0, 0.0, 1.0],
                             [0.0, 0.0, 1.0, 3.0],
                             [0.0, 1.0, 0.0, 5.0],
                             [0.0, 1.0, 0.0, 1.0],
                             [0.0, 1.0, 0.0, 1.0],
                             [0.0, 1.0, 0.0, 1.0],
                             [0.0, 0.0, 1.0, 1.0],
                             [0.0, 0.0, 1.0, 2.0]])
        assert_array_equal(calculated, expected)

    def test_neutralizer(self):
        industry = self.data['industry']
        factor = self.data['factor']
        calculated = Neutralizer(industry=industry).fit_transform(factor)
        expected = np.array(
            [11.5, -11.5, 1.14, 0.0333333333333, 0.54, 1.24, -0.96, -1.96, 0.233333333333, -0.266666666667])
        assert_array_almost_equal(calculated, expected)

        industry = self.data['industry']
        factor = self.data['factor']
        cap = self.data['cap']
        calculated = Neutralizer(industry, cap).fit_transform(factor)
        expected = np.array(
            [11.5, -11.5, 1.22627682982, -0.101047981403, 0.194892680726, 1.32627682982, -0.873723170181,
             -1.87372317018, 0.393417510971, -0.292369529568])
        assert_array_almost_equal(calculated, expected)

        industry = self.data['np_industry']
        factor = self.data['np_factor']
        cap = self.data['np_cap']
        calculated = Neutralizer(industry, cap).fit_transform(factor)
        expected = np.array(
            [11.5, -11.5, 1.22627682982, -0.101047981403, 0.194892680726, 1.32627682982, -0.873723170181,
             -1.87372317018, 0.393417510971, -0.292369529568])
        assert_array_almost_equal(calculated, expected)

    def test_factor_neutralizer(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28'], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 1.0, 1.2, 2.0, 0.9, 5.0, 5.0, 5.1])
        factor_test1 = Factor(data=data1, name='test1',
                              property_dict={'norm_type': FactorNormType.Industry_Cap_Neutral})

        data2 = pd.DataFrame(index=index, data=[2.6, 2.5, 2.8, 2.9, 2.7, 1.9, 5.0, 2.1])
        factor_test2 = Factor(data=data2, name='test2', property_dict={'type': FactorType.ALPHA_FACTOR_MV,
                                                                       'norm_type': FactorNormType.Industry_Neutral})

        data3 = pd.DataFrame(index=index, data=['a', 'b', 'a', 'a', 'a', 'b', 'c', 'b'])
        factor_test3 = Factor(data=data3, name='test3', property_dict={'type': FactorType.INDUSTY_CODE})

        data4 = pd.DataFrame(index=index, data=[1.0, 1.0, 1.2, 2.0, 0.9, 5.0, 5.0, 5.1])
        factor_test4 = Factor(data=data4, name='test4', property_dict={'norm_type': FactorNormType.Industry_Neutral})

        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test1, factor_test2, factor_test3, factor_test4])

        calculated = FactorNeutralizer().fit_transform(fc)
        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        expected = pd.DataFrame({'test1': [0.0983574180639, 8.881784197e-16, -0.306074564019, 0.207717145955,
                                           -2.10942374679e-15, 8.881784197e-16, -5.3290705182e-15, 0.0],
                                 'test2': [-0.166666666667, 0.0, 0.0333333333333, 0.133333333333, 0.0, -0.1, 0.0, 0.1],
                                 'test3': ['a', 'b', 'a', 'a', 'a', 'b', 'c', 'b'],
                                 'test4': [-0.4, 0.0, -0.2, 0.6, 0.0, -0.05, 0.0, 0.05]},
                                index=index,
                                dtype=object)
        assert_frame_equal(calculated, expected)

        calculated = FactorNeutralizer(out_container=True).fit_transform(fc)
        assert_frame_equal(calculated.data, expected)
        self.assertEqual(calculated.container_property, fc.container_property) class TestStandardizer(TestCase):
    def test_standardizer(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28'], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 1.0, 1.2, 200.0, 0.9, 5.0, 5.0, 5.1])
        factor_test1 = Factor(data=data1, name='test1')

        data2 = pd.DataFrame(index=index, data=[2.6, 2.5, 2.8, 2.9, 2.7, 1.9, -10.0, 2.1])
        factor_test2 = Factor(data=data2, name='test2')

        data3 = pd.DataFrame(index=index, data=['a', 'b', 'a', 'd', 'a', 'b', 'c', 'b'])
        factor_test3 = Factor(data=data3, name='test3', property_dict={'type': FactorType.INDUSTY_CODE})

        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test1, factor_test2, factor_test3])
        calculated = FactorStandardizer().fit_transform(fc)
        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003', '004']],
                                           names=['trade_date', 'ticker'])
        expected = pd.DataFrame({'test1': [-0.578123937458, -0.578123937458, -0.575802154576, 1.73205002949,
                                           -1.73160039778, 0.558580773478, 0.558580773478, 0.614438850826],
                                 'test2': [-0.632455532034, -1.26491106407, 0.632455532034, 1.26491106407,
                                           0.664422038189, 0.513631221012, -1.72938218451, 0.551328925306],
                                 'test3': ['a', 'b', 'a', 'd', 'a', 'b', 'c', 'b']},
                                index=index,
                                dtype=object)
        assert_frame_equal(calculated, expected) class TestWinsorizer(TestCase):
    @parameterized.expand([(np.array([1, 2, 3, 10, 4, 1, 3]),
                            (2.5, 97.5),
                            np.array([1, 2, 3, 9.1, 4, 1, 3]))])
    def test_winsorize(self, x, quantile_range, expected):
        calculated = Winsorizer(quantile_range).fit_transform(x)
        assert_array_almost_equal(calculated, expected)

    def test_factor_winsorizer(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28'], ['001', '002', '003', '004', '005']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 1.0, 1.2, 200.0, 0.9, 5.0, 5.0, 5.1, 5.9, 5.0])
        factor_test1 = Factor(data=data1, name='test1')

        data2 = pd.DataFrame(index=index, data=[2.6, 2.5, 2.8, 2.9, 2.7, 1.9, -10.0, 2.1, 2.0, 1.9])
        factor_test2 = Factor(data=data2, name='test2')

        data3 = pd.DataFrame(index=index, data=[3.0, 3.0, 30.0, 5.0, 4.0, 6.0, 7.0, 6.0, 6.0, 5.9])
        factor_test3 = Factor(data=data3, name='test3')

        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test1, factor_test2, factor_test3])
        quantile_range = (1, 99)
        calculated = FactorWinsorizer(quantile_range).fit_transform(fc)
        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003', '004', '005']],
                                           names=['trade_date', 'ticker'])
        expected = pd.DataFrame({'test1': [1.0, 1.0, 1.2, 192.048, 0.904, 5.0, 5.0, 5.1, 5.868, 5.0],
                                 'test2': [2.6, 2.504, 2.8, 2.896, 2.7, 1.9, -9.524, 2.096, 2.0, 1.9],
                                 'test3': [3.0, 3.0, 29.0, 5.0, 4.0, 6.0, 6.96, 6.0, 6.0, 5.904]},
                                index=index)
        assert_frame_equal(calculated, expected) class TestDateUtils(TestCase):
    @parameterized.expand([([dt(2017, 1, 1), dt(2017, 2, 1), dt(2017, 3, 1)],
                            'China.SSE',
                            BizDayConventions.Preceding,
                            pd.Series([dt(2016, 12, 30), dt(2017, 1, 26), dt(2017, 3, 1)])),
                           ([dt(2017, 1, 1), dt(2017, 2, 1), dt(2017, 2, 1)],
                            'China.SSE',
                            BizDayConventions.Following,
                            pd.Series([dt(2017, 1, 3), dt(2017, 2, 3), dt(2017, 2, 3)]))
                           ])
    def test_map_to_biz_day(self, date_series, calendar, convention, expected):
        calculated = map_to_biz_day(date_series, calendar, convention)
        assert_series_equal(calculated, expected)

    @parameterized.expand([('2016-01-01',
                            '2016-3-31',
                            FreqType.EOM,
                            'China.SSE',
                            '%Y-%m-%d',
                            [dt(2016, 1, 29), dt(2016, 2, 29), dt(2016, 3, 31)]),
                           ('2017-01-01',
                            '2017-02-01',
                            FreqType.EOW,
                            'China.SSE',
                            '%Y-%m-%d',
                            [dt(2017, 1, 6), dt(2017, 1, 13), dt(2017, 1, 20), dt(2017, 1, 26)]),
                           ('2016/01/01',
                            '2017/02/01',
                            FreqType.EOY,
                            'China.SSE',
                            '%Y/%m/%d',
                            [dt(2016, 12, 30)]),
                           (dt(2014, 1, 1),
                            dt(2014, 3, 31),
                            FreqType.EOM,
                            'China.SSE',
                            '%Y/%m/%d',
                            [dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 3, 31)])
                           ])
    def test_get_tiaocang_date(self, start_date, end_date, freq, calendar, date_format, expected):
        calculated = get_tiaocang_date(start_date, end_date, freq, calendar, date_format)
        self.assertEqual(calculated, expected) class TestInputValidation(TestCase):
    @parameterized.expand([([1, 2, 3], pd.Series([1, 2, 3])),
                           (np.array([1.0, 2.0, 3.0]), pd.Series([1.0, 2.0, 3.0])),
                           (pd.Series([1, 2, 3]), pd.Series([1, 2, 3]))
                           ])
    def test_ensure_pd_series(self, data, expected):
        calculated = ensure_pd_series(None, None, data)
        assert_series_equal(calculated, expected)

    @parameterized.expand([('2014-01-02', '%Y-%m-%d', Date(2014, 1, 2)),
                           ('2013/05/02', '%Y/%m/%d', Date(2013, 5, 2)),
                           (Date(2013, 5, 2), '%Y/%m/%d', Date(2013, 5, 2))])
    def test_ensure_pyfin_date(self, data, date_format, expected):
        calculated = ensure_pyfin_date(data, date_format)
        self.assertEqual(calculated, expected)

    @parameterized.expand([(None, None, pd.Series([1, 2, 3]), np.array([1, 2, 3])),
                           (None, None, pd.DataFrame([[1, 2, 3], [2, 3, 4]]), np.array([[1, 2, 3], [2, 3, 4]])),
                           (None, None, np.array([1, 2, 3]), np.array([1, 2, 3]))])
    def test_ensure_np_array(self, func, argname, data, expected):
        calculated = ensure_np_array(func, argname, data)
        assert_array_equal(calculated, expected)

    @parameterized.expand([(pd.DataFrame([1, 2],
                                         index=pd.MultiIndex.from_product([['2010-01-01', '2010-01-02'], ['001']],
                                                                          names=['trade_date', 'sec'])),
                            OutputDataFormat.MULTI_INDEX_DF,
                            INDEX_INDUSTRY_WEIGHT,
                            pd.DataFrame([1, 2],
                                         index=pd.MultiIndex.from_product([['2010-01-01', '2010-01-02'], ['001']],
                                                                          names=['trade_date', 'industry_code'])
                                         )),
                           (pd.DataFrame([1, 2], index=pd.Index(['2010-01-01', '2010-01-02'], name='trade_date')),
                            OutputDataFormat.PITVOT_TABLE_DF,
                            INDEX_FACTOR,
                            pd.DataFrame([1, 2], index=pd.Index(['2010-01-01', '2010-01-02'], name='trade_date'))
                            )])
    def test_ensure_pd_index_names(self, data, data_format, valid_index, expected):
        calculated = ensure_pd_index_names(data, data_format, valid_index)
        assert_frame_equal(calculated, expected) class TestNumpyUtils(TestCase):
    @parameterized.expand([(np.array([1, 2, 5, -1]), 2, np.array([2, 1])),
                           (np.array([7, 2, 5, -1]), 3, np.array([0, 2, 1]))])
    def test_index_n_largest(self, array, n, expected):
        calculated = index_n_largest(array, n)
        assert_array_equal(calculated, expected)

    @parameterized.expand([(np.array([1, 2, 5, -1]), 2, np.array([3, 0])),
                           (np.array([7, 2, 5, -1]), 3, np.array([3, 1, 2]))])
    def test_index_n_largest(self, array, n, expected):
        calculated = index_n_smallest(array, n)
        assert_array_equal(calculated, expected) class TestPandasUtils(TestCase):
    @parameterized.expand([(pd.DataFrame({'001': [1, 2, 3], '002': [2, 3, 4]}, index=['2014', '2015', '2016']),
                            OutputDataFormat.MULTI_INDEX_DF,
                            'test_factor',
                            INDEX_FACTOR,
                            pd.DataFrame(index=MultiIndex(levels=[['2014', '2015', '2016'], ['001', '002']],
                                                          labels=[[0, 0, 1, 1, 2, 2], [0, 1, 0, 1, 0, 1]],
                                                          names=['trade_date', 'ticker']),
                                         data=[1, 2, 2, 3, 3, 4],
                                         columns=['test_factor']))])
    def test_convert_df_format_1(self, data, target_format, col_name, multi_index, expected):
        calculated = convert_df_format(data, target_format, col_name, multi_index)
        assert_frame_equal(calculated, expected)

    @parameterized.expand(
        [(pd.DataFrame(
            index=MultiIndex.from_product([['2014', '2015', '2016'], ['001', '002']], names=['trade_date', 'ticker']),
            data=[1, 2, 3, 4, 5, 6],
            columns=['factor']),
          OutputDataFormat.PITVOT_TABLE_DF,
          'factor',
          INDEX_FACTOR,
          pd.DataFrame({'001': [1, 3, 5], '002': [2, 4, 6]},
                       index=Index(['2014', '2015', '2016'], name='trade_date')))])
    def test_convert_df_format_2(self, data, target_format, col_name, multi_index, expected):
        calculated = convert_df_format(data, target_format, col_name, multi_index)
        assert_frame_equal(calculated, expected)

    @parameterized.expand(
        [(pd.DataFrame(data=[[1, 23, 4, 5], [4, 5, 7, 8], [10, 5, 11, 8], [34, 65, 27, 78]],
                       columns=['A', 'B', 'C', 'D']),
          2,
          ['A'],
          pd.DataFrame(data=[[34, 65, 27, 78], [10, 5, 11, 8]], index=[3, 2], columns=['A', 'B', 'C', 'D'])
          )])
    def test_top_1(self, data, n, column, expected):
        calculated = top(data, column=column, n=n)
        assert_frame_equal(calculated, expected)

    @parameterized.expand(
        [(pd.Series(data=[35, 12, 45, 79, 123, 74, 35]),
          3,
          pd.Series(data=[123, 79, 74], index=[4, 3, 5])
          )])
    def test_top_2(self, data, n, expected):
        calculated = top(data, n=n)
        assert_series_equal(calculated, expected)

    @parameterized.expand(
        [(pd.DataFrame(data=[1, 2, 3, 4, 5, 6, 7, 9, 0, 12],
                       index=[dt(2017, 7, 1), dt(2017, 6, 1), dt(2017, 7, 2), dt(2017, 6, 1), dt(2017, 3, 1),
                              dt(2017, 3, 1), dt(2017, 1, 1), dt(2017, 2, 1), dt(2017, 1, 1), dt(2017, 2, 1)]),
          dt(2017, 7, 31),
          FreqType.EOM,
          pd.DataFrame(data=[1, 3], index=[dt(2017, 7, 1), dt(2017, 7, 2)])
          ),
         (pd.Series(data=[1, 2, 3, 4, 5, 6, 7, 9, 0, 12],
                    index=[dt(2016, 7, 1), dt(2016, 6, 1), dt(2017, 7, 2), dt(2017, 7, 1), dt(2017, 3, 1),
                           dt(2017, 3, 1), dt(2017, 1, 1), dt(2017, 2, 1), dt(2017, 1, 1), dt(2017, 2, 1)]),
          dt(2016, 12, 31),
          FreqType.EOY,
          pd.DataFrame(data=[2, 1], index=[dt(2016, 6, 1), dt(2016, 7, 1)])
          ),
         (pd.Series(data=[1, 2, 3, 4, 5, 6, 7, 9, 0, 12],
                    index=[dt(2016, 7, 1), dt(2016, 7, 1), dt(2017, 7, 2), dt(2017, 7, 1), dt(2017, 3, 1),
                           dt(2017, 3, 1), dt(2017, 1, 1), dt(2017, 2, 1), dt(2017, 1, 1), dt(2017, 2, 1)]),
          (2016, 7, 1),
          FreqType.EOD,
          pd.DataFrame(data=[1, 2], index=[dt(2016, 7, 1), dt(2016, 7, 1)])
          )
         ])
    def test_group_by_freq(self, data, group, freq, expected):
        calculated = group_by_freq(data, freq=freq).get_group(group)
        assert_frame_equal(calculated, expected)

    @parameterized.expand([(pd.Series(data=[1, 2, 3, 4],
                                      index=pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['a', 'b']],
                                                                       names=['trade_date', 'ticker'])),
                            1,
                            pd.DataFrame(data=[3, 4],
                                         index=pd.MultiIndex.from_product([[dt(2014, 1, 30)], ['a', 'b']],
                                                                          names=['trade_date', 'ticker']),
                                         columns=['fwd_return'])
                            ),
                           (pd.DataFrame(data=[1, 2, 3, 4, 5, 6],
                                         index=pd.MultiIndex.from_product(
                                             [[dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 3, 30)], ['a', 'b']],
                                             names=['trade_date', 'ticker'])),
                            2,
                            pd.DataFrame(data=[5, 6],
                                         index=pd.MultiIndex.from_product([[dt(2014, 1, 30)], ['a', 'b']],
                                                                          names=['trade_date', 'ticker']),
                                         columns=['fwd_return'])
                            )
                           ])
    def test_fwd_return(self, data, period, expected):
        calculated = fwd_return(data, period=period)
        assert_frame_equal(calculated, expected)

    @parameterized.expand(
        [(pd.DataFrame({'a': [1, 2, 3], 'b': [2, 4, 6]}), [1, 1], None, True, pd.DataFrame([0.0, 1.0, 2.0])),
         (pd.DataFrame({'a': [1, 2, 3], 'b': [2, 4, 6]}), [1, 0], [0.6, 0.4], False, np.array([0.8, 1.0, 1.2]))])
    def test_weighted_rank(self, data, order, weight, out_df, expected):
        calculated = weighted_rank(data, order, weight, out_df)
        if isinstance(expected, pd.DataFrame):
            assert_frame_equal(calculated, expected)
        else:
            assert_array_equal(calculated, expected) class TestSelector(TestCase):
    @parameterized.expand(
        [(pd.Series([3, 2, 4, 5, 6], index=['001', '002', '003', '004', '005'], name='score'),
          2,
          0.1,
          pd.DataFrame({'score': [6, 5], 'weight': [50.0, 50.0]}, index=['005', '004'])),
         (pd.Series([3, 2, 4, -5, -6], index=['001', '002', '003', '004', '005'], name='score'),
          2,
          0.1,
          pd.DataFrame({'score': [4, 3], 'weight': [50.0, 50.0]}, index=['003', '001'])),
         (pd.Series([3, 2, 4, 5, 6], index=['001', '002', '003', '004', '005'], name='score'),
          None,
          0.8,
          pd.DataFrame({'score': [6, 5, 4, 3],
                        'weight': [25.0, 25.0, 25.0, 25.0]},
                       index=['005', '004', '003', '001']))])
    def test_brutal_selector(self, X, nb_select, prop_select, expected):
        calculated = BrutalSelector(nb_select, prop_select).fit_transform(X)
        assert_frame_equal(calculated, expected)

    @parameterized.expand(
        [(pd.DataFrame({'score': [2, 3, 3, 8, 4, 5], 'industry_code': ['a', 'a', 'a', 'b', 'b', 'b']},
                       index=['001', '002', '003', '004', '005', '006']),
          pd.DataFrame({'weight': [0.5, 0.4, 0.1]}, index=['a', 'b', 'c']),
          0.1,
          2,
          pd.DataFrame({'score': [3, 3, 8, 5],
                        'industry_code': ['a', 'a', 'b', 'b'],
                        'weight': [0.25, 0.25, 0.2, 0.2]},
                       index=['002', '003', '004', '006'])
          ),
         (pd.DataFrame({'score': [2, 3, 3, 8, 4, 5, 2, 3, 1, 11],
                        'industry_code': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'b', 'c']},
                       index=['001', '002', '003', '004', '005', '006', '007', '008', '009', '010']),
          pd.DataFrame({'weight': [0.5, 0.4, 0.1]}, index=['a', 'b', 'c']),
          0.6,
          1,
          pd.DataFrame({'score': [8, 3, 5, 4, 3, 11],
                        'industry_code': ['a', 'a', 'b', 'b', 'b', 'c'],
                        'weight': [0.25, 0.25, 0.1333333333, 0.133333333333, 0.1333333333, 0.1]},
                       index=['004', '002', '006', '005', '008', '010'])
          )])
    def test_industry_neutral_selector(self,
                                       X,
                                       industry_weight,
                                       prop_select,
                                       min_select_per_industry,
                                       expected):
        calculated = IndustryNeutralSelector(industry_weight=industry_weight,
                                             min_select_per_industry=min_select_per_industry,
                                             prop_select=prop_select,
                                             ).fit_transform(X)

        expected = expected[['score', 'industry_code', 'weight']]
        assert_frame_equal(calculated, expected)

    def test_selector(self):
        index_weight = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['a', 'b', 'other']],
                                                  names=INDEX_INDUSTRY_WEIGHT.full_index)
        industry_weight = pd.DataFrame([0.5, 0.4, 0.1, 0.5, 0.3, 0.2], index=index_weight)

        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28'], ['001', '002', '003', '004', '005']],
                                           names=INDEX_FACTOR.full_index)
        X = pd.DataFrame({'score': [2, 3, 3, 8, 4, 5, 9, 11, 2, 0],
                          'industry_code': ['a', 'a', 'a', 'b', 'b', 'a', 'a', 'other', 'b', 'b']},
                         index=index)

        score = Factor(data=X['score'], name='score', property_dict={'type': FactorType.SCORE})
        industry_code = Factor(data=X['industry_code'], name='industry_code',
                               property_dict={'type': FactorType.INDUSTY_CODE})
        fc = FactorContainer(start_date='2014-01-30', end_date='2014-02-28')
        fc.add_factor(score)
        fc.add_factor(industry_code)

        calculated = Selector(industry_weight=industry_weight,
                              method=SelectionMethod.INDUSTRY_NEUTRAL).fit(fc).predict(fc)

        index_exp = pd.MultiIndex.from_arrays(
            [[dt(2014, 1, 30), dt(2014, 1, 30), dt(2014, 1, 30), dt(2014, 1, 30), dt(2014, 2, 28), dt(2014, 2, 28),
              dt(2014, 2, 28), dt(2014, 2, 28), dt(2014, 2, 28)],
             ['002', '003', '004', '005', '002', '001', '004', '005', '003']], names=['trade_date', 'ticker'])
        expected = pd.DataFrame({'score': [3, 3, 8, 4, 9, 5, 2, 0, 11],
                                 'industry_code': ['a', 'a', 'b', 'b', 'a', 'a', 'b', 'b', 'other'],
                                 'weight': [0.25, 0.25, 0.2, 0.2, 0.25, 0.25, 0.15, 0.15, 0.2]},
                                index=index_exp, dtype=object)
        expected = expected[['score', 'industry_code', 'weight']]
        assert_frame_equal(calculated, expected) class TestFactorIC(TestCase):
    def test_factor_ic(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28', '2014-03-31'], ['001', '002']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
        factor_test1 = Factor(data=data1, name='alpha1')
        factor_test3 = Factor(data=data1, name='alpha2')
        test2_property = {'type': FactorType.FWD_RETURN,
                          'data_format': OutputDataFormat.MULTI_INDEX_DF,
                          'norm_type': FactorNormType.Null,
                          'freq': FreqType.EOM}

        data2 = pd.DataFrame(index=index, data=[3.0, 2.0, 3.0, 7.0, 8.0, 9.0])
        factor_test2 = Factor(data=data2, name='fwd_return1', property_dict=test2_property)
        factor_test4 = Factor(data=data2, name='fwd_return2', property_dict=test2_property)

        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test1, factor_test2, factor_test3, factor_test4])
        t = FactorIC()
        calculate = t.predict(fc)
        expected = pd.DataFrame(data=[[-1.0, -1.0, -1.0, -1.0], [1.0, 1.0, 1.0, 1.0]],
                                index=pd.DatetimeIndex(['2014-01-30', '2014-02-28'], freq=None),
                                columns=['alpha1_fwd_return1', 'alpha2_fwd_return1', 'alpha1_fwd_return2',
                                         'alpha2_fwd_return2'])
        assert_frame_equal(calculate, expected) class TestFactorQuantile(TestCase):
    def test_factor_quantile(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28', '2014-03-31'], ['001', '002']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
        factor_test1 = Factor(data=data1, name='alpha1')
        factor_test3 = Factor(data=data1, name='alpha2')
        test2_property = {'type': FactorType.FWD_RETURN,
                          'data_format': OutputDataFormat.MULTI_INDEX_DF,
                          'norm_type': FactorNormType.Null,
                          'freq': FreqType.EOM}

        data2 = pd.DataFrame(index=index, data=[3.0, 2.0, 3.0, 7.0, 8.0, 9.0])
        factor_test2 = Factor(data=data2, name='fwd_return1', property_dict=test2_property)
        factor_test4 = Factor(data=data2, name='fwd_return2', property_dict=test2_property)

        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test1, factor_test2, factor_test3, factor_test4])
        t = FactorQuantile(quantiles=2)
        calculate = t.predict(fc)
        expected = pd.DataFrame(
            data=[[3.0, 2.0, 3.0, 2.0, 3.0, 2.0, 3.0, 2.0], [3.0, 7.0, 3.0, 7.0, 3.0, 7.0, 3.0, 7.0]],
            index=pd.DatetimeIndex(['2014-01-30', '2014-02-28'], freq=None),
            columns=['alpha1_fwd_return1_1', 'alpha1_fwd_return1_2', 'alpha2_fwd_return1_1', 'alpha2_fwd_return1_2',
                     'alpha1_fwd_return2_1', 'alpha1_fwd_return2_2', 'alpha2_fwd_return2_1',
                     'alpha2_fwd_return2_2'])
        assert_frame_equal(calculate, expected) class TestFactorSimpleRank(TestCase):
    def test_factor_simple_rank_1(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28'], ['001', '002', '003']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0])

        factor_test = Factor(data=data1, name='alpha1')
        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test])
        t = FactorSimpleRank()
        t.fit(fc)
        calculate = t.transform(fc)['score']
        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003']],
                                           names=['trade_date', 'ticker'])

        expected = pd.Series(index=index,
                             data=[0.0, 1.0, 2.0, 0.0, 1.0, 2.0], name='score')
        assert_series_equal(calculate, expected)

    def test_factor_simple_rank_2(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28'], ['001', '002', '003']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
        data2 = pd.DataFrame(index=index, data=[7.0, 2.0, 3.0, 9.0, 5.0, 6.0])
        factor_test_1 = Factor(data=data1, name='alpha1')
        factor_test_2 = Factor(data=data2, name='alpha2')
        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test_1, factor_test_2])
        t = FactorSimpleRank(factor_name=['alpha2'], out_container=True)
        t.fit(fc)
        calculate = t.transform(fc).data['score']
        index = pd.MultiIndex.from_product([[dt(2014, 1, 30), dt(2014, 2, 28)], ['001', '002', '003']],
                                           names=['trade_date', 'ticker'])

        expected = pd.Series(index=index,
                             data=[1.0, 2.0, 0.0, 1.0, 2.0, 0.0], name='score')
        assert_series_equal(calculate, expected) class TestTopMinusBottom(TestCase):
    def test_top_minus_bottom(self):
        index = pd.MultiIndex.from_product([['2014-01-30', '2014-02-28', '2014-03-31'], ['001', '002']],
                                           names=['trade_date', 'ticker'])
        data1 = pd.DataFrame(index=index, data=[1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
        factor_test1 = Factor(data=data1, name='alpha1')
        factor_test3 = Factor(data=data1, name='alpha2')
        test2_property = {'type': FactorType.FWD_RETURN,
                          'data_format': OutputDataFormat.MULTI_INDEX_DF,
                          'norm_type': FactorNormType.Null,
                          'freq': FreqType.EOM}

        data2 = pd.DataFrame(index=index, data=[3.0, 2.0, 3.0, 7.0, 8.0, 9.0])
        factor_test2 = Factor(data=data2, name='fwd_return1', property_dict=test2_property)
        factor_test4 = Factor(data=data2, name='fwd_return2', property_dict=test2_property)

        fc = FactorContainer('2014-01-30', '2014-02-28', [factor_test1, factor_test2, factor_test3, factor_test4])
        t = TopMinusBottom(quantiles=2)
        calculate = t.predict(fc)
        expected = pd.DataFrame(
            data=[[-1.0, -1.0, -1.0, -1.0], [4.0, 4.0, 4.0, 4.0]],
            index=pd.DatetimeIndex(['2014-01-30', '2014-02-28'], freq=None),
            columns=['alpha1_fwd_return1', 'alpha2_fwd_return1',
                     'alpha1_fwd_return2',
                     'alpha2_fwd_return2'])
        assert_frame_equal(calculate, expected)
import os
import sys
import unittest
from alphaware.tests.base import TestFactorContainer
from alphaware.tests.metrics import TestReturnMetrics
from alphaware.tests.pipeline import TestPipeline
from alphaware.tests.preprocess import (TestBenchmark,
                                        TestFactorImputer,
                                        TestExtCategoricalImputer,
                                        TestNeutralizer,
                                        TestStandardizer,
                                        TestWinsorizer)
from alphaware.tests.utils import (TestDateUtils,
                                   TestInputValidation,
                                   TestNumpyUtils,
                                   TestPandasUtils)
from alphaware.tests.test_selector import TestSelector
from alphaware.tests.analyzer import (TestFactorIC,
                                      TestFactorQuantile,
                                      TestFactorSimpleRank,
                                      TestTopMinusBottom)
# -*- coding: utf-8 -*-


thisFilePath = os.path.abspath(__file__)
sys.path.append(os.path.sep.join(thisFilePath.split(os.path.sep)[:-3]))


def test():
    print('Python ' + sys.version)
    suite = unittest.TestSuite()
    tests = unittest.TestLoader().loadTestsFromTestCase(TestFactorContainer)
    suite.addTests(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestReturnMetrics)
    suite.addTest(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestPipeline)
    suite.addTests(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestBenchmark)
    suite.addTests(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestFactorImputer)
    suite.addTests(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestExtCategoricalImputer)
    suite.addTests(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestNeutralizer)
    suite.addTests(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestStandardizer)
    suite.addTests(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestWinsorizer)
    suite.addTests(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestDateUtils)
    suite.addTests(tests)
    tests = unittest.TestLoader().loadTestsFromTestCase(TestInputValidation)
    suite.addTests(tests)

    tests = unittest.TestLoader().loadTestsFromTestCase(TestNumpyUtils)