FastMM documentation
FastMM C++ API 0.6.0
Public headers, tier 1 and tier 2
Loading...
Searching...
No Matches
fees.hpp
Go to the documentation of this file.
1#pragma once
2// Fee rates per instrument, in centi-basis-points (integer) of the fill notional.
3//
4// Sign convention: a POSITIVE rate is a fee the account pays, a NEGATIVE rate is a rebate the
5// account receives. `maker_bps = 10` is Binance spot VIP 0 (0.1 %), `maker_bps = -0.5` is a maker
6// rebate of half a basis point.
7//
8// FeeTable is a default pair plus per-instrument overrides. The configuration maps each venue's
9// [venues.<name>.fees] onto the instruments of that venue and [[instruments]] maker_bps /
10// taker_bps override one instrument (fee_table, config/config.hpp). The simulated venue charges
11// fills with it (sim::FeeModel is this type) and the engine hands the same table to strategies
12// (StrategyContext::fees).
13#include "fastmm/core/enums.hpp"
16
17#include <array>
18#include <cstdint>
19#include <type_traits>
20
21namespace fastmm {
22
23// One maker/taker pair. 1 cbps == 0.01 bps == 1e-6 of the notional.
24struct FeeRates {
25 std::int32_t maker_cbps = 0; // > 0 fee, < 0 rebate
26 std::int32_t taker_cbps = 0;
28 [[nodiscard]] static FeeRates from_bps(double maker_bps, double taker_bps) noexcept {
29 FeeRates f;
30 f.maker_cbps = to_cbps(maker_bps);
31 f.taker_cbps = to_cbps(taker_bps);
32 return f;
33 }
34 [[nodiscard]] static constexpr std::int32_t to_cbps(double bps) noexcept {
35 return static_cast<std::int32_t>(bps * 100.0 + (bps < 0 ? -0.5 : 0.5));
36 }
37 [[nodiscard]] constexpr double maker_bps() const noexcept { return maker_cbps / 100.0; }
38 [[nodiscard]] constexpr double taker_bps() const noexcept { return taker_cbps / 100.0; }
39 [[nodiscard]] constexpr std::int64_t cbps(Liquidity l) const noexcept {
41 }
42 [[nodiscard]] constexpr Notional fee(Notional notional, Liquidity l) const noexcept {
43 return Notional::from_raw(
44 static_cast<std::int64_t>(static_cast<Int128>(notional.raw) * cbps(l) / 1'000'000));
45 }
46 [[nodiscard]] constexpr Notional fee(Price px, Qty qty, Liquidity l) const noexcept {
47 return fee(mul(px, qty), l);
48 }
49 [[nodiscard]] constexpr bool operator==(const FeeRates&) const noexcept = default;
50};
52class FeeTable {
53 public:
54 constexpr FeeTable() noexcept = default;
55
56 // Every instrument pays the same rates.
57 [[nodiscard]] static FeeTable from_bps(double maker_bps, double taker_bps) noexcept {
58 return uniform(FeeRates::from_bps(maker_bps, taker_bps));
59 }
60 [[nodiscard]] static FeeTable uniform(FeeRates s) noexcept {
61 FeeTable f;
62 f.default_ = s;
63 return f;
64 }
65
66 // Rates of every instrument without an override.
67 void set_default(FeeRates s) noexcept { default_ = s; }
68 void set_instrument(InstrumentId id, FeeRates s) noexcept {
69 if (id.value >= kMaxInstruments) return;
70 per_[id.value] = s;
71 has_[id.value / 64] |= std::uint64_t{1} << (id.value % 64);
72 }
73 [[nodiscard]] constexpr bool has_override(InstrumentId id) const noexcept {
74 return id.value < kMaxInstruments &&
75 (has_[id.value / 64] & (std::uint64_t{1} << (id.value % 64))) != 0;
76 }
77 [[nodiscard]] constexpr const FeeRates& default_schedule() const noexcept { return default_; }
78 [[nodiscard]] constexpr const FeeRates& schedule(InstrumentId id) const noexcept {
79 return has_override(id) ? per_[id.value] : default_;
80 }
81 // True when every override equals the default, so one line describes the whole run.
82 [[nodiscard]] constexpr bool is_uniform() const noexcept {
83 for (std::size_t i = 0; i < kMaxInstruments; ++i) {
84 if (has_override(InstrumentId{static_cast<std::uint32_t>(i)}) && !(per_[i] == default_))
85 return false;
86 }
87 return true;
88 }
89
90 [[nodiscard]] constexpr std::int64_t maker_cbps() const noexcept { return default_.maker_cbps; }
91 [[nodiscard]] constexpr std::int64_t taker_cbps() const noexcept { return default_.taker_cbps; }
93 [[nodiscard]] constexpr Notional fee(InstrumentId id,
94 Price px,
95 Qty qty,
96 Liquidity l) const noexcept {
97 return schedule(id).fee(px, qty, l);
98 }
99 // The default rates; for callers without an instrument (the sim exchange server).
100 [[nodiscard]] constexpr Notional fee(Price px, Qty qty, Liquidity l) const noexcept {
101 return default_.fee(px, qty, l);
103 [[nodiscard]] constexpr Notional fee(Notional n, Liquidity l) const noexcept {
104 return default_.fee(n, l);
106
107 private:
108 FeeRates default_{};
109 std::array<FeeRates, kMaxInstruments> per_{};
110 std::array<std::uint64_t, kMaxInstruments / 64> has_{};
111};
112
113static_assert(std::is_trivially_copyable_v<FeeTable>);
114
115} // namespace fastmm
Definition fees.hpp:54
constexpr FeeTable() noexcept=default
constexpr std::int64_t maker_cbps() const noexcept
Definition fees.hpp:92
static FeeTable uniform(FeeRates s) noexcept
Definition fees.hpp:62
void set_default(FeeRates s) noexcept
Rates of every instrument without an override.
Definition fees.hpp:69
constexpr const FeeRates & default_schedule() const noexcept
Definition fees.hpp:79
void set_instrument(InstrumentId id, FeeRates s) noexcept
Definition fees.hpp:70
constexpr Notional fee(InstrumentId id, Price px, Qty qty, Liquidity l) const noexcept
Definition fees.hpp:95
constexpr bool is_uniform() const noexcept
True when every override equals the default, so one line describes the whole run.
Definition fees.hpp:84
constexpr const FeeRates & schedule(InstrumentId id) const noexcept
Definition fees.hpp:80
static FeeTable from_bps(double maker_bps, double taker_bps) noexcept
Every instrument pays the same rates.
Definition fees.hpp:59
constexpr bool has_override(InstrumentId id) const noexcept
Definition fees.hpp:75
constexpr std::int64_t taker_cbps() const noexcept
Definition fees.hpp:93
All engine enumerations.
Fixed<Tag>: int64 fixed point with a global 1e-8 scale (ADR-0001).
Instrument: the single definition of a tradable contract (5.3 / 5.15).
Definition strategy.hpp:16
StrongId< struct InstrumentTag, std::uint32_t > InstrumentId
Dense index into the engine's instrument table.
Definition strong_id.hpp:38
constexpr std::size_t kMaxInstruments
Definition instrument.hpp:26
constexpr Notional mul(Price p, Qty q) noexcept
price * qty with a 128-bit intermediate, truncated toward zero to 1e-8.
Definition fixed_point.hpp:362
Liquidity
Definition enums.hpp:434
One maker/taker pair. 1 cbps == 0.01 bps == 1e-6 of the notional.
Definition fees.hpp:26
constexpr Notional fee(Notional notional, Liquidity l) const noexcept
Definition fees.hpp:44
constexpr double maker_bps() const noexcept
Definition fees.hpp:39
static FeeRates from_bps(double maker_bps, double taker_bps) noexcept
Definition fees.hpp:30
std::int32_t maker_cbps
> 0 fee, < 0 rebate
Definition fees.hpp:27
std::int32_t taker_cbps
Definition fees.hpp:28
constexpr bool operator==(const FeeRates &) const noexcept=default
static constexpr std::int32_t to_cbps(double bps) noexcept
Definition fees.hpp:36
constexpr double taker_bps() const noexcept
Definition fees.hpp:40
constexpr std::int64_t cbps(Liquidity l) const noexcept
Definition fees.hpp:41
static constexpr Fixed from_raw(std::int64_t r) noexcept
Definition fixed_point.hpp:155