大浪淘沙:一个可以实盘的策略

策略分享
标签: #<Tag:0x00007fcf6c7e93f0>

(大胡子) #1

本策略逻辑如下:

  • 市盈率小于75倍、
  • 流通市值大于500亿
  • 净利润同比增长率大于10%
  • 选择前五只股票
  • 等权重买入
  • 无止盈止损

欢迎交流!

克隆策略

1.获取数据并整理出每日调仓应买入的股票

In [1]:
# 该函数的目的是通过history_data这个大的原始数据,获取每日满足价值投资股票列表
def seek_symbol(df):
    selected = df[(df['pe_ttm_0'] < 75)
        & (df['market_cap_float_0'] >  50000000000) 
        & (df['amount_0'] > 0) 
        & (df['fs_net_profit_yoy_0'] > 10)]
    return list(selected.instrument)[:5] # 买入前5只

def prepare(context):
    start_date = context.start_date # 开始日期
    end_date = context.end_date # 结束日期

    # 获取沪深300股票列表
    df = D.history_data(D.instruments(start_date, end_date),start_date,end_date,fields=['in_csi300'])
    hs300 = df[df['in_csi300']==1]['instrument']
    stocklist=list(set(hs300.tolist()))

    # 获取净利润同比增长率,流通市值,市盈率数据
    instruments = stocklist
    history_data = D.features(instruments, start_date=start_date,
               end_date= end_date, fields=[ 'fs_net_profit_yoy_0', 'market_cap_float_0','amount_0','pe_ttm_0'])
    # 每天应买入股票列表
    context.daily_buy_stock = history_data.groupby('date').apply(seek_symbol)

2. 回测主体函数

In [2]:
def initialize(context):
    # 设置交易费用,买入是万三,卖出是千分之1.3,如果不足5元按5元算
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))
    # 设置换仓规则,即每个月月初换仓,持有至下个月,再换仓
    context.schedule_function(rebalance, date_rule=date_rules.month_start(days_offset=0)) 
    # 设置最大杠杆不能超过1 
    context.set_max_leverage(1) 
   
def handle_data(context,data):
    pass

# 换仓
def rebalance(context, data):
    # 日期
    date = data.current_dt.strftime('%Y-%m-%d')
   
    # 买入股票列表
    stock_to_buy = context.daily_buy_stock.ix[date]
    # 目前持仓列表    
    stock_hold_now = [equity.symbol for equity 
                               in context.portfolio.positions]
    # 继续持有股票列表
    no_need_to_sell = [i for i in stock_hold_now 
                               if i in stock_to_buy]
    # 卖出股票列表 
    stock_to_sell = [i for i in stock_hold_now if
                           i not in no_need_to_sell]
    # 执行卖出
    for stock in stock_to_sell:
        if data.can_trade(context.symbol(stock)):
            context.order_target_percent(context.symbol(stock), 0)
    
    if len(stock_to_buy) == 0:
        return
    # 等权重
    weight = 1 / len(stock_to_buy)
    # 执行买入
    for  cp in stock_to_buy:
        if data.can_trade(context.symbol(cp)):
            context.order_target_percent(context.symbol(cp), weight)

3.回测接口

