成长性因子选股(1)

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年还是可以赚钱的,不过有点马后炮的意思了,估计年初的时候,应该不太可能有人预期到行情会这么走。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值