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

所以,让策略识别假突破,提高追击成功率尤为重要。一般来看,强势突破会伴随着成交量的释放,本文的策略优化将围绕成交量展开。成交量是识别是否为假突破的重要参考指标,通过它,能将一部分假突破挡在门外,减少摩擦成本。

另外,策略中追击成功的机会是十分稀有且宝贵的,整体收益也全都仰仗于它们。一次成功的收益可以覆盖十几次乃至几十次的失败亏损,所以策略调优必须遵循一个原则:在不错失任何一次追击成功机会的前提下,尽可能减少追击次数!

1.原始追击情况

在加入成交量因子后,判断策略是否优化最首要的指标就是成功次数和追击成功率。先获取策略未加入放量判断时的追击情况,作为对照。

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})

symbols.csv为爬虫获取到的49支券商股票代码,该文件放在了https://github.com/kaiforone/quantized-trade/tree/main/dealer_data


# 根据订单记录计算追击详情及汇总的函数
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

东方财富的追击情况

单只股票方便观察真假突破时的成交量特性,对策略进行预调优,然后拿整个行业来验证


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].日期)
### 追击情况
summary_df

近期,4月20号该股票涉及到转增分红,采取前复权计价方式后,该股票的每日价格相较前文会有变化,所以追击情况会和之前文章中有所不同,这里不用过分纠结。

券商行业的追击情况

### 券商行业
# 定义变量存放所有股票的追击详情以及每只股票的追击汇总
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)

# 对所有股票追击汇总再汇总
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],'总追击次数':dealer_total_profit_df['总追击次数'].sum(),'成功次数':dealer_total_profit_df['成功次数'].sum(),'追击成功率':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

整个券商行业,一共279次追击,24次成功。策略是否真正优化,首先要看这两个数据的变化。

2.策略优化

2.1 放量规律探索

上面两张图分别是策略在跟踪东方财富股价走势下发动的两次成功追击,二者起爆点(红色箭头)的成交量相较于近期都有比较明显的提升。

上图为两次假突破,可以看到,二者在起爆点都没有明显的放量情况,最终也突破失败。但并非所有的假突破都不会放量,比如下图2018-1-24这次,相较近期几乎算放了巨量,但最终依旧突破失败。

由此可初步得出结论,放量属于突破成功的必要非充分条件。放量未必成功突破,但不放量必定突破不成功。

那么思路就很清晰了,用成交量作为筛子,把价格突破但未放量的“假机会”甩出去。即在程序操作买入之前,加入一个放量条件限制,只有放量了,程序才会真正买入!

2.2 定义放量

再来揣摩这句话——追击成功时成交量相较近期有明显提升。里边有两个变量,一个是近期,多久叫近期?另一个是明显提升,提升多少才叫明显提升呢?

为简化模型,这里索性将近期定义为前7个交易日,比对当日交易量和前7个交易日平均交易量的变化。那么,明显提升如何定义呢?先来看看东方财富2次成功突破的成交量变化。


# 2014-10-30和2020-06-19 成交量比上前7个交易日的平均交易量
m = trade.data[trade.data['日期'] == '2014-10-30'].index[0]
print('2014-10-30放量情况:',trade.data['成交量'].iloc[m] / trade.data.iloc[m-7:m].成交量.mean())
n = trade.data[trade.data['日期'] == '2020-06-19'].index[0]
print('2020-06-19放量情况:',trade.data['成交量'].iloc[n] / trade.data.iloc[n-7:n].成交量.mean())

第一次成交量为前一周均值的两倍多,第二次也超过了1.5倍。要保证不丢失成功追击的机会,提升倍数的限制必须要小于1.53。并且越接近于这个值,越有可能矫枉过正,在其它股票上丢掉一些成功追击的机会。

先将提升倍数限制为1.5倍,看看策略的提升效果如何。即价格突破同时满足放量不低于前一周均值的1.5倍,才会触发策略买入。

2.3 代码更新

找到quan_trade文件(封装该文件的文章),修改Trade类中的by_right_attack方法,代码如下:


### 在策略买入位置添加放量条件限制
def by_right_attack(self):"""右侧追击"""# 定义两个变量,分别存放前高以及追击完成后的最高股价last_higt = max_price = Nonefor i in range(180, self.data.shape[0]):# 如果当天一字涨停或者跌停,无需交易if self.if_limit_move(self.data.iloc[i].最高, self.data.iloc[i].最低, self.data.iloc[i].涨跌幅):self.account.no_trade_update_asset(self.data.iloc[i].日期, self.symbol, self.data.iloc[i].收盘)continue# 更新前半年最高价last_higt = self.data['最高'][i-180:i].max()# 无持仓(持仓数据为空或者持仓数量为零)if self.account.position.empty or self.account.position.iloc[-1].amount == 0:# 价格未突破if self.data.iloc[i].收盘 <= last_higt:self.account.no_trade_update_asset(self.data.iloc[i].日期, self.symbol, self.data.iloc[i].收盘)continue# 破新高买入elif self.account.asset.iloc[-1].cash >= self.data.iloc[i].收盘 * self.trade_amount :### 												

