# Path: alphaware/base/factor_container.py
# def ensure_factor_container(func, argname, arg):
#     if isinstance(arg, FactorContainer):
#         return arg
#     else:
#         fc = FactorContainer(tiaocang_date=arg.trade_date_list)
#         fc.add_factor(arg)
#         return fc
# 
# Path: alphaware/base/factor_transformer.py
# class FactorTransformer(BaseEstimator, TransformerMixin):
#     def __init__(self, copy=True, out_container=False):
#         self.copy = copy
#         self.df_mapper = None
#         self.out_container = out_container
# 
#     @expect_types(out=bool)
#     def set_out_container(self, out):
#         self.out_container = out
# 
#     @preprocess(factor_container=ensure_factor_container)
#     def fit(self, factor_container, **kwargs):
#         self.df_mapper = self._build_mapper(factor_container)
#         return self
# 
#     def _build_mapper(self, factor_container):
#         raise NotImplementedError
# 
#     @preprocess(factor_container=ensure_factor_container)
#     def transform(self, factor_container):
#         if self.copy:
#             factor_container = copy.deepcopy(factor_container)
#         tiaocang_date = factor_container.tiaocang_date
#         calc_data = [self.df_mapper.fit_transform(factor_container.data.loc[date_]) for date_ in
#                      tiaocang_date]
#         calc_data_agg = np.vstack(calc_data)
#         factor_container.data = pd.DataFrame(calc_data_agg,
#                                              index=factor_container.data.index,
#                                              columns=factor_container.data.columns)
#         if self.out_container:
#             return factor_container
#         else:
#             return factor_container.data
# 
# Path: alphaware/enums.py
# class FactorType(StrEnum):
#     INDUSTY_CODE = 'industry_code'
#     ALPHA_FACTOR = 'alpha_factor'
#     RETURN = 'return'
#     PRICE = 'price'
#     ALPHA_FACTOR_MV = 'alpha_factor_mv'
#     SCORE = 'score'
#     FWD_RETURN = 'fwd_return'
#     WEIGHT = 'weight'
# 
# class FactorNormType(IntEnum):
#     Null = 0
#     Industry_Neutral = 1
#     Industry_Cap_Neutral = 2
# 
# Path: alphaware/utils/input_validation.py
# @expect_types(arg=(np.ndarray, pd.DataFrame, pd.Series))
# def ensure_np_array(func, argname, arg):
#     """
#     :return: 转换成np.ndarray格式
#     """
#     if isinstance(arg, np.ndarray):
#         return arg
#     else:
#         return arg.values


import copy
import numpy as np
import pandas as pd
from argcheck import (preprocess,
                      optionally)
from sklearn.base import (BaseEstimator,
                          TransformerMixin)
from sklearn.linear_model import LinearRegression
from sklearn_pandas import DataFrameMapper
from ..base import (FactorTransformer,
                    ensure_factor_container)
from ..enums import (FactorType,
                     FactorNormType)
from ..utils import ensure_np_array
        residues = Y - a

        return np.asmatrix(residues).A1


class FactorNeutralizer(FactorTransformer):
    def __init__(self, copy=True, out_container=False):
        super(FactorNeutralizer, self).__init__(copy=copy, out_container=out_container)

    def _build_mapper(self, factor_container, **kwargs):
        data_mapper_by_date = pd.Series()
        for date in factor_container.tiaocang_date:
            industry_code = factor_container.industry_code.loc[date]
            mkt_cap = factor_container.mkt_cap.loc[date]
            data = factor_container.data.loc[date]

            data_mapper = [([factor_name],
                            self._get_mapper(factor_type=factor_container.property[factor_name]['type'],
                                             factor_norm_type=factor_container.property[factor_name]['norm_type'],
                                             industry_code=industry_code,
                                             mkt_cap=mkt_cap))
                           for factor_name in data.columns]
            data_mapper_by_date[date] = DataFrameMapper(data_mapper)
        return data_mapper_by_date

    @staticmethod
    def _get_mapper(factor_type, factor_norm_type, industry_code, mkt_cap=None):
        if factor_type == FactorType.INDUSTY_CODE or factor_norm_type == FactorNormType.Null:
            return None
        else:

