Trading Agent Template
The Lockstep MCP repo includes a cloneable template in examples/trading-agent/ that any developer can use as a starting point for building an AI trading agent.
Template structure
examples/trading-agent/
├── src/
│ ├── agent.ts # Entry point + lifecycle
│ ├── mcp/
│ │ ├── lockstep.ts # Client for Lockstep MCP
│ │ └── uniswap.ts # Client for Uniswap v4 MCP (stub)
│ ├── strategies/
│ │ ├── base-strategy.ts # BaseStrategy interface
│ │ ├── arbitrage.ts
│ │ ├── arbitrage-internal.ts
│ │ ├── momentum.ts
│ │ └── market-making.ts
│ ├── risk/ # Position sizing, stop loss, exposure
│ └── capital/ # Fee manager, profit tracker
├── agent-config.yaml
└── README.mdAgent lifecycle
Connect to MCPs
Browse proposals
Calls list_proposals and evaluate_proposal to find proposals that match the agent's strategy and risk profile.
Register as agent
Calls register_trading_agent with the target capital, collateral amount, minimum return guarantee, and profit split. The collateral is locked on-chain.
Wait for funding
Periodically polls get_my_agent_status until the status transitions to Active — meaning investors have committed enough capital.
Trading loop
The strategy scans for opportunities. For each trade, it decides whether to route via the Lockstep smart router (internal pools) or Uniswap MCP (external pools). P&L is reported periodically.
// Main loop (simplified)
while (cycle.isActive()) {
const state = await getMarketState();
const signal = await strategy.evaluate(state);
if (signal) {
const route = await lockstepMCP.call("smart_route", {
token_in: signal.tokenIn,
token_out: signal.tokenOut,
amount_in: signal.amount,
execute: true,
});
}
await lockstepMCP.call("report_pnl", {
agent_id: agentId,
current_balance: await escrow.getBalance(),
open_positions: strategy.getOpenPositions(),
});
await sleep(strategy.interval);
}Close cycle
Custom strategy example
Implement the BaseStrategy interface to create your own strategy:
import { BaseStrategy, Opportunity, TradeResult } from "./base-strategy.js";
export class MyCustomStrategy implements BaseStrategy {
name = "MyCustomStrategy";
description = "Follows RSI signals on ETH/USDC";
init(riskLimits) {
this.riskLimits = riskLimits;
}
async scan(lockstepMCP, uniswapMCP): Promise<Opportunity[]> {
// Your signal detection logic here
return [];
}
async execute(opp, lockstepMCP, uniswapMCP): Promise<TradeResult> {
const route = await lockstepMCP.call("smart_route", {
token_in: opp.tokenIn,
token_out: opp.tokenOut,
amount_in: opp.size,
execute: true,
});
return { success: true, txHash: route.txHash };
}
async shouldClose(position, mcp): Promise<boolean> {
return position.age > 3600;
}
}Built-in strategies