时间加权平均价格算法(TWAP)和成交量平均算法(VWAP)在量化回测的应用
为什么要引入TWAP和 VWAP?
为了评估策略的资金容量,我们对M.trade模块里买入点和卖出点这两个参数进行了更丰富的扩展,支持了策略能够按更丰富的算法交易价格(WAP)进行撮合。
如果资金是10万的话,那么在开盘买入基本上没有什么问题,如果资金量是300万、或者1000万呢?开盘如果只买入几只股票的话,本身的交易行为就会改变市场状态,冲击成本巨大。因此我们支持了算法交易里TWAP和VWAP。
TWAP (Time Weighted Average Price),时间加权平均价格算法,是一种最简单的传统算法交易策略。TWAP模型设计的目的是使交易对市场影响减小的同时提供一个较低的平均成交价格,从而达到减小交易成本的目的。在分时成交量无法准确估计的情况下,该模型可以较好地实现算法交易的基本目的。
VWAP (Volume Weighted Average Price), 成交量加权平均价格。VWAP策略即是一种拆分大额委托单,在约定时间段内分批执行,以期使得最终买入或卖出成交均价尽量接近该段时间内整个市场成交均价的算法交易策略。
上述两种方式是最常用的算法交易执行方式。其实在我们实际交易的过程中也会发现,如果是一笔较大的订单,我们肯定不会直接全部下单,而是把订单进行拆分,逐渐成交。因此如果我们在回测的过程中也可以使用TWAP和VWAP的价格进行撮合,最直接的目的就是能够检验我们策略的资金容量,如果按照TWAP和VWAP进行撮合以后,收益率变动不大,那我们对策略的资金容量会有很大信心,即策略不再是只能管理几十万,管理上百万、上千万是没有问题的。
我们在stockranker模板策略的基础上,用多组WAP价格进行回测,并和默认回测价格做了一个对比,回测结果如下表所示:

可以看到使用WAP价格回测和使用默认的open买入close卖出回测相比,各项指标变化不大,这也一定程度上表明单一策略的资金容量其实比我们想象地要大很多。
字段查看
WAP相关的文档见:WAP算法交易字段18,截图如下:

设置方法
在回测模块右侧属性栏中,可以看到有买入点和卖出点的参数设置:

字段介绍
我们支持了TWAP,VWAP 两种WAP价格
每个字段对应了1-11 共11种时间规则指标,具体时间规则如下:

每一个字段对应了买卖两个方向
每一个字段又对应了两种数据:价格和成交量
综上,字段示例如下:

以上字段均储存在 bar1d_wap_CN_STOCK_A表 和 bar1d_wap_CN_STOCK_A_adj表 中,如果要手动核查下撮合价格的话,可以访问这两个表来获取股票的TWAP,VWAP价格以及成交量。(其中第一个表是真实的加权价格数据,后一个表是后复权的价格加权数据,两表中的字段相同)。
DataSource('bar1d_wap_CN_STOCK_A_adj').read(start_date='2017-12-28',end_date='2017-12-28',instruments=['000002.SZA'],fields=['date','instrument','wap_1_buy_volume', 'wap_1_sell_volume', 'wap_1_twap_buy','wap_1_twap_sell', 'wap_1_vwap_buy', 'wap_1_vwap_sell'])

也可以查询到表中所有字段如下:
DataSource('bar1d_wap_CN_STOCK_A_adj').read(start_date='2017-12-28',end_date='2017-12-28',instruments=['000002.SZA']).columns

我们选择买入点为twap_1,卖出点为twap_8,回测价格类型选择后复权,回测结果部分截图如下:

可以看到002801.SZA的买入价为128.17,000503.SZA的卖出价为319.99。
我们再从bar1d_wap_CN_STOCK_A_adj 表(如果回测价格类型选择的是真实价格,则用bar1d_wap_CN_STOCK_A 表)中读出这两只股票的wap_1_twap_buy和wap_8_twap_sell价格:
DataSource('bar1d_wap_CN_STOCK_A_adj').read(start_date='2016-12-30',end_date='2016-12-30',instruments=['002801.SZA','000503.SZA'],fields=['date','instrument','wap_1_twap_buy','wap_8_twap_sell'])

