在上文中用东方财富的历史数据,回测了右侧出击策略的表现。资金占用时间不到一年半,对应40%的收益,表现基本让人满意。不过仅凭一只股票的收益表现,偶然性太高,很难说明策略的可靠度。

本次我们拿证券公司(399975)成分股中的所有证券公司,一共49家来代表券商行业、再选定2012-01-01至今作为时间区间来做数据回测,基本上就能评判出策略在券商行业中的综合实力。

1.股票代码预览

首先需要知道,一共是哪些券商公司,它们的代码分别是多少?写了个小爬虫程序,在某行情网站中抓取到了我们的目标券商公司股票代码,然后保存到本地csv文件(爬虫过程及源码这里不做展示)。

先将所有券商的代码及公司读取出来,如下:

# 导入相关库
import akshare as ak
import pandas as pd
import quan_trade # 交易类
import time# 从本地读取所有券商股票代码
dealer_df = pd.read_csv('dealer_data/symbols.csv',dtype = {'symbol':str})
# 展示前5条
dealer_df.head()

2. 函数封装

在右侧追击(一)——东方财富中我们对单只股票每次追击情况进行了统计。本次涉及到49支股票,还需要将每只股票的多次追击详情汇总。

定义一个函数,需传入的参数有order——订单记录,symbol——股票代码,begin_date——该股票具备行情数据的起始日期,capital——本金(每次买卖为本金的1/5,默认值为100000)。在函数内部计算出两个DataFrame数据返回,profit_df记录单只股票每次追击的情况,summary_df对该股票多次追击详情进行汇总,代码如下:

def get_profit(order,symbol,begin_date,capital = 100000):# 创建profit_df用来存放每次追击的情况, summary_df存放每只股票的追击汇总profit_df = pd.DataFrame(columns = ['symbol','start_time','end_time', 'capital', 'attack_times', 'profit', 'profit_rate','total_profit_rate'])summary_df = pd.DataFrame(columns = ['跟踪起始时间','代码','公司','本金','总追击次数','成功次数','追击成功率','单次最大亏损','单次最大盈利','总利润','资金占用时间/天','折合年化'])# 订单记录为空,直接返回if order.empty:print(symbol, ": 订单记录为空")return profit_df,summary_df# 初始化部分数据start_time = Noneattack_times = 0profit = 0amount = 0 # 记录每次追击累积交易的数量# 遍历订单记录,计算每次追击后的数据,存放到profit_dffor i in range(0,order.shape[0]):if order.iloc[i]['trade_type'] == 'B':# 记录每次追击开始的时间if attack_times == 0:start_time = order['date'].iloc[i]#计算累计追击次数以及累计买入数量attack_times += 1amount += capital / 5 / order.iloc[i]['trade_price']else :# 数据存放profit_df = profit_df.append({'symbol':symbol,'start_time':start_time,'end_time':order['date'].iloc[i], 'capital':capital,'attack_times':attack_times, 'profit': order.iloc[i]['trade_price'] * amount - capital / 5 * attack_times, 'profit_rate': (order.iloc[i]['trade_price'] * amount /(capital / 5 * attack_times) - 1) * 100,'total_profit_rate':(order.iloc[i]['trade_price'] * amount - capital / 5 * attack_times) / capital * 100},ignore_index=True)# 卖出意味着本次追击结束,清零attack_times = amount = 0 ### 追击详情汇总summary_df = pd.DataFrame({'跟踪起始时间':begin_date,'代码':symbol,'公司': dealer_df[dealer_df['symbol'] == symbol].company,'本金': capital,'总追击次数' : profit_df['attack_times'].count(),'成功次数': profit_df[profit_df['attack_times'] == 5].attack_times.count(),'追击成功率':profit_df[profit_df['attack_times'] == 5].attack_times.count() / profit_df['attack_times'].count() * 100,'单次最大亏损':profit_df['profit'].min(),'单次最大盈利':profit_df['profit'].max(),'总利润':profit_df['profit'].sum(),'资金占用时间/天':(profit_df['end_time'] - profit_df['start_time']).dt.days.sum() + profit_df.start_time.count(),'折合年化':((profit_df['profit'].sum() /capital + 1) ** (365 / ((profit_df['end_time'] - profit_df['start_time']).dt.days.sum() + profit_df.start_time.count())) -1) * 100})return profit_df, summary_df

