楼主: _wallstreetcat_
1493 3

[交易策略] 漂亮50策略(思想+源码实现) [推广有奖]

  • 0关注
  • 36粉丝

讲师

9%

还不是VIP/贵宾

-

威望
0
论坛币
98 个
通用积分
40.7754
学术水平
14 点
热心指数
13 点
信用等级
13 点
经验
6402 点
帖子
257
精华
0
在线时间
234 小时
注册时间
2017-3-16
最后登录
2023-11-21

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
A股分两种:“漂亮50”和“要命3000”!

人们戏谑最近的股市行情时称市场分为“漂亮50”和其余的“要命3000”,意思是有一些被大家认为特别好的股票,股价一直在涨,而另一些股票要么纹丝不动,要么踩着各种地雷陷入深渊。

所谓“漂亮50”,是来自于美国的概念,中国投资者很早也提出来要筛选出类似公司,但是一直没有核心指标。

证券时报记者以三个指标筛选出A股的“漂亮50”,这三个指标分别是净利润增长率长大于15%,连续3年净资产收益率大于15%,市盈率低于35.

我用2014,2015,2016年报数据找出在2017年的漂亮50,一共34只,如下所示。一年后这34只股票收益如何呢?

共找到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 莎普爱思

接下来,开始回测。

  1. # 开始时间

  2. start_date ='2013-01-01'
  3. # 结束时间
  4. end_date = '2016-06-01'

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

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

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

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

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

  17. financial_data = financial_data.drop_duplicates(['instrument', 'fs_quarter']);

  18. stocks = pd.DataFrame()

  19. def good_stock(df):
  20.     global stocks
  21.     instrument = df.iloc[0]['instrument']
  22.     for q in quarters:
  23.     # 找出该股票年报的数据,q in ['20151231', '20141231', '20131231']
  24.         cur_df = df[df['fs_quarter'] == q]
  25.         # 没有该年的财报数据
  26.         if cur_df.empty:
  27.             return
  28.         # 连续三年净资产收益率 > 15
  29.         if np.isnan(cur_df.iloc[0]['fs_roe_ttm']) or cur_df.iloc[0]['fs_roe_ttm'] <= 15:
  30.             return
  31.     # 最近一年财报净利润同比增长率 > 15
  32.     latest_financial = df[df['fs_quarter'] == quarters[0]]
  33.     if np.isnan(latest_financial.iloc[0]['fs_net_profit_yoy']) or latest_financial.iloc[0]['fs_net_profit_yoy'] <= 15:
  34.         return
  35.    
  36.     # 找到年度财报日或者之前最近一天pe数据
  37.     pe_history = pe_data[(pe_data['instrument'] == instrument) & (pe_data['date'] <= latest_financial.iloc[0]['date'])];
  38.     pe_history.sort_values(by='date', ascending=False, inplace=True)

  39.     if pe_history.shape[0] == 0:
  40.     print ('no pe data of ' + instrument)
  41.     # 市盈率 < 35
  42.     if np.isnan(pe_history.iloc[0]['pe_ttm']) or pe_history.iloc[0]['pe_ttm'] >= 35:
  43.         return
  44.    
  45.     # 找到一只股票,添加到result中
  46.     stocks = stocks.append(pe_history.iloc[0][['instrument', 'name']], ignore_index=True)

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

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

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

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

  66.     # 策略比较参考标准,以沪深300为例
  67.     benchmark = '000300.INDX'
  68.     # 策略回测接口: https://bigquant.com/docs/strategy_backtest.html
  69.     # 回测最近一年数据,2016-06-01起的第一个工作日买入这些股票
  70. m = M.backtest.v5(
  71.     instruments=instruments,
  72.     start_date="2016-06-01",
  73.     end_date='2017-06-01',
  74.     initialize=initialize,
  75.     handle_data=handle_data,
  76.     # 买入订单以开盘价成交
  77.     order_price_field_buy='open',
  78.     # 卖出订单以开盘价成交
  79.     order_price_field_sell='open',
  80.     # 初始资金
  81.     capital_base=stocks.shape[0] * 10000,
  82.     benchmark=benchmark,
  83. )
复制代码

回测结果为:

总收益率 20.78%, 年化收益率 21.73% ,基准收益率 10.35%, 阿尔法 0.11, 贝塔 0.98。

来源:BigQuant   (www.bigquant.com)

原文链接:https://community.bigquant.com/t/%E2%80%9C%E6%BC%82%E4%BA%AE50%E2%80%9D%E7%AD%96%E7%95%A5%E5%B0%9D%E8%AF%95/342



二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:Instruments Instrument Statements duplicates financial 漂亮

已有 2 人评分经验 论坛币 学术水平 热心指数 信用等级 收起 理由
accumulation + 100 + 1 + 1 + 1 精彩帖子
fantuanxiaot + 33 + 33 + 2 + 2 + 2 精彩帖子

总评分: 经验 + 133  论坛币 + 33  学术水平 + 3  热心指数 + 3  信用等级 + 3   查看全部评分

本帖被以下文库推荐

沙发
lwell20 发表于 2017-6-20 08:34:58 |只看作者 |坛友微信交流群

使用道具

藤椅
sukiyou2000 发表于 2017-6-21 08:50:39 |只看作者 |坛友微信交流群
学习了!

使用道具

板凳
seanlee91 发表于 2017-7-29 16:36:15 |只看作者 |坛友微信交流群
感谢楼主分享

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注jr
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-4-27 04:20