CTP程序化交易入门系列之三:获取实时行情及k线合成

前面两篇有了基础知识的准备,这一篇讲通过CTP API获取实时行情,录入csv,实时合成k线。github上开源了录入csv及合成k线代码,后台回复pyctp可获取。先上两张效果图:

                                                                                       图1 csv数据

                                                                                  图2 1分钟K线图

一、CTP行情API介绍

CTP API分为行情和交易两类,两者是完全独立的,所以如果只对行情感兴趣的话,只用如下行情API相关部分三个文件就可以。

thosttraderapi.py

_thostmduserapi.pyd

thostmduserapi_se.dll

API中的重点函数,请求:

//登录函数,确认连上CTP后首先需要登录
def ReqUserLogin(self, pReqUserLoginField: 'CThostFtdcReqUserLoginField', nRequestID: 'int') -> "int":
//订阅函数,即通过这个函数来向CTP请求订阅哪些合约的实时行情
//第一个参数类型为list,写成["au1912","IC1909"]的形式,第二个参数必须为前面list的长度
def SubscribeMarketData(self, ppInstrumentID: 'char *[]', nCount: 'int') -> "int":

回报:

//行情回报函数,其中pDepthMarketData类内即为每次实时行情的相关数据
def OnRtnDepthMarketData(self, pDepthMarketData: 'CThostFtdcDepthMarketDataField') -> "void":

那么究竟可以获取到合约的哪些行情数据呢?从类型CThostFtdcDepthMarketDataField 中的字段就可以看出来,在thosttraderapi.py文件中搜CThostFtdcDepthMarketDataField类型即可看出有哪些字段,主要有更新时间UpdateTime,最新成交价LastPrice ,买卖一档的价格及数量BidPrice1,BidVolume1,AskPrice1,AskVolume1,累计成交量Volume等。

二、订阅获取行情的步骤

代码非常简单,50行内即可订阅全市场行情。通过上一章的学习应该知道CTP的API是异步回调的机制,底层dll在客户订阅成功后会自动推送订阅合约的实时行情。代码逻辑时序图如下:

                                                                               图3 订阅行情时序图

对应的主函数如下:

def main():mduserapi=mdapi.CThostFtdcMdApi_CreateFtdcMdApi() #第1步mduserspi=CFtdcMdSpi(mduserapi)  #第2步'''以下是生产环境'''#mduserapi.RegisterFront("tcp://180.168.146.187:10101")  #第3步'''以下是7*24小时环境'''mduserapi.RegisterFront("tcp://180.168.146.187:10131")mduserapi.RegisterSpi(mduserspi) #第4步mduserapi.Init()    #第5步,API正式启动,dll底层会自动去连上面注册的地址mduserapi.Join()    #join的目的是为了阻塞主线程,可以用sleep代替

回调实例类CFtdcMdSpi如下:

import thostmduserapi as mdapi
'''需要订阅的合约list'''
subID=["au1912","IC1909","i2001","TA001"]class CFtdcMdSpi(mdapi.CThostFtdcMdSpi):  #继承自spi基类mdapi.CThostFtdcMdSpidef __init__(self,tapi):mdapi.CThostFtdcMdSpi.__init__(self)self.tapi=tapidef OnFrontConnected(self) -> "void":print ("OnFrontConnected")loginfield = mdapi.CThostFtdcReqUserLoginField()loginfield.BrokerID="8000"loginfield.UserID="000005"loginfield.Password="123456"loginfield.UserProductInfo="python dll"self.tapi.ReqUserLogin(loginfield,0) #实现onfrontconnect函数,在里面调用登录,第7步def OnRspUserLogin(self, pRspUserLogin: 'CThostFtdcRspUserLoginField', pRspInfo: 'CThostFtdcRspInfoField', nRequestID: 'int', bIsLast: 'bool') -> "void":print (f"OnRspUserLogin, SessionID={pRspUserLogin.SessionID},ErrorID={pRspInfo.ErrorID},ErrorMsg={pRspInfo.ErrorMsg}")#继承实现登录回调,登录成功后去订阅,第9步ret=self.tapi.SubscribeMarketData([id.encode('utf-8') for id in subID],len(subID))     def OnRtnDepthMarketData(self, pDepthMarketData: 'CThostFtdcDepthMarketDataField') -> "void":#继承收取订阅行情,第11步,在这里将pDepthMarketData数据存入csv即可录得数据print(f"InstrumentID={pDepthMarketData.InstrumentID},LastPrice={pDepthMarketData.LastPrice}") 

