我是FIX协议和QuickFIX的新手。在我能够成功运行官方QuickFIX repo中的tradingclient
示例后,我尝试构建自己的类(启动器)。一切似乎都很顺利,直到我向服务器发送了一个MarketDataRequest
。之后,服务器没有响应。也没有例外。
我知道我的配置文件是正确的,因为正式的例子可以工作,并返回具有相同配置文件的市场数据。连接也是完整的,因为我可以看到心跳在指定的时间间隔通过。我可能做错了什么?
这是我的类头文件-FIXTrader.h
#pragma once
#include <quickfix/Session.h>
#include <quickfix/MessageCracker.h>
#include <quickfix/Values.h>
#include <quickfix/Mutex.h>
#include <quickfix/fix43/MarketDataRequest.h>
#include <queue>
namespace FIX
{
class FIXTrader: public Application, MessageCracker
{
public:
virtual ~FIXTrader() {};
void run();
private:
void onCreate(const SessionID&);
void onLogon(const SessionID&);
void onLogout(const SessionID&);
void toAdmin(Message&, const SessionID&);
void toApp(Message&, const SessionID&)
throw(DoNotSend);
void fromAdmin(const Message&, const SessionID&)
throw(FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon);
void fromApp(const Message&, const SessionID&)
throw(FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType);
void onMessage(const FIX43::ExecutionReport&, const FIX::SessionID&);
void onMessage(const FIX43::OrderCancelReject&, const FIX::SessionID&);
void onMessage(const FIX43::MarketDataRequest&, const FIX::SessionID&);
void onMessage(const FIX43::MarketDataRequestReject&, const FIX::SessionID&);
FIX43::MarketDataRequest queryMarketDataRequest43();
void queryHeader(FIX::Header& header);
};
}
#pragma comment(lib, "ws2_32.lib")
以下是我的FIXTrader.cpp
的相关部分(如果需要,我愿意添加更多):
void FIX::FIXTrader::onMessage
(const FIX43::ExecutionReport&, const FIX::SessionID&) {}
void FIX::FIXTrader::onMessage
(const FIX43::OrderCancelReject&, const FIX::SessionID&) {}
void FIX::FIXTrader::onMessage
(const FIX43::MarketDataRequest&, const FIX::SessionID&)
{
std::cout << "request success" << std::endl;
}
void FIX::FIXTrader::onMessage
(const FIX43::MarketDataRequestReject&, const FIX::SessionID&)
{
std::cout << "request rejected" << std::endl;
}
FIX43::MarketDataRequest FIX::FIXTrader::queryMarketDataRequest43()
{
FIX::MDReqID mdReqID("MARKETDATAID");
FIX::SubscriptionRequestType subType(FIX::SubscriptionRequestType_SNAPSHOT_PLUS_UPDATES);
FIX::MarketDepth marketDepth(0);
FIX43::MarketDataRequest::NoMDEntryTypes marketDataEntryGroup;
FIX::MDEntryType mdEntryType(FIX::MDEntryType_BID);
marketDataEntryGroup.set(mdEntryType);
FIX43::MarketDataRequest::NoRelatedSym symbolGroup;
FIX::Symbol symbol("EURUSD.x");
symbolGroup.set(symbol);
FIX43::MarketDataRequest message(mdReqID, subType, marketDepth);
message.addGroup(marketDataEntryGroup);
message.addGroup(symbolGroup);
queryHeader(message.getHeader());
std::cout << message.toXML() << std::endl;
std::cout << message.toString() << std::endl;
return message;
}
void FIX::FIXTrader::run()
{
try
{
FIX::Message md = queryMarketDataRequest43();
std::cout << "Sending marketrequest" << std::endl;
std::cout << "sendToTarget() => " << FIX::Session::sendToTarget(md) << std::endl;
std::cout << "Sent marketrequest" << std::endl;
while (_getwch() != 126);
}
catch (std::exception& e)
{
std::cout << "Message Not Sent: " << e.what();
}
}
下面是我的main
函数:
#include "FixTrader.h"
#include <quickfix/FileStore.h>
#include <quickfix/FileLog.h>
#include <quickfix/SocketInitiator.h>
#include <quickfix/SessionSettings.h>
#include <quickfix/config.h>
// #include "quickfix/Application.h"
int main(int argc, char** argv)
{
try
{
if (argc < 2) return 1;
std::string fileName = argv[1];
FIX::SessionSettings settings(fileName);
FIX::FIXTrader trader_app;
FIX::FileStoreFactory storeFactory(settings);
FIX::FileLogFactory logFactory(settings);
FIX::SocketInitiator initiator
(trader_app, storeFactory, settings, logFactory /*optional*/);
initiator.start();
trader_app.run();
initiator.stop();
return 0;
}
catch (FIX::ConfigError& e)
{
std::cout << e.what();
return 1;
}
}
下面是我尝试运行构建时的输出:
C:\fix_trader\Release>fix_trader.exe configfile.txt
<message>
<header>
<field number="8"><![CDATA[FIX.4.3]]></field>
<field number="35"><![CDATA[V]]></field>
<field number="49"><![CDATA[***]]></field>
<field number="56"><![CDATA[****]]></field>
</header>
<body>
<field number="146"><![CDATA[1]]></field>
<field number="262"><![CDATA[MARKETDATAID]]></field>
<field number="263"><![CDATA[1]]></field>
<field number="264"><![CDATA[0]]></field>
<field number="267"><![CDATA[1]]></field>
<group>
<field number="55"><![CDATA[EURUSD.x]]></field>
</group>
<group>
<field number="269"><![CDATA[0]]></field>
</group>
</body>
<trailer>
</trailer>
</message>
8=FIX.4.3 9=79 35=V 49=*** 56=**** 146=1 55=EURUSD.x 262=MARKETDATAID 263=1 264=0 267=1 269=0 10=223
Sending marketrequest
OUT: 8=FIX.4.3 9=109 35=V 34=5 49=*** 52=20220924-07:35:58.000 56=**** 146=1 55=EURUSD.x 262=MARKETDATAID 263=1 264=0 267=1 269=0 10=184
sendToTarget() => 1
Sent marketrequest
fromAdmin: 8=FIX.4.3 9=62 35=A 34=1 49=**** 52=20220924-07:35:58.404 56=*** 98=0 108=30 10=234
Logon successful! Session ID: FIX.4.3:***->****
fromAdmin: 8=FIX.4.3 9=50 35=0 34=2 49=**** 52=20220924-07:36:28.662 56=*** 10=194
fromAdmin: 8=FIX.4.3 9=50 35=0 34=3 49=**** 52=20220924-07:36:58.682 56=*** 10=200
fromAdmin: 8=FIX.4.3 9=50 35=5 34=4 49=**** 52=20220924-07:37:06.188 56=*** 10=201
Logged out from session: FIX.4.3:***->****
任何帮助都是感激不尽的。
2条答案
按热度按时间2guxujil1#
我终于明白了为什么它不起作用。一旦理解了这是一个愚蠢的错误。
我只需要包含
MarketDataSnapshotFullRefresh
(或者我请求的任何快照类型),并适当地重载onMessage
回调方法。在这里分享给任何人谁可能会发现这在未来有帮助。
因为我没有重载,所以看起来来自交易对手的响应就像是消失在虚空中一样,现在重载的函数捕获市场数据并将其发送给我的
fromApp
回调函数。to94eoyn2#
为什么不工作?
您正在发送MarketDataRequest,然后才实际逻辑连接到对方会话。请注意,您的消息是在07:35:58:000发送的,但FIXSession在404毫秒后连接:07点35分48.404秒。
尽管套接字已连接,但在双方交换35=A(LOGON消息)之前,您并未与对方建立逻辑连接(固定协议)。* 您可以在此处找到详细信息:https://javarevisited.blogspot.com/2011/02/fix-protocol-session-or-admin-messages.html#axzz7jSDzNMdi*
这就是对方未收到您的市场数据请求的原因。
您的市场数据请求
对方在您逻辑连接后404毫秒确认登录/连接。然后,您发送并接收35=0,HeartBeat。
然后,对方发送了注销请求,以断开您的应用。