大智慧365分笔数据结构及读取方案

Published

7.0版

*.prp,历史分笔
reportcps.dat,reportcps_2.dat,当天分笔

20160415.PRP.dat


day_1.dat,day_2.dat,日数据
min_1.dat,min_2.dat,五分数据
min1_1.dat,min1_2.dat,一分数据
L2D , 逐笔数据

 

1.订阅方法

订阅方法
 
(1)、发送http请求:http://localhost:10010/requestl2?list=SH600000,SH600362,SZ300059
 
list后面可以接多个股票,上限1000只,这是大智慧服务器的限制,不是本软件的限制,请注意,如果超过会收不到任何行情!!

https://github.com/freestockso/IssacLv2

2. 大智慧舵手版

大智慧舵手版是上海大智慧股份有限公司推出新一代的行情软件(客户端),客户端的数据均来自大智慧金融信息云.

大智慧舵手版

https://github.com/freestockso/pc

大智慧金融信息云

https://yun.gw.com.cn/cloud/#/home

 

3.模拟按钮读取

https://github.com/iaspnetcore/MFCApplication_dzhtest2/tree/master/src

https://github.com/anliu/star/blob/master/CA4/CA4.cpp

https://github.com/kofybq/hack/blob/master/test.py

4.软件直接读取

DzhTest.exe是解压缩大智慧7.0压缩数据的样本程序,用vs 2005编写.
这个程序只能看数据,不能输出数据,原代码是出售的.
可以解压缩:
*.prp,历史分笔
reportcps.dat,reportcps_2.dat,当天分笔
day_1.dat,day_2.dat,日数据
min_1.dat,min_2.dat,五分数据
L2D , 逐笔数据

显示部分用的是MFC,仅是为了方便,解压缩部分是纯粹的C++.
使用时请关闭大智慧或者把数据目录拷贝到其他地方,因为大智慧独占一些数据文件.
L2D逐笔数据只针对一个版本,就是文件开头是DDFF3322,
L2D文件里只有最后的是逐笔数据,程序也只对这些逐笔数据解压缩,其他数据都是明文,没有进行处理.

 

reportcps.dat  股票代码表从此文件读取

reportcps_2.dat 股票成交明细从此文件读取

///////////////////////////////////////////////////////////////////////////////
/*
 * Dzh70DecodeDemo.dll 没有包含解压缩分笔数据的代码,
 * 也就是不能解压缩Reportcps.dat和*.prp文件.
 * 所有对分笔数据的解压缩都是0,但是函数依然存在.
 * 出售的源代码包含全部功能.
 * QQ群 : 63727540
 */
///////////////////////////////////////////////////////////////////////////////
/*        void IDestroy();
 *        销毁DLL用的所有资源,在程序退出时调用
*/
///////////////////////////////////////////////////////////////////////////////
/*        void IGetDzhMainPath(StringBuilder sMainPath);
 *        参数: sMainPath , 返回大智慧的主路径,得到大智慧的主路径,可能是c:\dzh2
 *        这个函数与解压缩无关.
*/
///////////////////////////////////////////////////////////////////////////////
/*        int IReadFile(string sFileName, int nDataType);
 *        参数: sFileName , 要读的文件全名,必须含有完整的目录.如 c:\dzh2\data\sh\day_1.dat.
 *                          可以是4种文件类型,
 *                          Day_1.dat ,日数据.
 *                          Min1_1.dat,五分数据.
 *                          Reportcps.dat,当天分笔数据.
 *                          *.Prp,历史分笔数据.
 *              nDataType , 数据类型,1 = 日数据 , 2 = 五分数据, 3 = 当天分笔数据 , 4 = 历史分笔数据
 *        返回值: -2 , 数据类型错误,必须是 1,2,3,4之一.
 *                -1 , 文件有错误 , 使用IGetErrorInfo(StringBuilder sErrorInfo)得到错误描述.
 *                 0 , 文件没有包含数据,
 *                 返回大于0 的数表示读成功.
 *        这是第一个必须调用的函数,在这个函数成功后,才能调用其他函数.
*/
///////////////////////////////////////////////////////////////////////////////
/*        int IDecode(string sStockCode);
 *        参数:sStockCode , 要解压缩的股票代码.
 *        返回值: -1 , 数据有错误 , 使用IGetErrorInfo(StringBuilder sErrorInfo)得到错误描述.
 *                 0 , 这个代码没有包含数据,
 *               > 0 , 解压缩后的数据个数,使用这个返回值分配足够的内存来取得数据
 *        IReadFile(string sFileName, int nDataType)之后使用.
 *        样本:
 *        int  nResult = IReadFile("c:\\dzh2\\data\\sh\\day_1.dat", (int)DZH70_DECODE_DATATYPE.DAY);
 *        if(nResult > 0)
 *             nResult = IDecode("600000");
 *        if(nResult > 0)
 *        {
 *             TIME_70 []pTime70 = new TIME_70[nResult];
 *             IGetDecodeData(ref pTime70[ 0 ])
 *             int i;
 *             for(i = 0;i < pTime70.Length ; i++)
 *             {
 *                 //这里处理数据
 *             }
 *        }
 */
