Skip to content

Commit

Permalink
Merge pull request #295 from northwesternfintech/mm-overflow-fix
Browse files Browse the repository at this point in the history
Added better overflow fix in market maker by using float ratio
  • Loading branch information
stevenewald authored Oct 9, 2024
2 parents 4da713c + 0d78947 commit cf51530
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 19 deletions.
15 changes: 8 additions & 7 deletions exchange/src/common/types/decimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ template <std::uint8_t Scale>
Decimal<Scale>
Decimal<Scale>::operator-() const
{
return -value_;
return Decimal{-value_};
}

template <std::uint8_t Scale>
Expand All @@ -27,28 +27,28 @@ template <std::uint8_t Scale>
Decimal<Scale>
Decimal<Scale>::operator-(const Decimal& other) const
{
return value_ - other.value_;
return Decimal{value_ - other.value_};
}

template <std::uint8_t Scale>
Decimal<Scale>
Decimal<Scale>::operator+(const Decimal& other) const
{
return value_ + other.value_;
return Decimal{value_ + other.value_};
}

template <std::uint8_t Scale>
Decimal<Scale>
Decimal<Scale>::operator/(const Decimal& other) const
{
return value_ * MULTIPLIER / other.value_;
return Decimal{value_ * MULTIPLIER / other.value_};
}

template <std::uint8_t Scale>
Decimal<Scale>
Decimal<Scale>::operator*(const Decimal& other) const
{
return (value_ * other.value_) / MULTIPLIER;
return Decimal{(value_ * other.value_) / MULTIPLIER};
}

template <std::uint8_t Scale>
Expand Down Expand Up @@ -101,14 +101,15 @@ Decimal<Scale>
Decimal<Scale>::difference(const Decimal& other) const
{
if (value_ >= other.value_) {
return value_ - other.value_;
return Decimal{value_ - other.value_};
}
return other.value_ - value_;
return Decimal{other.value_ - value_};
}

template class Decimal<PRICE_DECIMAL_PLACES>;

#if PRICE_DECIMAL_PLACES != QUANTITY_DECIMAL_PLACES
template class Decimal<QUANTITY_DECIMAL_PLACES>;
#endif

} // namespace nutc::common
19 changes: 12 additions & 7 deletions exchange/src/common/types/decimal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pow10(int pow)
}
} // namespace detail

// THIS CLASS PRIORITIZES PRECISION OVER AVOIDING OVERFLOW
template <std::uint8_t Scale>
class Decimal {
using decimal_type = std::int64_t;
Expand Down Expand Up @@ -56,7 +57,7 @@ class Decimal {
Decimal difference(const Decimal& other) const;

private:
constexpr Decimal(decimal_type value) : value_(value) {}
constexpr explicit Decimal(decimal_type value) : value_(value) {}

static constexpr bool
double_within_bounds(double value)
Expand Down Expand Up @@ -110,19 +111,23 @@ struct hash<nutc::common::Decimal<Scale>> {
// TODO: add unit tests
template <std::uint8_t Scale>
class numeric_limits<nutc::common::Decimal<Scale>> {
using scaled_decimal = nutc::common::Decimal<Scale>;

public:
static nutc::common::Decimal<Scale>
static scaled_decimal
max()
{
return std::numeric_limits<
typename nutc::common::Decimal<Scale>::decimal_type>::max();
return scaled_decimal{
std::numeric_limits<typename scaled_decimal::decimal_type>::max()
};
}

static nutc::common::Decimal<Scale>
static scaled_decimal
min()
{
return std::numeric_limits<
typename nutc::common::Decimal<Scale>::decimal_type>::min();
return scaled_decimal{
std::numeric_limits<typename scaled_decimal::decimal_type>::min()
};
}
};

Expand Down
2 changes: 1 addition & 1 deletion exchange/src/exchange/bots/bot_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ BotContainer::generate_orders(
{
variance_calculator_.record_price(midprice);

decimal_price cumulative_interest_limit{};
common::decimal_price cumulative_interest_limit{};
common::decimal_quantity cumulative_quantity_held{};

for (const auto& bot : bots_) {
Expand Down
5 changes: 3 additions & 2 deletions exchange/src/exchange/bots/bot_types/market_maker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,9 @@ MarketMakerBot::place_orders_(
decimal_price
MarketMakerBot::calculate_lean_percent(const shared_bot_state& state)
{
auto lean_price = state.CUMULATIVE_QUANTITY_HELD / state.CUMULATIVE_INTEREST_LIMIT;
return lean_price * state.MIDPRICE;
double ratio = double{state.CUMULATIVE_QUANTITY_HELD}
/ double{state.CUMULATIVE_INTEREST_LIMIT};
return ratio * static_cast<double>(state.MIDPRICE);
}

// TODO: clean up
Expand Down
17 changes: 15 additions & 2 deletions exchange/test/src/unit/types/decimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ TEST(UnitDecimalPrice, AssignmentOperator)
EXPECT_EQ(second, 5.0);
}

TEST(UnitDecimalPrice, TestCommutativity)
{
decimal_price three = 3.0;
decimal_price four = 4.0;
decimal_price six = 6.0;

decimal_price twelve = three*four;
EXPECT_EQ(double{twelve/six}, 2.0);

decimal_price point_five = three/six;
EXPECT_EQ(double{point_five*four}, 2.0);
}

TEST(UnitDecimalPrice, UnaryNegate)
{
decimal_price first = 5.0;
Expand Down Expand Up @@ -45,8 +58,8 @@ TEST(UnitDecimalPrice, DecimalDecimalDivision)
{
decimal_price first = 10.0;
decimal_price second = 2.0;
double third{first / second};
EXPECT_EQ(third, 5.0);
decimal_price third = first/second;
EXPECT_EQ(double{third}, 5.0);
}

TEST(UnitDecimalPrice, DecimalDecimalMultiplication)
Expand Down

0 comments on commit cf51530

Please sign in to comment.