-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathLow_Valuation_Stock_Selection.py
More file actions
133 lines (118 loc) · 4.82 KB
/
Copy pathLow_Valuation_Stock_Selection.py
File metadata and controls
133 lines (118 loc) · 4.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
'''
1.市净率小于2;
2.负债比例低于市场平均值;
3.企业的流动资产至少是流动负债的1.2倍;
4.每年四次调仓,即在1/4/7/10月调仓;
5. 可加入止损(十天中证500跌幅达10%清仓);
'''
## 初始化函数,设定要操作的股票、基准等等
def initialize(context):
# 设定指数
g.stockindex = '000905.XSHG'
# 设定中证500作为基准
set_benchmark('000905.XSHG')
# True为开启动态复权模式,使用真实价格交易
set_option('use_real_price', True)
# 设定成交量比例
set_option('order_volume_ratio', 1)
# 股票类交易手续费是:买入时佣金万分之三,卖出时佣金万分之三加千分之一印花税, 每笔交易佣金最低扣5块钱
set_order_cost(OrderCost(open_tax=0, close_tax=0.001, \
open_commission=0.0003, close_commission=0.0003,\
close_today_commission=0, min_commission=5), type='stock')
# 最大持仓数量
g.stocknum = 10
## 自动设定调仓月份(如需使用自动,注销下段)
f = 4 # 调仓频率
log.info(list(range(1,13,12//f)))
g.Transfer_date = list(range(1,13,12//f))
## 手动设定调仓月份(如需使用手动,注释掉上段)
# g.Transfer_date = (3,9)
#根据大盘止损,如不想加入大盘止损,注释下句即可
# run_daily(dapan_stoploss, time='open')
## 按月调用程序
run_monthly(trade, monthday=20, time='open')
## 交易函数
def trade(context):
# 获取当前月份
months = context.current_dt.month
# 如果当前月为交易月
if months in g.Transfer_date:
## 获得Buylist
Buylist = check_stocks(context)
## 卖出
if len(context.portfolio.positions) > 0:
for stock in context.portfolio.positions.keys():
if stock not in Buylist:
order_target(stock, 0)
## 分配资金
if len(context.portfolio.positions) < g.stocknum :
Num = g.stocknum - len(context.portfolio.positions)
Cash = context.portfolio.cash/Num
else:
Cash = 0
## 买入
if len(Buylist) > 0:
for stock in Buylist:
if stock not in context.portfolio.positions.keys():
order_value(stock,Cash)
else:
return
## 选股函数
def check_stocks(context):
# 获取沪深成分股
security = get_index_stocks(g.stockindex)
Stocks = get_fundamentals(query(
valuation.code,
valuation.pb_ratio,
balance.total_assets,
balance.total_liability,
balance.total_current_assets,
balance.total_current_liability
).filter(
valuation.code.in_(security),
valuation.pb_ratio < 2, #市净率低于2
balance.total_current_assets/balance.total_current_liability > 1.2 #流动资产至少是流动负债的1.2倍
))
# 计算股票的负债比例
Stocks['Debt_Asset'] = Stocks['total_liability']/Stocks['total_assets']
# 获取负债比率的市场均值
me = Stocks['Debt_Asset'].median()
# 获取满足上述条件的股票列表(负债比例低于中位数,财务更稳健)
Stocks = Stocks[Stocks['Debt_Asset'] < me]
# 按市净率升序排列,选择估值最低的10只
Stocks = Stocks.sort_values(by='pb_ratio', ascending=True)
# 只返回前 g.stocknum 只股票
Codes = Stocks.code[:g.stocknum]
return list(Codes)
## 根据局大盘止损,具体用法详见dp_stoploss函数说明
def dapan_stoploss(context):
stoploss = dp_stoploss(kernel=2, n=3, zs=0.1)
if stoploss:
if len(context.portfolio.positions)>0:
for stock in list(context.portfolio.positions.keys()):
order_target(stock, 0)
## 大盘止损函数
def dp_stoploss(kernel=2, n=10, zs=0.03):
'''
方法1:当大盘N日均线(默认60日)与昨日收盘价构成“死叉”,则发出True信号
方法2:当大盘N日内跌幅超过zs,则发出True信号
'''
# 止损方法1:根据大盘指数N日均线进行止损
if kernel == 1:
t = n+2
hist = attribute_history('000300.XSHG', t, '1d', 'close', df=False)
temp1 = sum(hist['close'][1:-1])/float(n)
temp2 = sum(hist['close'][0:-2])/float(n)
close1 = hist['close'][-1]
close2 = hist['close'][-2]
if (close2 > temp2) and (close1 < temp1):
return True
else:
return False
# 止损方法2:根据大盘指数跌幅进行止损
elif kernel == 2:
hist1 = attribute_history('000905.XSHG', n, '1d', 'close', df=False)
if ((1-float(hist1['close'][-1]/hist1['close'][0])) >= zs):
return True
else:
return False