Skip to content

Commit

Permalink
Implement the 'Add Order - Short' message in PITCH-2.X.
Browse files Browse the repository at this point in the history
Refactored common code to both add_order_message
and short_add_order_message to a common template.
  • Loading branch information
coryan committed May 28, 2017
1 parent a83d6f1 commit d9f38e6
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 21 deletions.
9 changes: 9 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ jb_itch5_unit_tests = \
jb_pitch2_unit_tests = \
jb/pitch2/ut_add_order_message \
jb/pitch2/ut_auction_update_message \
jb/pitch2/ut_short_add_order_message \
jb/pitch2/ut_time_message \
jb/pitch2/ut_unit_clear_message

Expand Down Expand Up @@ -479,11 +480,14 @@ jb_libjb_pitch2_adir = $(includedir)
jb_libjb_pitch2_a_SOURCES = \
jb/pitch2/add_order_message.cpp \
jb/pitch2/auction_update_message.cpp \
jb/pitch2/short_add_order_message.cpp \
jb/pitch2/time_message.cpp \
jb/pitch2/unit_clear_message.cpp
jb_libjb_pitch2_a_HEADERS = \
jb/pitch2/add_order_message.hpp \
jb/pitch2/auction_update_message.hpp \
jb/pitch2/base_add_order_message.hpp \
jb/pitch2/short_add_order_message.hpp \
jb/pitch2/time_message.hpp \
jb/pitch2/unit_clear_message.hpp

Expand Down Expand Up @@ -1242,6 +1246,11 @@ jb_pitch2_ut_auction_update_message_CPPFLAGS = $(UT_CPPFLAGS) -DBOOST_TEST_MODUL
jb_pitch2_ut_auction_update_message_LDFLAGS = $(jb_ut_pitch2_ldflags)
jb_pitch2_ut_auction_update_message_LDADD = $(jb_ut_pitch2_ldadd)

jb_pitch2_ut_short_add_order_message_SOURCES = jb/pitch2/ut_short_add_order_message.cpp
jb_pitch2_ut_short_add_order_message_CPPFLAGS = $(UT_CPPFLAGS) -DBOOST_TEST_MODULE=jb_pitch2_ut_short_add_order_message
jb_pitch2_ut_short_add_order_message_LDFLAGS = $(jb_ut_pitch2_ldflags)
jb_pitch2_ut_short_add_order_message_LDADD = $(jb_ut_pitch2_ldadd)

jb_pitch2_ut_time_message_SOURCES = jb/pitch2/ut_time_message.cpp
jb_pitch2_ut_time_message_CPPFLAGS = $(UT_CPPFLAGS) -DBOOST_TEST_MODULE=jb_pitch2_ut_time_message
jb_pitch2_ut_time_message_LDFLAGS = $(jb_ut_pitch2_ldflags)
Expand Down
30 changes: 9 additions & 21 deletions jb/pitch2/add_order_message.hpp
Original file line number Diff line number Diff line change
@@ -1,38 +1,26 @@
#ifndef jb_pitch2_add_order_message_hpp
#define jb_pitch2_add_order_message_hpp

#include <jb/fixed_string.hpp>
#include <boost/endian/buffers.hpp>

#include <iosfwd>
#include <utility>
#include <jb/pitch2/base_add_order_message.hpp>