///////////////////////////////////////////////////////////////////////////////
/*        int IGetDecodeData(ref TIME_70 pTime70);
 *        int IGetDecodeData(ref TICK_70 pTick70);
 *        参数 : pTime70 , pTick70 , 返回结构化的解压缩数据.
 *        返回值:pTime70 , pTick70 里得到的字节的数量.不是数据个数,要除以结构长度才是数据个数
 *        IDecode(string sStockCode)之后使用.
 *        样本:
 *        int  nResult = IReadFile("c:\\dzh2\\data\\sh\\day_1.dat", (int)DZH70_DECODE_DATATYPE.DAY);
 *        if(nResult > 0)
 *             nResult = IDecode("600000");
 *        if(nResult > 0)
 *        {
 *             TIME_70 []pTime70 = new TIME_70[nResult];
 *             IGetDecodeData(ref pTime70[ 0 ]);
 *             int i;
 *             for(i = 0;i < pTime70.Length ; i++)
 *             {
 *                 //这里处理数据
 *             }
 *        }
 */
///////////////////////////////////////////////////////////////////////////////
/*        int IGetPriceMode();
 *        返回值:价格的小数点模,可能是100,表示二位小数点,1000 ,表示三位小数点
 *        IDecode(string sStockCode)之后使用.
 *        样本:
 *        int  nResult = IReadFile("c:\\dzh2\\data\\sh\\day_1.dat", (int)DZH70_DECODE_DATATYPE.DAY);
 *        if(nResult > 0)
 *             nResult = IDecode("600000");
 *        if(nResult > 0)
 *        {
 *             int nPriceMode = IGetPriceMode();
 *             TIME_70 []pTime70 = new TIME_70[nResult];
 *             IGetDecodeData(ref pTime70[ 0 ]);
 *             int i;
 *             for(i = 0;i < pTime70.Length ; i++)
 *             {
 *                 float fClose = (float)pTime70[i].nClose / (float)nPriceMode;//真实价格
 *                 //这里处理数据
 *             }
 *        }
 */
///////////////////////////////////////////////////////////////////////////////
/*        int IGetVolMode();
 *        返回值:量的小数点模,实际是一手的股数,可能是100 , 10
 *        IDecode(string sStockCode)之后使用.
 *        样本:
 *        int  nResult = IReadFile("c:\\dzh2\\data\\sh\\day_1.dat", (int)DZH70_DECODE_DATATYPE.DAY);
 *        if(nResult > 0)
 *             nResult = IDecode("600000");
 *        if(nResult > 0)
 *        {
 *             int nVolMode = IGetVolMode();
 *             TIME_70 []pTime70 = new TIME_70[nResult];
 *             IGetDecodeData(ref pTime70[ 0 ]);
 *             int i;
 *             for(i = 0;i < pTime70.Length ; i++)
 *             {
 *                 Int64 nVol = pTime70[i].nVol * nVolMode ;//手数变成股数,实际上大智慧数据是不精确的
 *                 //这里处理数据
 *             }
 *        }
 */
//////////////////////////////////////////////////////////////////////////////
/*        int IGetCurrentStockCode(StringBuilder sStockCode)
 *        参数 : sStockCode , 返回的当前股票代码,也就是刚刚解压缩的股票代码.
 *        返回值: 0 失败
 *                1 成功
 *        IDecode(string sStockCode)之后使用.
 *               
 */
//////////////////////////////////////////////////////////////////////////////
/*        int IGetAllStockCode(int nStockIndex , StringBuilder sStockCode)
 *        参数 : nStockIndex , 0 开始的索引,每次加1.
 *               sStockCode , 返回的股票代码.
 *        返回值: -1 结束
 *                >= 0 继续
 *        IReadFile(string sFileName, int nDataType)之后使用.
 *        这个函数可以历遍当前文件包含的股票代码.
 */
