1 # 可以自己import我们平台支持的第三方python模块,比如pandas、numpy等。
  2 import numpy  as np
  3 from sklearn.linear_model import LinearRegression
  4 
  5 
  6 # 在这个方法中编写任何的初始化逻辑。context对象将会在你的算法策略的任何方法之间做传递。
  7 def init(context):
  8     # 初始化股票池
  9     context.hs300 = index_components("000300.XSHG")
 10     # (9,)
 11     # (1,9)
 12     weight = np.mat(np.array(
 13         [0.02953221, -0.04920124, -0.10791485, 0.00801783, -0.03613599, 0.1310877, -0.03030564, 0.40286239,
 14          -0.30166898]))
 15 
 16     context.weight = weight.T
 17 
 18     # 选股 的数量
 19     context.stock_num = 20
 20 
 21     # 每月进行一次调仓
 22     # 设置定时器
 23     # 参数1 每月执行的逻辑--函数
 24     # 参数2 tradingday 每月执行逻辑的交易日
 25     scheduler.run_monthly(MyLinearRegression, tradingday=1)
 26 
 27 
 28 def three_sigma(data):
 29     """
 30     基于3sigma原则的离群值处理
 31     :param data: 需要处理的数据
 32     :return: 处理之后的数据
 33     """
 34     # 上限
 35     up = data.mean() + 3 * data.std()
 36     # 下限
 37     low = data.mean() - 3 * data.std()
 38 
 39     # 超过上限 变为上限,超过下限变为下限
 40     data = np.where(data > up, up, data)
 41     data = np.where(data < low, low, data)
 42 
 43     return data
 44 
 45 
 46 def stand_sca(data):
 47     """
 48     标准差标准化
 49     :param data:原数据
 50     :return: 标准差之后的数据
 51     """
 52     data = (data - data.mean()) / data.std()
 53 
 54     return data
 55 
 56 
 57 def deal_data(data):
 58     """
 59     因子数据处理
 60     """
 61     # (1)缺失值处理
 62     # 直接删除--dropna
 63     data.dropna(how="any", axis=0, inplace=True)
 64 
 65     market_cap = data.loc[:, "market_cap"]
 66     for column in data.columns:
 67         # (2)离群值处理
 68         data.loc[:, column] = three_sigma(data.loc[:, column])
 69         # (3)标准化处理
 70         data.loc[:, column] = stand_sca(data.loc[:, column])
 71         if column == "market_cap":
 72             continue
 73         # (4)市值因子--中性化处理 # market_cap---市值因子
 74         # 以市值因子为特征值,其他因子为目标值建立线性关系
 75         x = market_cap.values.reshape((-1, 1))
 76         y = data.loc[:, column].values
 77         # 实例化算法对象
 78         lr = LinearRegression()
 79         # 构建模型
 80         lr.fit(x, y)  # 特征值必须是二维数据,目标值必须是一维的
 81         # 进行预测--预测值----受市值影响部分
 82         y_predict = lr.predict(x)
 83 
 84         # 不受市值影响的部分  =  其他因子的值 - 受市值影响的部分
 85         data.loc[:, column] = data.loc[:, column] - y_predict
 86 
 87     return data
 88 
 89 
 90 def tiaocang(context):
 91     """
 92     调整仓位
 93     """
 94     # 获取所有的仓位中的股票
 95     for tmp in context.portfolio.positions.keys():
 96         # 遍历仓位,如果股票不在stock_list就卖出
 97         if tmp not in context.stock_list:
 98             order_target_percent(tmp, 0)
 99     # 买入
100     for tmp in context.stock_list:
101         order_target_percent(tmp, 1 / len(context.stock_list))
102 
103 
104 def MyLinearRegression(context, bar_dict):  # context此时必须传递
105     """
106     每月执行的逻辑函数
107     """
108     # 1、获取因子数据
109     q = query(
110         fundamentals.eod_derivative_indicator.pe_ratio, fundamentals.eod_derivative_indicator.pb_ratio,
111         fundamentals.eod_derivative_indicator.market_cap, fundamentals.financial_indicator.ev,
112         fundamentals.financial_indicator.return_on_asset_net_profit,
113         fundamentals.financial_indicator.du_return_on_equity, fundamentals.financial_indicator.earnings_per_share,
114         fundamentals.income_statement.revenue, fundamentals.income_statement.total_expense
115     ).filter(
116         fundamentals.stockcode.in_(context.hs300)
117     )
118 
119     fund = get_fundamentals(q)
120 
121     context.factor = fund.T
122 
123     # print(context.factor)
124 
125     # 2、因子数据处理
126     context.factor = deal_data(context.factor)
127 
128     print("因子处理之后的结果:\n", context.factor)
129 
130     # 3、因子 * 权重  + B = 预测收益
131     # (300,9) * (9,1)  = [300,1]
132     context.factor.loc[:, "factor_return"] = np.dot(context.factor, context.weight)
133 
134     # 4、将数据以 收益进行降序排序---预测的收益较好的20支股票
135     context.stock_list = context.factor.sort_values(by="factor_return", ascending=False).head(context.stock_num).index
136 
137     # 5、调仓
138     tiaocang(context)
139 
140 
141 # before_trading此函数会在每天策略交易开始前被调用,当天只会被调用一次
142 def before_trading(context):
143     pass
144 
145 
146 # 你选择的证券的数据更新将会触发此段逻辑,例如日或分钟历史数据切片或者是实时数据切片更新
147 def handle_bar(context, bar_dict):
148     pass
149 
150 
151 # after_trading函数会在每天交易结束后被调用,当天只会被调用一次
152 def after_trading(context):
153     pass