Skip to main content

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 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[]>
ParameterTypeRequiredDefaultDescription
strategyIdstringYes--Strategy or order ID to query
limitnumberNo100Maximum 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[]>
ParameterTypeRequiredDefaultDescription
limitnumberNo50Maximum 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