克隆策略
In [62]:
# 开始时间

start_date ='2013-01-01'
# 结束时间
end_date = '2017-06-01'

# 15,14,13三年的年终财报时间  
quarters = ['20161231', '20151231', '20141231'];

instruments = D.instruments(start_date, end_date)
# 代码,日期,净资产收益率, 归属母公司股东的净利润同比增长率,财报季度时间,财报对应的季度取值 1/2/3/4
# 参见 https://bigquant.com/docs/data_financial_statements.html
fields = ['instrument', 'date', 'fs_roe_ttm', 'fs_net_profit_yoy', 'fs_quarter' ,'fs_quarter_index']

# 获取以上字段的财报数据
financial_data = D.financial_statements(instruments, start_date, end_date, fields)

# 筛选出第四季度财报数据
financial_data = financial_data[financial_data['fs_quarter_index'] == 4]

# 获取市盈率历史数据
pe_data = D.history_data(instruments, start_date, end_date, ['name', 'pe_ttm'])

financial_data = financial_data.drop_duplicates(['instrument', 'fs_quarter']);
financial_data.sort_values(by='date', ascending=False, inplace=True)


stocks = pd.DataFrame()

def good_stock(df):
    global stocks
    instrument = df.iloc[0]['instrument']
    for q in quarters:
     # 找出该股票年报的数据,q in ['20151231', '20141231', '20131231']
     cur_df = df[df['fs_quarter'] == q]
     # 没有该年的财报数据
     if cur_df.empty:
        return
     # 连续三年净资产收益率 > 15
     if np.isnan(cur_df.iloc[0]['fs_roe_ttm']) or cur_df.iloc[0]['fs_roe_ttm'] <= 15:
        return
    # 最近一年财报净利润同比增长率 > 15
    latest_financial = df[df['fs_quarter'] == quarters[0]]
    if np.isnan(latest_financial.iloc[0]['fs_net_profit_yoy']) or latest_financial.iloc[0]['fs_net_profit_yoy'] <= 15:
        return
    
    # 找到年度财报日或者之前最近一天pe数据
    pe_history = pe_data[(pe_data['instrument'] == instrument) & (pe_data['date'] <= latest_financial.iloc[0]['date']) & (~np.isnan(pe_data['pe_ttm']))];
    pe_history.sort_values(by='date', ascending=False, inplace=True)
    
    if pe_history.shape[0] == 0:
        print ('no pe data of ' + instrument)
    # 市盈率 < 35
    if np.isnan(pe_history.iloc[0]['pe_ttm']) or pe_history.iloc[0]['pe_ttm'] >= 35:
        return
    
    # 找到一只股票,添加到result中
    stocks = stocks.append(pe_history.iloc[0][['instrument', 'name']], ignore_index=True)

financial_data.groupby('instrument').apply(good_stock)

print("共找到" + str(stocks.shape[0]) + "支好股票:")
print(stocks)

# 初始化虚拟账户状态,只在第一个交易日运行
def initialize(context):
    # 设置手续费,买入时万3,卖出是千分之1.3,不足5元以5元计
    context.set_commission(PerOrder(buy_cost=0.0003, sell_cost=0.0013, min_cost=5))

# 策略交易逻辑,每个交易日运行一次
def handle_data(context, data):
    for index, row in stocks.iterrows():  
        # 字符型股票代码转化成BigQuant回测引擎所需的股票代码
        instrument = context.symbol(row['instrument'])
        
        # 目前持仓数量
        curr_position =  context.portfolio.positions[instrument].amount
        # 第一个能买入的时间买入股票
        if curr_position == 0 and data.can_trade(instrument):
            # 买入一万元股票
            order_value(instrument, 10000)

# 策略比较参考标准,以沪深300为例
benchmark = '000300.INDX'
# 策略回测接口: https://bigquant.com/docs/strategy_backtest.html
# 回测最近一年数据,2016-06-01起的第一个工作日买入这些股票
m = M.backtest.v5(
    instruments=instruments,
    start_date="2017-05-01",
    end_date='2017-06-15',
    initialize=initialize,
    handle_data=handle_data,
    # 买入订单以开盘价成交
    order_price_field_buy='open',
    # 卖出订单以开盘价成交
    order_price_field_sell='open',
    # 初始资金
    capital_base=stocks.shape[0] * 10000,
    benchmark=benchmark,
)
共找到34支好股票:
    instrument  name
0   000002.SZA   万科A
1   000046.SZA  泛海控股
2   000333.SZA  美的集团
3   000418.SZA  小天鹅A
4   000501.SZA  鄂武商A
5   000651.SZA  格力电器
6   000957.SZA  中通客车
7   000963.SZA  华东医药
8   002032.SZA   苏泊尔
9   002041.SZA  登海种业
10  002051.SZA  中工国际
11  002271.SZA  东方雨虹
12  002372.SZA  伟星新材
13  002415.SZA  海康威视
14  002508.SZA  老板电器
15  300017.SZA  网宿科技
16  300202.SZA  聚龙股份
17  300253.SZA  卫宁健康
18  300408.SZA  三环集团
19  600167.SHA  联美控股
20  600201.SHA  生物股份
21  600299.SHA   安迪苏
22  600338.SHA  西藏珠峰
23  600340.SHA  华夏幸福
24  600563.SHA  法拉电子
25  600566.SHA  济川药业
26  600660.SHA  福耀玻璃
27  600690.SHA  青岛海尔
28  600741.SHA  华域汽车
29  600816.SHA  安信信托
30  600885.SHA  宏发股份
31  600887.SHA  伊利股份
32  601633.SHA  长城汽车
33  603168.SHA  莎普爱思
[2017-06-15 13:17:17.954673] INFO: bigquant: backtest.v5 start ..
[2017-06-15 13:17:17.961217] INFO: bigquant: hit cache
  • 收益率3.57%
  • 年化收益率34.23%
  • 基准收益率2.78%
  • 阿尔法0.08
  • 贝塔0.99
  • 夏普比率2.19
  • 收益波动率13.63%
  • 信息比率0.93
  • 最大回撤3.52%
[2017-06-15 13:17:18.456004] INFO: bigquant: backtest.v5 end [0.501411s].