2018年的A股市场的确是血雨腥风,估值一降再降,不断创出新低,如果使用传统的成长性选股方案,仅仅能够跑赢沪深300指数,想要进一步取得正收益,还真不能完全依靠基本面。
通过成长性因子来选股的话,去年的收益是-20%,略微跑赢沪深300的-25%,因子有:
1.PB小于2
2.流动资产/流动负债大于1.2
3.EPS大于0.2
4.ROE大于20%
5.毛利率大于30%
6.营业收入同比大于30%
按照EPS排名,取前10只股票,满仓干,代码如下:
# 导入函数库
from jqdata import *
# 初始化函数,设定基准等等
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的)
g.n=4
run_daily(trade ,'every_bar')
def trade(context):
dt=context.current_dt.month
# print(dt)
# print(list(range(1,13,12/g.n)))
if dt in [1,4,7,10]:
st=get_index_stocks('399905.XSHE')
stockpool=get_fundamentals(query(
valuation.code,valuation.pb_ratio,balance.total_current_assets,balance.total_current_liability,balance.total_liability,
balance.total_assets,indicator.eps,indicator.gross_profit_margin,indicator.inc_return,indicator.inc_total_revenue_year_on_year
).filter(
valuation.pb_ratio<2,balance.total_current_assets/balance.total_current_liability>1.2,indicator.eps>0.2,indicator.gross_profit_margin>0.3,
indicator.inc_return>0.2,indicator.inc_total_revenue_year_on_year>0.3
).order_by(indicator.eps).limit(10)
)
cc=context.portfolio.positions.keys()
for i in cc:
if i not in list(stockpool['code']):
order_target(i,0)
# buy=[]
# for i in list(stockpool['code']):
# if i not in cc:
# buy.append(i)
for i in list(stockpool['code']):
order_target_value(i,100000/len(stockpool['code']))
# if len(buy)>0:
# cash=context.portfolio.available_cash/len(buy)
# for i in buy:
# order_value(i,cash)
注意事项:
1.在下单的时候,stockpool['code']的返回值是一个series,前面必须加list,不然 if str in series:返回值是faulse,就会出现股票频繁买卖的情况。
2.我用的是每只股票固定10 0000/持仓股数的满仓交易,意味着满仓市值不变,而不是根据市值进行调整持仓股票的市值
3.下单函数拆成buylist,selist,hold也可以,也是一种方法。
4.从结论来看,低估值的选股思路虽然跑赢了沪深300,但是还是没有能够取得正收益,主要是买入持有策略,还是抵不过大盘的弱势下跌,估值不断下行,就算业绩再好也白搭,可以加入一些技术指标进行优化,因子本身还算说得过去。
以上选股因子不变的条件之下,加入两个技术指标因子:
1.如果大盘跌穿60均线
2.如果大盘连续3天的跌幅大于5%
代码如下:
# 导入函数库
from jqdata import *
# 初始化函数,设定基准等等
def initialize(context):
# 设定沪深300作为基准
set_benchmark('000300.XSHG')
# 开启动态复权模式(真实价格)
set_option('use_real_price', True)
set_order_cost(OrderCost(close_tax=0.001, open_commission=0.0003, close_commission=0.0003, min_commission=5), type='stock')
## 运行函数(reference_security为运行时间的参考标的;传入的标的只做种类区分,因此传入'000300.XSHG'或'510300.XSHG'是一样的)
g.n=4
g.m=[30,60,90,120]
run_daily(trade ,'every_bar')
def trade(context):
dt=context.current_dt.month
# print(dt)
# print(list(range(1,13,12/g.n)))
if dt in [1,4,7,10]:
st=get_index_stocks('399905.XSHE')
stockpool=get_fundamentals(query(
valuation.code,valuation.pb_ratio,balance.total_current_assets,balance.total_current_liability,balance.total_liability,
balance.total_assets,indicator.eps,indicator.gross_profit_margin,indicator.inc_return,indicator.inc_total_revenue_year_on_year
).filter(
valuation.pb_ratio<2,balance.total_current_assets/balance.total_current_liability>1.2,indicator.eps>0.2,indicator.gross_profit_margin>0.3,
indicator.inc_return>0.2,indicator.inc_total_revenue_year_on_year>0.3
).order_by(indicator.eps).limit(10)
)
cc=context.portfolio.positions.keys()
for i in cc:
if i not in list(stockpool['code']):
order_target(i,0)
hs=attribute_history('000300.XSHG',g.m[1],'1d','close')['close']
if hs[-1]>hs.mean() and (1-hs[-1]/hs[-4]<0.05):
# buy=[]
# for i in list(stockpool['code']):
# if i not in cc:
# buy.append(i)
for i in list(stockpool['code']):
order_target_value(i,100000/len(stockpool['code']))
# if len(buy)>0:
# cash=context.portfolio.available_cash/len(buy)
# for i in buy:
# order_value(i,cash)
同时满足以上两个条件就空仓,回测的结果就非常不错,沪深300还是跌幅25%,但是策略收益是-7.8%,很明显的大幅降低亏损,说明技术分析方法在熊市的表现非常不错,单纯的价值投资在熊市中还是很难的。
注意事项:
1.获取历史数据的函数attribute_history 的返回值是df,不是Series,所以得加['close']才能取到收盘价
2.简单遍历了一下均线的参数,30.60.90.120,发现60就可以了,并非越大越好
3.连续下跌N天大于M%的参数没有遍历,凭经验应该足够
4.两个技术因子表现就很明显,是行情太配合的原因吧,换行情可能需要更多的因子
5.亏损幅度的确下降了,但是还没有盈利,从目前的结论来看,价值投资在2018年不可能赚钱,只有趋势投机才有可能,所以,通过引入新的技术指标,可能实现最后盈利
6.其实从两次回测的结果来看,如果换个盈利方向,2018年还是可以赚钱的,不过有点马后炮的意思了,估计年初的时候,应该不太可能有人预期到行情会这么走。