看总共就30+行代码,就完成了订阅收取行情的工作。如果将subID列表中填入入全市场合约,就能订阅得到全市场的行情,是不是很简单?

四、由CTP API得到K线数据

首先需要区分下tick数据和切片(快照)数据有什么区别。

tick数据一般是指市场上的逐笔数据,例如一笔委托会产生一笔行情,一笔成交也会产生一笔行情。目前国内期货交易所还不支持推送这种逐笔的数据,只推送切片(快照)数据。

切片数据是指将一定时间内的逐笔数据统计成一个快照发出,一般是1秒2笔。但郑商所有点特殊,可能是1s多笔,就不展开来讲了。

CTP发出的行情正是转发的交易所的行情,所以也是500ms一次快照。一般业内也将这个快照数据称之为tick,虽然这不是真正的tick,但我们依照惯例,下面都称之为tick数据。

很多客户做交易更关心K线数据,用K线数据计算信号。CTP不推送K线数据,所以需要客户自己根据tick数据计算得出。

K线数据的基本要素有Time、Volume、Price、Open、High、Low、Close这6个值,可以根据这个周期内CTP的tick数据中的UpdateTime、 LastPrice、 Volume三个字段算出。我们以1分钟K线为例,逻辑如下:

#根据行情中的UpdateTime字段判断是否为新1分钟
st= pDepthMarketData.UpdateTime.split(':')
if not self.bar:newMinitue = True
else:if int(st[1]) == self.bar.updateTime.minute :newMinitue = Falseelse:newMinitue = True
#如果是新1分钟,生成一个新k线变量,CBarData结构体中有OHLC,time等K线字段
if newMinitue :self.bar = CBarData()self.bar.instrumentID = pDepthMarketData.InstrumentIDself.bar.exchangeID = pDepthMarketData.ExchangeIDself.bar.updateTime = time(int(st[0]),int(st[1]),0,0)self.bar.volume = 0self.bar.openInterest = pDepthMarketData.OpenInterestself.bar.openPrice = pDepthMarketData.LastPriceself.bar.highPrice = pDepthMarketData.LastPriceself.bar.lowPrice = pDepthMarketData.LastPriceself.bar.closePrice = pDepthMarketData.LastPrice
else :
#如果不是新1分钟,将最新价与HL价相比然后更新,更新C价 self.bar.highPrice = max(self.bar.highPrice, pDepthMarketData.LastPrice)self.bar.lowPrice = min(self.bar.lowPrice, pDepthMarketData.LastPrice)self.bar.closePrice = pDepthMarketData.LastPriceself.bar.openInterest = pDepthMarketData.OpenInterest
#注意Volume字段是累计成交量,所以这个时间段内成交量为该值与上一时间段末成交量的差值
if not self.lastVolume:self.bar.volume += max(pDepthMarketData.Volume-self.lastVolume,0)self.lastVolume = pDepthMarketData.Volume#打印实时k线数据   print(f"{bar update[pDepthMarketData.UpdateTime],O[self.bar.openPrice],H[self.bar.highPrice],L[self.bar.lowPrice],C[self.bar.closePrice]}")   

有这一段代码加入到上面的OnRtnDepthMarketData函数中,就能获得1分钟K线数据了。其余的3、5、10、15、30分钟这类的K线数据获取方式原理也相似。