函数get_profit的使用,拿东方财富为例:

df = ak.stock_zh_a_hist(symbol='300059', period="daily", start_date="20120101", end_date='20221231', adjust="qfq")
trade = quan_trade.Trade('300059', df, 'right_attack', 100 , 1000000, max_volatility = 10)
trade.main()
profit_df, summary_df = get_profit(trade.account.order, '300059', trade.data.iloc[0].日期)
# 查看每次追击情况
profit_df

# 查看汇总
summary_df

profit_df几乎就是我们在上一篇中所用到的数据,记录了对应股票每次追击情况;summary_df是对profit_df中数据的汇总,里边还计算出了对应股票右侧追击的折合年化回报。

3.计算每只股票的追击汇总

将49支股票的追击详情及汇总分别放到一个DateFrame中,基本上能看出来策略在券商行业中的整体表现了

# 记录程序运行开始时间
start = time.time()
# 定义变量存放所有股票的追击详情以及每只股票的追击汇总
dealer_profit_df = pd.DataFrame()
dealer_total_profit_df = pd.DataFrame()
# 遍历dealer_df取出所有股票代码
for symbol in dealer_df['symbol']:# 回测区间范围设定从2012年开始,截止到现在df = ak.stock_zh_a_hist(symbol= symbol, period="daily", start_date="20120101", end_date='20221231', adjust="qfq")trade = quan_trade.Trade(symbol, df, 'right_attack', 100 , 1000000, max_volatility = 10)trade.main()profit_df, summary_df = get_profit(trade.account.order, symbol, trade.data.iloc[0].日期)# 将每只股票追击详情及汇总分别添加到dealer_profit_df,dealer_total_profit_dfdealer_profit_df = dealer_profit_df.append(profit_df)dealer_total_profit_df = dealer_total_profit_df.append(summary_df)print("程序运行时间/min: ",(time.time() - start)/60 )

上面的代码涉及到一定数量的运算,会耗费一点时间。一共有6支股票没有订单记录,股票代码打印在了上面。也就是说在它们上面没有找到任何参与机会。经过简单的分析就可以知道,这些股票都是在最近两三年内上市,策略还需要有大半年的缓冲期(需跟踪180个交易日内的最高价),跟踪周期较短,没有参与机会也很正常。

# 查看所有股票的追击详情
dealer_profit_df

# 查看所有股票的追击汇总前5条
dealer_total_profit_df.head()

策略从2012-01-01开始追踪,其后的第一个交易日是2012-01-04,但dealer_total_profit_df中的起始跟踪时间有一些会晚于这个时间,那是因为它们直到这个起始跟踪时间点才上市挂牌交易。

根据追击汇总dealer_total_profit_df计算策略在券商行业中的平均收益

# 对所有股票追击汇总再汇总
avg_profit_df = pd.DataFrame({'参与股票数量':dealer_total_profit_df.shape[0],'盈利数量':dealer_total_profit_df[dealer_total_profit_df['总利润'] > 0].shape[0],'亏损数量':dealer_total_profit_df[dealer_total_profit_df['总利润'] <= 0].shape[0],'追击成功率':100 * dealer_total_profit_df['成功次数'].sum() / dealer_total_profit_df['总追击次数'].sum(),'单支股票最大利润':dealer_total_profit_df['总利润'].max(),'单支股票最大亏损':dealer_total_profit_df['总利润'].min(),'平均收益':dealer_total_profit_df['总利润'].mean(),'平均年化回报':dealer_total_profit_df['折合年化'].mean()
},index = [0])
avg_profit_df

4.结论分析

收益总览

一共参与了43支股票,追击成功率8.63%,平均收益2.8w,对应平均年化回报49.42%,整体还不错。

其中盈利的有25支,取得最大利润的是光大证券,18.8w。该股票追击了7次,就有2次追击成功。28%的成功率极大的拉高了收益,按171天的资金占用时间来计算,折合年化高达856.62%。

