量化之行,始于数据

Posted AlgoPlus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了量化之行,始于数据相关的知识,希望对你有一定的参考价值。

机会和风险相关的全部信息都蕴藏于数据之中”是一个量化交易员的基础信仰。

所以,一直以来我都有一个执念,就是想要收集全市场的实时交易数据。

国内有三家股票交易所、四家期货交易,共所涉及数万个标的,包括股票、债券、基金、指数、期货、期权等。

交易时段,全市场实时交易数据流就像一座开闸泄洪的水坝,想以优雅的姿态站在下游转存这些数据,并没有想象中那么简单。

经过数次迭代更新,终于实现了一个自己还算满意的方案。未来希望能从这些数据中发现更多有趣的事情。

标的

首先,就是要明确当前市场有哪些在交易的标的。

期货合约有固定的开始和结束时间,期权的合约还会根据行情变化随时加挂,股票虽然相对稳定,但也有新股上市的情况。

好在,TraderApi提供了查询全部标的列表的功能。虽然,我觉得这个查询应该放在MdApi中,但是官方这样设计,我们也就只能这样用。

int ReqQryInstrument(CThostFtdcQryInstrumentField *pQryInstrument, int nRequestID) = 0;

要用TraderApi,就要完成创建实例、连接柜台、看穿式认证、登录等一系列操作。

查询到全部标的之后,根据交易所标的类别分类存储,方便后续根据交易所或者类别查询到相关标的。

证券交易所有,上交所、深交所和北交所。期货交易所有,中金所、上期所、上能所、大商所、郑商所。

标的类别就比较多了,包括期货、期权、股票、基金、债券、指数等。

实时行情

接下来,需要使用MdApi订阅全部标的的实时行情。

MdApi收到推送的实时行情时会调用OnRtnDepthMarketData方法,所以,我们就需要把逻辑写到这个方法中。

由于订阅的标的比较多,要避免在这里进行效率比较低的操作,例如io。

我最初使用的方案是,把数据拷贝之后存放到list中:

void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketDataField)

    CThostFtdcDepthMarketDataField *pCopy = new CThostFtdcDepthMarketDataField;
    memcpy(pCopy, pDepthMarketDataField, sizeof(CThostFtdcDepthMarketDataField));
    std::lock_guard<std::mutex> lock(m_mutex);
    m_lDataList.push_back(pCopy)

在另一个线程中从list将数据取出来写进文件中或者存入数据库中:

void process()

    CThostFtdcDepthMarketDataField *pData = NULL;
    
        std::lock_guard<std::mutex> lock(m_mutex);
        if (m_lDataList.size() > 0)
        
            pData = m_lDataList.front();
        
    
    
    if (NULL != pData)
    
        saveToFile(pData);
        delete pData;
        std::lock_guard<std::mutex> lock(m_mutex);
        m_lDataList.pop_front();
    

还有一种更高效的方案就是使用mmap将文件映射进内存,直接将收到的行情拷贝到映射出来的内存地址:

void OnRtnDepthMarketData(CThostFtdcDepthMarketDataField *pDepthMarketDataField)

    m_pMMAPWriter->write(pDepthMarketDataField);

但是,需要维护写入地址的指针,以及可能存在扩展文件等问题,所以,也相对比较复杂。

数据处理

当然,这一步并不需要实时来做。只要有tick数据源,随时可以处理需要的数据。

为了省去盘后的麻烦,我选择了实时合成1分钟K线数据、日线数据、期货加权指数,以及一些我感兴趣的组合价格数据。

K线的逻辑比较简单:

if (bIsMinuteStart)

    Open = pData->LastPrice;
    High = pData->LastPrice;
    Low = pData->LastPrice;
    Close = pData->LastPrice;

else

    Close = pData->LastPrice;
    if (Close > High)
    
        High = pData->LastPrice;
    
    if (Close < Low)
    
        Low = pData->LastPrice;
    

当然,还可以根据需要计算其他数据,例如,成交量、均价等。

期货加权指数价格,是把某一个品种所有月份合约的价格以持仓量为权重计算出来的均价。

组合价格则是按照一个公式计算出来的价格,例如:a*IC2210 + b*IC2210,通常a为1,b为-1。

线程管理

最后,实践中发现,为了提交效率,需要多个MdApi实例分别完成订阅任务。另外,程序可能会部署在多台服务器上同时运行。

这就要求能够通过配置文件分配订阅任务。

这也是前面提到的要根据交易所标的类别分类的主要目的。

//上期所期货
#define ENUM_DataFlag_SHFEFuture 'a'
//上期所期权
#define ENUM_DataFlag_SHFEOption 'b'
//上能所期货
#define ENUM_DataFlag_INEFuture 'c'
//上能所期权
#define ENUM_DataFlag_INEOption 'd'
……

如果配置DataFlaga,c,就表示这个实例负责订阅上期所和上能所的期货行情。

因为对数据处理部分的实时性没有太高的要求,所以我只使用了一个线程按照顺序读取所有行情实例写到本地的数据,合成k线、期货指数、组合价格,然后写入数据库,最后记录日志。

系统启动之后就用N个MdApi线程+1个数据处理线程。

千里之行始于足下,黑客之路始于--黑客内参

现在国内的互联网事业在蓬勃的发展。与之相呼应的就是黑客事业也在快速的发展,现在的年轻人几乎人人都有一个成为黑客的梦想。
 
而我也特别的喜欢关注关注黑客类信息,但是现在的黑客网站就像雨后春笋一般种类繁多,质量也是参差不齐。
 
技术分享
 
而在媒体的报道中黑客总是那么的神奇,那么的无所不能。
 
他们认为供职与各个大型网络公司的IT人员都是黑客。
 
其实这么说是不对的,供职于各大网络安全公司或企业安全部门的白帽黑客,工作包括监测漏洞、查杀木马、修复系统。
 
技术分享
 
从虚拟世界里不守规则、四处捣乱的不羁青年,变成谨守行业规则、安分守己的极客,是很多人都曾经历的一个过程。作为交换,他们所服务的机构会给他们提供一个安全的身份,一个享有最大程度攻击自由的平台,以及一份不错的薪水。
 
这样的人只能称之为程序员或者更高级一点的网络工程师,但决不是黑客。而真正的黑客我也只是自黑客内参里面见过!
 
技术分享
 
真正地黑客是有自己的文化特质的。
 
成为具备这些特质的人才能成为黑客。
 
而黑客们都是大师。
 
他们能够有助于你的学习,给你提供源源不断的动力。
 
如果你也想成为一名黑客,最重要的一点就是模仿他们精神,情感,模仿他们身上的具有创造性的艺术气息。
 
就像黑客论坛之所以能够成为黑客们聚集地,有一点最重要的就是这里面不光是探讨技术的集合地,也是大家抒写情怀的平台!
 
而这样的一个平台,除了探讨技术之外,还会把大家讨论出来的技术精华进行结合总衲,以帮助后来人学习,所以黑客内参才会这么的火爆,而这个也正是黑客内参的黑客精神!



以上是关于量化之行,始于数据的主要内容,如果未能解决你的问题,请参考以下文章

VTM10.0量化之一般量化技术

VTM10.0量化之一般量化技术

VTM10.0量化之一般量化技术

R语言量化投资常用包总结

[转载]Python量化交易平台开发教程系列1-类CTP交易API的工作原理

量化交易期货ctp使用说明(企业版,穿透式监管)(值得收藏)