右侧追击(三)——策略优化相关推荐

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

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

  2. 右侧追击(二)——券商行业

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

  3. 【详解+推导!!】PPO 近端策略优化

    近端策略优化(PPO, Proximal Policy Optimization)是强化学习中十分重要的一种算法,被 OpenAI 作为默认强化学习算法,在多种强化学习应用中表现十分优异. 文章目录 ...

  4. 强化学习笔记:PPO 【近端策略优化(Proximal Policy Optimization)】

    1 前言 我们回顾一下policy network: 强化学习笔记:Policy-based Approach_UQI-LIUWJ的博客-CSDN博客 它先去跟环境互动,搜集很多的 路径τ.根据它搜集 ...

  5. 深度学习分布式策略优化、显存优化、通信优化、编译优化综述

    综述 因为我个人最近在从事可能是AI领域对性能挑战最大的方向,自动驾驶领域,所以对整个深度学习训练的优化尤为关注,最近一直在学习相关内容,谨以此篇文章做一个总结. 我一直很看好深度学习训练优化这个方向 ...

  6. 高级SQL优化(三) 常用优化工具 ——《12年资深DBA教你Oracle开发与优化——性能优化部分》...

    目录: Oracle数据完整性和锁机制  索引及优化之表分析  表分析.约束及表间关系  Oracle体系结构1 Oracle体系结构2  海量数据库及分区1  海量数据库及分区2  海量数据库及分区 ...

  7. tablewidget 行数自适应_控制|基于自适应遗传算法的增程式电动汽车能量管理策略优化...

    点击上方蓝字关注我们! 摘要:建立增程式电动汽车整车仿真模型,以恒温器控制策略为例,以车辆最长续驶里程和百公里油耗为优化目标,利用自适应遗传算法对其能量管理策略进行了优化。优化结果表明,采用自适应遗传 ...

  8. 伯克利、OpenAI等提出基于模型的元策略优化强化学习

    基于模型的强化学习方法数据效率高,前景可观.本文提出了一种基于模型的元策略强化学习方法,实践证明,该方法比以前基于模型的方法更能够应对模型缺陷,还能取得与无模型方法相近的性能. 引言 强化学习领域近期 ...

  9. 读薄《高性能MySql》(三)索引优化

    读薄<高性能MySql>(一)MySql基本知识 读薄<高性能MySql>(二)Scheme与数据优化 读薄<高性能MySql>(三)索引优化 读薄<高性能M ...

最新文章

  1. AR独角兽的死亡教训:融资3亿美元后,成投资人提线木偶,营销大于产品技术...
  2. jsp上传文件名乱码
  3. Transaction And Lock--事务中使用return会回滚事务吗?
  4. Linux中ifcfg-eth0配置参数解释
  5. 计算机网络(十八)-以太网
  6. Nexus 3.31.1-01搭建 maven 私服 windows
  7. CSS魔法堂:选择器及其优先级
  8. 用 Python 写出这样的进度条,刷新了我对进度条的认知
  9. git的历史版本拉分支、回撤revert、回退reset
  10. ES6学习笔记七(Set和Map)
  11. 基于Arduino的智能避障小车
  12. 114-select(基础)
  13. 用Java实现家庭收支记账软件
  14. 科学计算机的英文怎么拼读,科学的英语读音,科学的英文怎么读谐音。
  15. 质量码——工业互联网平台入口
  16. 计算机水平怎么填范例,简历表个人能力怎么写(大学生个人获奖情况范例)
  17. Java注释规范 - 88250的灰色天空 - CSDNBlog
  18. 一篇弄懂主成分分析及matlab实现
  19. flutter中compute和isolate
  20. 罗胖精选 | 如何打造高效运转的团队?

热门文章

  1. 什么是PDO及怎么使用
  2. MVVC(多版本并发控制)
  3. window 版 Charles 抓包 手机 app (以抓取 “华图在线” App为例)
  4. #Scoop windows下的包管理器
  5. youtube的深度学习推荐系统模型
  6. 清空一行的c语言指令,grep命令保留第一行(C语言实现)
  7. App页面提示样式小总结
  8. 手机端虚拟键盘弹出使界面布局混乱解决方法
  9. hznu 1437: Clockwise(隐藏的暴力水题,数学)
  10. 切入政务大数据领域 美亚柏科设合资公司