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