namespace jb {
namespace pitch2 {

/**
* Represent the 'Add Order' message in the PITCH-2.X protocol.
*
* Sometimes the specification refers to this message as 'Add Order -
* long'.
*
* A full description of the fields can be found in the BATS PITCH-2.X
* specification:
* https://www.batstrading.com/resources/membership/BATS_MC_PITCH_Specification.pdf
*/
struct add_order_message {
struct add_order_message
: public base_add_order_message<boost::endian::little_uint32_buf_t,
boost::endian::little_uint64_buf_t> {
/// Define the messsage type
constexpr static int type = 0x21;

/// The type for the symbol field.
using symbol_type = jb::fixed_string<6>;

boost::endian::little_uint8_buf_t length;
boost::endian::little_uint8_buf_t message_type;
boost::endian::little_int32_buf_t time_offset;
boost::endian::little_uint64_buf_t order_id;
boost::endian::little_uint8_buf_t side_indicator;
boost::endian::little_uint32_buf_t quantity;
symbol_type symbol;
boost::endian::little_uint64_buf_t price;
boost::endian::little_uint8_buf_t add_flags;
constexpr static int type = 0x22;
};

/// Streaming operator for jb::pitch2::add_order_message.
Expand All @@ -41,4 +29,4 @@ std::ostream& operator<<(std::ostream& os, add_order_message const& x);
} // namespace pitch2
} // namespace jb

#endif // jb_pitch2_aution_update_message_hpp
#endif // jb_pitch2_add_order_message_hpp
40 changes: 40 additions & 0 deletions jb/pitch2/base_add_order_message.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#ifndef jb_pitch2_base_add_order_message_hpp
#define jb_pitch2_base_add_order_message_hpp

#include <jb/fixed_string.hpp>
#include <boost/endian/buffers.hpp>

#include <iosfwd>
#include <utility>

namespace jb {
namespace pitch2 {

/**
* Common type for the 'Add Order' messages in the PITCH-2.X protocol.
*
* The protocol defines 3 different 'Add Order' messages, which are
* largely identical except for the width of some of the fields. We
* use this template class to represent the common structure of these
* messages.
*/
template <typename quantity_type, typename price_type>
struct base_add_order_message {
/// The type for the symbol field.
using symbol_type = jb::fixed_string<6>;

boost::endian::little_uint8_buf_t length;
boost::endian::little_uint8_buf_t message_type;
boost::endian::little_int32_buf_t time_offset;
boost::endian::little_uint64_buf_t order_id;
boost::endian::little_uint8_buf_t side_indicator;
quantity_type quantity;
symbol_type symbol;
price_type price;
boost::endian::little_uint8_buf_t add_flags;
};

} // namespace pitch2
} // namespace jb

#endif // jb_pitch2_base_add_order_message_hpp
20 changes: 20 additions & 0 deletions jb/pitch2/short_add_order_message.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include <jb/pitch2/short_add_order_message.hpp>

#include <ostream>

namespace jb {
namespace pitch2 {

std::ostream& operator<<(std::ostream& os, short_add_order_message const& x) {
return os << "length=" << static_cast<int>(x.length.value())
<< ",message_type=" << static_cast<int>(x.message_type.value())
<< ",time_offset=" << x.time_offset.value()
<< ",order_id=" << x.order_id.value()
<< ",side_indicator=" << static_cast<char>(x.side_indicator.value())
<< ",quantity=" << x.quantity.value() << ",symbol=" << x.symbol
<< ",price=" << x.price.value()
<< ",add_flags=" << static_cast<int>(x.add_flags.value());
}

} // namespace pitch2
} // namespace jb
32 changes: 32 additions & 0 deletions jb/pitch2/short_add_order_message.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#ifndef jb_pitch2_short_add_order_message_hpp
#define jb_pitch2_short_add_order_message_hpp

#include <jb/pitch2/base_add_order_message.hpp>

namespace jb {
namespace pitch2 {

/**
* Represent the short version of 'Add Order' message in the PITCH-2.X protocol.
*
* Sometimes the specification refers to this message as 'Add Order -
* short'.
*
* A full description of the fields can be found in the BATS PITCH-2.X
* specification:
* https://www.batstrading.com/resources/membership/BATS_MC_PITCH_Specification.pdf
*/
struct short_add_order_message
: public base_add_order_message<boost::endian::little_uint16_buf_t,
boost::endian::little_uint16_buf_t> {
/// Define the messsage type
constexpr static int type = 0x21;
};

/// Streaming operator for jb::pitch2::short_add_order_message.
std::ostream& operator<<(std::ostream& os, short_add_order_message const& x);

} // namespace pitch2
} // namespace jb

#endif // jb_pitch2_short_add_order_message_hpp
44 changes: 44 additions & 0 deletions jb/pitch2/ut_short_add_order_message.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include <jb/pitch2/short_add_order_message.hpp>

#include <boost/test/unit_test.hpp>
#include <type_traits>

/**
* @test Verify that jb::pitch2::short_add_order_message works as expected.
*/
BOOST_AUTO_TEST_CASE(short_add_order_message_basic) {
using namespace jb::pitch2;
BOOST_CHECK_EQUAL(true, std::is_pod<short_add_order_message>::value);
BOOST_CHECK_EQUAL(sizeof(short_add_order_message), std::size_t(26));

char const buf[] = u8"\x1A" // Length (26)
"\x22" // Message Type (34 '"')
"\x18\xD2\x06\x00" // Time Offset (447,000)
"\x05\x40\x5B\x77\x8F\x56\x1D\x0B" // Order Id
"\x42" // Side Indicator (66 'B' Buy)
"\x20\x4E" // Quantity (20,000)
"\x5A\x56\x5A\x5A\x54\x20" // Symbol (ZVZZT)
"\x0A\x28" // Price ($102.50)
"\x01" // Add Flags (Bit 0 on -> Displayed)
;
short_add_order_message msg;
BOOST_REQUIRE_EQUAL(sizeof(buf) - 1, sizeof(msg));
std::memcpy(&msg, buf, sizeof(msg));
BOOST_CHECK_EQUAL(int(msg.length.value()), 26);
BOOST_CHECK_EQUAL(int(msg.message_type.value()), 34);
BOOST_CHECK_EQUAL(msg.time_offset.value(), 447000);
BOOST_CHECK_EQUAL(msg.order_id.value(), 0x0B1D568F775B4005ULL);
BOOST_CHECK_EQUAL(msg.side_indicator.value(), 0x42);
BOOST_CHECK_EQUAL(msg.quantity.value(), 20000);
BOOST_CHECK_EQUAL(msg.symbol, jb::fixed_string<6>("ZVZZT"));
BOOST_CHECK_EQUAL(msg.price.value(), 10250);
BOOST_CHECK_EQUAL(msg.add_flags.value(), 0x01);

std::ostringstream os;
os << msg;
BOOST_CHECK_EQUAL(
os.str(), std::string(
"length=26,message_type=34,time_offset=447000,"
"order_id=800891482924597253,side_indicator=B,"
"quantity=20000,symbol=ZVZZT ,price=10250,add_flags=1"));
}

0 comments on commit d9f38e6

Please sign in to comment.