//////////////////////////////////////////////////////////////////////////////
/*        int IGetDataType();
 *        返回值:当前读取的文件的数据类型,可能是1,2,3,4之一.
 *               看public enum DZH70_DECODE_DATATYPE.
 *        IReadFile(string sFileName, int nDataType)之后使用.
 */
//////////////////////////////////////////////////////////////////////////////
/*        int IWriteCodeToText(string sFileName);
 *        参数:sFileName , 要写入代码的文件名.
 *        返回值:0 , 没有代码.
 *               -1, 写错误.
 *               1 ,成功
 *        IReadFile(string sFileName, int nDataType)之后使用.
 *        将读取的文件包含的股票代码写入文本文件
 *               
 */
///////////////////////////////////////////////////////////////////////////////
/*        int IWriteDataToText(string sFileName);
 *        参数:sFileName , 要写入数据的文件名,一般是股票代码做文件名
 *        返回值:0 , 没有数据.
 *               -1, 写错误.
 *               1 ,成功
 *        IDecode(string sStockCode)之后使用.
 *        将解压缩之后的数据写入文本文件
 *               
 */
///////////////////////////////////////////////////////////////////////////////
/*        IDebugDumpData(string sDumpPath, string sStockCode);
 *        参数:sDumpPath, 分割数据保存的目录.
 *             sStockCode,要分割的股票代码
 *        返回值:0 , 代码不存在.
 *               -1, 写错误.
 *               1 ,成功
 *        IReadFile(string sFileName, int nDataType)之后使用.
 *        这是解析文件格式时使用的函数,把一个股票的压缩数据分割出来,生成一个小文件,
 *        方便观察,没有其他用处
 */
///////////////////////////////////////////////////////////////////////////////
/*        IDebugCheckData(string sResultFileName);
 *        参数:sResultFileName, 检查结果保存的文本文件名
 *        返回值: -1, 写错误.
 *               1 ,成功
 *        IReadFile(string sFileName, int nDataType)之后使用.
 *        这是解析文件格式时使用的函数,对每个解压缩的股票数据进行检验,
 *        比如日期时间必须是合理的等,结果发现大智慧数据也有很多不合逻辑的地方,
 *        估计是历史数据如此,检查结果中有很多疑似错误,就是这些不合理的地方.
 *        比如最低价不是最低,分笔数据的挂单价格有相等的.后来发现这些不是解压缩错误, 
 *        是数据源本身如此.
 */

using System;
using System.Text;
using System.Runtime.InteropServices;

namespace Dzh70DecodeTest
{
    public enum DZH70_DECODE_DATATYPE
    {
        NONE = 0,
        DAY = 1,//日数据
        MIN5 = 2,//五分数据
        REPORTCPS = 3,//当天分笔数据
        PRP = 4,//历史分笔数据
    }
    [StructLayout(LayoutKind.Sequential, Pack = 2, Size = 48)]
    public struct TIME_70//日数据和五分数据等固定时间间隔的用这个结构
    {
        public int nDate;//数据日期,如20110908
        public int nTime;//数据时间,如093001,对日数据没意义
        public int nOpen;//开盘价
        public int nHigh;//最高价
        public int nLow;//最低价
        public int nClose;//手盘价
        public Int64 nVol;//成交量
        public Int64 nMoney;//成交额
        public int nUp;//涨家数,仅对大盘有意义
        public int nDown;//跌家数,仅对大盘有意义
    }
    [StructLayout(LayoutKind.Sequential, Pack = 2, Size = 176)]
    public struct TICK_70//分笔数据结构,Reportcps.dat和*.prp用这个结构
    {
        public int nDate;//数据日期,如20110908
        public int nTime;//数据时间,如093001
        public int nOpen;//本笔价格
        public Int64 nCurrentVol;//本笔成交量
        public Int64 nCurrentMoney;//本笔成交额
        public Int64 nTotalVol;//总成交量
        public Int64 nTotalMoney;//总成交额
        public int nBuySellFlag;//0 主动买, 1 主动卖
        public int nAskPriceBuy5;//买盘挂单价格5
        public int nAskPriceBuy4;//买盘挂单价格4
        public int nAskPriceBuy3;//买盘挂单价格3
        public int nAskPriceBuy2;//买盘挂单价格2
        public int nAskPriceBuy1;//买盘挂单价格1
        public int nAskPriceSell1;//卖盘挂单价格1
        public int nAskPriceSell2;//卖盘挂单价格2
        public int nAskPriceSell3;//卖盘挂单价格3
        public int nAskPriceSell4;//卖盘挂单价格4
        public int nAskPriceSell5;//卖盘挂单价格5

