策略管理
AI 交易订单激活后,您可以管理其生命周期:临时暂停交易、恢复交易或提前赎回。本页介绍订单生命周期状态和每个状态转换对应的 API 方法。
订单生命周期
createAIOrder()
│
v
┌────────┐
│pending │
└───┬────┘
│ (auto-activates)
v
┌────────┐
┌────────│ active │────────┐
│ └───┬────┘ │
│ │ │
pauseAIOrder() │ redeemAIOrder()
│ │ │
v │ v
┌────────┐ │ ┌──────────┐
│ paused │ │ │ redeemed │
└───┬────┘ │ └──────────┘
│ │
resumeAIOrder() │ (cycle ends)
│ │
v v
┌────────┐ ┌───────────┐
│ active │ │ completed │
└────────┘ └───────────┘
AIOrderStatus 状态
| 状态 | 描述 | 可转换为 |
|---|---|---|
pending | 订单已提交,等待激活 | active、failed |
active | AI 代理正在活跃交易 | paused、completed、redeemed |
paused | 用户临时暂停交易 | active(恢复)、redeemed |
completed | 周期正常结束,利润已分配 | --(终态) |
redeemed | 用户在周期结束前赎回 | --(终态) |
failed | 订单激活失败 | --(终态) |
type AIOrderStatus =
| 'pending'
| 'active'
| 'paused'
| 'completed'
| 'redeemed'
| 'failed';
暂停订单
暂停订单会通知 AI 代理停止开立新仓位。根据策略配置,现有的持仓可能会被平仓。资金仍然保持锁定状态。
pauseAIOrder
import { OneEngineClient } from '@one_deploy/sdk';
const engine = new OneEngineClient({
apiKey: process.env.ONE_API_KEY!,
projectId: process.env.ONE_PROJECT_ID!,
});
const updatedOrder = await engine.pauseAIOrder('order_xyz789');
console.log('Status:', updatedOrder.status); // 'paused'
console.log('NAV at pause:', updatedOrder.currentNav);
方法签名
pauseAIOrder(orderId: string): Promise<AIOrder>
| 参数 | 类型 | 描述 |
|---|---|---|
orderId | string | 要暂停的订单 ID。必须处于 active 状态。 |
返回值: Promise<AIOrder> -- 更新后的订单对象,status: 'paused'。
警告
只能暂停处于 active 状态的订单。尝试暂停 pending、paused、completed、redeemed 或 failed 状态的订单会返回 400 错误。
恢复订单
恢复暂停的订单允许 AI 代理继续交易。
resumeAIOrder
const updatedOrder = await engine.resumeAIOrder('order_xyz789');
console.log('Status:', updatedOrder.status); // 'active'
方法签名
resumeAIOrder(orderId: string): Promise<AIOrder>
| 参数 | 类型 | 描述 |
|---|---|---|
orderId | string | 要恢复的订单 ID。必须处于 paused 状态。 |
返回值: Promise<AIOrder> -- 更新后的订单对象,status: 'active'。
警告
只能恢复处于 paused 状态的订单。锁定期计时器会持续运行,无论订单是暂停还是活跃状态 -- 暂停不会延长周期时长。
赎回订单
赎回订单会在周期结束前提取资金。如果周期尚未完成,将收取提前赎回罚金。详见提前赎回了解罚金计算方式。
redeemAIOrder
const result = await engine.redeemAIOrder('order_xyz789');
console.log('Status:', result.order.status); // 'redeemed'
console.log('Final NAV:', result.finalNav);
console.log('Penalty:', result.penaltyAmount);
console.log('Net payout:', result.netPayout);
console.log('Payout address:', result.payoutAddress);
console.log('Payout tx:', result.transactionHash);
方法签名
redeemAIOrder(orderId: string): Promise<AIRedemptionResult>
| 参数 | 类型 | 描述 |
|---|---|---|
orderId | string | 要赎回的订单 ID。必须处于 active 或 paused 状态。 |
AIRedemptionResult 类型
interface AIRedemptionResult {
/** The updated order object with status 'redeemed'. */
order: AIOrder;
/** NAV at the time of redemption. */
finalNav: number;
/** Gross profit before penalty (finalNav - invested amount). */
grossProfit: number;
/** Penalty amount deducted for early withdrawal. 0 if the cycle has completed. */
penaltyAmount: number;
/** Penalty percentage applied. */
penaltyPercent: number;
/** Net amount paid out to the user (finalNav - penaltyAmount). */
netPayout: number;
/** Wallet address the payout was sent to. */
payoutAddress: string;
/** On-chain transaction hash for the payout. */
transactionHash: string;
/** Completion rate at the time of redemption (0-1). */
completionRate: number;
/** ISO 8601 timestamp of the redemption. */
redeemedAt: string;
}
管理活跃订单
以下是一个完整示例,展示了包含暂停/恢复和赎回操作的订单管理页面。
import { useState, useEffect } from 'react';
import { OneEngineClient } from '@one_deploy/sdk';
import type { AIOrder, AIRedemptionResult } from '@one_deploy/sdk';
interface OrderManagementProps {
engine: OneEngineClient;
orderId: string;
}
function OrderManagement({ engine, orderId }: OrderManagementProps) {
const [order, setOrder] = useState<AIOrder | null>(null);
const [redemption, setRedemption] = useState<AIRedemptionResult | null>(null);
const [loading, setLoading] = useState(true);
const [actionLoading, setActionLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
// Load order details
useEffect(() => {
engine
.getAIOrder(orderId, { includeNavHistory: false })
.then(setOrder)
.finally(() => setLoading(false));
}, [orderId]);
const handlePause = async () => {
setActionLoading(true);
setError(null);
try {
const updated = await engine.pauseAIOrder(orderId);
setOrder(updated);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to pause');
} finally {
setActionLoading(false);
}
};
const handleResume = async () => {
setActionLoading(true);
setError(null);
try {
const updated = await engine.resumeAIOrder(orderId);
setOrder(updated);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to resume');
} finally {
setActionLoading(false);
}
};
const handleRedeem = async () => {
setActionLoading(true);
setError(null);
try {
const result = await engine.redeemAIOrder(orderId);
setOrder(result.order);
setRedemption(result);
} catch (err) {
setError(err instanceof Error ? err.message : 'Failed to redeem');
} finally {
setActionLoading(false);
}
};
if (loading || !order) return <ActivityIndicator />;
const isTerminal = ['completed', 'redeemed', 'failed'].includes(order.status);
return (
<View style={styles.container}>
<Text style={styles.heading}>{order.strategyName}</Text>
<Text>Order ID: {order.id}</Text>
<Text>Status: {order.status}</Text>
<Text>Pair: {order.pair}</Text>
<Text>Invested: ${order.amount.toFixed(2)}</Text>
<Text>Current NAV: ${order.currentNav.toFixed(2)}</Text>
<Text>
P&L: {order.unrealisedPnl >= 0 ? '+' : ''}${order.unrealisedPnl.toFixed(2)}
({order.unrealisedPnlPercent.toFixed(2)}%)
</Text>
<Text>Cycle: {order.cycleDays} days</Text>
<Text>Expires: {new Date(order.expiresAt).toLocaleDateString()}</Text>
{error && <Text style={styles.error}>{error}</Text>}
{/* Redemption result */}
{redemption && (
<View style={styles.redemptionInfo}>
<Text>Redeemed at: {new Date(redemption.redeemedAt).toLocaleString()}</Text>
<Text>Final NAV: ${redemption.finalNav.toFixed(2)}</Text>
<Text>Penalty: ${redemption.penaltyAmount.toFixed(2)} ({redemption.penaltyPercent}%)</Text>
<Text>Net payout: ${redemption.netPayout.toFixed(2)}</Text>
<Text>Tx: {redemption.transactionHash}</Text>
</View>
)}
{/* Action buttons */}
{!isTerminal && (
<View style={styles.actions}>
{order.status === 'active' && (
<Pressable onPress={handlePause} disabled={actionLoading}>
<Text style={styles.pauseButton}>
{actionLoading ? 'Pausing...' : 'Pause Trading'}
</Text>
</Pressable>
)}
{order.status === 'paused' && (
<Pressable onPress={handleResume} disabled={actionLoading}>
<Text style={styles.resumeButton}>
{actionLoading ? 'Resuming...' : 'Resume Trading'}
</Text>
</Pressable>
)}
{(order.status === 'active' || order.status === 'paused') && (
<Pressable onPress={handleRedeem} disabled={actionLoading}>
<Text style={styles.redeemButton}>
{actionLoading ? 'Redeeming...' : 'Redeem (Early Withdrawal)'}
</Text>
</Pressable>
)}
</View>
)}
</View>
);
}