Skip to content

Commit

Permalink
Added order volume limits
Browse files Browse the repository at this point in the history
  • Loading branch information
stevenewald committed Oct 8, 2024
1 parent 2944d76 commit f4cfcd6
Show file tree
Hide file tree
Showing 23 changed files with 362 additions and 112 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/exchange-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ jobs:
run: cmake --install build --config Release --prefix .

- name: Move config file
run: cp -r config.yml build/test/config.yml
run: cp config.yml build/test/config.yml

- name: Move test algo files
run: cp -r -L test/src/integration/test_algos build/test/test_algos
Expand Down
47 changes: 23 additions & 24 deletions exchange/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ global:

order_fee: .0000
sandbox_trial_seconds: 300
max_cumulative_order_volume: 5000

tickers:
- ticker: "ETH"
Expand All @@ -20,28 +21,26 @@ tickers:
std_dev_capital: 2000

# perfect: 5/250000/5000, 25/1000/200
- ticker: "LTC"
start_price: 50
bots:
- type: "market_maker"
number_of_bots: 5
average_capital: 200000
std_dev_capital: 50000
- type: "retail"
number_of_bots: 25
average_capital: 5000
std_dev_capital: 2000

# - ticker: "LTC"
# start_price: 200
# bots:
# - type: "market_maker"
# number_of_bots: 10
# average_capital: 100000
# std_dev_capital: 25000
#
# - type: "retail"
# number_of_bots: 100
# average_capital: 7500
# std_dev_capital: 100
#
# - ticker: "BTC"
# start_price: 50
# bots:
# - type: "market_maker"
# number_of_bots: 10
# average_capital: 100000
# std_dev_capital: 10000
# - type: "retail"
# number_of_bots: 100
# average_capital: 2000
# std_dev_capital: 1000
- ticker: "BTC"
start_price: 200
bots:
- type: "market_maker"
number_of_bots: 25
average_capital: 200000
std_dev_capital: 50000
- type: "retail"
number_of_bots: 125
average_capital: 5000
std_dev_capital: 2000
28 changes: 14 additions & 14 deletions exchange/src/common/types/decimal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,56 @@

namespace nutc::common {

template <std::int8_t Scale>
template <std::uint8_t Scale>
Decimal<Scale>
Decimal<Scale>::operator-() const
{
return -value_;
}

template <std::int8_t Scale>
template <std::uint8_t Scale>
typename Decimal<Scale>::decimal_type
Decimal<Scale>::get_underlying() const
{
return value_;
}

template <std::int8_t Scale>
template <std::uint8_t Scale>
void
Decimal<Scale>::set_underlying(decimal_type value)
{
value_ = value;
}

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

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

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

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

template <std::int8_t Scale>
template <std::uint8_t Scale>
Decimal<Scale>&
Decimal<Scale>::operator*=(const Decimal& other)
{
Expand All @@ -60,7 +60,7 @@ Decimal<Scale>::operator*=(const Decimal& other)
return *this;
}

template <std::int8_t Scale>
template <std::uint8_t Scale>
Decimal<Scale>&
Decimal<Scale>::operator/=(const Decimal& other)
{
Expand All @@ -69,34 +69,34 @@ Decimal<Scale>::operator/=(const Decimal& other)
return *this;
}

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

template <std::int8_t Scale>
template <std::uint8_t Scale>
bool
Decimal<Scale>::operator==(double other) const
{
return value_ == static_cast<decimal_type>(other * MULTIPLIER);
}

template <std::int8_t Scale>
template <std::uint8_t Scale>
Decimal<Scale>::operator double() const
{
return static_cast<double>(value_) / static_cast<double>(MULTIPLIER);
}

template <std::int8_t Scale>
template <std::uint8_t Scale>
Decimal<Scale>::operator float() const
{
return static_cast<float>(value_) / static_cast<float>(MULTIPLIER);
}

template <std::int8_t Scale>
template <std::uint8_t Scale>
Decimal<Scale>
Decimal<Scale>::difference(const Decimal& other) const
{
Expand Down
27 changes: 24 additions & 3 deletions exchange/src/common/types/decimal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pow10(int pow)
}
} // namespace detail

