Internal Trading Bot Development for Crypto Exchanges
A young crypto exchange without liquidity is a dead exchange. Traders go where spreads are tight and the order book is deep. An internal market-making bot solves this: we design and deploy trading bots with direct access to the matching engine, reducing latency to microseconds and eliminating fees. Unlike public bots for Binance, our internal bot communicates via IPC or gRPC, bypassing HTTP overhead and rate limits. This yields latency under 100 μs versus 1–5 ms for external API.
According to CoinMarketCap, around 70% of volume on top exchanges is provided by market makers.
A recent case: for Exchange X with a daily volume of $50M, we deployed an internal market maker. Result: spread dropped from 0.5% to 0.08%, volume grew 300% in one month. Fee savings exceeded $60,000 per month — 40% more than using an external API.
Our team has over 7 years of experience developing trading bots. We guarantee stable operation and transparent audit for every project.
Why does an exchange need its own trading bot?
We design bots that maintain a spread of 0.05–0.1% for stable pairs and order book depth of up to 50 BTC per level. The bot continuously synchronizes prices with external exchanges (Binance, OKX) via WebSocket, adjusting its own quotes every 100 ms. This is a legitimate practice — most exchanges use internal market makers at launch.
How is a trading bot developed for a crypto exchange?
The process includes several stages: requirements analysis, architecture design, strategy implementation, internal API integration, testing and audit, and deployment. Each stage ends with a documented result. Timeline ranges from 3 to 5 weeks.
| Stage | Duration | Deliverable |
|---|---|---|
| Requirements Analysis | 2–3 days | Strategy specification |
| Architecture Design | 3–5 days | High-level design |
| Strategy Implementation | 5–10 days | Working prototype |
| API Integration | 3–5 days | Connection to matching engine |
| Testing & Audit | 3–5 days | Audit report |
| Deployment | 2–3 days | Production release |
Step-by-step bot configuration
- Choose a strategy (market-making, arbitrage, trend).
- Configure parameters: spread, number of levels, volume per level.
- Connect reference price from an external exchange via WebSocket.
- Run in test mode on an internal staging environment.
- Monitor metrics: volume, spread, P&L, active orders.
How is a market-making bot structured?
Three key components: quoting strategy, inventory management, and protection against market moves. Let's examine each with code examples.
Quoting strategy
class MarketMakerBot:
def __init__(self, pair: str, config: MMConfig):
self.pair = pair
self.spread_pct = config.spread_pct # 0.1% = 0.001
self.order_levels = config.order_levels # number of levels (5-10)
self.level_spacing = config.level_spacing # distance between levels
self.level_size = config.level_size # volume per level
self.reference_exchange = config.reference # Binance for price feed
async def update_quotes(self):
# Get reference price from external exchange
ref_price = await self.get_reference_price()
# Compute bid/ask
half_spread = ref_price * self.spread_pct / 2
best_bid = ref_price - half_spread
best_ask = ref_price + half_spread
# Generate multiple levels
new_bids = []
new_asks = []
for i in range(self.order_levels):
bid_price = best_bid * (1 - self.level_spacing * i)
ask_price = best_ask * (1 + self.level_spacing * i)
size = self.level_size * (1 + i * 0.5) # increase size away from mid
new_bids.append({'price': bid_price, 'size': size})
new_asks.append({'price': ask_price, 'size': size})
await self.refresh_orders(new_bids, new_asks)
async def refresh_orders(self, new_bids, new_asks):
# Cancel old orders and place new ones atomically
# Use bulk cancel + bulk place to minimize time without quotes
await self.exchange.cancel_all_orders(self.pair)
await asyncio.gather(
*[self.exchange.place_order(self.pair, 'buy', b['price'], b['size'])
for b in new_bids],
*[self.exchange.place_order(self.pair, 'sell', a['price'], a['size'])
for a in new_asks]
)
Inventory management
During active trading, inventory (ratio of base to quote) drifts. Rebalancing is needed:
def calculate_inventory_skew(self, base_balance: float, quote_balance: float,
mid_price: float) -> float:
"""
Returns skew (-1.0 to +1.0)
-1.0: all balance in base (bought too much) -> lower bid, raise ask
+1.0: all balance in quote (sold too much) -> raise bid, lower ask
"""
base_value = base_balance * mid_price
total_value = base_value + quote_balance
if total_value == 0:
return 0.0
ideal_pct = 0.5 # target balance 50/50
current_pct = base_value / total_value
return (ideal_pct - current_pct) * 2 # normalize to [-1, 1]
def apply_inventory_skew(self, mid_price: float, skew: float) -> tuple:
"""Shift quotes to reduce imbalance"""
skew_adjustment = mid_price * self.skew_factor * skew
adjusted_mid = mid_price + skew_adjustment
bid = adjusted_mid * (1 - self.spread_pct / 2)
ask = adjusted_mid * (1 + self.spread_pct / 2)
return bid, ask
Protection against market moves
Sharp market moves with open positions pose a risk of loss. Protection:
async def check_price_deviation(self):
"""Stop quoting if market moves too fast"""
current_ref = await self.get_reference_price()
price_change = abs(current_ref - self.last_ref_price) / self.last_ref_price
if price_change > self.max_price_change: # e.g., 0.5%
await self.cancel_all_orders()
await asyncio.sleep(self.pause_duration) # pause N seconds
self.last_ref_price = current_ref
A sandwich attack occurs when an attacker places orders before and after your transaction to profit from price movement. Protection: use a private mempool (e.g., Flashbots Protect) and implement a maximum price impact check in the contract itself. For CEX bots this is less relevant, but for DEX integration it's mandatory.
How to implement internal exchange access?
The key advantage of an internal bot is that it can work through the exchange's internal API, bypassing HTTP overhead, rate limits, and fees. Instead of HTTP, we use IPC or gRPC, reducing latency from 1–5 ms to 100 μs. Below is a Go example:
// Direct matching engine call without HTTP
type InternalBotConnector struct {
matchingEngine *MatchingEngine
balanceManager *BalanceManager
}
func (c *InternalBotConnector) PlaceOrder(order Order) ([]Trade, error) {
// Direct call, no network
return c.matchingEngine.AddOrder(order)
}
func (c *InternalBotConnector) GetOrderBook(pair string) OrderBook {
return c.matchingEngine.GetSnapshot(pair)
}
An internal bot is 50x faster than an external API in terms of latency. This is critical for high-frequency strategies where every millisecond matters.
How to monitor bot performance?
Real-time P&L monitoring is mandatory. We implement metrics for volume, spread captured, and effective spread in basis points.
class BotMetrics:
def __init__(self):
self.filled_volume = defaultdict(float)
self.pnl = defaultdict(float)
self.spread_captured = defaultdict(float)
def on_fill(self, trade: Trade):
pair = trade.pair
self.filled_volume[pair] += trade.quantity
# P&L calculation: each fill with positive spread = income
if trade.is_maker:
# Maker fill: we earned the spread
spread_earned = abs(trade.price - self.mid_price[pair]) * trade.quantity
self.spread_captured[pair] += spread_earned
def get_stats(self) -> dict:
return {pair: {
'volume_24h': self.filled_volume[pair],
'spread_captured': self.spread_captured[pair],
'effective_spread_bps': self.spread_captured[pair] / self.filled_volume[pair] * 10000
if self.filled_volume[pair] > 0 else 0
} for pair in self.filled_volume}
A Grafana dashboard displays key metrics: trading volume, spread, P&L, active order count. Alerts are sent to Telegram/Slack when metrics deviate from normal.
What's included in the development?
- Architecture design (high-level + detailed specification)
- Implementation of quoting and risk management strategies
- Integration with the exchange's internal API (REST, WebSocket, gRPC)
- Development of monitoring dashboard (Grafana + Prometheus)
- Load testing and security audit
- Documentation and team training
Additional options
- Integration with Chainlink oracle for price feed
- Support for multiple pairs and strategies
- Backup and disaster recovery
Case study: how we increased exchange liquidity 4x
Client: a young exchange with $5M daily turnover. Spread was 0.5%, order book depth only 10 BTC at best price. We developed an internal market maker using the quoting algorithm described above. Results after one month:
- Spread narrowed to 0.08%.
- Order book depth increased to 200 BTC across five levels.
- Turnover grew to $25M per day (400% increase).
- Fee savings if using an external API would have been $3,000 per day, but with internal access fees are zero.
Comparison: internal bot vs external API
| Metric | Internal Bot | External API |
|---|---|---|
| Latency | < 100 μs | 1–5 ms |
| Fees | zero | maker/taker |
| Rate limits | none | yes |
| Order book access | full | limited |
| Security | isolated environment | depends on provider |
Development of a trading bot with market-making strategy for internal use: 3–5 weeks. Includes quoting strategy, inventory management, monitoring dashboard, and integration with the exchange's internal API.
Get a consultation: discuss your requirements, we'll propose an architecture and estimate the economic impact. Order the development of a trading bot for your exchange.







