#ifndef FIX_FIELD
#define FIX_FIELD
#ifdef _MSC_VER
#pragma warning(disable : 4786)
#endif
#include "FieldConvertors.h"
#include "FieldNumbers.h"
#include "FieldTypes.h"
#include "Utility.h"
#include <numeric>
#include <sstream>
#if defined(__SUNPRO_CC)
#include <algorithm>
#endif
namespace FIX {
class FieldBase {
class field_metrics {
public:
field_metrics(const int length, const int checksum)
: m_length(length),
m_checksum(checksum) {}
int getLength() const { return m_length; }
int getCheckSum() const { return m_checksum; }
bool isValid() const { return m_length > 0; }
private:
int m_length;
int m_checksum;
};
friend class Message;
FieldBase(
int tag,
std::string::const_iterator valueStart,
std::string::const_iterator valueEnd,
std::string::const_iterator tagStart,
std::string::const_iterator tagEnd)
: m_tag(tag),
m_string(valueStart, valueEnd),
m_metrics(calculateMetrics(tagStart, tagEnd)) {}
public:
FieldBase(int tag, const std::string &string)
: m_tag(tag),
m_string(string),
m_metrics(no_metrics()) {}
virtual ~FieldBase() {}
FieldBase(const FieldBase &rhs)
: m_tag(rhs.getTag()),
m_string(rhs.m_string),
m_metrics(rhs.m_metrics) {}
FieldBase &operator=(const FieldBase &rhs) {
m_tag = rhs.getTag();
m_string = rhs.m_string;
m_metrics = rhs.m_metrics;
m_data.clear();
return *this;
}
void swap(FieldBase &rhs) {
std::swap(m_tag, rhs.m_tag);
std::swap(m_metrics, rhs.m_metrics);
m_string.swap(rhs.m_string);
m_data.swap(rhs.m_data);
}
void setTag(int tag) {
m_tag = tag;
m_metrics = no_metrics();
m_data.clear();
}
[[deprecated("Use setTag")]]
void setField(int field) {
setTag(field);
}
void setString(const std::string &string) {
m_string = string;
m_metrics = no_metrics();
m_data.clear();
}
int getTag() const { return m_tag; }
[[deprecated("Use getTag")]]
int getField() const {
return getTag();
}
const std::string &getString() const { return m_string; }
const std::string &getFixString() const {
if (m_data.empty()) {
encodeTo(m_data);
}
return m_data;
}
int getLength() const {
calculate();
return m_metrics.getLength();
}
int getTotal() const {
calculate();
return m_metrics.getCheckSum();
}
bool operator<(const FieldBase &field) const { return m_tag < field.m_tag; }
private:
void calculate() const {
if (m_metrics.isValid()) {
return;
}
m_metrics = calculateMetrics(getFixString());
}
void encodeTo(std::string &result) const {
size_t tagLength = FIX::number_of_symbols_in(m_tag);
size_t totalLength = tagLength + m_string.length() + 2;
result.resize(totalLength);
char *buf = (char *)result.c_str();
FIX::integer_to_string(buf, tagLength, m_tag);
buf[tagLength] = '=';
memcpy(buf + tagLength + 1, m_string.data(), m_string.length());
buf[totalLength - 1] = '\001';
}
static field_metrics no_metrics() { return field_metrics(0, 0); }
static field_metrics calculateMetrics(
std::string::const_iterator const start,
std::string::const_iterator const end) {
int checksum = 0;
for (std::string::const_iterator str = start; str != end; ++str) {
checksum += (unsigned char)(*str);
}
#if defined(__SUNPRO_CC)
std::ptrdiff_t d;
std::distance(start, end, d);
return field_metrics(d, checksum);
#else
return field_metrics(static_cast<int>(std::distance(start, end)), checksum);
#endif
}
static field_metrics calculateMetrics(const std::string &field) {
return calculateMetrics(field.begin(), field.end());
}
int m_tag;
std::string m_string;
mutable std::string m_data;
mutable field_metrics m_metrics;
};
inline std::ostream &operator<<(std::ostream &stream, const FieldBase &field) {
stream << field.getString();
return stream;
}
inline void swap(FieldBase &lhs, FieldBase &rhs) { lhs.swap(rhs); }
class StringField : public FieldBase {
public:
explicit StringField(int field, const std::string &data)
: FieldBase(field, data) {}
StringField(int field)
: FieldBase(field, "") {}
void setValue(const std::string &value) { setString(value); }
const std::string &getValue() const { return getString(); }
operator const std::string &() const { return getString(); }
bool operator<(const StringField &rhs) const { return getString() < rhs.getString(); }
bool operator>(const StringField &rhs) const { return getString() > rhs.getString(); }
bool operator==(const StringField &rhs) const { return getString() == rhs.getString(); }
bool operator!=(const StringField &rhs) const { return getString() != rhs.getString(); }
bool operator<=(const StringField &rhs) const { return getString() <= rhs.getString(); }
bool operator>=(const StringField &rhs) const { return getString() >= rhs.getString(); }
friend bool operator<(const StringField &, const char *);
friend bool operator<(const char *, const StringField &);
friend bool operator>(const StringField &, const char *);
friend bool operator>(const char *, const StringField &);
friend bool operator==(const StringField &, const char *);
friend bool operator==(const char *, const StringField &);
friend bool operator!=(const StringField &, const char *);
friend bool operator!=(const char *, const StringField &);
friend bool operator<=(const StringField &, const char *);
friend bool operator<=(const char *, const StringField &);
friend bool operator>=(const StringField &, const char *);
friend bool operator>=(const char *, const StringField &);
friend bool operator<(const StringField &, const std::string &);
friend bool operator<(const std::string &, const StringField &);
friend bool operator>(const StringField &, const std::string &);
friend bool operator>(const std::string &, const StringField &);
friend bool operator==(const StringField &, const std::string &);
friend bool operator==(const std::string &, const StringField &);
friend bool operator!=(const StringField &, const std::string &);
friend bool operator!=(const std::string &, const StringField &);
friend bool operator<=(const StringField &, const std::string &);
friend bool operator<=(const std::string &, const StringField &);
friend bool operator>=(const StringField &, const std::string &);
friend bool operator>=(const std::string &, const StringField &);
};
inline bool operator<(const StringField &lhs, const char *rhs) { return lhs.getValue() < rhs; }
inline bool operator<(const char *lhs, const StringField &rhs) { return lhs < rhs.getValue(); }
inline bool operator>(const StringField &lhs, const char *rhs) { return lhs.getValue() > rhs; }
inline bool operator>(const char *lhs, const StringField &rhs) { return lhs > rhs.getValue(); }
inline bool operator==(const StringField &lhs, const char *rhs) { return lhs.getValue() == rhs; }
inline bool operator==(const char *lhs, const StringField &rhs) { return lhs == rhs.getValue(); }
inline bool operator!=(const StringField &lhs, const char *rhs) { return lhs.getValue() != rhs; }
inline bool operator!=(const char *lhs, const StringField &rhs) { return lhs != rhs.getValue(); }
inline bool operator<=(const StringField &lhs, const char *rhs) { return lhs.getValue() <= rhs; }
inline bool operator<=(const char *lhs, const StringField &rhs) { return lhs <= rhs.getValue(); }
inline bool operator>=(const StringField &lhs, const char *rhs) { return lhs.getValue() >= rhs; }
inline bool operator>=(const char *lhs, const StringField &rhs) { return lhs >= rhs.getValue(); }
inline bool operator<(const StringField &lhs, const std::string &rhs) { return lhs.getValue() < rhs; }
inline bool operator<(const std::string &lhs, const StringField &rhs) { return lhs < rhs.getValue(); }
inline bool operator>(const StringField &lhs, const std::string &rhs) { return lhs.getValue() > rhs; }
inline bool operator>(const std::string &lhs, const StringField &rhs) { return lhs > rhs.getValue(); }
inline bool operator==(const StringField &lhs, const std::string &rhs) { return lhs.getValue() == rhs; }
inline bool operator==(const std::string &lhs, const StringField &rhs) { return lhs == rhs.getValue(); }
inline bool operator!=(const StringField &lhs, const std::string &rhs) { return lhs.getValue() != rhs; }
inline bool operator!=(const std::string &lhs, const StringField &rhs) { return lhs != rhs.getValue(); }
inline bool operator<=(const StringField &lhs, const std::string &rhs) { return lhs.getValue() <= rhs; }
inline bool operator<=(const std::string &lhs, const StringField &rhs) { return lhs <= rhs.getValue(); }
inline bool operator>=(const StringField &lhs, const std::string &rhs) { return lhs.getValue() >= rhs; }
inline bool operator>=(const std::string &lhs, const StringField &rhs) { return lhs >= rhs.getValue(); }
class CharField : public FieldBase {
public:
explicit CharField(int field, char data)
: FieldBase(field, CharConvertor::convert(data)) {}
CharField(int field)
: FieldBase(field, "") {}
void setValue(char value) { setString(CharConvertor::convert(value)); }
char getValue() const EXCEPT(IncorrectDataFormat) {
try {
return CharConvertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator char() const { return getValue(); }
};
class DoubleField : public FieldBase {
public:
explicit DoubleField(int field, double data, int padding = 0)
: FieldBase(field, DoubleConvertor::convert(data, padding)) {}
DoubleField(int field)
: FieldBase(field, "") {}
void setValue(double value, int padding = 0) { setString(DoubleConvertor::convert(value, padding)); }
double getValue() const EXCEPT(IncorrectDataFormat) {
try {
return DoubleConvertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator double() const { return getValue(); }
};
class IntField : public FieldBase {
public:
explicit IntField(int field, int data)
: FieldBase(field, IntConvertor::convert(data)) {}
IntField(int field)
: FieldBase(field, "") {}
void setValue(int value) { setString(IntConvertor::convert(value)); }
int getValue() const EXCEPT(IncorrectDataFormat) {
try {
return IntConvertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator int() const { return getValue(); }
};
class Int64Field : public FieldBase {
public:
explicit Int64Field(int field, int64_t data)
: FieldBase(field, Int64Convertor::convert(data)) {}
Int64Field(int field)
: FieldBase(field, "") {}
void setValue(int64_t value) { setString(Int64Convertor::convert(value)); }
int64_t getValue() const EXCEPT(IncorrectDataFormat) {
try {
return Int64Convertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator int64_t() const { return getValue(); }
};
class UInt64Field : public FieldBase {
public:
explicit UInt64Field(int field, uint64_t data)
: FieldBase(field, UInt64Convertor::convert(data)) {}
UInt64Field(int field)
: FieldBase(field, "") {}
void setValue(uint64_t value) { setString(UInt64Convertor::convert(value)); }
uint64_t getValue() const EXCEPT(IncorrectDataFormat) {
try {
return UInt64Convertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator uint64_t() const { return getValue(); }
};
class BoolField : public FieldBase {
public:
explicit BoolField(int field, bool data)
: FieldBase(field, BoolConvertor::convert(data)) {}
BoolField(int field)
: FieldBase(field, "") {}
void setValue(bool value) { setString(BoolConvertor::convert(value)); }
bool getValue() const EXCEPT(IncorrectDataFormat) {
try {
return BoolConvertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator bool() const { return getValue(); }
};
class UtcTimeStampField : public FieldBase {
public:
explicit UtcTimeStampField(int field, const UtcTimeStamp &data, int precision = 0)
: FieldBase(field, UtcTimeStampConvertor::convert(data, precision)) {}
UtcTimeStampField(int field, int precision = 0)
: FieldBase(field, UtcTimeStampConvertor::convert(UtcTimeStamp::now(), precision)) {}
void setValue(const UtcTimeStamp &value) { setString(UtcTimeStampConvertor::convert(value)); }
UtcTimeStamp getValue() const EXCEPT(IncorrectDataFormat) {
try {
return UtcTimeStampConvertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator UtcTimeStamp() const { return getValue(); }
bool operator<(const UtcTimeStampField &rhs) const { return getValue() < rhs.getValue(); }
bool operator==(const UtcTimeStampField &rhs) const { return getValue() == rhs.getValue(); }
bool operator!=(const UtcTimeStampField &rhs) const { return getValue() != rhs.getValue(); }
};
class UtcDateField : public FieldBase {
public:
explicit UtcDateField(int field, const UtcDate &data)
: FieldBase(field, UtcDateConvertor::convert(data)) {}
UtcDateField(int field)
: FieldBase(field, UtcDateConvertor::convert(UtcDate())) {}
void setValue(const UtcDate &value) { setString(UtcDateConvertor::convert(value)); }
UtcDate getValue() const EXCEPT(IncorrectDataFormat) {
try {
return UtcDateConvertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator UtcDate() const { return getValue(); }
bool operator<(const UtcDateField &rhs) const { return getValue() < rhs.getValue(); }
bool operator==(const UtcDateField &rhs) const { return getValue() == rhs.getValue(); }
bool operator!=(const UtcDateField &rhs) const { return getValue() != rhs.getValue(); }
};
class UtcTimeOnlyField : public FieldBase {
public:
explicit UtcTimeOnlyField(int field, const UtcTimeOnly &data, int precision = 0)
: FieldBase(field, UtcTimeOnlyConvertor::convert(data, precision)) {}
UtcTimeOnlyField(int field, int precision = 0)
: FieldBase(field, UtcTimeOnlyConvertor::convert(UtcTimeOnly(), precision)) {}
void setValue(const UtcTimeOnly &value) { setString(UtcTimeOnlyConvertor::convert(value)); }
UtcTimeOnly getValue() const EXCEPT(IncorrectDataFormat) {
try {
return UtcTimeOnlyConvertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator UtcTimeOnly() const { return getValue(); }
bool operator<(const UtcTimeOnlyField &rhs) const { return getValue() < rhs.getValue(); }
bool operator==(const UtcTimeOnlyField &rhs) const { return getValue() == rhs.getValue(); }
bool operator!=(const UtcTimeOnlyField &rhs) const { return getValue() != rhs.getValue(); }
};
class CheckSumField : public FieldBase {
public:
explicit CheckSumField(int field, int data)
: FieldBase(field, CheckSumConvertor::convert(data)) {}
CheckSumField(int field)
: FieldBase(field, "") {}
void setValue(int value) { setString(CheckSumConvertor::convert(value)); }
int getValue() const EXCEPT(IncorrectDataFormat) {
try {
return CheckSumConvertor::convert(getString());
} catch (FieldConvertError &) {
throw IncorrectDataFormat(getTag(), getString());
}
}
operator int() const { return getValue(); }
};
typedef DoubleField PriceField;
typedef DoubleField AmtField;
typedef DoubleField QtyField;
typedef StringField CurrencyField;
typedef StringField MultipleValueStringField;
typedef StringField MultipleStringValueField;
typedef StringField MultipleCharValueField;
typedef StringField ExchangeField;
typedef StringField LocalMktDateField;
typedef StringField DataField;
typedef DoubleField FloatField;
typedef DoubleField PriceOffsetField;
typedef StringField MonthField;
typedef StringField MonthYearField;
typedef StringField DayOfMonthField;
typedef UtcDateField UtcDateOnlyField;
typedef IntField LengthField;
typedef IntField NumInGroupField;
typedef UInt64Field SeqNumField;
typedef IntField TagNumField;
typedef DoubleField PercentageField;
typedef StringField CountryField;
typedef StringField TzTimeOnlyField;
typedef StringField TzTimeStampField;
}
#define DEFINE_FIELD_CLASS_NUM(NAME, TOK, TYPE, NUM) \
class NAME : public TOK##Field { \
public: \
static constexpr int tag = NUM; \
NAME() \
: TOK##Field(NUM) {} \
NAME(const TYPE &value) \
: TOK##Field(NUM, value) {} \
}
#define DEFINE_TRIVIAL_FIELD_CLASS_NUM(NAME, TOK, TYPE, NUM) \
class NAME : public TOK##Field { \
public: \
static constexpr int tag = NUM; \
NAME() \
: TOK##Field(NUM) {} \
NAME(TYPE value) \
: TOK##Field(NUM, value) {} \
}
#define DEFINE_FIELD_CLASS(NAME, TOK, TYPE) DEFINE_FIELD_CLASS_NUM(NAME, TOK, TYPE, FIELD::NAME)
#define DEFINE_TRIVIAL_FIELD_CLASS(NAME, TOK, TYPE) DEFINE_TRIVIAL_FIELD_CLASS_NUM(NAME, TOK, TYPE, FIELD::NAME)
#define DEFINE_DEPRECATED_FIELD_CLASS(NAME, TOK, TYPE) DEFINE_FIELD_CLASS_NUM(NAME, TOK, TYPE, DEPRECATED_FIELD::NAME)
#define DEFINE_FIELD_TIMECLASS_NUM(NAME, TOK, TYPE, NUM) \
class NAME : public TOK##Field { \
public: \
static constexpr int tag = NUM; \
static NAME now() { return NAME(TYPE::now()); } \
static NAME now(int precision) { return NAME(TYPE::now(), precision); } \
NAME() \
: TOK##Field(NUM, TYPE::now(), false) {} \
NAME(int precision) \
: TOK##Field(NUM, TYPE::now(), precision) {} \
NAME(const TYPE &value) \
: TOK##Field(NUM, value) {} \
NAME(const TYPE &value, int precision) \
: TOK##Field(NUM, value, precision) {} \
}
#define DEFINE_FIELD_TIMECLASS(NAME, TOK, TYPE) DEFINE_FIELD_TIMECLASS_NUM(NAME, TOK, TYPE, FIELD::NAME)
#define DEFINE_DEPRECATED_FIELD_TIMECLASS(NAME, TOK, TYPE) \
DEFINE_FIELD_TIMECLASS_NUM(NAME, TOK, TYPE, DEPRECATED_FIELD::NAME)
#define DEFINE_CHECKSUM(NAME) DEFINE_TRIVIAL_FIELD_CLASS(NAME, CheckSum, FIX::INT)
#define DEFINE_STRING(NAME) DEFINE_FIELD_CLASS(NAME, String, FIX::STRING)
#define DEFINE_CHAR(NAME) DEFINE_FIELD_CLASS(NAME, Char, FIX::CHAR)
#define DEFINE_PRICE(NAME) DEFINE_FIELD_CLASS(NAME, Price, FIX::PRICE)
#define DEFINE_INT(NAME) DEFINE_TRIVIAL_FIELD_CLASS(NAME, Int, FIX::INT)
#define DEFINE_INT64(NAME) DEFINE_TRIVIAL_FIELD_CLASS(NAME, Int64, FIX::INT64)
#define DEFINE_AMT(NAME) DEFINE_FIELD_CLASS(NAME, Amt, FIX::AMT)
#define DEFINE_QTY(NAME) DEFINE_FIELD_CLASS(NAME, Qty, FIX::QTY)
#define DEFINE_CURRENCY(NAME) DEFINE_FIELD_CLASS(NAME, Currency, FIX::CURRENCY)
#define DEFINE_MULTIPLEVALUESTRING(NAME) DEFINE_FIELD_CLASS(NAME, MultipleValueString, FIX::MULTIPLEVALUESTRING)
#define DEFINE_MULTIPLESTRINGVALUE(NAME) DEFINE_FIELD_CLASS(NAME, MultipleStringValue, FIX::MULTIPLESTRINGVALUE)
#define DEFINE_MULTIPLECHARVALUE(NAME) DEFINE_FIELD_CLASS(NAME, MultipleCharValue, FIX::MULTIPLECHARVALUE)
#define DEFINE_EXCHANGE(NAME) DEFINE_FIELD_CLASS(NAME, Exchange, FIX::EXCHANGE)
#define DEFINE_UTCTIMESTAMP(NAME) DEFINE_FIELD_TIMECLASS(NAME, UtcTimeStamp, FIX::UTCTIMESTAMP)
#define DEFINE_BOOLEAN(NAME) DEFINE_FIELD_CLASS(NAME, Bool, FIX::BOOLEAN)
#define DEFINE_LOCALMKTTIME(NAME) DEFINE_FIELD_CLASS(NAME, String, FIX::LOCALMKTTIME)
#define DEFINE_LOCALMKTDATE(NAME) DEFINE_FIELD_CLASS(NAME, String, FIX::LOCALMKTDATE)
#define DEFINE_DATA(NAME) DEFINE_FIELD_CLASS(NAME, Data, FIX::DATA)
#define DEFINE_FLOAT(NAME) DEFINE_FIELD_CLASS(NAME, Float, FIX::FLOAT)
#define DEFINE_PRICEOFFSET(NAME) DEFINE_FIELD_CLASS(NAME, PriceOffset, FIX::PRICEOFFSET)
#define DEFINE_MONTHYEAR(NAME) DEFINE_FIELD_CLASS(NAME, MonthYear, FIX::MONTHYEAR)
#define DEFINE_DAYOFMONTH(NAME) DEFINE_FIELD_CLASS(NAME, DayOfMonth, FIX::DAYOFMONTH)
#define DEFINE_UTCDATE(NAME) DEFINE_FIELD_CLASS(NAME, UtcDate, FIX::UTCDATE)
#define DEFINE_UTCDATEONLY(NAME) DEFINE_FIELD_CLASS(NAME, UtcDateOnly, FIX::UTCDATEONLY)
#define DEFINE_UTCTIMEONLY(NAME) DEFINE_FIELD_CLASS(NAME, UtcTimeOnly, FIX::UTCTIMEONLY)
#define DEFINE_NUMINGROUP(NAME) DEFINE_TRIVIAL_FIELD_CLASS(NAME, NumInGroup, FIX::NUMINGROUP)
#define DEFINE_SEQNUM(NAME) DEFINE_TRIVIAL_FIELD_CLASS(NAME, SeqNum, FIX::SEQNUM)
#define DEFINE_TAGNUM(NAME) DEFINE_TRIVIAL_FIELD_CLASS(NAME, TagNum, FIX::TAGNUM)
#define DEFINE_LENGTH(NAME) DEFINE_TRIVIAL_FIELD_CLASS(NAME, Length, FIX::LENGTH)
#define DEFINE_PERCENTAGE(NAME) DEFINE_FIELD_CLASS(NAME, Percentage, FIX::PERCENTAGE)
#define DEFINE_COUNTRY(NAME) DEFINE_FIELD_CLASS(NAME, Country, FIX::COUNTRY)
#define DEFINE_TZTIMEONLY(NAME) DEFINE_FIELD_CLASS(NAME, String, FIX::TZTIMEONLY)
#define DEFINE_TZTIMESTAMP(NAME) DEFINE_FIELD_CLASS(NAME, String, FIX::TZTIMESTAMP)
#define DEFINE_XMLDATA(NAME) DEFINE_FIELD_CLASS(NAME, String, FIX::XMLDATA)
#define DEFINE_LANGUAGE(NAME) DEFINE_FIELD_CLASS(NAME, String, FIX::LANGUAGE)
#define DEFINE_XID(NAME) DEFINE_FIELD_CLASS(NAME, String, FIX::XID)
#define DEFINE_XIDREF(NAME) DEFINE_FIELD_CLASS(NAME, String, FIX::XIDREF)
#define USER_DEFINE_STRING(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, String, FIX::STRING, NUM)
#define USER_DEFINE_CHAR(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Char, FIX::CHAR, NUM)
#define USER_DEFINE_PRICE(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Price, FIX::PRICE, NUM)
#define USER_DEFINE_INT(NAME, NUM) DEFINE_TRIVIAL_FIELD_CLASS_NUM(NAME, Int, FIX::INT, NUM)
#define USER_DEFINE_AMT(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Amt, FIX::AMT, NUM)
#define USER_DEFINE_QTY(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Qty, FIX::QTY, NUM)
#define USER_DEFINE_CURRENCY(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Currency, FIX::CURRENCY, NUM)
#define USER_DEFINE_MULTIPLEVALUESTRING(NAME, NUM) \
DEFINE_FIELD_CLASS_NUM(NAME, MultipleValueString, FIX::MULTIPLEVALUESTRING, NUM)
#define USER_DEFINE_MULTIPLESTRINGVALUE(NAME, NUM) \
DEFINE_FIELD_CLASS_NUM(NAME, MultipleStringValue, FIX::MULTIPLESTRINGVALUE, NUM)
#define USER_DEFINE_MULTIPLECHARVALUE(NAME, NUM) \
DEFINE_FIELD_CLASS_NUM(NAME, MultipleCharValue, FIX::MULTIPLECHARVALUE, NUM)
#define USER_DEFINE_EXCHANGE(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Exchange, FIX::EXCHANGE, NUM)
#define USER_DEFINE_UTCTIMESTAMP(NAME, NUM) DEFINE_FIELD_TIMECLASS_NUM(NAME, UtcTimeStamp, FIX::UTCTIMESTAMP, NUM)
#define USER_DEFINE_BOOLEAN(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Bool, FIX::BOOLEAN, NUM)
#define USER_DEFINE_LOCALMKTTIME(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, String, FIX::LOCALMKTTIME, NUM)
#define USER_DEFINE_LOCALMKTDATE(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, String, FIX::STRING, NUM)
#define USER_DEFINE_DATA(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Data, FIX::DATA, NUM)
#define USER_DEFINE_FLOAT(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Float, FIX::FLOAT, NUM)
#define USER_DEFINE_PRICEOFFSET(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, PriceOffset, FIX::PRICEOFFSET, NUM)
#define USER_DEFINE_MONTHYEAR(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, MonthYear, FIX::MONTHYEAR, NUM)
#define USER_DEFINE_DAYOFMONTH(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, DayOfMonth, FIX::DAYOFMONTH, NUM)
#define USER_DEFINE_UTCDATE(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, UtcDate, FIX::UTCDATE, NUM)
#define USER_DEFINE_UTCDATEONLY(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, UtcDateOnly, FIX::UTCDATEONLY, NUM)
#define USER_DEFINE_UTCTIMEONLY(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, UtcTimeOnly, FIX::UTCTIMEONLY, NUM)
#define USER_DEFINE_NUMINGROUP(NAME, NUM) DEFINE_TRIVIAL_FIELD_CLASS_NUM(NAME, NumInGroup, FIX::NUMINGROUP, NUM)
#define USER_DEFINE_SEQNUM(NAME, NUM) DEFINE_TRIVIAL_FIELD_CLASS_NUM(NAME, SeqNum, FIX::SEQNUM, NUM)
#define USER_DEFINE_TAGNUM(NAME, NUM) DEFINE_TRIVIAL_FIELD_CLASS_NUM(NAME, TagNum, FIX::TAGNUM, NUM)
#define USER_DEFINE_LENGTH(NAME, NUM) DEFINE_TRIVIAL_FIELD_CLASS_NUM(NAME, Length, FIX::LENGTH, NUM)
#define USER_DEFINE_PERCENTAGE(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Percentage, FIX::PERCENTAGE, NUM)
#define USER_DEFINE_COUNTRY(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, Country, FIX::COUNTRY, NUM)
#define USER_DEFINE_TZTIMEONLY(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, String, FIX::TZTIMEONLY, NUM)
#define USER_DEFINE_TZTIMESTAMP(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, String, FIX::TZTIMESTAMP, NUM)
#define USER_DEFINE_XMLDATA(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, String, FIX::XMLDATA, NUM)
#define USER_DEFINE_LANGUAGE(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, String, FIX::LANGUAGE, NUM)
#define USER_DEFINE_XID(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, String, FIX::XID, NUM)
#define USER_DEFINE_XIDREF(NAME, NUM) DEFINE_FIELD_CLASS_NUM(NAME, String, FIX::XIDREF, NUM)
#endif