In [3]:
# 使用该回测接口,需要传入多个策略参数
m=M.trade.v3( 
    instruments=D.instruments(),
    start_date='2016-01-01', 
    end_date='2017-12-15',
    # 必须传入initialize,只在第一天运行
    initialize=initialize,
    prepare=prepare, # 该函数用于整理出每日应买入的股票列表
    # 必须传入handle_data,每个交易日都会运行
    handle_data=handle_data,
    # 买入以开盘价成交
    order_price_field_buy='open',
    # 卖出也以开盘价成交
    order_price_field_sell='open',
    # 策略本金
    capital_base=1000000,
    # 比较基准:沪深300
    benchmark='000300.INDX',
    price_type='real'
)
[2017-12-20 08:59:47.408127] INFO: bigquant: backtest.v7 开始运行..
[2017-12-20 09:00:02.964339] INFO: algo: set price type:PriceType.real
[2017-12-20 09:00:33.735893] INFO: Trade Simulation: get splits [2016-05-06 00:00:00+00:00] [asset:Equity(2166 [000333.SZA]), ratio:0.6423158780377346]
[2017-12-20 09:00:33.737342] INFO: Position: position handle split[sid:2166, orig_amount:5800, new_amount:9029.0, orig_cost:29.541387768600966,new_cost:18.97, ratio:0.6423158780377346, last_sale_price:21.190000816464867]
[2017-12-20 09:00:33.738173] INFO: Position: after split: asset: Equity(2166 [000333.SZA]), amount: 9029.0, cost_basis: 18.97, last_sale_price: 32.99
[2017-12-20 09:00:33.738926] INFO: Position: returning cash: 17.48
[2017-12-20 09:00:33.858725] INFO: Trade Simulation: get splits [2016-06-15 00:00:00+00:00] [asset:Equity(1922 [000538.SZA]), ratio:0.9903846317782032]
[2017-12-20 09:00:33.860060] INFO: Position: position handle split[sid:1922, orig_amount:3100, new_amount:3130.0, orig_cost:67.10001910789056,new_cost:66.45, ratio:0.9903846317782032, last_sale_price:61.80000102295988]
[2017-12-20 09:00:33.861269] INFO: Position: after split: asset: Equity(1922 [000538.SZA]), amount: 3130.0, cost_basis: 66.45, last_sale_price: 62.4
[2017-12-20 09:00:33.862179] INFO: Position: returning cash: 6.0
[2017-12-20 09:00:33.871528] INFO: Trade Simulation: get splits [2016-06-17 00:00:00+00:00] [asset:Equity(2877 [002304.SZA]), ratio:0.9758129715919495]
[2017-12-20 09:00:33.873015] INFO: Position: position handle split[sid:2877, orig_amount:2800, new_amount:2869.0, orig_cost:70.00101057927724,new_cost:68.31, ratio:0.9758129715919495, last_sale_price:72.62000274658203]
[2017-12-20 09:00:33.874281] INFO: Position: after split: asset: Equity(2877 [002304.SZA]), amount: 2869.0, cost_basis: 68.31, last_sale_price: 74.41999816894531
[2017-12-20 09:00:33.875457] INFO: Position: returning cash: 29.22
[2017-12-20 09:00:33.948562] INFO: Trade Simulation: get splits [2016-07-12 00:00:00+00:00] [asset:Equity(294 [002142.SZA]), ratio:0.9706841123482084]
[2017-12-20 09:00:33.949723] INFO: Position: position handle split[sid:294, orig_amount:13800, new_amount:14216.0, orig_cost:14.744367849837383,new_cost:14.31, ratio:0.9706841123482084, last_sale_price:14.900001124544998]
[2017-12-20 09:00:33.950813] INFO: Position: after split: asset: Equity(294 [002142.SZA]), amount: 14216.0, cost_basis: 14.31, last_sale_price: 15.35
[2017-12-20 09:00:33.951699] INFO: Position: returning cash: 11.58
[2017-12-20 09:00:33.991143] INFO: Trade Simulation: get splits [2016-07-25 00:00:00+00:00] [asset:Equity(481 [000858.SZA]), ratio:0.9770838932167122]
[2017-12-20 09:00:33.992463] INFO: Position: position handle split[sid:481, orig_amount:6300, new_amount:6447.0, orig_cost:30.834254639555432,new_cost:30.13, ratio:0.9770838932167122, last_sale_price:34.10999856310425]
[2017-12-20 09:00:33.993342] INFO: Position: after split: asset: Equity(481 [000858.SZA]), amount: 6447.0, cost_basis: 30.13, last_sale_price: 34.90999984741211
[2017-12-20 09:00:33.994105] INFO: Position: returning cash: 25.84
[2017-12-20 09:00:37.090317] INFO: Trade Simulation: get splits [2017-05-10 00:00:00+00:00] [asset:Equity(2166 [000333.SZA]), ratio:0.971671374900417]
[2017-12-20 09:00:37.091518] INFO: Position: position handle split[sid:2166, orig_amount:7000.0, new_amount:7204.0, orig_cost:15.943629021304904,new_cost:15.49, ratio:0.971671374900417, last_sale_price:34.29999879265829]
[2017-12-20 09:00:37.092482] INFO: Position: after split: asset: Equity(2166 [000333.SZA]), amount: 7204.0, cost_basis: 15.49, last_sale_price: 35.29999923706055
[2017-12-20 09:00:37.093329] INFO: Position: returning cash: 2.8
[2017-12-20 09:00:37.198626] INFO: Trade Simulation: get splits [2017-06-19 00:00:00+00:00] [asset:Equity(1014 [000069.SZA]), ratio:0.9894179725239525]
[2017-12-20 09:00:37.200010] INFO: Trade Simulation: get splits [2017-06-19 00:00:00+00:00] [asset:Equity(2543 [000568.SZA]), ratio:0.980531317163184]
[2017-12-20 09:00:37.201062] INFO: Position: position handle split[sid:1014, orig_amount:28600, new_amount:28905.0, orig_cost:8.80264093101211,new_cost:8.71, ratio:0.9894179725239525, last_sale_price:9.34999965163485]
[2017-12-20 09:00:37.201990] INFO: Position: after split: asset: Equity(1014 [000069.SZA]), amount: 28905.0, cost_basis: 8.71, last_sale_price: 9.449999809265137
[2017-12-20 09:00:37.202878] INFO: Position: returning cash: 8.25
[2017-12-20 09:00:37.204185] INFO: Position: position handle split[sid:2543, orig_amount:5300, new_amount:5405.0, orig_cost:41.736056968578765,new_cost:40.92, ratio:0.980531317163184, last_sale_price:48.35000059587145]
[2017-12-20 09:00:37.205612] INFO: Position: after split: asset: Equity(2543 [000568.SZA]), amount: 5405.0, cost_basis: 40.92, last_sale_price: 49.310001373291016
[2017-12-20 09:00:37.206853] INFO: Position: returning cash: 11.25
[2017-12-20 09:00:37.298316] INFO: Trade Simulation: get splits [2017-07-18 00:00:00+00:00] [asset:Equity(1922 [000538.SZA]), ratio:0.9910812812909336]
[2017-12-20 09:00:37.299493] INFO: Position: position handle split[sid:1922, orig_amount:2900.0, new_amount:2926.0, orig_cost:65.73185271856055,new_cost:65.15, ratio:0.9910812812909336, last_sale_price:88.89999093179675]
[2017-12-20 09:00:37.300536] INFO: Position: after split: asset: Equity(1922 [000538.SZA]), amount: 2926.0, cost_basis: 65.15, last_sale_price: 89.7
[2017-12-20 09:00:37.301642] INFO: Position: returning cash: 8.63
[2017-12-20 09:00:37.728100] INFO: Performance: Simulated 478 trading days out of 478.
[2017-12-20 09:00:37.729408] INFO: Performance: first open: 2016-01-04 01:30:00+00:00
[2017-12-20 09:00:37.730453] INFO: Performance: last close: 2017-12-15 07:00:00+00:00
  • 收益率72.03%
  • 年化收益率33.11%
  • 基准收益率6.7%
  • 阿尔法0.3
  • 贝塔0.87
  • 夏普比率1.41
  • 收益波动率20.37%
  • 信息比率2.14
  • 最大回撤17.23%
[2017-12-20 09:00:39.230630] INFO: bigquant: backtest.v7 运行完成[51.822482s].