QuickFix Java 讲解(五)消息的收发与查看

本系列力求手把手教你怎样利用 QuickFix Java 搭建自己的 FIX 协议收发平台,以及其中的注意事项。

所有源码的地址(免费):

https://github.com/zongzhec/QuickFixPractise

 

这节我们讨论将Acceptor和Initiator启动以后,收到的消息极其查看方式。

6. 收发双方的通信

6.1. 启动后的通信和登录

为方便起见,这里我们使用统一的源码:https://github.com/zongzhec/QuickFixPractise

注意:请参照上一篇的方法配置你的IP地址,端口,和收发双方的ID!

启动acceptor之后,会调用onCreate方法,随后系统便会开启监听状态。

QuickFix Java 讲解(五)消息的收发与查看_第1张图片

 

启动Initiator之后,基本也是一样。我们可以让Initiator率先发起通信,发送一个35=V的信息。这个时候就会调用toApp方法,因为具体信息的传输是应用层的(Application)。

QuickFix Java 讲解(五)消息的收发与查看_第2张图片

 

随后我们看到在Admin层开始有消息的通信,具体表现为日志中出现了“fromAdmin” 和 “toAdmin” 字样。

Admin层的消息一般为登录登出,以及心跳活动。心跳的间隔设置在property文件中的HeartBtInt,单位是秒。

 

6.2. 协议消息的收发

在Initiator的代码中,我们让它率先发送一个MarketDataRequest(行情订阅)的信息:

    public void sendMarketDataRequest(SessionID sessionID) throws SessionNotFound {
        // 具体set哪些字段,参考你的FIX44.modified.xml
        MarketDataRequest req = new MarketDataRequest();
        req.set(new MDReqID("mockedMDReqID"));
        req.set(new SubscriptionRequestType('1'));

        // 重复组的设置
        MarketDataRequest.NoRelatedSym symGroup1 = new MarketDataRequest.NoRelatedSym();
        symGroup1.set(new Symbol("mockedSymbol1"));
        req.addGroup(symGroup1);

        MarketDataRequest.NoRelatedSym symGroup2 = new MarketDataRequest.NoRelatedSym();
        symGroup2.set(new Symbol("mockedSymbol2"));
        req.addGroup(symGroup2);

        System.out.println("Sending MarketDataRequest");
        Session.sendToTarget(req, sessionID);
    }

在第一章我们就说过,如果不用“暗号”,拼凑起来的通信字段将会非常长,比如一个MarketDataRequest就要好多字节,因此程序就回去查阅FIX44的字典,找到它对应的代码:

QuickFix Java 讲解(五)消息的收发与查看_第3张图片

上图中的msgtype=“V”就是那个“暗号”,而msgcat=“app”就代表这是一个app层的传输信息。因此在发送出的消息就会有35=V的识别符号:

上图中的问号小图标是IDE无法识别的分隔符,每一段的格式是X=Y的形式,X为字段代码编号,可以在字典中查到。Y为具体的数值。

 

如果是发送别的消息,形式也是一样,可以自行解析如下消息片段:

 

相应的,acceptor端会受到消息,因此它会调用“fromApp”方法:

 

6.3. 收到消息后的解析

acceptor端收到消息以后,会读取35字段中的值。比如上述的35=D,则会被解析为NewOrderSingle,也就是新订单。

解析完成后,acceptor就会去看用户有没有针对NewOrderSingle重写onMessage方法,在FixAcceptorApplication里:

    @Override
    public void onMessage(NewOrderSingle message, SessionID sessionID) throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
        System.out.println("Received NewOrderSingle: " + message + ", sessionID: " + sessionID);
        // 收都收了,解析一下
        System.out.println(String.format("clOrderID: %s, symbol: %s, side: %s",
                message.getClOrdID().getValue(),
                message.getSymbol().getValue(),
                message.getSide().getValue()));

        // 返还一个订单回复
        ExecutionReport executionReport = new ExecutionReport();
        executionReport.set(message.getClOrdID());
        executionReport.set(new ExecID("mockedExecID"));
        executionReport.set(message.getSide());
        executionReport.set(message.getSymbol());
        try {
            Session.sendToTarget(executionReport, sessionID);
        } catch (SessionNotFound sessionNotFound) {
            sessionNotFound.printStackTrace();
        }
    }

重写之后就能进行自定义的解析,比如输出关键字:

 

如果没有重写此方法,就什么也不做。因此我建议大家至少重写以下方法:

public void onMessage(Reject message, SessionID sessionID)

public void onMessage(BusinessMessageReject message, SessionID sessionID)

 

6.4. 其他查看消息的方式

有人问:粽子君,我的代码是部署在服务器上的,怎么查看收发的消息呢?

——还是在properties文件里:

FileStorePath=fileStore
FileLogPath=log

在fileStore里,主要存储真是传输中的消息头、消息体,和当下的消息序列号。如果序列号对不上,消息就会被废弃或者拒收。

在log里,分为两种文件:一种是event,来记录消息和事件。一种是message,记录消息本身。

新建项目的时候,要确保程序对上述两个文件的地址有写入权限。

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(QuickFIX,java,quickfix)