这几天的股市涨势极猛,上证上涨1.84%,深证成上涨2.43%,创业板上涨2.21%,两市合计金额再次破万亿。盘面上看,两市个股涨多跌少,行业板块全线飘红。

这样的大好局势却让大家纠结万分,继续跟怕买了就跌,不跟但看着心里又难受,怎么办呢?

其实交易行为都可以用数据来分析和量化的,如今,很多企业和投资金融领域保持竞争力,开始采用Python编程来解决期货量化交易。从数据分析的角度切入,以技巧的形式深入数据背后,让读者从基本的期货交易规则开始,了解相关的技术指标,并能够熟练使用Python编程走上量化交易之路。

当我们在市场上交易,对于当前市场的趋势变动没有把握时,就需要历史回测来验证 自己的想法是否可行。历史回测不仅仅只是数学量化模型的计算,同时也包含了量化模型以外的市场行为分析。

期货交易,简单来说就是一买一卖,赚取价差。算法的目的在于将投资人的交易行为,量化转化为代码。程序化交易中的回测算法与实盘交易算法有不同的编写方式,所以来了解一下回测吧!

回测算法就是通过历史数据,模拟真实的开盘环境,进行数据解读、计算、判断,决 定是否建仓、平仓,获取成交信息。 量化回测的必要步骤:

(1)读取历史数据;

(2)转换回测指标;

(3)历史算法设计;

(4)历史回测回传明细格式设计;

(5)绩效计算。

建立回测流程

1.读取历史数据

本技巧要介绍的“读取历史数据”不仅仅是通过函数去取得数据,还要去运用数据。

(1)获取数据函数

算法程序必须先获取交易指标数据或历史报价。我们会通过open函数获取文件内的数据。

用Python处理文件,常见的方式是通过open、read来读取数据,也可以直接通过列表推导式(list comprehension)来直接将文件存成list对象,常用的用法如下:

变量名称=[循环变量for循环变量inopen('读取文件')]

(2)运用历史数据方式

在读取数据后,如何运用这些数据才是重点,因为交易所历史数据的种类是属于按时间顺序的数据,而交易算法与时间字段也息息相关,所以从某个程度上来说时间格式的掌握是相当重要的。

在Python中,我们会读取文件并存成一个list对象。读取数据的方式基本上有两种,原理都是通过循环来进行数据筛选,但是代码编写上会有很大的差异。

第一种是通过for循环,逐笔判断list当中的值,通常用于有较多逻辑判断的情况。例如,回测的进出场判断,在本章后面的示例中会应用到。

第二种是使用列表推导式,简单来说就是可以直接在list中进行循环筛选。在简易的应用中可以用该方式来解决,例如数据处理、筛选字段、简易的逻辑判断筛选数据。以下是一般性的数据读取、筛选字段和操作介绍。