template <std::int8_t Scale>
template <std::uint8_t Scale>
class Decimal {
using decimal_type = std::int64_t;
static constexpr std::int64_t MULTIPLIER = detail::pow10<decimal_type>(Scale);
Expand Down Expand Up @@ -88,6 +88,7 @@ class Decimal {
}

friend std::hash<Decimal<Scale>>;
friend std::numeric_limits<Decimal<Scale>>;
friend glz::meta<nutc::common::Decimal<Scale>>;
};

Expand All @@ -97,18 +98,38 @@ using decimal_quantity = Decimal<QUANTITY_DECIMAL_PLACES>;
} // namespace nutc::common

namespace std {
template <std::int8_t Scale>
template <std::uint8_t Scale>
struct hash<nutc::common::Decimal<Scale>> {
std::size_t
operator()(const nutc::common::Decimal<Scale>& obj) const
{
return std::hash<int64_t>{}(obj.value_);
}
};

// TODO: add unit tests
template <std::uint8_t Scale>
class numeric_limits<nutc::common::Decimal<Scale>> {
public:
static nutc::common::Decimal<Scale>
max()
{
return std::numeric_limits<
typename nutc::common::Decimal<Scale>::decimal_type>::max();
}

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

} // namespace std

/// \cond
template <std::int8_t Scale>
template <std::uint8_t Scale>
struct glz::meta<nutc::common::Decimal<Scale>> {
using t = nutc::common::Decimal<Scale>;
static constexpr auto value = object(&t::value_);
Expand Down
8 changes: 7 additions & 1 deletion exchange/src/exchange/config/dynamic/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,22 @@ Config::get_global_config_(const YAML::Node& full_config)
const auto& wait_secs = global["wait_secs"];
const auto& sandbox_secs = global["sandbox_trial_seconds"];
const auto& order_fee = global["order_fee"];
const auto& max_order_volume = global["max_cumulative_order_volume"];

if (!starting_capital.IsDefined())
throw_undef_err("global/starting_capital");
if (!wait_secs.IsDefined())
throw_undef_err("global/wait_secs");
if (!sandbox_secs.IsDefined())
throw_undef_err("global/sandbox_trial_seconds");
if (!max_order_volume.IsDefined())
throw_undef_err("global/max_cumulative_order_volume");

return {
common::decimal_price(starting_capital.as<double>()), wait_secs.as<size_t>(),
sandbox_secs.as<unsigned int>(),
order_fee.IsDefined() ? order_fee.as<double>() : 0
order_fee.IsDefined() ? order_fee.as<double>() : 0,
common::decimal_quantity(max_order_volume.as<double>())
};
}

Expand Down
1 change: 1 addition & 0 deletions exchange/src/exchange/config/dynamic/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ struct global_config {
const size_t WAIT_SECS;
const unsigned int SANDBOX_TRIAL_SECS;
const double ORDER_FEE;
const common::decimal_quantity MAX_CUMULATIVE_OPEN_ORDER_VOLUME;
};

class Config {
Expand Down
13 changes: 10 additions & 3 deletions exchange/src/exchange/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,22 @@ create_cycle(TraderContainer& traders, const auto& mode)
const auto& ticker_config = Config::get().get_tickers();
double order_fee = Config::get().constants().ORDER_FEE;
auto tickers = TickerContainer(ticker_config, traders);
auto max_order_volume = Config::get().constants().MAX_CUMULATIVE_OPEN_ORDER_VOLUME;

switch (mode) {
case Mode::normal:
return std::make_unique<BaseMatchingCycle>(tickers, traders, order_fee);
return std::make_unique<BaseMatchingCycle>(
tickers, traders, order_fee, max_order_volume
);
case Mode::sandbox:
return std::make_unique<SandboxMatchingCycle>(tickers, traders, order_fee);
return std::make_unique<SandboxMatchingCycle>(
tickers, traders, order_fee, max_order_volume
);
case Mode::bots_only:
case Mode::dev:
return std::make_unique<DevMatchingCycle>(tickers, traders, order_fee);
return std::make_unique<DevMatchingCycle>(
tickers, traders, order_fee, max_order_volume
);
}

std::unreachable();
Expand Down
33 changes: 20 additions & 13 deletions exchange/src/exchange/matching_cycle/base/base_cycle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,20 +55,27 @@ BaseMatchingCycle::match_orders_(std::vector<OrderVariant> orders)
{
std::vector<common::match> matches;

for (OrderVariant& order_variant : orders) {
auto match_incoming_order = [&]<typename OrderT>(OrderT& order) {
auto& ticker_data = tickers_[order.ticker];
auto& orderbook = ticker_data.get_orderbook();
if constexpr (std::is_same_v<OrderT, common::cancel_order>) {
orderbook.remove_order(order.order_id);
}
else {
if (order.quantity <= 0.0)
return;
auto tmp = match_order(order, orderbook, order_fee_);
std::copy(tmp.begin(), tmp.end(), std::back_inserter(matches));
auto match_incoming_order = [&]<typename OrderT>(OrderT& order) {
auto& ticker_data = tickers_[order.ticker];
auto& orderbook = ticker_data.get_orderbook();
if constexpr (std::is_same_v<OrderT, common::cancel_order>) {
orderbook.remove_order(order.order_id);
}
else {
if (order.quantity <= 0.0)
return;
// TODO: delegate elsewhere
if (order.quantity + order.trader->get_open_bids()
+ order.trader->get_open_asks()
> max_cumulative_order_volume_) {
return;
}
};
auto tmp = match_order(order, orderbook, order_fee_);
std::copy(tmp.begin(), tmp.end(), std::back_inserter(matches));
}
};

for (OrderVariant& order_variant : orders) {
std::visit(match_incoming_order, order_variant);
}
return matches;
Expand Down
8 changes: 6 additions & 2 deletions exchange/src/exchange/matching_cycle/base/base_cycle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ class BaseMatchingCycle : public MatchingCycleInterface {
TickerContainer tickers_;
TraderContainer& traders_;
common::decimal_price order_fee_;
common::decimal_quantity max_cumulative_order_volume_;

public:
// Require transfer of ownership
BaseMatchingCycle(
TickerContainer tickers, TraderContainer& traders, common::decimal_price order_fee
) : tickers_(std::move(tickers)), traders_(traders), order_fee_(order_fee)
TickerContainer tickers, TraderContainer& traders,
common::decimal_price order_fee, common::decimal_quantity max_order_volume
) :
tickers_(std::move(tickers)), traders_(traders), order_fee_(order_fee),
max_cumulative_order_volume_{max_order_volume}
{}

protected:
Expand Down
8 changes: 6 additions & 2 deletions exchange/src/exchange/matching_cycle/dev/dev_cycle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ class DevMatchingCycle : public BaseMatchingCycle {
TickerMetricsPusher pusher;

public:
DevMatchingCycle(TickerContainer tickers, TraderContainer& traders, common::decimal_price order_fee) :
BaseMatchingCycle(std::move(tickers), traders, order_fee), pusher(traders)
DevMatchingCycle(
TickerContainer tickers, TraderContainer& traders,
common::decimal_price order_fee, common::decimal_quantity max_order_volume
) :
BaseMatchingCycle(std::move(tickers), traders, order_fee, max_order_volume),
pusher(traders)
{}

protected:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ namespace nutc::exchange {

class SandboxMatchingCycle : public DevMatchingCycle {
public:
SandboxMatchingCycle(TickerContainer tickers, TraderContainer& traders, common::decimal_price order_fee) :
DevMatchingCycle(std::move(tickers), traders, order_fee)
SandboxMatchingCycle(TickerContainer tickers, TraderContainer& traders, common::decimal_price order_fee, common::decimal_quantity max_order_volume) :
DevMatchingCycle(std::move(tickers), traders, order_fee, max_order_volume)
{}

private:
Expand Down
1 change: 1 addition & 0 deletions exchange/src/exchange/orders/orderbook/limit_orderbook.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "common/types/decimal.hpp"
#include "common/util.hpp"
#include "exchange/config/dynamic/config.hpp"
#include "exchange/orders/storage/order_storage.hpp"

namespace nutc::exchange {
Expand Down
Loading

0 comments on commit f4cfcd6

Please sign in to comment.