Crypto Exchange Trading Bot Development

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1 servicesAll 1306 services
Crypto Exchange Trading Bot Development
Medium
~1-2 weeks
FAQ
Blockchain Development Services
Blockchain Development Stages
Latest works
  • image_website-b2b-advance_0.png
    B2B ADVANCE company website development
    1214
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    852
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1041
  • image_logo-advance_0.png
    B2B Advance company logo design
    561
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    823

Exchange Trading Bot Development

A bot for your own exchange is different from a bot for Binance. Here you have direct access to internal API, ability to market make without network latency, control over commissions. This is both a liquidity provisioning tool and a monetization tool for the exchange.

Why Exchange Needs Its Own Bots

Young exchange without liquidity is dead. Traders go where there's tight spread and deep orderbook. Solution: internal market-making bot that:

  • Maintains tight spread (0.05–0.1% for stable pairs)
  • Keeps orderbook depth (sufficient volume at each level)
  • Watches price vs external exchanges (Binance, OKX)

This is legitimate practice — most young exchanges use internal market makers on launch.

Market Maker Bot Architecture

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 farther 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

With active trading, inventory (base/quote ratio) shifts. Needs rebalancing:

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 50/50 balance
    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 from Market Moves

Sharp market move with open positions is risky. Protection:

async def check_price_deviation(self):
    """Stop quoting on sharp market move"""
    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

Internal Exchange Access

Key advantage of internal bot — direct access to exchange internal API, bypassing:

  • HTTP overhead (internal call via IPC or gRPC)
  • Rate limits (internal bots excluded)
  • Commissions (MM bot may have zero or negative commissions)
// 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)
}

This reduces latency from 1–5 ms (HTTP) to < 100 microseconds.

Monitoring and P&L

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}

Developing MM bot with quoting strategy, inventory management, and monitoring dashboard: 3–5 weeks. Includes strategy, inventory manager, monitoring, and internal API integration.