• 上交所行情文件解析之mktdt00.txt


    finalshell太好用了吧

    一、前言

      近期在研究上交所行情接口,由于接口比较复杂,种类也很多,所以从最基础的文件行情开始研究吧。

    二、行情文件接口

      之前研究期货行情,都是通过API来获取的,包括实时行情,产品信息等等,现在证券行情很奇怪,都是通过文件的形式获取的,而且我发现不止上交所这样,似乎通过文件来获取行情和产品信息是证券交易所的通用规则。不过证券行情的更新频率很低,倒是不碍事。

      所谓行情文件接口包含两个部分,一个是实时行情,一个是产品信息。其中产品信息又区分交易产品信息和非交易产品信息,这块后面再说。现在我们主要是解析实时行情。

      对于上交所,mktdt00.txt是竞价撮合平台的行情文件接口,竞价撮合平台其实是涵盖了股债基三个品种大类,其中股票、债券和基金在上交所别的平台也有交易,只是交易方式不一定是竞价撮合,一般称之为“多种交易方式”,比如科创板的盘后固定价格交易就是在综业平台。那么我们可以理解为,所有以竞价撮合作为交易方式的“股票、债券、基金”都在竞价撮合平台交易,行情以mktdt00发布。不过最近搞了个新债券平台,未来是要把所有债券业务都迁移到新债券,这样以竞价撮合方式成交的债券可能会迁移走,但这是很多年后的事了。

      那文件是如何发行情的呢?

      首先你得先拿到这个文件,渠道有上交所技术(券商)和上证所信息(信息商),这两家都会给下游提供接入行情的软件,我们可以称之为“终端”。以上证所信息来说,他提供的终端只有一个,就是VDE,而上交所技术则提供了很多不同类型的终端,因为他业务比较宽泛些。

      以VDE和文件行情为例,整个行情接口示意如下图所示:

      我们打开mktdt00文件,会发现每一行其实就是一个证券的行情信息,那要解析这些信息的内容就需要参考行情接口文档了,其中mktdt00.txt对应的接口文档是《IS101_上海证券交易所竞价撮合平台市场参与者接口规格说明书》。

    三、行情解析

    1、文件头

      文件的第一行是文件头,内容如下:

    BeginString|Version|BodyLength|TotNumTradeReports|MDReportID|SenderCompID|MDTime|MDUpdateType|MDSesStatus

      含义如下:

    起始标识符号、版本、数据长度、文件体记录数、行情序号、发送方、行情时间、发送方式、市场行情状态

      示例如下:

    HEADER|MTP1.00 |   1474865| 3744|        |XSHG01|20220422-11:56:28.070|0|T100

      对比说明如下:

    起始标识符号,HEADER;固定值

    版本,MTP1.00;固定值

    数据长度,1474865

    文件体记录数,3744

    行情序号;留空

    发送方,XSHG01;固定值

    行情时间,20220422-11:56:28.070

    发送方式,0;默认0快照行情,1增量不支持

    市场行情状态,T100;每一位分别代表不同含义

      第一位:S表示全市场启动期间(开市前),

          T表示全市场处于交易期间(含中间休市)

          E表示全市场处于闭市期间

      第二位:1表示开盘集合竞价结束

          0表示开盘集合竞价未结束

      第三位:1表示全市场行情结束

          0表示全市场行情未结束

      第四位:1表示上海市场行情结束

          0表示上海市场行情未结束

      第五位:债券质押回购行情是否结束标志,技术预留

      第6-8位:预留位

    其他说明:上海市场包括股票、基金、债券分销、单市场指数;全市场包括上海市场及跨市场指数

    2、文件尾

      文件的最后一行,内容如下:

    EndString|CheckSum

      含义如下:

    结束标识符、校验和

      示例如下:

    TRAILER|045

      对比说明如下:

    结束标识符,TRAILER;固定值

    校验和,045;可用于开盘前和收盘后文件正确性校验。实时交易期间,因文件循环写入覆盖,校验和字段存在一定的概率不匹配。

      校验和计算逻辑:

    校验和是通过计算不包括校验和字段(也不包括该字段后的换行符)数值的文件中其他每一个字符(包含分隔符、换行符)之和然后模 256 得出,然后转化为 3 位ASCII 码。例如,如果经计算校验和为274,则模 256 后的数为 18,校验和域将取为 ASCII 字符串 018。

    后面计算一下看看具体是取了那些值来计算校验和。

    3、文件体

      文件体就是行情部分了,根据不同的行情类型其字段含义也不同,主要原因是指数行情字段相对会少一些。

    3.1 指数行情文件体

      MDStreamID=MD001

      内容如下:

    MDStreamID|SecurityID|Symbol|TradeVolume|TotalValueTraded|PreClosePx|OpenPrice|HighPrice|LowPrice|TradePrice|ClosePx|TradingPhaseCode|Timestamp

      含义如下:
    行情数据类型、产品代码、产品名称、成交数量、成交金额、昨日收盘价、今日开盘价、最高价、最低价、最新价、今收盘价、指数实时阶段及标志、时间戳
      示例如下:
    MD001|000001|上证指数|       218419869| 220544090001.10|  3079.8077|  3058.4044|  3099.4873|  3049.3555|  3077.8002|     0.0000|        |11:56:03.000
      对比说明如下:
    行情数据类型,MD001;取值范围有MD001‘、MD002、MD003、MD004,分别代表指数、股票、债券分销、基金
    产品代码,000001
    产品名称,上证指数
    成交数量,218419869;单位手
    成交金额,220544090001.10;单位元
    昨日收盘价,3079.8077
    今日开盘价,3058.4044
    最高价,3099.4873
    最低价,3049.3555
    最新价,3077.8002
    今收盘价,0.0000;文档说无值取空格,实际是0.0000
    指数实时阶段及标志;预留,无定义填空格
    时间戳,11:56:03.000
     
    3.2 股债基行情文件体
      MDStreamID=MD002(股)、MD003(债券分销)、MD004(基金)
      内容如下:
    MDStreamID|SecurityID|Symbol|TradeVolume|TotalValueTraded|PreClosePx|OpenPrice|HighPrice|LowPrice|TradePrice|ClosePx|BuyPrice1|BuyVolume1|SellPrice1|SellVolume1|BuyPrice2|BuyVolume2|SellPrice2|SellVolume2|BuyPrice3|BuyVolume3|SellPrice3|SellVolume3|BuyPrice4|BuyVolume4|SellPrice4|SellVolume4|BuyPrice5|BuyVolume5|SellPrice5|SellVolume5|PreCloseIOPV|IOPV|TradingPhaseCode|Timestamp
      含义如下:

    行情数据类型、产品代码、产品名称、成交数量、成交金额、昨日收盘价、今日开盘价、最高价、最低价、最新价、今收盘价、申买价一、申买量一、申卖价一、申卖量一、申买价二、申买量二、申卖价二、申卖量二、申买价三、申买量三、申卖价三、申卖量三、申买价四、申买量四、申卖价四、申卖量四、申买价五、申买量五、申卖价五、申卖量五、基金 T-1 日收盘时刻 IOPV基金 IOPV、产品实时阶段及标志、时间戳

      示例如下:

    MD002|600000|浦发银行| 18376247| 148252802.00| 8.070| 8.010| 8.120| 8.010| 8.090| 0.000| 8.090| 3100| 8.100| 389696| 8.080| 57500| 8.110| 538800| 8.070| 63700| 8.120| 817800| 8.060| 107600| 8.130| 180700| 8.050| 184700| 8.140| 168000|T111 |11:29:37.570

      对比说明如下:

    行情数据类型 MD002;取值范围有MD001、MD002、MD003、MD004,分别代表指数、股票、债券分销、基金
    产品代码 600000
    产品名称 浦发银行
    成交数量 18376247
    成交金额 148252802
    昨日收盘价 8.07
    今日开盘价 8.01
    最高价 8.12
    最低价 8.01
    最新价 8.09
    今收盘价 0
    申买价一 8.09
    申买量一 3100
    申卖价一 8.1
    申卖量一 389696
    申买价二 8.08
    申买量二 57500
    申卖价二 8.11
    申卖量二 538800
    申买价三 8.07
    申买量三 63700
    申卖价三 8.12
    申卖量三 817800
    申买价四 8.06
    申买量四 107600
    申卖价四 8.13
    申卖量四 180700
    申买价五 8.05
    申买量五 184700
    申卖价五 8.14
    申卖量五 168000
    基金 T-1 日收盘时刻 IOPV;仅当MDStreamID=MD004时有此字段,其他情况无此字段
    基金 IOPV;仅当MDStreamID=MD004时有此字段,其他情况无此字段
    产品实时阶段及标志 T111,8位的字符串,前4位有具体含义,后四位预留无值
    时间戳 29:37.6

      关于PreCloseIOPV和IOPV,当MDStreamID不等于MD004时,PreCloseIOPV和IOPV字段不存在,也就是行情文件中该行会少2个字段,而不是赋空值

      关于TradingPhaseCode,第 1 位:

                    ‘S’表示启动(开市前)时段,

                    ‘C’表示开盘集合竞价时段,

                    ‘T’表示连续交易时段,

                    ‘E’表示闭市时段,

                    ‘P’表示产品停牌,

                    ‘M’表示可恢复交易的熔断时段(盘中集合竞价),

                    ‘N’表示不可恢复交易的熔断时段(暂停交易至闭市),

                    ‘U’表示收盘集合竞价时段

                  第 2 位:‘0’表示此产品不可正常交易,‘1’表示此产品可正常交易,无意义填空格。
                  第 3 位:‘0’表示未上市,‘1’表示已上市。
                  第 4 位:‘0’表示此产品在当前时段不接受订单申报,‘1’ 表示此产品在当前时段可接受订单申报。无意义填空格。

    5、数据长度字段的特别说明

      在我尝试对文件内容进行校验和时,首先是校验和肯定没对上,接着发现我从文件读取到的字符串长度与文件中写明的“数据长度”数值也对不上。

      以我使用的测试文件为例,mktdt00文件中数据长度字段值为1474865,而我读文件后输出的长度是1461226,少了13639和字符。

      我很快想到,行情文件是中英文混合的,一个英文字符占位是1个字节,而中文字符占位是2个字节,于是我先将读到的字符串转为16进制数,英文字符应该是0xAB这样,中文字符则是0xABCD这样,接着将中文字符的0xABCD拆分成AB和CD来存。通过下面的代码我就得到了比原来多了很多的字符长度。结果是1474892,但这下又多了27个字符。

      

      我试着换了好几个行情文件,发现都是会多27个字符,于是再次打开IS101文档中关于mktdt00的说明,发现下面这样一段话。

      也就是说,在计算长度时,长度字段本身不能算进去,于是我将长度字段(包括分隔符)以及前面的字符都删了。

      得到了正确的结果1474865。

    6、校验和的特别说明

      根据前面的经验,首先需要将校验和本身删除,包括后面的回车换行符。

       得到

      同时要注意,前面删除的数据长度字段要保留下来一起做校验和。

      根据前面求数据长度的经验,我自然就想到把前面获得的十六进制list依次转成10进制,再求和,但结果是错误的。

      想了很多办法,后经高人指点,原来是需要先转成byte再求和,直接上结果:

      得到正确结果:

     

      其中encode一定是gbk而不是utf-8,我在这个地方卡了很久才搞对。

      同时可以发现,直接用encode方法求前面的数据长度也是可行的。

    7、注意点

    1)MD003债券分销

    因为债券分销业务很少通过竞价平台做了,所以mktdt00文件中涉及债券分销的行情几乎都是0。

    2)成交数量和成交金额是累积值,而不是切片值

    3)接口可能会更新,本文仅供参考

     
     
     
     
     
     
     
  • 相关阅读:
    iOS开发~UI布局(二)storyboard中autolayout和size class的使用详解
    iOS开发~UI布局(一)初探Size Class
    OC登陆界面登陆按钮动画
    Git学习 --> 个人常用命令add,commit以及push
    Git使用之设置SSH Key
    【iOS开发】多屏尺的自动适配 AutoLayout (纯代码方式)
    iOS网络检测Reachability 使用 Demo,可检测2、3、4G
    iOS提醒用户进入设置界面进行重新授权通知定位等功能
    iOS中 @synthesize 和 @dynamic 区别
    iOS 开发笔记
  • 原文地址:https://www.cnblogs.com/cation/p/16362767.html
Copyright © 2020-2023  润新知