亏损数量为18支,踩坑的概率还是有一些的。创造最大亏损是国投资本,超过了1.8w。8次追击,0次成功。对应10w的本金,摩擦成本高达18%,风险也不容小觑。

利润周期

# 摘取追击成功的追击详情
dealer_profit_df[dealer_profit_df['attack_times'] == 5].sort_values(by='start_time')

看利润分布,绝大部分的收益都是2014第4季度创造的,追击成功的时间区间大部分也集中于此。

翻看证券公司(399975)的周线图,在我们跟踪的十年期间,2014年尾部也是其表现最为疯狂的时期,从10月份600点左右一路飙升,到12月下旬时涨到了第一个高点1500点左右,这一波所有股票加在一起吃到了接近120万的利润,极大的拉高了平均收益。随后在2015年2季度再创新高,同样也吃到了一小部分利润,相较而言其它时间段都没有特别突出的表现。

再往前看,2007年有类似行情,如果策略跟踪到2007年,收益应该还能再创辉煌。这里单纯意淫一下,2007年中到2014下旬花了7年多的时间,2014年底到现在也是7年多,券商行业是否又在酝酿一次大腾飞呢?

亏损分析

# 查看所有亏损股票的追击总览
dealer_total_profit_df[dealer_total_profit_df['总利润'] <= 0]

18支亏损的股票中,它们的追击成功次数全部为0。换句话说,只要有一次追击成功,没有一只股票是亏损的。

不过也并非所有成功次数为0的股票,都会亏损。比如国信、西南、哈投,它们都创造了正收益。其实只要策略在开启追击后,能连续买到第3、4次,就有很大机会创造正收益!

# 追击成功次数为0且利润为正的股票记录
dealer_total_profit_df[dealer_total_profit_df['总利润'] > 0 ][dealer_total_profit_df['成功次数'] == 0]

另外可以看到,所有亏损的股票中,除了国投和国海,其它的上市时间都晚于2014年,错过了券商行业最疯狂的黄金时段。乐观的看,如果未来再有这么一波强势行情,它们中的绝大部分是不是都能收回摩擦成本,并跑出可观的正收益?这个有待时间给我们答案!

# 国海证券的每次追击详情
dealer_profit_df[dealer_profit_df['symbol'] == '000750']

# 国投证券的每次追击详情
dealer_profit_df[dealer_profit_df['symbol'] == '600061']

国海和国投对于策略而言,彻底就是个坑了。即便在2014年底遍地捡黄金的时代,二者也没有完成一次完整的追击。

所以即便是券商这种反身性行业、严格遵守右侧追击制度、在整个行业疯狂上涨的3层buff加持下,追击个股也有踩坑的风险!国海和国投就是血淋淋的教训,把资金丢到它们身上,就等同于从枪林弹雨般的黄金中完美的躲了过去!

总结

  1. 平均年化回报达到49.42%,整体表现不错;

  2. 追击成功率8.63%,策略有待优化提高成功率;

  3. 绝大部分利润都贡献于2014年年底的行情,右侧追击博的就是这种机会;

  4. 虽然券商这种行业适合右侧追击,但追击个股依然有踩坑的风险。

