JayBeams  0.1
Another project to have fun coding.
price_levels.hpp
Go to the documentation of this file.
1 #ifndef jb_itch5_price_levels_hpp
2 #define jb_itch5_price_levels_hpp
3 
5 
6 #include <stdexcept>
7 
8 namespace jb {
9 namespace itch5 {
10 
11 /**
12  * Compute the number of price levels between two prices.
13  *
14  * @param lo the low end of the range of price levels
15  * @param hi the hi end of the range of price levels
16  * @returns the number of price levels between @a lo and @a hi
17  * @throws std::bad_range if @a hi < @a lo
18  */
19 template <typename price_field_t>
20 std::size_t price_levels(price_field_t lo, price_field_t hi) {
21  static_assert(
22  price_field_t::denom >= 10000,
23  "price_levels() does not work with denom < 10000");
24  static_assert(
25  price_field_t::denom % 10000 == 0,
26  "price_levels() does not work with (denom % 10000) != 0");
27 
28  price_field_t const unit = price_field_t::dollar_price();
29  auto constexpr penny = price_field_t::denom / 100;
30  auto constexpr mill = penny / 100;
31 
32  if (hi < lo) {
33  throw std::range_error("invalid price range in price_levels()");
34  }
35  if (unit <= lo) {
36  // ... range is above $1.0, return the number of levels for that
37  // case ...
38  return (hi.as_integer() - lo.as_integer()) / penny;
39  }
40  if (hi <= unit) {
41  // ... range is below $1.0, return the number of levels for that
42  // case ...
43  return (hi.as_integer() - lo.as_integer()) / mill;
44  }
45  if (lo.as_integer() == 0) {
46  // ... we treat lo == 0 especially because it is a very common
47  // case, better to avoid the extra computation if we can ...
48  return 10000 + (hi.as_integer() - unit.as_integer()) / penny;
49  }
50  // ... split the analysis ...
51  return price_levels(lo, unit) + price_levels(unit, hi);
52 }
53 
54 /**
55  * Compute the absolute price of a price level.
56  *
57  * @param p_level price level
58  * @returns absolute price
59  * @throws std::bad_range if p_level out of range
60  */
61 template <typename price_field_t>
62 auto level_to_price(typename price_field_t::wire_type const p_level) {
63  static_assert(
64  price_field_t::denom >= 10000,
65  "price_levels() does not work with denom < 10000");
66  static_assert(
67  price_field_t::denom % 10000 == 0,
68  "price_levels() does not work with (denom % 10000) != 0");
69 
70  price_field_t const max_price = max_price_field_value<price_field_t>();
71  std::size_t const max_level = price_levels(price_field_t(0), max_price);
72  if (p_level > max_level) {
73  throw std::range_error("invalid price range in price_levels()");
74  }
75  if (p_level <= price_field_t::denom) {
76  return price_field_t(p_level);
77  }
78  int rem = (p_level - price_field_t::denom) * 100 + price_field_t::denom;
79  return price_field_t(rem);
80 }
81 
82 } // namespace itch5
83 } // namespace jb
84 
85 #endif // jb_itch5_price_levels_hpp
auto level_to_price(typename price_field_t::wire_type const p_level)
Compute the absolute price of a price level.
std::size_t price_levels(price_field_t lo, price_field_t hi)
Compute the number of price levels between two prices.
The top-level namespace for the JayBeams library.
Definition: as_hhmmss.hpp:7