您的位置:首页 > 产品设计 > UI/UE

【转】编译quickfast解析库(沪深level2行情转码库)

2016-07-17 20:53 465 查看
转自http://blog.csdn.net/hacode/article/details/7065889

编译quickfast解析库(沪深level2行情转码库)

目录(?)[-]

1 下载源代码

2 下载第三方库和配置脚本

1 下载activeperl

2 下载mpc

3 下载boost

4 下载xerces

5 配置脚本

3 生成项目文件

4 编译生成QuickFast库

5 样例程序文档

6 行情解码例子程序

7 行情解码的几个主要步骤

1 构造xml解析对象

2 解析xml模板生成fast模板

3 创建一个decoder对象

4 实现一个消息消费者并且注册给解码器

5 开始解码

6实现消息消费者接口

7 消费消息的过程就是消息的格式化过程

8 输出

8 资源下载

为了方便大家编译和使用QuickFast库,我在GitHub上放置了一个v1.4版本的构建环境:

https://github.com/imharrywu/quickfast

包括了预编译的依赖库(boost, xcerces) 以及工程管理的MPC, 同时生成了一个预编译的库在Output\Release下。

说明一下,对1.4的构建环境稍作了修改:

1,使用MPC4.1,因为需要boost_system

2,全部使用了动态库,官方编译的时候,只有boost_thread使用动态库,感觉不太协调,所以统一全部是动态库.

3,需要boost_date_time, boost_chrono等。

详细步骤请直接看GitHub上的README.md

1) 下载源代码

下载quickfast项目(windows平台):

http://quickfast.googlecode.com/files/quickfast_win_src_1_4.zip

公布一个QQ群:229609210 同行们可以申请加入一起讨论。

2) 下载第三方库和配置脚本

2.1) 下载activeperl

(google it)

2.2) 下载mpc

http://www.ociweb.com/products/mpc

2.3) 下载boost

(google it)

2.4) 下载xerces

http://xerces.apache.org/xerces-c/

2.5) 配置脚本

下载 行情转码库的配置脚本setup.bat(gif文件另存为zip,解压可以得到bat文件)

http://hi.csdn.net/attachment/201112/13/0_1323743665laAL.gif

setup.bat配置脚本设置三方库路径和编译器选项

[cpp] view plain copy







@REM 1) Customize this file by setting variables to suit your environment

@REM 2) Also you should customize QuickFAST.features to enable particular features on your system.

@REM 3) Delete the following line when you finishing customizing this file.

@REM [==DELETED==]echo See remarks in %0 for information about setting your build environment