可以看到表中的价格和回测中的成交价是一致的,回测时确实使用了我们选择的WAP价格进行撮合成交。
计算方法和成交逻辑
成交量: 如果对应的是买,将涨停的分钟k线去除,不参与计算,即非涨停的量 如果对应的是卖,将跌停的分钟k线去除,不参与计算,即非跌停的量 例如: 假设000002股票在上午【2h】成交100手,涨停;下午【1h】打开涨停(非跌停),成交200手,收盘【1h】跌停,成交50手。 则,买入经调整的成交量是250 ,卖出经调整的成交量是 300
600339.SHA在2016-12-30这天盘中涨停,我们读这天的价量数据可以看到,当天的总成交量为15055283.0
DataSource('bar1d_CN_STOCK_A').read(start_date='2016-12-30',end_date='2016-12-30',instruments=['600339.SHA'])

而我们读取这个股票这一天的全天的buy_volume,可以看到交易量为8937100.0,去除了涨停的量:
DataSource('bar1d_wap_CN_STOCK_A_adj').read(start_date='2016-12-30',end_date='2016-12-30',instruments=['600339.SHA'],fields=['date','instrument','wap_11_buy_volume'])

平均价格: 如果对应的是买,将涨停的分钟k线去除 如果对应的是卖,将跌停的分钟k线去除 TWAP: Time Weighted Average Price, 是时间加权平均价格。 计算公式为 mean(Pm,n) ,其中n为k线数量,Pm为典型价格(等于 (high+low+close)/3)。 VWAP: Volume Weighted Average Price, 是交易量加权平均价格。 计算公式为 (close_0 * volume_0 + close_1 * volume_1 +close_2 * volume_2 +…+close_59* volume_59) / (volume_0+volume_1+…+volume_59) 。
成交逻辑: 实际成交量会受到我们选择的买点卖点的价格类型所对应的的成交量的影响,例如: 假设某天A股票成交1万手,而我们想买入2万手,假如买入点选择close,则实际可以成交1万手;假如买入点选择twap1,而当天wap_1_buy的成交量为500手,则实际只会成交500手。
更新后的WAP功能相比之前做了更进一步的细化和优化,考虑到了真实交易的涨跌和跌停情形,因此计算出来的算法交易平均价格更精准和符合实际,进一步提高了回测的准确性。
时间加权平均价格算法(TWAP)和成交量平均算法(VWAP)在量化回测的应用的更多相关文章
- 用numpy计算成交量加权平均价格(VWAP),并实现读写文件
VWAP(Volume-Weighted Average Price,成交量加权平均价格)是一个非常重要的经济学量,它代表着金融资产的“平均”价格.某个价格的成交量越高,该价格所占的权重就越大.VWA ...
- 联邦平均算法(Federated Averaging Algorithm,FedAvg)
设一共有\(K\)个客户机, 中心服务器初始化模型参数,执行若干轮(round),每轮选取至少1个至多\(K\)个客户机参与训练,接下来每个被选中的客户机同时在自己的本地根据服务器下发的本轮(\(t\ ...
- 数据结构和算法(Golang实现)(25)排序算法-快速排序
快速排序 快速排序是一种分治策略的排序算法,是由英国计算机科学家Tony Hoare发明的, 该算法被发布在1961年的Communications of the ACM 国际计算机学会月刊. 注:A ...
- 基于改进人工蜂群算法的K均值聚类算法(附MATLAB版源代码)
其实一直以来也没有准备在园子里发这样的文章,相对来说,算法改进放在园子里还是会稍稍显得格格不入.但是最近邮箱收到的几封邮件让我觉得有必要通过我的博客把过去做过的东西分享出去更给更多需要的人.从论文刊登 ...
- 图的生成树(森林)(克鲁斯卡尔Kruskal算法和普里姆Prim算法)、以及并查集的使用
图的连通性问题:无向图的连通分量和生成树,所有顶点均由边连接在一起,但不存在回路的图. 设图 G=(V, E) 是个连通图,当从图任一顶点出发遍历图G 时,将边集 E(G) 分成两个集合 T(G) 和 ...
- JVM内存管理------GC算法精解(复制算法与标记/整理算法)
本次LZ和各位分享GC最后两种算法,复制算法以及标记/整理算法.上一章在讲解标记/清除算法时已经提到过,这两种算法都是在此基础上演化而来的,究竟这两种算法优化了之前标记/清除算法的哪些问题呢? 复制算 ...
- 转载: scikit-learn学习之K-means聚类算法与 Mini Batch K-Means算法
版权声明:<—— 本文为作者呕心沥血打造,若要转载,请注明出处@http://blog.csdn.net/gamer_gyt <—— 目录(?)[+] ================== ...
- 从零开始学C++之STL(四):算法简介、7种算法分类
一.算法 算法是以函数模板的形式实现的.常用的算法涉及到比较.交换.查找.搜索.复制.修改.移除.反转.排序.合并等等. 算法并非容器类型的成员函数,而是一些全局函数,要与迭代器一起搭配使用. 算法的 ...
- 深入浅出KNN算法(一) KNN算法原理
一.KNN算法概述 KNN可以说是最简单的分类算法之一,同时,它也是最常用的分类算法之一,注意KNN算法是有监督学习中的分类算法,它看起来和另一个机器学习算法Kmeans有点像(Kmeans是无监督学 ...
- 算法——001BitMap(位图)算法
哈希表在查找定位操作上具有O(1)的常量时间,常用于做性能优化,但是内存毕竟是有限的,当数据量太大时用哈希表就会内存溢出了.而考虑对这些大数据进行存盘分批处理又有IO上的开销,性能又不能满足要求.这个 ...
随机推荐
- CCF 202012-5星际旅行(20~100分)
前置知识 线段树:通过懒惰标记,可实现区间处理,和区间询问皆为\(O(logn)\)时间复杂度的数据结构,是一种二叉树.因此对于一个节点\(st\),其左儿子节点为\(st*2\),右节点为\(st* ...
- vsftp简单配置
添加用户 vi /etc/pam.d/vsftdp 注释掉 auth required pam_shells.so
- 树莓派4b装系统到运行 Blazor Linux 本地程序全记录
在Linux下运行gui程序,咱也是第一次做,属于是瞎子过河乱摸一通,写得有什么不对和可以优化的地方,希望各位看官斧正斧正. 1. 下载烧录器 https://www.raspberrypi.com/ ...
- Mysql高级11-后台进程
一.前言 MySQL的服务实现通过后台多个线程.内存池.文件交互来实现对外服务的,不同线程实现不同的资源操作,各个线程相互协助,共同来完成数据库的服务.MySQL常用的后台线程概括如下,分为Maste ...
- Fireboom on Sealos:半小时搞定一个月的接口工作
后端日常开发工作中有 88% 的接口都是 CURD,占用了超过 6 成开发时间.这些工作枯燥乏味,且价值低下,不仅荒废了时间,还无法获得任何成就感.而 Fireboom 可在 2 分钟内,完成传统模式 ...
- 秋招还没Offer怎么办?
如果你是双非院线.没有实习经历.没有出众的技术(算法没刷一千道,也没做过 Spring Cloud 项目).现在还没有面试(或只有少量的面试).并且目前还没有 Offer,那么恭喜你,你和目前大部分同 ...
- 使用CEF(六)— 解读CEF的cmake工程配置
距离笔者的<使用CEF>系列的第一篇文章居然已经过去两年了,在这么长一段时间里,笔者也写了很多其它的文章,再回看<使用CEF(一)- 起步>编写的内容,文笔稚嫩,内容单薄是显而 ...
- JNI编程之字符串处理
java中的字符串类型是String,对应的jni类型是jstring,由于jstring是引用类型,所以我们不能像基本数据类型那样去使用它,我们需要使用JNIEnv中的函数去处理jstring,下面 ...
- kubernetes集群部署redis5.0.6单机版
1.首先,通过Config Map来对容器中redis应用的配置进行管理,如自定义配置文件.密码.日志路径等 redis-standalone-conf.yml apiVersion: v1 kind ...
- QSplitter 自我总结
①.QSplitter(QWidget* parent = Q_NULLPTR); //构造函数 QSplitter(Qt::Orientation orientation , QWidget* pa ...