首先获取数据(文件名:Futures_20170815_I020.csv),存成I020变量。

 >>> I020 = [ line for line in open('Futures_20170815_I020.csv')]  >>>  >>> I020[0:5]   ['INFO_TIME,MATCH_TIME,PROD,ITEM,PRICE,QTY,AMOUNT,MATCH_BUY_CNT,MATCH_SELL_CNT\n',  '8450010, 8450009,TXFH7,128,10310,732,732,202,349\n',  8450011,8450010,TXFH7,128, 10309,4,736,206,350\n',  '8450011,8450010,TXFH7,128,10309,1,737,207,351\n',  '8450011,8450010,TXFH7,128,10310,1,738,208,352\n'] 

接着除去数据表头,舍去每行的换行符(\n)。

>>> I020a = [ line.strip("\n") for line in I020[1:] ]   >>> I020a[0:5]  ['8450010,8450009,TXFH7,128,10310,732,732,202,349',  '8450011,8450010,TXFH7,128,  10309,4,736,206,350',  '8450011,8450010,TXFH7,128,10309,1,737,207,351', '8450011, 8450010, TXFH7,128,10310,1,738,208,352',  '8450011,8450010,TXFH7,128,10310,1,739, 209,353']  

然后将数据通过逗号分隔。

>>> I020b = [ line.split(",") for line in I020a ]   >>> I020b[0:5]   [['8450010', '8450009', 'TXFH7', '128', '10310', '732', '732', '202', '349'],   ['8450011', '8450010', 'TXFH7', '128', '10309', '4', '736', '206', '350'],   ['8450011', '8450010', 'TXFH7', '128', '10309', '1', '737', '207', '351'],   ['8450011', '8450010', 'TXFH7', '128', '10310', '1', '738', '208', '352'],  ['8450011', '8450010', 'TXFH7', '128', '10310', '1', '739', '209', '353']] 

最后依照每个使用者的需求,可以直接对数据进行初步筛选。这里进行时间筛选(取9点之后的数据)。

>>> I020c = [ line for line in I020b if int(line[0]) > 9000000 ]   >>> I020c[0:5]   [['9000006', '8595997', 'TXFH7', '128', '10311', '2', '12906', '6457', '6827'],   ['9000006', '9000000', 'TXFH7', '128', '10311', '1', '12907', '6458', '6828'],    ['9000018', '9000010', 'TXFH7', '128', '10311', '1', '12908', '6459', '6829'],   ['9000018', '9000012', 'TXFH7', '128', '10311', '4', '12912', '6461', '6830'],   ['9000031', '9000024', 'TXFH7', '129', '10311', '1', '12914', '6463', '6831']] 

两种方式各有优缺点,假如要依照时间序列判断目前是否锁定收益出场,可以通过for循环来逐笔判断;若要获取特定时期的价格高低点,则会直接通过Python的list搭配max、min来完成。

2.转换回测指标

“转换回测指标”就是将现有的历史数据进一步转换成指标,而每个交易者对于指标的定义都不尽相同,所以必须明确定义指标。

以下提供常见的交易指标,供大家参考。

(1)移动平均价

假如在期货交易市场上的交易算法是通过移动平均(MA)为主要的交易指标,那就会定义移动平均的周期以及长度。假设是10分MA,周期就是分钟,长度就是10,而显示出来的信息也就是由10分钟的每分钟收盘价所计算的指标。

若10分MA通过前10分钟的收盘价计算,那就只能看到上一分钟的状态,无法掌控最新的市场价格动态。若获取tick数据,也就是逐笔信息,就能够依照最新的价格来进行计算,也就是说,从原本的10分钟收盘价变为9分钟的每笔收盘价加上当前的tick计算,可以即时地反映最新的市场动态。

(2)当日价格高低点

回测指标所指的是当日的高低点,并非是直接通过历史数据获取当天的最高价和当天的最低价,而是回测时逐笔地去计算当日最高价和最低价。若回测当前时间为09:50:35,则目前的最高价和最低价就是09:50:35以前的最高价和最低价。

若直接取得当日高低点,可能会造成程序逻辑上的错误,所以在定义指标前必须先厘清观念。

动态计算当日最高点和当日最低点,代码如下:

# -*- coding: UTF-8 -*-   # 取I020,依照逗号分隔,并将分隔符号去除  I020 = [ line.strip('\n').split(",") for line in open('Futures_20170815_I020.csv')][1:]   # 定义变量初始值  lastPrice=int(I020[0][4])   outDesk=0  inDesk=0   # 开始计算内外盘  for i in I020[1:]:    price = int(i[4])    qty = int(i[5])    if price > lastPrice:     outDesk+=qty    if price < lastPrice:     inDesk+=qty    print ("Time:",i[0]," Price:",price," OutDesk:",outDesk," InDesk:",inDesK)   lastPrice = price 

若要将指标存成新文件,可以将上面示例程序中的print函数改为write函数。通过CMD执行Python指令,输出如下:

>python 42-1.py   Time: 8450011 Price: 10309 High: 10310 Low: 10309   Time: 8450011 Price: 10309 High: 10310 Low: 10309   Time: 8450011 Price: 10310 High: 10310 Low: 10309   Time: 8450011 Price: 10310 High: 10310 Low: 10309   Time: 8450011 Price: 10309 High: 10310 Low: 10309   Time: 8450011 Price: 10309 High: 10310 Low: 10309   ...  Time: 8450043 Price: 10312 High: 10312 Low: 10309   Time: 8450043 Price: 10312 High: 10312 Low: 10309   Time: 8450056 Price: 10310 High: 10312 Low: 10309   Time: 8450056 Price: 10313 High: 10313 Low: 10308   Time: 8450056 Price: 10313 High: 10313 Low: 10308   Time: 8450056 Price: 10310 High: 10313 Low: 10308   Time: 8450056 Price: 10313 High: 10313 Low: 10308   Time: 8450056 Price: 10313 High: 10313 Low: 10308 

(3)内外盘量

内外盘是大家常用的指标之一,一般的计算方式为下一笔成交价落在上一档价(卖方价格)还是下一档价(买方价格),若价格落在上一档价时,则为“外盘价”;落在下一档价时,则为“内盘价”。

内外盘还有另外一种算法,就是当成交价大于上一笔成交价时,则为“外盘量”;反之,则为“内盘量”。

计算内外盘量的总和可以用来判断目前的多空方趋势:若外盘量较多,则多方趋势较空方趋势重,价格往上的概率较高;反之,若内盘量较多,则空方趋势较多方趋势重,价格往下的概率较高。

动态计算当天的内外盘量,预测当天的多空趋势,代码如下:

# -*- coding: UTF-8 -*-   # 取I020,依照逗号分隔,并将分隔符号去除  I020 = [ line.strip('\n').split(",") for line in open('Futures_20170815_I020.csv')][1:]   # 定义变量初始值  lastPrice=int(I020[0][4])   outDesk=0  inDesk=0   # 开始计算内外盘  for i in I020[1:]:    price = int(i[4])    qty = int(i[5])    if price > lastPrice:     outDesk+=qty    if price < lastPrice:     inDesk+=qty    print ("Time:",i[0]," Price:",price," OutDesk:",outDesk," InDesk:",inDesK)   lastPrice = price 

若要将指标存成新文件,可以将上面示例程序中的print函数改为write函数。

本示例是通过单纯的成交价比对计算的,若要通过上下五档价来做内外盘判断计算,则需要搭配I080数据计算。

通过CMD执行Python指令,输出如下:

# -*- coding: UTF-8 -*-   # 取I020,依照逗号分隔,并将分隔符号去除  I020 = [ line.strip('\n').split(",") for line in open('Futures_20170815_I020. csv')][1:]  # 起始时间至结束时间  I020a= [ line for line in I020 if int(line[0])>9000000 and int(line[0])<11000000]  # 初始仓位  index=0  for i in I020a:    if index==0:     if 进场条件:       OrderTime=i[0]  #下单时间记录      OrderPrice=i[4] #下单价格记录   elif index!=0:    if 出场条件:     OrderTime=i[0]  #下单时间记录     OrderPrice=i[4] #下单价格记录 

(4)委托手数差值

委托手数差值是通过委托信息来计算的,会将委托的买方手数以及委托的卖方手数相减。若值为负数,则代表目前委托买方手数较少,代表目前市场委托趋势较偏向空方;反之,若值为正数,则代表卖方手数较少,代表目前市场委托趋势较偏向多方。

(5)委托比重

委托比重指标是从委托信息计算而来的,会将委托的买卖方分别用手数除以笔数来计 算买卖方的平均单笔手数,进而通过比重的方式计算该指标。假设委托的买方为 100 手、50 笔,卖方为 80 手、20 笔,则委托的买方平均手数为 2 手,卖方平均手数为 4 手,进而 计算出多方委托比重为 33.33%,空方委托比重为 66.67%。

这个指标与委托手数差值指标最大的不同在于委托比重不会受到手数绝对的影响,就 算买方的手数相当多,但笔数也相对多,还是有可能被空方趋势胜过。

(6)成交买卖单笔数

成交买卖单笔数是由成交信息获取的,通常交易者会根据成交买卖笔数来做趋势的判断,因为对于累积成交量,买卖方是相等的,所以当成交买笔数小于成交卖笔数时,代表 成交买方平均手数大于卖方平均手数,这时就可以判断买方趋势大于卖方趋势。

3.历史算法设计

由于回测算法获取的是历史数据,因此在编写回测算法时可以依照需求去撷取需要的 部分信息。假设交易算法只操作当日开盘的第二个小时,那么通过子集合的函数去获取那 一段期间的数据即可,不必再从文件的开始读取到结尾。

回测算法也是交易算法,所以依照流程会有趋势判断、进场、出场和止损等相关步骤。 下面会通过简单的程序流程来帮助大家了解如何操作。

# -*- coding: UTF-8 -*-   # 取I020,依照逗号分隔,并将分隔符号去除  I020 = [ line.strip('\n').split(",") for line in open('Futures_20170815_I020. csv')][1:]  # 起始时间至结束时间  I020a= [ line for line in I020 if int(line[0])>9000000 and int(line[0])<11000000]  # 初始仓位  index=0  for i in I020a:    if index==0:     if 进场条件:       OrderTime=i[0]  #下单时间记录      OrderPrice=i[4] #下单价格记录   elif index!=0:    if 出场条件:     OrderTime=i[0]  #下单时间记录     OrderPrice=i[4] #下单价格记录 

该策略仅展示用途,并没有实际用意,要编写回测算法,可以通过上述概念来进行, 但实际上还是有许多细节需要注意。

4.历史回测回传明细格式设计

回测交易格式的设计,是希望完整地保存回测交易记录,并且真实地表达交易事件的 细节,最后让这些记录能够被适度地分析,让回测的效益最佳化。 以下是交易事件回传格式:

交易序列号、交易商品、开仓日期、开仓时间、开仓价格、买卖、 数量、平仓日期、平仓时间、平仓价格、注记、税金、 手续费、策略编号、交易者编号  SerialNumber,Good,ODate,OTime,OPrice,BorS,Number,CDate,CTime,CPrice,Comment,Tax,Fee, PID,ID 

读者看到这里,或许会好奇,为什么没有盈亏字段呢?首先,通过原有的数据字段就 可以计算出盈亏,为了避免表格字段过于冗长,所以不另外设置字段。另外,若要观察回 测的效益,盈亏也并非绝对标准。怎么说呢?就好比一个回测程序虽然说一个月的总盈亏 是−1000,但它并不代表就是一个不好的策略,或许买方的头寸净利是 3000,卖方的头寸 净利是−4000,只要将这个策略设置为只做买方,就会是一个赚钱的策略。除了盈亏,也有 很多角度可以分析策略的好坏,例如:交易时间、持仓时间等。除盈亏以外的分析对于交 易而言也是相当重要的,后面会有介绍。

每个字段都具有存在的价值,而第一个字段交易序列号代表唯一值,所以每笔数据并 不会发生重复的现象。上述交易回传格式不一定符合每种交易类型的需求,可以依照自己 的需求做更改。 以下是开盘买、收盘卖的策略,做一个基础的交易回传明细:

# -*- coding: UTF-8 -*-    # 取I020,依照逗号分隔,并将分隔符号去除  I020 = [ line.strip('\n').split(",") for line in open('Futures_20170815_I020. csv')][1:]   OrderTime=I020[0][0] #下单时间记录  OrderPrice=int(I020[0][4])  #下单价格记录  CoverTime=I020[-1][0]       #平仓时间记录  CoverPrice=int(I020[-1][4]) #平仓时间记录  print ("Buy OrderTime:",OrderTime," OrderPrice:",OrderPrice,)   print (" CoverTime:",CoverTime," CoverPrice:",CoverPrice," Profit:",CoverPrice- OrderPrice) 

执行回测后,输出如下:

>python 42-4.py   Buy OrderTime: 8450010 OrderPrice: 10310 CoverTime: 13450006 CoverPrice: 10309 Profit: -1 

5.绩效计算

读取交易记录后,就可以依照交易回传的数据去加以计算分析。绩效不仅可以从盈亏 去观察,也可以从买卖、交易次数、交易时间点来进行分析。本节提供的绩效分析示例虽 不多,但主要是让读者熟悉系统分析命令的用法。

某些策略会符合某些时期的趋势条件,但不代表那些策略会符合长期市场的走势,毕竟交 易市场是瞬息万变的,若要调试出一个长期稳定获利的策略,必须要经过长期回测的测试。

绩效计算不一定是从获利盈余的数字上来看,以下提供其他参考绩效的方向让读者参考:

(1)交易次数胜率;

(2)买卖个别成交结果。

股市有风险,投资需谨慎,并不是学了这个技巧后,你就能成为股神巴菲特,在相应的资讯,信息,海量数据之下,用python程序量化交易可以降低风险,稳定获益。想了解更多关于程序量化交易的技巧,这本《Python期货量化交易实战》一定别错过哦!

本书内容由最基本的期货交易规则开始,逐步切入程序编写,通过计算技术指标,能进行历史回测,最后透过下单函数进行程序交易。通过对案例的逐步演练,可降低学习的门坎,带领读者进入程序交易的殿堂。

全书通过121个技巧,以10章内容的形式呈现给读者精简的操作方法和思路,帮助读者快速入门,并能够在实际的案例式学习中,更好地掌握核心思想。

-END-

股市大涨该买吗?教你用算法量化交易行为!相关推荐

  1. 股市大涨是不是楼市就要跌了?

    最近A股表现比较理想,从年初到现在已经上涨了差不多30%,随着A股不断上涨,很多资金都从楼市出来进入到股市里面去,对此有些朋友可能会觉得股市大涨了,那楼市会不会下跌呢? 其实股市上涨跟楼市下跌没有必然 ...

  2. 有向加权图 最大弱连通分支_开盘引来大涨,当下股市最大的风险是它?

    何为昨天的大涨定性? 昨天的大涨,上午的加权量能水平达到了2921亿元,一个非常健康的温和放量状态:下午的加权量能水平快速下降到2242亿元的水平,这是略高于五日均量的量能水平:大幅高开,集合竞价成交 ...

  3. 拉伯证券|A股大涨!外资30分钟爆买百亿!汽车股狂飙

    在很多利好音讯的轮番影响下,兔年首个交易日,A股迎来大涨.沪指开盘便站上3300点整数关口,尔后继续高位震动.深证成指.创业板指涨势更甚,到午盘涨幅均超1.5%. 外资继续"高调" ...

  4. 职场3大涨工资技能,今天教你其中1个。

    职场有3大涨工资技能:英语.沟通能力和PPT. 提升英语和沟通能力需要长时间的训练,提高PPT的制作能力却是很快的.利用80/20法则,提升PPT制作能力,只需要几个技巧. 选好模板 模板,是我们做P ...

  5. 越卖越涨?腾讯股票3月后大涨45%,超越“阿里”成中国第一,市值相当于14.3个百度!...

    01    腾讯股价大涨 据股市最新消息:腾讯股价已连续3个交易日上涨, 其中6月22日腾讯股价重返470港元关口,公司市值突破4.5万亿港元,折合4.0万亿人民币:而6月23日上午腾讯股价再度大涨4 ...

  6. 跑赢A股95%的公司,半年大涨115%!明年的海尔智家更令人期待!

    文 | 易牟 来源 | 螳螂财经(ID:TanglangFin) 近日,海尔智家(600690.SH)再次在A股市场上备受瞩目--连续8个交易日,涨幅超26%!如果再进一步看,根据wind数据显示,截 ...

  7. 买房一定要知道的购房误区 买涨不买跌的心态可能得改

    买房子是人生的大事,当然要研究好,尤其是首次买房,很多误区需要用心才能避免,随万家小编一起看看吧! 在房地产市场上,买了房的人无不盼望大涨,没买的无不盼望大跌.几乎很少看到有异常冷静的市民. 燕郊部分 ...

  8. 棕榈油增仓大涨,铁矿石认购上涨,豆粕09-01季节性正套2022.5.27

    <期货套利基础系列>介绍套利的基础知识: 期货套利基础第一篇:对套利的误解 第2-3篇是套利基础知识,内容来自电子书,有做过套利的人可以跳过: 期货套利基础第二篇:套利交易的基本概念 期货 ...

  9. 大白话说期权——除了买涨买跌,我们还能怎么交易?二元期权又是什么鬼?

    转自:许哲 http://zhuanlan.zhihu.com/wontfallinyourlap/19962890 期权,作为现代金融衍生品的代表产品,越来越多的被提及,然而关于它的诸多金融术语,似 ...

最新文章

  1. Python 标准库之 subprocesss
  2. css绝对定位如何在不同分辨率下的电脑正常显示定位位置?
  3. favicon自动获取_友情链接前面自动获取并添加favicon.ico小图标
  4. 有序数组中查找数字的范围
  5. 快速git本地项目到github的关键命令及执行步骤(附上idea到git的步骤)
  6. P4922-[MtOI2018]崩坏3?非酋之战!【dp】
  7. jfinal mysql存储过程_jfinal调用mysql存储过程
  8. 剑指offer——面试题44:扑克牌顺子
  9. Runloop与autoreleasePool联系
  10. python绘制柱状统计图_Python画柱状统计图操作示例【基于matplotlib库】
  11. 世界上最大的二房东上市了
  12. 着色问题 一个圆分成N个扇形,M种颜色,相邻区块重色 总工的着色方法数
  13. 基因重组-冲刺日志(第七天)
  14. yii mysql gii_yii中gii如何使用
  15. 2019计算机考研各科目时间安排,2019考研时间安排
  16. Ruby读取Excel文件的两种方法
  17. 不会“思维”只会“批判”,谨防网络舆论“怨妇化”
  18. 鸿蒙系统有没有红外遥控,红外遥控与蓝牙遥控的区别
  19. 从零开始学微信小程序开发:1
  20. 简述矩阵的秩和向量组的秩的定义 从定义出发分析两者之间的相互关系

热门文章

  1. java嵌套for循环基础练习 -班级平均分
  2. java上位机开发(编译和部署)
  3. 译:Two-stream convolutional networks for action recognition in videos
  4. 阿根廷夺冠!梅西圆梦!历届世界杯还有哪些数据看点?
  5. 海康存储服务器虚拟机,unraid 安装虚拟机攻略
  6. 一个UWP 框架开发的哔哩哔哩非官方应用
  7. 毕业设计基础教学:SPI 通信接口
  8. 企查查在哪查实缴_如何查询一家企业的注册资金是实缴的还是认缴的?
  9. 十字路口待转区什么用_左转待转区的几种违章 稍不注意你绝对就要中招
  10. 怎样才能使你的Mac桌面干净整洁?