@REM 4) And, then run the `m.cmd' to generate *.sln & *.vcproj files

@echo off

REM =====================================================================================

REM EDIT THE FOLLOWING LINES OR SET THESE VALUES IN YOUR ENVIRONMENT BEFORE RUNNING SETUP

if "a" == "a%MPC_ROOT%" set MPC_ROOT=H:\workspace\qf\MPC

if "a" == "a%XERCES_ROOT%" set XERCES_ROOT=H:\workspace\qf\xerces-c-3.1.1-x86-windows-vc-8.0

if "a" == "a%XERCES_LIBNAME%" set XERCES_LIBNAME=xerces-c_3

if "a" == "a%BOOST_VERSION%" set BOOST_VERSION=boost_1_47_0

if "a" == "a%BOOST_ROOT%" set BOOST_ROOT=H:\workspace\qf\%BOOST_VERSION%

REM END OF VALUES TO BE SET

REM =====================================================================================

注意:boost默认编译出来的include和lib不在同一个目录下,需要move一下。



3) 生成项目文件

在vc的命令行下,运行这个setup.bat && m.bat就可以生成QuickFast.sln

4) 编译生成QuickFast库

vs2008打开QuickFast.sln编译连接,生成的文件在Output目录的相应配置文件夹下。

5) 样例程序文档

这个解决方案提供了很多例子,最简单的是TutorialApplication和InterpretApplication这2个例子。

也可以用doxygen生成文档。

http://hi.csdn.net/attachment/201112/26/0_1324861393eteG.gif

6) 行情解码例子程序

楼主用Codecs::SynchronousDecoder(同步解码器,官方例子使用的是异步解码器) 实现了一个简单的解码封装DLL,通过tcp socket从上游数据源获取fast的码流并且解码。

同行们你们主要参考 RunDecoderLoop(...)函数内部的行情解码步骤

这个dll的其他代码都可以忽略, 主要关注 《第七节 行情解码的几个主要步骤》 的内容。

这个例子是一个dll库,导出了一个API,这个API以市场代码等为参数(上海市场解码,或者深圳市场解码),开始各个市场的解码。

同时这个API接受一组回调接口来通知数据消费者来处理解码后的行情数据, 参看 IDataExInterface 定义。

建议大家把2个市场的解码放在2个线程里面,最好分别在2个机房里面。

FAST码流是剥掉了STEP协议头以后STEP协议BODY部分用FAST编码过的内容。

Fast_Steam = Fast(STEP_PACKET -STEP_HEAD) =Fast(STEP_BODY)

导出库的头文件

[cpp] view plain copy







#ifdef __cplusplus

extern "C"

{

#endif

enum MarketTag

{

ShenzhenMarket = 0,

ShanghaiMarket = 1,

};

[cpp] view plain copy







struct IDataExInterface /*解码以后的数据通过接口中的pNotify接口来通知客户端更新数据*/

{

void (__stdcall * pfnFeedStatus)(ConnectionStatus connStatus);

// 上海的行情数据通知接口

void (__stdcall * pfnFeed_SHFAST30_UA3202)(const SHFAST30_UA3202_t * );

void (__stdcall * pfnFeed_SHFAST30_UA3201)(const SHFAST30_UA3201_t * );

void (__stdcall * pfnFeed_SHFAST30_UA3113)(const SHFAST30_UA3113_t * );

// 深圳的行情数据通知接口

void (__stdcall * pfnFeed_SZFAST_103)(const SZFAST_103_t *);

void (__stdcall * pfnFeed_SZFAST_202)(const SZFAST_202_t *);

void (__stdcall * pfnFeed_SZFAST_201)(const SZFAST_201_t *);

void (__stdcall * pfnFeed_SZFAST_104)(const SZFAST_104_t *);

};

[cpp] view plain copy







FASTDECODER_API

int RunDecoderLoop(const char * pIp

, unsigned short nPort

, MarketTag nMarketTag

, const char * templateFileName

, const struct IDataExInterface * pNotify

);

#ifdef __cplusplus

};

#endif

客户端可以这样调用DLL

[cpp] view plain copy







void Level2Thread(void * arg) // 把各个市场的解码放在各自的线程里面

{

MarketTag nMarketTag = static_cast<MarketTag>((int)arg);

IDataExInterface * pNotify = new IDataExInterface;

memset(pNotify, 0, sizeof(IDataExInterface));

pNotify->pfnFeedStatus = FeedStatus; // 用于报告解码状态的回调

switch (nMarketTag)

{

case ShenzhenMarket:

{

SetThreadAffinityMask(GetCurrentThread(), 1);

pNotify->pfnFeed_SZFAST_103 = Feed_SZFAST_103;

pNotify->pfnFeed_SZFAST_104 = Feed_SZFAST_104;

pNotify->pfnFeed_SZFAST_201 = Feed_SZFAST_201;

pNotify->pfnFeed_SZFAST_202 = Feed_SZFAST_202;

RunDecoderLoop( // 在该线程里面开始深圳市场解码

"127.0.0.1", 1111

, MarketTag(ShenzhenMarket)

, ".\\fasttemplates_2.00.xml"

, pNotify);

} break;

case ShanghaiMarket:

{

SetThreadAffinityMask(GetCurrentThread(), 2);

pNotify->pfnFeed_SHFAST30_UA3113 = Feed_SHFAST30_UA3113;

pNotify->pfnFeed_SHFAST30_UA3201 = Feed_SHFAST30_UA3201;

pNotify->pfnFeed_SHFAST30_UA3202 = Feed_SHFAST30_UA3202;

RunDecoderLoop( // 在该线程里面开始上海市场解码

"127.0.0.1", 2222

, MarketTag(ShanghaiMarket)

, ".\\template.2.03.xml"

, pNotify);

} break;

}

return ;

}

/**

*

* 简单的开启两个市场的解码线程开始解码,

* 导出函数RunDecoderLoop是一个循环解码的阻塞调用过程,

* 所以放在2个独立的线程中。

*

**/ int main(int argc, char* argv[])

{

_beginthread(Level2Thread, 0, (void *)ShanghaiMarket);

_beginthread(Level2Thread, 0, (void *)ShenzhenMarket);

printf("Press any key to quit decoder.\n"); getchar();

return 0;

}

7) 行情解码的几个主要步骤

用Codecs::SynchronousDecoder解码fast的几个重要步骤

7.1) 构造xml解析对象

[cpp] view plain copy







/************************************************************************

*

* 全局的xml解析类

*

* 注意: 多线程同时构造parser会资源冲突

*

*

************************************************************************/

static Codecs::XMLTemplateParser parser;

7.2) 解析xml模板生成fast模板

[cpp] view plain copy







/////////////////////////////////////////////

// Parse the templates from the template file

// errors are reported by throwing exceptions

// which are caught below.

std::ifstream tmplFile(templateFileName, openMode);

Codecs::TemplateRegistryPtr registry;

try {

registry = parser.parse(tmplFile);

}catch (std::exception & e){

std::cerr << e.what() << std::endl;

return -1;

}

7.3) 创建一个decoder对象

[cpp] view plain copy







//////////////////////////////////////

// Create a sync decoder and

// setup attributes.

Codecs::SynchronousDecoder * pDecoder

= new Codecs::SynchronousDecoder(registry);

pDecoder->setHeaderBytes(0);

pDecoder->setResetOnMessage(false);

pDecoder->setLimit(0);

7.4) 实现一个消息消费者,并且注册给解码器

[cpp] view plain copy







//////////////////////////////////////

// Create an application object to use

// the incoming data. In this case to

// accept complete messages and interpret

// them to standard out.

CMessageConsumerImpl * pHandler

= new CMessageConsumerImpl(nMarketTag

, pNotify

, pDecoder);

//////////////////////////////////////

// and use the interpreter as the consumer

// of generic messages.

Codecs::GenericMessageBuilder builder(*pHandler);

7.5) 开始解码

接收网络数据包(放置在pFastBody, 长度位nBodyLength)

[cpp] view plain copy







pDataSource = new Codecs::DataSourceBuffer(pFastBody , pFastHeader->nBodyLength);

[cpp] view plain copy







try{

pDecoder->reset();

pDecoder->decode(*pDataSource, builder);

} catch (std::exception & e)

{

std::cout<<e.what()<<std::endl;

}

delete pDataSource;

pDataSource = NULL;

7.6)实现消息消费者接口

[cpp] view plain copy







/// @brief A message consumer that attempts to produce a human readable version

/// of a message that has been decoded by QuickFAST.

class CMessageConsumerImpl : public Codecs::MessageConsumer

重写消费消息函数

[cpp] view plain copy







virtual bool consumeMessage(Messages::Message & message);

7.7) 消费消息的过程就是消息的格式化过程

在消息的格式化过程中,主要是遍历Message的各个filed,如果field是

一般类型,直接转换成相应的值;如果是sequence和group,则需要将

field转换成sequence和group,遍历;另外,由于sequence里面的每一个

item也是一个Message结构,所以需要以Message的方式遍历结构的每一个成员;

[cpp] view plain copy







foreach(item in seq)

foreach(member in item)

7.8) 输出



8) 资源下载

=========================================================================

项目源文件下载

(将下面的gif链接另存为zip,解压->重命名->解压,有加密,确实有需要的朋友请留言获取)

=========================================================================

最新版本

version 2.0,修改了日志打印方式和配置文件加载quickfast-v2-[8n0].zip.png

http://hi.csdn.net/attachment/201112/27/0_132498087296Py.gif

历史版本

version 1.0,项目源文件Examples-8n0.zip

http://hi.csdn.net/attachment/201112/26/0_132486187064m4.gif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: