交易所费用模型
Exchange Fee Model
题目详情
交易所通常采用 maker-taker 费用模型,为提供流动性的 maker 订单和消耗流动性的 taker 订单设置不同费率。大交易量客户可享受阶梯折扣。
任务:实现一个费用计算器,支持 maker/taker 费率、阶梯折扣和产品差异化定价。
英文原题
Cryptocurrency and traditional exchanges utilize tiered fee structures to incentivize liquidity provision and high-volume trading. Accurately modeling these fees based on a participant's rolling historical volume is essential for precise backtesting and live execution cost analysis.
Task
Implement an ExchangeFeeModel class to calculate maker and taker fees for trades based on a participant's trailing trading volume.
The class should support the following operations:
- ExchangeFeeModel(double wi
解析
问题分析
交易所通常采用 maker-taker 费率模型:提供流动性的 maker 订单支付较低费用甚至获得回扣,而消耗流动性的 taker 订单支付较高费用。一些交易所还实施阶梯费率(基于交易量)和产品差异化费率。
实现
struct FeeSchedule { double maker_bps, taker_bps; double volume_tier_bps[5]; };
class FeeCalculator {
std::unordered_map<std::string, FeeSchedule> product_fees_;
std::unordered_map<std::string, double> monthly_volumes_; // per account
public:
double calculate(const std::string& account, const std::string& product,
bool is_maker, double notional) {
auto& fee = product_fees_[product];
double rate = is_maker ? fee.maker_bps : fee.taker_bps;
double volume = monthly_volumes_[account];
// 阶梯折扣:月交易量每超过一档,费率降 10%
for (int i = 0; i < 5 && volume > fee.volume_tier_bps[i]; ++i)
rate *= 0.9;
return notional * rate / 10000.0;
}
};复杂度与边界
- 时间复杂度:calculate 为 O(1),最多遍历 5 个阶梯
- 空间复杂度:O(P + A),P 产品数 + A 账户数
- 边界条件:(1) 未知产品应使用默认费率 (2) notional 为 0 或负数返回 0 (3) maker_bps 可以为负(回扣) (4) 月度重置时清空 volume
英文解析
Analysis
Exchanges typically use a maker-taker fee model: maker orders that provide liquidity pay lower fees or even receive rebates, while taker orders that consume liquidity pay higher fees. Some exchanges also use tiered fee schedules (based on volume) and product-differentiated rates.
Solution
struct FeeSchedule { double maker_bps, taker_bps; double volume_tier_bps[5]; };
class FeeCalculator {
std::unordered_map<std::string, FeeSchedule> product_fees_;
std::unordered_map<std::string, double> monthly_volumes_; // per account
public:
double calculate(const std::string& account, const std::string& product,
bool is_maker, double notional) {
auto& fee = product_fees_[product];
double rate = is_maker ? fee.maker_bps : fee.taker_bps;
double volume = monthly_volumes_[account];
// Tiered discount: each volume tier exceeded reduces rate by 10%
for (int i = 0; i < 5 && volume > fee.volume_tier_bps[i]; ++i)
rate *= 0.9;
return notional * rate / 10000.0;
}
};Complexity & Edge Cases
- Time complexity: calculate O(1), at most 5 tiers traversed
- Space complexity: O(P + A), P products + A accounts
- Edge cases: (1) Unknown product should use default rates (2) notional=0 or negative returns 0 (3) maker_bps can be negative (rebate) (4) Monthly reset clears volume counters
Key Considerations
- Fee timing: Maker rebates may be credited T+1, not immediately — real-time P&L must account for deferred credits
- Tier transitions: Volume thresholds trigger tier upgrades mid-month; must track cumulative volume to apply correct tier
- Multi-product fee schedules: Different products (equities, options, futures) have independent fee tables — model must support per-product configuration
- Negative fees: Maker rebates (negative fees) improve net execution cost; strategy optimization should favor maker execution when rebate exceeds spread