# Path: alphaware/base/factor_container.py
# def ensure_factor_container(func, argname, arg):
#     if isinstance(arg, FactorContainer):
#         return arg
#     else:
#         fc = FactorContainer(tiaocang_date=arg.trade_date_list)
#         fc.add_factor(arg)
#         return fc
# 
# Path: alphaware/base/factor_transformer.py
# class FactorTransformer(BaseEstimator, TransformerMixin):
#     def __init__(self, copy=True, out_container=False):
#         self.copy = copy
#         self.df_mapper = None
#         self.out_container = out_container
# 
#     @expect_types(out=bool)
#     def set_out_container(self, out):
#         self.out_container = out
# 
#     @preprocess(factor_container=ensure_factor_container)
#     def fit(self, factor_container, **kwargs):
#         self.df_mapper = self._build_mapper(factor_container)
#         return self
# 
#     def _build_mapper(self, factor_container):
#         raise NotImplementedError
# 
#     @preprocess(factor_container=ensure_factor_container)
#     def transform(self, factor_container):
#         if self.copy:
#             factor_container = copy.deepcopy(factor_container)
#         tiaocang_date = factor_container.tiaocang_date
#         calc_data = [self.df_mapper.fit_transform(factor_container.data.loc[date_]) for date_ in
#                      tiaocang_date]
#         calc_data_agg = np.vstack(calc_data)
#         factor_container.data = pd.DataFrame(calc_data_agg,
#                                              index=factor_container.data.index,
#                                              columns=factor_container.data.columns)
#         if self.out_container:
#             return factor_container
#         else:
#             return factor_container.data
# 
# Path: alphaware/enums.py
# class FactorType(StrEnum):
#     INDUSTY_CODE = 'industry_code'
#     ALPHA_FACTOR = 'alpha_factor'
#     RETURN = 'return'
#     PRICE = 'price'
#     ALPHA_FACTOR_MV = 'alpha_factor_mv'
#     SCORE = 'score'
#     FWD_RETURN = 'fwd_return'
#     WEIGHT = 'weight'
# 
# class FactorNormType(IntEnum):
#     Null = 0
#     Industry_Neutral = 1
#     Industry_Cap_Neutral = 2
# 
# Path: alphaware/utils/input_validation.py
# @expect_types(arg=(np.ndarray, pd.DataFrame, pd.Series))
# def ensure_np_array(func, argname, arg):
#     """
#     :return: 转换成np.ndarray格式
#     """
#     if isinstance(arg, np.ndarray):
#         return arg
#     else:
#         return arg.values


# Path: alphaware/preprocess/neutralizer.py
import copy
import numpy as np
import pandas as pd
from argcheck import (preprocess,
                      optionally)
from sklearn.base import (BaseEstimator,
                          TransformerMixin)
from sklearn.linear_model import LinearRegression
from sklearn_pandas import DataFrameMapper
from ..base import (FactorTransformer,
                    ensure_factor_container)
from ..enums import (FactorType,
                     FactorNormType)
from ..utils import ensure_np_array

        residues = Y - a

        return np.asmatrix(residues).A1


class FactorNeutralizer(FactorTransformer):
    def __init__(self, copy=True, out_container=False):
        super(FactorNeutralizer, self).__init__(copy=copy, out_container=out_container)

    def _build_mapper(self, factor_container, **kwargs):
        data_mapper_by_date = pd.Series()
        for date in factor_container.tiaocang_date:
            industry_code = factor_container.industry_code.loc[date]
            mkt_cap = factor_container.mkt_cap.loc[date]
            data = factor_container.data.loc[date]

            data_mapper = [([factor_name],
                            self._get_mapper(factor_type=factor_container.property[factor_name]['type'],
                                             factor_norm_type=factor_container.property[factor_name]['norm_type'],
                                             industry_code=industry_code,
                                             mkt_cap=mkt_cap))
                           for factor_name in data.columns]
            data_mapper_by_date[date] = DataFrameMapper(data_mapper)
        return data_mapper_by_date

    @staticmethod
    def _get_mapper(factor_type, factor_norm_type, industry_code, mkt_cap=None):
        if factor_type == FactorType.INDUSTY_CODE or factor_norm_type == FactorNormType.Null:
            return None
        else:

            if factor_norm_type == FactorNormType.Industry_Cap_Neutral: