in src/dxapi-tests.cpp [671:841]
bool test_l2msg_fmt2(TickDb& db) {
//static const uintptr_t preloadSize = 35000000;
static const uintptr_t preloadSize = 24000000;
enum MsgType { UNKNOWN = 0, LEVEL2ACTION, L2MESSAGE, LEVEL2MESSAGE };
const char *messageNames[] = { "Unknown", "deltix.qsrv.hf.pub.Level2Action",
"deltix.qsrv.hf.pub.L2Message", "deltix.qsrv.hf.pub.Level2Message"
};
class Level2Action {
int level; // int8, non-nullable
bool isAsk; // boolean, non-nullable
int action; // enum 0..2
double price; // Float 64, nullable
double size; // Float 64, nullable
int numOfOrders; // int32, nullable
bool has_price, has_size, has_numOfOrders;
public:
inline void readFrom(DataReader& reader)
{
#define READER reader
READ(level, Int8);
READ(isAsk, Boolean);
READ(action, Enum8); // TODO:
READ_NULLABLE(price, Float64);
READ_NULLABLE(size, Float64);
READ_NULLABLE(numOfOrders, Int32);
}
virtual std::string toString() const
{
char tmp[0x1000];
sprintf(tmp, "\n\t%1d %c %c %lf %lf %d", level, "BA??"[isAsk], "_+*-???"[action + 1], price, size, has_numOfOrders ? numOfOrders : -1);
return std::string(tmp);
}
};
class L2Message : public MarketMessage {
vector<Level2Action> actions;
std::string exchangeCode;
bool isImplied, isSnapshot;
int64_t sequenceId;
bool has_actions, has_exchangeCode, has_sequenceId;
public:
inline void readFrom(DataReader &reader)
{
READ_NULLABLE(originalTimestamp, Timestamp);
READ_NULLABLE(currencyCode, Int16);
READ_NULLABLE(sequenceNumber, Int64);
intptr_t count;
//{ reader.skipArray(); return; }
count = reader.readArrayStart();
has_actions = false;
if (count >= 0) {
has_actions = true;
actions.resize(count);
for (intptr_t i = 0; i < count; ++i) {
if (reader.readObjectStart() >= 0) {
Level2Action act;
act.readFrom(reader);
actions[i] = act;
reader.readObjectEnd();
}
}
READ_NULLABLE2(exchangeCode, Alphanumeric, 10);
READ(isImplied, Boolean);
READ(isSnapshot, Boolean);
READ_NULLABLE(sequenceId, Int64);
reader.readArrayEnd();
}
}
virtual std::string toString() const
{
char tmp[0x1000];
sprintf(tmp, " currency: %d, actions(%d): ", (int)currencyCode, (int)actions.size());
std::string s = MarketMessage::toString().append(tmp);
for (intptr_t i = 0, count = actions.size(); i < count; ++i) {
s/*.append(i ? "," : "")*/.append(actions[i].toString());
}
return s;
}
};
class Level2Message : public MarketMessage {
double price; // Float 64, nullable
double size; // Float 64, nullable
std::string exchangeCode; // Alpha(10), nullable
int8_t depth; // int8, nullable
bool isAsk; // boolean, non-nullable
int action; // enum 0..2
bool _isLast; // boolean, non-nullable
int numOfOrders; // int32, nullable
bool has_exchangeCode, has_price, has_size, has_depth, has_action, has_numOfOrders;
public:
inline void readFrom(DataReader &reader)
{
READ_NULLABLE(originalTimestamp, Timestamp);
READ_NULLABLE(currencyCode, Int16);
READ_NULLABLE(sequenceNumber, Int64);
READ_NULLABLE(price, Float64);
READ_NULLABLE(size, Float64);
READ_NULLABLE2(exchangeCode, Alphanumeric, 10);
READ_NULLABLE(depth, Int8);
READ(isAsk, Boolean);
READ(action, Enum8);
READ(_isLast, Boolean);
READ_NULLABLE(numOfOrders, Int32);
}
virtual std::string toString() const
{
return MarketMessage::toString().append("Price: ").append(::toString(price));
}
};
SelectionOptions opt;
//TickStream stream = db.getStream("l2msg");
unique_ptr<TickStream>pstream(db.getStream("l2msg4"));
TickStream &stream = *pstream;
unique_ptr<TickCursor> pCursor(stream.select(TIMESTAMP_NULL, opt, NULL, NULL));
TickCursor &cursor = *pCursor;
for (intptr_t i = 0; i < COUNTOF(messageNames); ++i)
cursor.registerMessageType((unsigned)i, messageNames[i]);
#ifdef PRELOAD
preload(cursor, preloadSize, 0x400);
#endif
//MessageHeader msg;
MarketMessage marketMessage; // We are using this as a default type
Level2Action l2Action;
L2Message l2Message;
Level2Message level2Message;
START_TEST(L2Msg2);
DataReader &reader = cursor.getReader();
marketMessage.cursor = &cursor;
// Note: C++ API is not a priority, it will be made better-looking, but that code is not useful for Managed API, so it is not written yet.
while (cursor.next(&marketMessage) && nMessagesRead < 5000000) {
switch (marketMessage.typeIdLocal) {
case L2MESSAGE:
l2Message.copyHeaderFrom(marketMessage);
l2Message.readFrom(reader);
PRINT(l2Message.toString().c_str());
break;
case LEVEL2MESSAGE:
level2Message.copyHeaderFrom(marketMessage);
level2Message.readFrom(reader);
PRINT(level2Message.toString().c_str());
break;
default:
printf("Unknown message <%s>. id: %d -> localId: %d", marketMessage.getTypeName()->c_str(), (int)marketMessage.typeId, (int)marketMessage.typeIdLocal);
//puts(marketMessage.toString().c_str());
}
// Print contents
//puts(msg->toString().c_str());
++nMessagesRead;
}
END_READING(L2Msg2);
return true;
}