当然要得到令自己满意的k线数据还是有很多坑要自己踩过才知道,每个人对K线的要求也不一样,这里提几点思考,就不一一列举解答了。

  1. 根据最新价LastPrice更新得到的highPrice一定是真的最高价吗?
  2. 上下午收盘分别是11:30和15:00,那收到11:30:00.500和15:30:00.500ms的行情如何处理?
  3. 非主力合约有的很长时间才来一个tick,如何处理?

建议大家可以一边做一边对应快期等终端对比,得到自己满意的k线数据。

一般有k线数据就可以直接计算指标得到信号量便于交易,为了更直观地看到K线,这里也提供下PyQt + PyQtGraph实现的K线图,源码一样提供在github上。

代码参考了github上uiKLine和vnpy两个开源项目,大家可以看我github上fork的这两个项目。感谢两位作者!

 

下节预告:

CTP API获取行情常见问题及解答

关注公众号,一起学习程序化交易!

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/51202.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

三月券商金工精选

✦研报目录✦ ✦简述✦ 按发布时间排序 东北证券 因子选股系列之四:高频数据下的已实现高阶矩因子及改进 发布日期:2023-03-01 关键词:股票、高频数据、高阶矩 主要内容:本文作为对高频因子研究的初探。对于收益率分布类别中…

十一月券商金工精选

✦ 研报目录 ✦ ✦ 简述 ✦ 按发布时间排序 国信证券 财报中的竞争对手分析能否用来预测股票收益? 发布日期:2022-11-01 关键词:股票、文本分析、竞争对手 主要内容:竞争对手提及次数被定义为一家公司在全市场所有公司的最新…

九月券商金工精选

✦研报目录✦ ✦简述✦ 按发布时间排序 国盛证券 可转债资产替代策略与多因子策略 发布日期:2022-09-01 关键词:可转债、多因子 主要内容:报告主要从两个方面进行了研究:1)如何构建偏债型转债的Beta策略&#xf…

十月券商金工精选

✦研报目录✦ ✦简述✦ 按发布时间排序 华福证券 估值系列专题(二):市场大底都长咋样?从估值分位数角度进行复盘 发布日期:2022-10-09 关键词:股票、指数、估值 主要内容:文章发现宽基指数的…

蒋鑫鸿:9.10国际黄金原油最新外盘行情趋势点评附解一套技术指导

​  明月本无价,高山皆有情。人虽不至,心向往之。蒋鑫鸿衷心祝愿您和家人团圆美满,幸福安康!      在黄金原油白银这个高风险高收益的市场,不是谁随随便便投入就能轻松赚个盆满钵满。它是需要专业的分析团队做好…

九龙证券|这一刻,资本市场进入全新时代!

2023年4月10日,第一批10家主板注册制企业上市鸣锣敲钟,奏响了触及本钱商场灵魂深处革新的序曲。 动能切换中的我国对于高效资源配置的渴望,与革新进行时的本钱商场对于全面注册制的探究,一起凝集成一股连绵有力之暖流,…

金融信息化及交易管理系统(股票交易系统APP)

目 录 1 绪 论 1 1.1 选题背景及意义 1 1.2 研究现状 1 1.3 研究主要内容 4 2 需求分析与实施方案 5 2.1 虚拟金融信息化交易系统的功能 5 2.2 可行性分析 5 2.3 系统开发技术 5 2.4 系统开发工具及环境 6 2.5 系统开发方式 7 3 需求分析 8 3.1 系统结构 8 3.2 系统描述 9 3.2.…

十二月券商金工精选

✦研报目录✦ ✦简述✦ 按发布时间排序 华宝证券 主动暴露的得与失—从Barra框架到私募指增因子分析方法 发布日期:2022-12-01 关键词:股票、Barra、风险暴露、指数增强 主要内容:本文针对私募指数增强产品的策略流程,设计…

同建金融IT新生态——令克软件富途证券达成战略合作

