Agent Infrastructure Overview
Build sophisticated automated trading agents using Matchr’s infrastructure. Our platform provides the building blocks for algorithmic trading on prediction markets.
For Institutional Traders — Agent infrastructure is designed for
quantitative teams building automated strategies.
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Your Trading Agent │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Strategy │ │ Signal │ │ Risk │ │
│ │ Engine │──▶│ Generator │──▶│ Manager │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────┐ │
│ │ Execution Engine │ │
│ └─────────────────────────────────────────────────┘ │
│ │ │
└───────────────────────────┼───────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Matchr API Layer │
├─────────────────────────────────────────────────────────────┤
│ REST API │ WebSocket │ Smart Routing │ Webhooks │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Polymarket │ │ Kalshi │ │ Future │
│ CLOB │ │ API │ │ Platforms │
└─────────────┘ └─────────────┘ └─────────────┘
Getting Started
1. API Key with Agent Permissions
Request an API key with elevated rate limits:
curl -X POST "https://api.matchr.xyz/v1/api-keys" \
-H "Authorization: Bearer YOUR_AUTH_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Trading Agent",
"type": "agent",
"permissions": ["read", "trade", "manage_orders"]
}'
Agent keys have:
10,000 requests/minute (vs 1,000 for standard)
Priority WebSocket connections
Dedicated support channel
2. Install the SDK
npm install @matchr/agent-sdk
3. Initialize the Client
import { MatchrAgent } from '@matchr/agent-sdk' ;
const agent = new MatchrAgent ({
apiKey: process . env . MATCHR_API_KEY ,
environment: 'production' , // or 'sandbox'
walletId: 'wallet_abc123'
});
await agent . connect ();
Real-Time Data Streams
Subscribe to Price Updates
// Subscribe to multiple markets
agent . subscribe ([ "mkt_yes123" , "mkt_no456" ], ( update ) => {
console . log ( ` ${ update . market_id } : ${ update . price } ` );
// React to price changes
if ( update . price < 0.4 && shouldBuy ( update . market_id )) {
agent . submitOrder ({
market_id: update . market_id ,
side: "buy" ,
type: "limit" ,
price: update . price ,
amount: 100 ,
});
}
});
Subscribe to Orderbook
agent . subscribeOrderbook ( "mkt_yes123" , ( orderbook ) => {
const spread = orderbook . asks [ 0 ]. price - orderbook . bids [ 0 ]. price ;
const midPrice = ( orderbook . asks [ 0 ]. price + orderbook . bids [ 0 ]. price ) / 2 ;
console . log ( `Spread: ${ spread } , Mid: ${ midPrice } ` );
});
Subscribe to Trades
agent . subscribeTrades ( "mkt_yes123" , ( trade ) => {
console . log ( `Trade: ${ trade . side } ${ trade . size } @ ${ trade . price } ` );
// Track flow
flowTracker . add ( trade );
});
Execution Engine
Smart Order Submission
// Market order with slippage protection
const order = await agent . submitOrder ({
market_id: "mkt_yes123" ,
side: "buy" ,
type: "market" ,
amount: 1000 ,
max_slippage: 0.02 , // 2% max slippage
});
// Limit order
const limitOrder = await agent . submitOrder ({
market_id: "mkt_yes123" ,
side: "buy" ,
type: "limit" ,
price: 0.5 ,
amount: 500 ,
time_in_force: "GTC" ,
});
TWAP Execution
Split large orders over time to minimize market impact:
const twapOrder = await agent . executeTWAP ({
market_id: "mkt_yes123" ,
side: "buy" ,
total_amount: 10000 ,
duration_minutes: 60 ,
slice_count: 12 , // Execute every 5 minutes
price_limit: 0.55 , // Don't buy above this price
});
// Monitor progress
twapOrder . on ( "slice_executed" , ( slice ) => {
console . log ( `Slice ${ slice . index } : ${ slice . amount } @ ${ slice . price } ` );
});
twapOrder . on ( "completed" , ( summary ) => {
console . log ( `TWAP complete. Avg price: ${ summary . average_price } ` );
});
Iceberg Orders
Execute large orders in smaller visible pieces:
const icebergOrder = await agent . executeIceberg ({
market_id: "mkt_yes123" ,
side: "buy" ,
total_amount: 5000 ,
visible_amount: 200 , // Show only 200 at a time
price: 0.52 ,
variance: 0.001 , // Random variance in visible size
});
Strategy Building Blocks
Market Making
class SimpleMarketMaker {
constructor ( agent , config ) {
this . agent = agent ;
this . spread = config . spread || 0.02 ;
this . size = config . size || 100 ;
this . maxPosition = config . maxPosition || 1000 ;
}
async run ( marketId ) {
const position = await this . agent . getPosition ( marketId );
const orderbook = await this . agent . getOrderbook ( marketId );
const midPrice = ( orderbook . bids [ 0 ]. price + orderbook . asks [ 0 ]. price ) / 2 ;
// Adjust quotes based on position
const skew = ( position . size / this . maxPosition ) * this . spread ;
const bidPrice = midPrice - this . spread / 2 - skew ;
const askPrice = midPrice + this . spread / 2 - skew ;
// Cancel existing orders
await this . agent . cancelAllOrders ( marketId );
// Place new quotes
if ( position . size < this . maxPosition ) {
await this . agent . submitOrder ({
market_id: marketId ,
side: "buy" ,
type: "limit" ,
price: bidPrice ,
amount: this . size ,
});
}
if ( position . size > - this . maxPosition ) {
await this . agent . submitOrder ({
market_id: marketId ,
side: "sell" ,
type: "limit" ,
price: askPrice ,
amount: this . size ,
});
}
}
}
Arbitrage Detection
class ArbitrageScanner {
constructor ( agent , minSpread = 0.03 ) {
this . agent = agent ;
this . minSpread = minSpread ;
}
async scan () {
const matches = await this . agent . getMatchedMarkets ();
const opportunities = [];
for ( const match of matches ) {
const spread = Math . abs (
match . polymarket . yes_price - match . kalshi . yes_price
);
if ( spread > this . minSpread ) {
opportunities . push ({
match_id: match . id ,
title: match . title ,
spread ,
buy_platform:
match . polymarket . yes_price < match . kalshi . yes_price
? "polymarket"
: "kalshi" ,
sell_platform:
match . polymarket . yes_price < match . kalshi . yes_price
? "kalshi"
: "polymarket" ,
expected_profit: spread - this . estimateFees ( match ),
});
}
}
return opportunities . sort (( a , b ) => b . expected_profit - a . expected_profit );
}
}
Signal Generation
class MomentumSignal {
constructor ( lookbackPeriod = 24 ) {
this . lookbackPeriod = lookbackPeriod ; // hours
this . priceHistory = new Map ();
}
async generate ( marketId , currentPrice ) {
const history = await this . getPriceHistory ( marketId );
if ( history . length < this . lookbackPeriod ) {
return { signal: "neutral" , confidence: 0 };
}
const oldPrice = history [ 0 ]. price ;
const momentum = ( currentPrice - oldPrice ) / oldPrice ;
if ( momentum > 0.05 ) {
return { signal: "bullish" , confidence: Math . min ( momentum * 10 , 1 ) };
} else if ( momentum < - 0.05 ) {
return { signal: "bearish" , confidence: Math . min ( - momentum * 10 , 1 ) };
}
return { signal: "neutral" , confidence: 0 };
}
}
Risk Management
Position Limits
const riskManager = agent . createRiskManager ({
maxPositionSize: 10000 , // Max $10K per position
maxTotalExposure: 50000 , // Max $50K total
maxDailyLoss: 2000 , // Stop trading if down $2K/day
maxDrawdown: 0.15 , // 15% max drawdown
categoryLimits: {
politics: 20000 ,
sports: 15000 ,
crypto: 10000 ,
},
});
// Check before trading
const canTrade = await riskManager . checkOrder ({
market_id: "mkt_yes123" ,
side: "buy" ,
amount: 500 ,
});
if ( ! canTrade . allowed ) {
console . log ( `Order blocked: ${ canTrade . reason } ` );
}
Stop Loss Management
// Set stop loss on position
await agent . setStopLoss ({
position_id: "pos_xyz789" ,
type: "trailing" ,
trail_percent: 0.1 , // 10% trailing stop
min_price: 0.3 , // Never sell below 0.30
});
// Portfolio-level stop
await agent . setPortfolioStop ({
daily_loss_limit: 2000 ,
action: "close_all" , // Close all positions if hit
});
Backtesting
Test strategies against historical data:
const backtest = await agent . backtest ({
strategy: myStrategy ,
markets: [ "mkt_yes123" , "mkt_no456" ],
start_date: "2025-01-01" ,
end_date: "2025-10-01" ,
initial_capital: 10000 ,
fees: {
maker: 0.001 ,
taker: 0.002 ,
},
});
console . log ( "Backtest Results:" );
console . log ( `Total Return: ${ backtest . totalReturn } %` );
console . log ( `Sharpe Ratio: ${ backtest . sharpeRatio } ` );
console . log ( `Max Drawdown: ${ backtest . maxDrawdown } %` );
console . log ( `Win Rate: ${ backtest . winRate } %` );
console . log ( `Total Trades: ${ backtest . totalTrades } ` );
Monitoring & Alerts
Set Up Alerts
// Price alerts
await agent . createAlert ({
type: "price" ,
market_id: "mkt_yes123" ,
condition: "crosses_above" ,
value: 0.6 ,
channel: "webhook" ,
webhook_url: "https://your-app.com/alerts" ,
});
// Position alerts
await agent . createAlert ({
type: "position_pnl" ,
position_id: "pos_xyz789" ,
condition: "below" ,
value: - 100 , // Alert if down $100
channel: "email" ,
});
// System alerts
await agent . createAlert ({
type: "connection" ,
condition: "disconnected" ,
channel: "sms" ,
});
const dashboard = await agent . getDashboard ();
console . log ( "Performance Summary:" );
console . log ( `PnL Today: $ ${ dashboard . pnl . today } ` );
console . log ( `PnL This Week: $ ${ dashboard . pnl . week } ` );
console . log ( `Open Positions: ${ dashboard . positions . open } ` );
console . log ( `Open Orders: ${ dashboard . orders . open } ` );
console . log ( `API Calls Today: ${ dashboard . api . calls_today } ` );
console . log ( `Rate Limit Usage: ${ dashboard . api . rate_limit_pct } %` );
Sandbox Environment
Test your agent without real money:
const agent = new MatchrAgent ({
apiKey: process . env . MATCHR_SANDBOX_KEY ,
environment: "sandbox" ,
});
// Sandbox features:
// - Simulated order matching
// - Fake USDC balance
// - Real market data
// - Full API compatibility
Best Practices
Handle Disconnections Implement reconnection logic with exponential backoff.
Use Idempotency Keys Prevent duplicate orders with client-side order IDs.
Log Everything Keep detailed logs for debugging and auditing.
Test in Sandbox Always test new strategies in sandbox first.
Rate Limits
Plan Requests/min WebSocket Connections Markets/Subscription Standard 1,000 2 50 Agent 10,000 10 500 Enterprise Custom Custom Custom
Support