Bot Console
The bot console provides real-time visibility into what an AI trading agent is doing: NAV (net asset value) over time, individual trade executions, and capital allocations across positions. Use the botSimulationEngine service for client-side projections and the OneEngineClient API for live data.
botSimulationEngine Service
The botSimulationEngine is a client-side simulation engine that can project future NAV trajectories and back-test strategies against historical data.
import { botSimulationEngine } from '@one_deploy/sdk';
Running a Simulation
import { botSimulationEngine } from '@one_deploy/sdk';
const simulation = await botSimulationEngine.simulate({
strategyId: 'strat_abc123',
pair: 'ETH_USDT',
initialCapital: 1000,
cycleDays: 30,
riskLevel: 'moderate',
});
console.log('Projected final NAV:', simulation.projectedNav);
console.log('Projected return:', simulation.projectedReturn, '%');
console.log('Max drawdown:', simulation.maxDrawdown, '%');
console.log('Snapshots:', simulation.snapshots.length);
// Each snapshot represents one simulated day
simulation.snapshots.forEach((snap) => {
console.log(`Day ${snap.day}: NAV $${snap.nav.toFixed(2)}`);
});
Simulation Options
interface BotSimulationOptions {
/** Strategy to simulate. */
strategyId: string;
/** Trading pair. */
pair: string;
/** Starting capital in quote currency. */
initialCapital: number;
/** Number of days to simulate. */
cycleDays: number;
/** Risk level for the simulation. */
riskLevel: RiskLevel;
/** Number of Monte Carlo iterations. Defaults to 1000. */
iterations?: number;
/** Use historical data for back-testing. Defaults to false (forward projection). */
useHistorical?: boolean;
}
interface BotSimulationResult {
projectedNav: number;
projectedReturn: number;
maxDrawdown: number;
sharpeRatio: number;
winRate: number;
totalTrades: number;
snapshots: BotSimulationSnapshot[];
}
interface BotSimulationSnapshot {
day: number;
nav: number;
dailyReturn: number;
cumulativeReturn: number;
drawdown: number;
}
NAV Snapshots
NAV snapshots track the net asset value of an active order over time. The AINavSnapshot type is used across the portfolio, bot console, and simulation results.
AINavSnapshot Type
interface AINavSnapshot {
/** ISO 8601 timestamp of the snapshot. */
timestamp: string;
/** Net asset value at this point in time. */
nav: number;
/** Daily return percentage. */
dailyReturn: number;
/** Cumulative return percentage since order creation. */
cumulativeReturn: number;
/** Current drawdown from peak NAV. */
drawdown: number;
/** Number of open positions at this snapshot. */
openPositions: number;
}
Fetching NAV History for an Order
NAV snapshots for a specific order are available through the order detail endpoint.
import { OneEngineClient } from '@one_deploy/sdk';
const engine = new OneEngineClient({
apiKey: process.env.ONE_API_KEY!,
projectId: process.env.ONE_PROJECT_ID!,
});
// Fetch order with NAV history included
const order = await engine.getAIOrder('order_xyz789', {
includeNavHistory: true,
});
order.navHistory?.forEach((snap) => {
console.log(
`${snap.timestamp}: NAV $${snap.nav.toFixed(2)} ` +
`(${snap.cumulativeReturn >= 0 ? '+' : ''}${snap.cumulativeReturn.toFixed(2)}%)`
);
});
Trade History
The getAITradeHistory method returns the list of trades executed by the AI agent for a given strategy or order.
getAITradeHistory
const trades = await engine.getAITradeHistory('strat_abc123', 50);
trades.forEach((trade) => {
console.log(
`${trade.action} ${trade.pair} @ ${trade.price} -- ` +
`Size: ${trade.size} -- P&L: ${trade.realisedPnl}`
);
});
Method Signature
getAITradeHistory(strategyId: string, limit?: number): Promise<AITradeExecution[]>
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
strategyId | string | Yes | -- | Strategy or order ID to query |
limit | number | No | 100 | Maximum number of trades to return |
AITradeExecution Type
interface AITradeExecution {
/** Unique trade execution identifier. */
id: string;
/** The order ID this trade belongs to. */
orderId: string;
/** Strategy ID. */
strategyId: string;
/** Trading pair symbol. */
pair: string;
/** Trade action taken. */
action: TradeAction;
/** Execution price. */
price: number;
/** Trade size in base currency. */
size: number;
/** Trade size in quote currency. */
quoteSize: number;
/** Realised profit/loss from this trade (0 for opening trades). */
realisedPnl: number;
/** Fee paid for this trade. */
fee: number;
/** ISO 8601 execution timestamp. */
executedAt: string;
/** On-chain transaction hash, if applicable. */
txHash?: string;
}
Trade Allocations
The getAITradeAllocations method returns the current capital allocation across open positions.
getAITradeAllocations
const allocations = await engine.getAITradeAllocations(20);
allocations.forEach((alloc) => {
console.log(
`${alloc.pair}: ${alloc.direction} -- ` +
`Size: $${alloc.notionalValue.toFixed(2)} -- ` +
`Weight: ${(alloc.weight * 100).toFixed(1)}%`
);
});
Method Signature
getAITradeAllocations(limit?: number): Promise<AITradeAllocation[]>
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
limit | number | No | 50 | Maximum number of allocations to return |
AITradeAllocation Type
interface AITradeAllocation {
/** Unique allocation identifier. */
id: string;
/** Order ID this allocation belongs to. */
orderId: string;
/** Trading pair symbol. */
pair: string;
/** Position direction. */
direction: 'long' | 'short';
/** Entry price. */
entryPrice: number;
/** Current mark price. */
markPrice: number;
/** Position size in base currency. */
size: number;
/** Notional value in quote currency. */
notionalValue: number;
/** Portfolio weight (0-1). */
weight: number;
/** Unrealised P&L. */
unrealisedPnl: number;
/** Unrealised P&L percentage. */
unrealisedPnlPercent: number;
/** ISO 8601 timestamp when this position was opened. */
openedAt: string;
}
Building a Console View
Here is a complete example combining NAV chart, trade history, and allocations into a single console screen.
import { useState, useEffect } from 'react';
import { OneEngineClient, botSimulationEngine } from '@one_deploy/sdk';
import type {
AINavSnapshot,
AITradeExecution,
AITradeAllocation,
} from '@one_deploy/sdk';
interface ConsoleProps {
engine: OneEngineClient;
orderId: string;
strategyId: string;
}
function BotConsole({ engine, orderId, strategyId }: ConsoleProps) {
const [navHistory, setNavHistory] = useState<AINavSnapshot[]>([]);
const [trades, setTrades] = useState<AITradeExecution[]>([]);
const [allocations, setAllocations] = useState<AITradeAllocation[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadData() {
setLoading(true);
try {
const [orderDetail, tradeHistory, tradeAllocations] = await Promise.all([
engine.getAIOrder(orderId, { includeNavHistory: true }),
engine.getAITradeHistory(strategyId, 50),
engine.getAITradeAllocations(20),
]);
setNavHistory(orderDetail.navHistory ?? []);
setTrades(tradeHistory);
setAllocations(tradeAllocations);
} finally {
setLoading(false);
}
}
loadData();
}, [orderId, strategyId]);
if (loading) return <ActivityIndicator />;
return (
<ScrollView style={styles.console}>
{/* NAV Chart */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Net Asset Value</Text>
{navHistory.length > 0 && (
<View>
<Text style={styles.currentNav}>
${navHistory[navHistory.length - 1].nav.toFixed(2)}
</Text>
<Text
style={{
color:
navHistory[navHistory.length - 1].cumulativeReturn >= 0
? '#22c55e'
: '#ef4444',
}}
>
{navHistory[navHistory.length - 1].cumulativeReturn >= 0 ? '+' : ''}
{navHistory[navHistory.length - 1].cumulativeReturn.toFixed(2)}%
</Text>
{/* Render your chart component with navHistory data */}
</View>
)}
</View>
{/* Open Positions */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Open Positions ({allocations.length})</Text>
{allocations.map((alloc) => (
<View key={alloc.id} style={styles.allocationRow}>
<Text style={styles.pair}>{alloc.pair}</Text>
<Text>{alloc.direction.toUpperCase()}</Text>
<Text>Entry: ${alloc.entryPrice.toFixed(4)}</Text>
<Text>Mark: ${alloc.markPrice.toFixed(4)}</Text>
<Text>Size: ${alloc.notionalValue.toFixed(2)}</Text>
<Text>Weight: {(alloc.weight * 100).toFixed(1)}%</Text>
<Text
style={{
color: alloc.unrealisedPnl >= 0 ? '#22c55e' : '#ef4444',
}}
>
P&L: {alloc.unrealisedPnl >= 0 ? '+' : ''}
${alloc.unrealisedPnl.toFixed(2)} ({alloc.unrealisedPnlPercent.toFixed(2)}%)
</Text>
</View>
))}
</View>
{/* Trade History */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Recent Trades ({trades.length})</Text>
{trades.map((trade) => (
<View key={trade.id} style={styles.tradeRow}>
<Text style={styles.action}>{trade.action.toUpperCase()}</Text>
<Text>{trade.pair}</Text>
<Text>Price: ${trade.price.toFixed(4)}</Text>
<Text>Size: {trade.size}</Text>
<Text>P&L: ${trade.realisedPnl.toFixed(2)}</Text>
<Text style={styles.timestamp}>
{new Date(trade.executedAt).toLocaleString()}
</Text>
</View>
))}
</View>
</ScrollView>
);
}
Next Steps
- Strategy Management -- pause, resume, or redeem an order from the console.
- Portfolio Dashboard -- aggregated view across all orders.
- Early Withdrawal -- understand penalties for early redemption.