Crypto Exchanger Development
A crypto exchanger is architecturally simpler than an exchange, but requires thoughtful business logic: liquidity management, rate formation, integration with payment systems. The exchanger's task is to buy cryptocurrency from one party and sell to another, converting it with a margin or directly.
Exchanger Models
Aggregator (Without Own Liquidity)
The exchanger routes transactions through partner APIs: Changelly, ChangeNow, SimpleSwap. No own reserves, profit comes from partner commissions or rate differences.
Pros: minimal operational risks, quick launch. Cons: partner dependency, limited rate control.
With Own Reserves
The exchanger holds reserves of different currencies. On exchange — issues from reserve, replenishes through exchanges.
Pros: full rate control, no partner dependency. Cons: operational risks (cryptocurrency storage), need for liquidity management.
Hybrid Model
Small exchanges from reserve, large ones through aggregator. Optimal choice for most projects.
Rate Formation
class RateCalculator:
def __init__(self, markup_pct: float = 1.5):
self.markup_pct = markup_pct # exchanger margin
self.price_feeds: dict[str, PriceFeed] = {} # prices from external exchanges
def get_exchange_rate(self, from_currency: str, to_currency: str,
amount: Decimal) -> ExchangeQuote:
# Get base market price
market_rate = self.price_feeds['binance'].get_price(from_currency, to_currency)
# Apply markup
markup_multiplier = Decimal(1) - Decimal(str(self.markup_pct)) / 100
client_rate = market_rate * markup_multiplier
# Account for network fee (sum lost on transfer)
network_fee = self.get_network_fee(to_currency)
result_amount = amount * client_rate - network_fee
return ExchangeQuote(
from_currency=from_currency,
to_currency=to_currency,
from_amount=amount,
to_amount=result_amount,
rate=client_rate,
network_fee=network_fee,
expires_at=datetime.utcnow() + timedelta(minutes=15), # fix rate for 15 min
)
Dynamic Margin
Margin depends on amount: small sums — high margin (high % fee from network), large — reduced for attracting big clients:
def get_dynamic_markup(self, amount_usd: Decimal) -> Decimal:
tiers = [
(Decimal('100'), Decimal('3.0')), # up to $100 — 3%
(Decimal('1000'), Decimal('2.0')), # up to $1000 — 2%
(Decimal('10000'), Decimal('1.5')), # up to $10k — 1.5%
(Decimal('inf'), Decimal('1.0')), # above $10k — 1%
]
for threshold, markup in tiers:
if amount_usd <= threshold:
return markup
return tiers[-1][1]
Exchange Process
1. Client specifies: give BTC, receive USDT, amount X
2. System: generates deposit address BTC, fixes rate for 15-30 min
3. Client sends BTC to deposit address
4. System: monitors blockchain, waits for N confirmations
5. After confirmation: converts and sends USDT to client address
6. Client receives notification with output TxHash
Key transaction states:
class ExchangeStatus(str, Enum):
CREATED = 'created' # created, awaiting deposit
AWAITING = 'awaiting' # deposit noticed, awaiting confirmation
CONFIRMING = 'confirming' # N/M confirmations
EXCHANGING = 'exchanging' # converting
SENDING = 'sending' # sending to client
FINISHED = 'finished' # completed
EXPIRED = 'expired' # time expired, no deposit
FAILED = 'failed' # error
REFUNDED = 'refunded' # refund
Reserve Management
class ReserveManager:
def reserve_for_exchange(self, currency: str, amount: Decimal) -> bool:
"""Reserve amount for client payout"""
available = self.get_available_reserve(currency)
if available < amount:
# Not enough reserves — need to top up
self.trigger_reserve_topup(currency, amount)
return False
# Atomically reserve
self.db.execute(
"UPDATE reserves SET reserved = reserved + %s WHERE currency = %s",
(amount, currency)
)
return True
def check_low_reserves(self):
"""Alert on low reserves"""
for currency, balance in self.get_all_reserves():
threshold = self.config.reserve_thresholds[currency]
if balance < threshold:
self.alerter.send(f"Low reserve: {currency} = {balance} (threshold: {threshold})")
Tech Stack
| Component | Technology |
|---|---|
| Backend | Python (FastAPI) / Go |
| Database | PostgreSQL |
| Blockchain monitoring | Own + Alchemy/QuickNode |
| Price data | Binance / CoinGecko API |
| Task queues | Redis + Celery / Bull |
| Frontend | React / Next.js |
| KYC/AML | Sumsub / Veriff (optional) |
Development Timeline
- MVP (2–3 pairs, no KYC): 6–8 weeks
- Full exchanger (10+ pairs, KYC, admin panel): 3–4 months
- Mobile app: +2–3 months