        public Int64 nAskVolBuy5;//买盘挂单量5
        public Int64 nAskVolBuy4;//买盘挂单量4
        public Int64 nAskVolBuy3;//买盘挂单量3
        public Int64 nAskVolBuy2;//买盘挂单量2
        public Int64 nAskVolBuy1;////买盘挂单量1,对于大盘,是总的委买手数,
        public Int64 nAskVolSell1;//卖盘挂单量1,对于大盘,是总的委卖手数
        public Int64 nAskVolSell2;//卖盘挂单量2
        public Int64 nAskVolSell3;//卖盘挂单量3
        public Int64 nAskVolSell4;//卖盘挂单量4
        public Int64 nAskVolSell5;//卖盘挂单量5

        public Int64 nOther64;//不知道
    }

    public class Dzh70DecodeDLL
    {
        const string m_sDllName = "Dzh70DecodeDemo.dll";

        [DllImport(m_sDllName, EntryPoint = "IDestroy")]
        public static extern void IDestroy();
        [DllImport(m_sDllName, EntryPoint = "IGetDzhMainPath")]
        public static extern void IGetDzhMainPath(StringBuilder sMainPath);
        
        [DllImport(m_sDllName, EntryPoint = "IReadFile")]
        public static extern int IReadFile(string sFileName, int nDataType);
        [DllImport(m_sDllName, EntryPoint = "IDecode")]
        public static extern int IDecode(string sStockCode);

        [DllImport(m_sDllName, EntryPoint = "IGetDecodeData")]
        public static extern int IGetDecodeData(ref byte pResult);//实际传递的是字节数组的第一个地址
        [DllImport(m_sDllName, EntryPoint = "IGetDecodeData")]
        public static extern int IGetDecodeData(ref TIME_70 pTime70);//实际传递的是字节数组的第一个地址
        [DllImport(m_sDllName, EntryPoint = "IGetDecodeData")]
        public static extern int IGetDecodeData(ref TICK_70 pTick70);//实际传递的是字节数组的第一个地址

        [DllImport(m_sDllName, EntryPoint = "IGetPriceMode")]
        public static extern int IGetPriceMode();
        [DllImport(m_sDllName, EntryPoint = "IGetVolMode")]
        public static extern int IGetVolMode();
        [DllImport(m_sDllName, EntryPoint = "IGetDataType")]
        public static extern int IGetDataType();

        [DllImport(m_sDllName, EntryPoint = "IGetCurrentStockCode")]
        public static extern int IGetCurrentStockCode(StringBuilder sStockCode);
        [DllImport(m_sDllName, EntryPoint = "IGetAllStockCode")]
        public static extern int IGetAllStockCode(int nStockIndex, StringBuilder sStockCode);
        [DllImport(m_sDllName, EntryPoint = "IGetErrorInfo")]
        public static extern int IGetErrorInfo(StringBuilder sErrorInfo);
        [DllImport(m_sDllName, EntryPoint = "IWriteCodeToText")]
        public static extern int IWriteCodeToText(string sFileName);
        [DllImport(m_sDllName, EntryPoint = "IWriteDataToText")]
        public static extern int IWriteDataToText(string sFileName);
        

        [DllImport(m_sDllName, EntryPoint = "IDebugDumpData")]
        public static extern int IDebugDumpData(string sDumpPath, string sStockCode);
        [DllImport(m_sDllName, EntryPoint = "IDebugCheckData")]
        public static extern int IDebugCheckData(string sResultFileName);

        public static object GetObject(ref byte[] bByte, int nPos, Type type)
        {
            try
            {
                int nStructLen = Marshal.SizeOf(type);
                if (bByte == null || (nPos + nStructLen) > bByte.Length)
                    return null;
                IntPtr pStructPtr = Marshal.AllocHGlobal(nStructLen);
                Marshal.Copy(bByte, nPos, pStructPtr, nStructLen);
                object cObject = Marshal.PtrToStructure(pStructPtr, type);
                Marshal.FreeHGlobal(pStructPtr);
                //返回结构体
                return cObject;
            }
            catch
            {
            }
            return null;
        }
    }
}

 

Useful links

大智慧预警从窗口获取预警数据(c#)

https://github.com/Joysing/StockWarningListener/blob/9d787efebedd26c8dffdb1b3f3c55f39fc0438c1/StockWarningListener/DZH_Warning.cs