最新消息!令克软件与富途证券国际(香港)有限公司达成战略合作,并签署战略合作协议!双方将本着互惠互利的共赢原则,充分发挥富途证券在全球主流金融市场的优势,开启新型战略合作,共同…

解决微信QQ邮箱提醒收不到通知的问题

微信中的QQ邮箱提醒功能很实用, 但是有一天我发现收不到提醒了. 网上搜索基本都是说安装QQ邮箱然后把仅在QQ邮箱接收通知的开关关闭, 可是我这样操作后仍然收不到通知. 今天登录web页QQ邮箱查看账户设置, 偶然发现邮箱的pop3,smtp服务的"开启"是禁止的, 并提示要取…

设置谷歌邮箱gmail转发到qq邮箱550 DMARC check failed

手机qq邮箱收gmail反应太慢,要刷新好久。直接转发反应比较快,延迟大概5秒以内 前提 能上一次谷歌邮箱 1.谷歌邮箱设置 这部分可以参考这篇百度经验,我就不重复了。 https://jingyan.baidu.com/article/375c8e19a0683925f2a229f9.html …

在telnet登录并使用SMTP和POP收发邮件(QQ邮箱)

目录 一、什么是POP3、SMTP和IMAP?二、使用SMTP协议手工发送邮件1.开启QQ邮箱的SMTP服务2.开启TELNET客户端3.使用SMTP协议手工发送邮件 三、POP查看邮件四、总结参考资料 一、什么是POP3、SMTP和IMAP? POP3 POP3是Post Office Protocol 3的简称,即邮局协议的第…

手机查看企业qq邮件服务器,QQ企业邮箱怎么用?手机QQ邮箱收发邮件的方法

QQ企业邮箱,是腾讯提供的一项免费服务,您只要有自己的域名就能创建自己的邮箱系统,QQ邮箱手机软件,设置相对简单,两者结合,能够提高我们的工作效率,方便我们的工作。 软件名称:QQ邮箱…

QQ邮箱功能隔天使用不了?

刚毕业的大学生或者刚进公司的实习人员注意: 平常咱们登录的QQ,使用这个QQ邮箱来实现邮箱功能也只能用来测试或者练习。这是本人踩过的坑。 第一天测试的很完美,隔天第二天就用不了了?这是为什么,我百思不得其解&…

突发!ChatGPT爆炸级更新~

因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享 点击关注#互联网架构师公众号,领取架构师全套资料 都在这里 0、2T架构师学习资料干货分 上一篇:2T架构师学习资料干货分享 大家好,我是互联网架构师&…

OpenAI CEO公布AGI规划,谨慎思考超级智能风险与人类未来

来源:智东西 编译:ZeR0 编辑:漠影 成功过渡到一个拥有超级智能的世界可能是人类历史上最重要、最有希望、最可怕的项目。 智东西2月25日消息,OpenAI CEO萨姆阿尔特曼(Sam Altman)发布博客文章,分…

Unity联网插件(PUN)

PUN简单介绍: Photon引擎属于Exit Games公司,是世界排名第一的独立网络引擎和多人通信平台,适用于独立开发者和专业工作室 Photon引擎具有通信快速、高可靠性、使用方便、容易扩展等优点 针对Unity网络游戏开发,Photon引擎是首…

chatgpt赋能python:Python连接模拟器——提高网络仿真效率的终极解决方案

Python连接模拟器——提高网络仿真效率的终极解决方案 什么是模拟器? 模拟器是一种能够模拟计算机硬件和软件环境的工具。在网络模拟中,模拟器可以模拟路由器、交换机等网络设备,从而帮助我们进行网络仿真和测试。 模拟器的使用可以帮助我…

Uniapp开发笔记(持续更新中)

不是微信小程序原生,就是uniapp开发人都傻了,索性都记录吧。 为什么又用uniapp来开发小程序了,因为微信小程序就是源码裸奔…轻易就能被反编译了。索性用来uniapp虽然也能被反编译,最起码是混淆了,读起来也能恶心反编译…