跳至主要内容

机器人控制台

机器人控制台提供了对 AI 交易代理活动的实时可见性:包括 NAV(净资产价值)随时间的变化、单笔交易执行记录,以及各持仓的资金分配。使用 botSimulationEngine 服务进行客户端预测,使用 OneEngineClient API 获取实时数据。

botSimulationEngine 服务

botSimulationEngine 是一个客户端模拟引擎,可以预测未来的 NAV 走势,并针对历史数据回测策略。

import { botSimulationEngine } from '@one_deploy/sdk';

运行模拟

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)}`);
});

模拟选项

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 快照追踪活跃订单的净资产价值随时间的变化。AINavSnapshot 类型在投资组合、机器人控制台和模拟结果中均有使用。

AINavSnapshot 类型

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;
}

获取订单的 NAV 历史

特定订单的 NAV 快照可通过订单详情端点获取。

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)}%)`
);
});

交易历史

getAITradeHistory 方法返回 AI 代理为给定策略或订单执行的交易列表。

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}`
);
});

方法签名

getAITradeHistory(strategyId: string, limit?: number): Promise<AITradeExecution[]>
参数类型必填默认值描述
strategyIdstring--要查询的策略或订单 ID
limitnumber100返回的最大交易数量

AITradeExecution 类型

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;
}

交易分配

getAITradeAllocations 方法返回当前各持仓的资金分配情况。

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)}%`
);
});

方法签名

getAITradeAllocations(limit?: number): Promise<AITradeAllocation[]>
参数类型必填默认值描述
limitnumber50返回的最大分配数量

AITradeAllocation 类型

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;
}

构建控制台视图

以下是一个完整示例,将 NAV 图表、交易历史和分配情况整合到一个控制台页面中。

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>
);
}

后续步骤