右侧追击(二)——券商行业相关推荐

  1. 右侧追击(三)——策略优化

    前文数据表明,右侧追击确实是抓取券商强势行情的一把利器.不过策略也有一个明显的弊端,也是有待优化的地方--追击成功率.从整个券商行业来看,10次追击,都未必有一次成功.在实战中,每一次失败,不仅意味着 ...

  2. 右侧追击(一)——东方财富

    本文旨在策略学习探讨,不构成任何投资建议! 之前我们用两篇文章将账户和交易封装,做了一定准备工作.今天,将正式开启对策略的考核. 对于券商.钢铁.有色.甚至房地产等右侧行情的行业,通常会用到一个方法- ...

  3. 产品经理在路上之二——用户/行业调研

    一般来说,一个项目的生命周期可以简单得用P D C A(Plan Do Check Action,计划.执行.验收.反馈的往复循环)来表示.其中在项目的早期,就包含了大量Plan的工作,PM在Plan ...

  4. IT产品销售人员的压力之二 - IT行业的“小灶”

    在上一篇文章IT产品销售人员的压力之一 - 传统销售人员的压力 ,我们在深入分析IT行业的销售人员从业者的压力之前,先分享了所有销售人员都会面对的压力.IT行业销售人员作为高科技从业人员,除了&quo ...

  5. 指数基金(二):行业指数简介

    全球行业分类标准(GICS),将行业分为10个一级行业,24个二级行业,67个子行业.最主要的是个一级行业分别是: 材料:金属.采矿.化学制品等等 可选消费:汽车.零售.媒体.房地产等等 必须消费:食 ...

  6. 神策数据易向文:打造券商上层数据应用的坚实基础

    本文根据神策数据解决方案顾问易向文<打造券商上层数据应用的坚实基础>直播整理而成,本文的主要内容如下: 浅析券商数据采集 常见的埋点方式介绍 如何做好用户数据关联 数据管理与数据校验 注: ...

  7. 视频 + PPT | 财富管理转型,券商如何精细化运营?

    科技正在重构证券交易的业态,从坐商到行商再到服务商,线上尤其移动端场景成为相关服务获取的主要渠道,这一变化使得证券公司摆脱网点束缚,可以随时随地接触和服务客户,催生了以移动端为核心的新战场. 利用数据 ...

  8. 李奇霖:通道业务山穷水尽 券商资管何去何从?

    转自http://stock.qq.com/a/20170711/006492.htm 腾讯"证券研究院" 李奇霖 联讯证券董事总经理.首席宏观研究员 券商资管是什么?从字面简单看 ...

  9. 李沐华:变革前夜的券商集中交易系统

    变革前夜的券商集中交易系统 原创 李沐华 计算机文艺复兴 3天前 图片 行业深度系列 - 作者:李沐华 - 券商交易系统是证券公司的IT核心之一 1.1. 券商交易系统的核心是数据库和报盘系统 经纪业 ...

最新文章

  1. Three levels at which any machine carrying out an Information-Processing task must be understood
  2. dsst依赖opencv
  3. 文件系统磁盘管理(一)--文件系统
  4. pfile文件怎么恢复格式_回收站清空的文件怎么恢复?值得收藏的恢复方法
  5. GCD HDU - 1695
  6. C++primer第九章 顺序容器 9.6 容器适配器
  7. linux make命令实现,Linux make命令主要参数详解
  8. kafka(一)—基本概念
  9. CAN笔记(22) 特殊协议
  10. oracle 11gr2 rac价格,调整Oracle 11gR2 RAC为单实例库
  11. JQuery_九大选择器
  12. mysql 只开放某个表_MySQL只恢复某个库或某张表
  13. bzoj 1488: [HNOI2009]图的同构
  14. 【上外青年】人物 ‖ 何晗:天才都是异类
  15. UTC时间转成北京时间
  16. 【补丁】YYC松鼠短视频系统补丁,增加视频点赞数据管理功能,可修改点赞数量,V2.8的功能
  17. 鼓励你大胆追梦的三个移动互联网案例
  18. 滚动轴承故障特征频率计算公式
  19. 生物信息学 陈铭_生物信息学Bioinformatics-山东大学课程中心.PDF
  20. 使用爬虫爬取天气历史数据(https://lishi.tianqi.com/)

热门文章

  1. 用c语言实现作曲与播放教程~,原创哦~
  2. 经验分享-iMX8MQ设计底板硬件指南-第一章
  3. android 3d成像,android camera 实现3d效果
  4. 联想昭阳k43c-80 BIOS里UEFI是灰色项,改不了为legacy
  5. 北京科技大学 数值计算方法实验代码
  6. php怎么将中文翻译成英文,PHP将中文翻译成拼音
  7. HTML+CSS+JS网页设计期末课程大作业 web前端开发技术 web课程设计 html网页规划与设计
  8. 陌生单词-专业英语代码编码符号2
  9. tcp/ip的模型与原理
  10. PRACH, preamble, RO 的关系与区别