Exchange Fee Structure Development
Fee structure is a key monetization tool. Too high — traders leave, too low — business becomes unprofitable. Proper system gives flexibility: attract large traders with discounts, retain market makers with zero or negative fees (rebate).
Fee Models
Maker-Taker Model
Standard for most modern CEX. Maker adds liquidity (limit order not immediately executed), taker removes liquidity (market order or limit immediately executed).
- Maker fee: usually 0.01–0.1% (lower, sometimes negative — rebate)
- Taker fee: usually 0.05–0.2%
Negative maker fee (rebate) — exchange pays trader for providing liquidity. Done by Kraken, Binance for high-tier MM.
Volume-Based Tiers
type FeeTier struct {
MinVolume30d Decimal // USD volume for 30 days
MakerFee Decimal // % (can be negative for rebate)
TakerFee Decimal // %
Label string
}
var DefaultTiers = []FeeTier{
{MinVolume30d: Decimal("0"), MakerFee: Decimal("0.10"), TakerFee: Decimal("0.20"), Label: "Regular"},
{MinVolume30d: Decimal("100000"), MakerFee: Decimal("0.08"), TakerFee: Decimal("0.16"), Label: "VIP 1"},
{MinVolume30d: Decimal("500000"), MakerFee: Decimal("0.05"), TakerFee: Decimal("0.12"), Label: "VIP 2"},
{MinVolume30d: Decimal("2000000"), MakerFee: Decimal("0.02"), TakerFee: Decimal("0.08"), Label: "VIP 3"},
{MinVolume30d: Decimal("10000000"), MakerFee: Decimal("0.00"), TakerFee: Decimal("0.05"), Label: "VIP 4"},
{MinVolume30d: Decimal("50000000"), MakerFee: Decimal("-0.01"), TakerFee: Decimal("0.03"), Label: "VIP 5"},
}
func (fs *FeeSystem) GetUserTier(userID int64) FeeTier {
volume30d := fs.db.GetUserVolume30d(userID)
var currentTier FeeTier = DefaultTiers[0]
for _, tier := range DefaultTiers {
if volume30d.GreaterThanOrEqual(tier.MinVolume30d) {
currentTier = tier
}
}
return currentTier
}
Platform Token Discount
Binance set standard: paying commission with platform token gives 25% discount.
Per-Pair Fee Overrides
Different pairs can have different fees:
- Stablecoin pairs (USDT/USDC): 0.01% — minimal, highly competitive
- Meme coins: 0.3–0.5% — less competition
- Insider pairs (own token): 0% for market makers
Fee Calculation and Application on Trade
On each fill matching engine must:
- Determine tier of each participant
- Calculate fee
- Apply discounts
- Debit fee from balance
func (fe *FeeEngine) ProcessTrade(trade Trade) (FeeDeductions, error) {
takerFee := fe.Calculate(trade.TakerUserID, trade.Value, Taker)
makerFee := fe.Calculate(trade.MakerUserID, trade.Value, Maker)
// Taker receives base currency minus taker fee
takerReceives := trade.Quantity.Sub(takerFee.FinalFee.Div(trade.Price))
// Maker receives quote currency minus maker fee
makerReceives := trade.Value.Sub(makerFee.FinalFee)
// If maker rebate (negative fee) — add bonus
if makerFee.FinalFee.IsNegative() {
makerReceives = trade.Value.Add(makerFee.FinalFee.Abs())
}
return FeeDeductions{
TakerDeduction: takerFee.FinalFee,
MakerDeduction: makerFee.FinalFee,
TakerReceives: takerReceives,
MakerReceives: makerReceives,
PlatformEarned: takerFee.FinalFee.Add(makerFee.FinalFee),
}, nil
}
Special Fee Structures
Promo Codes and Referral Discounts
type PromoCode struct {
Code string
DiscountPct Decimal
MaxUses int
ExpiresAt time.Time
UserID *int64 // nil = available to all
}
type ReferralProgram struct {
ReferrerRebatePct Decimal // % of referred user's fee
RefereeDiscountPct Decimal // discount for referred
MaxDepth int // referral network levels
}
Monitoring and Analytics
SELECT
DATE(t.created_at) AS date,
t.pair_id,
SUM(t.taker_fee) AS taker_revenue,
SUM(CASE WHEN t.maker_fee > 0 THEN t.maker_fee ELSE 0 END) AS maker_revenue,
SUM(CASE WHEN t.maker_fee < 0 THEN t.maker_fee ELSE 0 END) AS maker_rebates_paid,
SUM(t.taker_fee) + SUM(t.maker_fee) AS net_revenue,
COUNT(*) AS trade_count
FROM trades t
WHERE t.created_at >= NOW() - INTERVAL '30 days'
GROUP BY DATE(t.created_at), t.pair_id
ORDER BY date DESC;
Full fee system with maker-taker model, volume tiers, token discounts and referral program: 3–4 weeks.







