Skip to main content

Strategy Management

Once an AI trading order is active, you can manage its lifecycle: pause trading temporarily, resume it, or redeem early. This page covers the order lifecycle states and the API methods for each transition.

Order Lifecycle

                  createAIOrder()

v
┌────────┐
│pending │
└───┬────┘
│ (auto-activates)
v
┌────────┐
┌────────│ active │────────┐
│ └───┬────┘ │
│ │ │
pauseAIOrder() │ redeemAIOrder()
│ │ │
v │ v
┌────────┐ │ ┌──────────┐
│ paused │ │ │ redeemed │
└───┬────┘ │ └──────────┘
│ │
resumeAIOrder() │ (cycle ends)
│ │
v v
┌────────┐ ┌───────────┐
│ active │ │ completed │
└────────┘ └───────────┘

AIOrderStatus States

StatusDescriptionCan Transition To
pendingOrder submitted, awaiting activationactive, failed
activeAI agent is actively tradingpaused, completed, redeemed
pausedTrading temporarily halted by useractive (resumed), redeemed
completedCycle ended normally, profits distributed-- (terminal)
redeemedUser withdrew before cycle end-- (terminal)
failedOrder failed to activate-- (terminal)
type AIOrderStatus =
| 'pending'
| 'active'
| 'paused'
| 'completed'
| 'redeemed'
| 'failed';

Pausing an Order

Pausing an order tells the AI agent to stop opening new positions. Existing open positions may be closed depending on the strategy configuration. The capital remains locked.

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

Method Signature

pauseAIOrder(orderId: string): Promise<AIOrder>
ParameterTypeDescription
orderIdstringThe ID of the order to pause. Must be in active status.

Returns: Promise<AIOrder> -- the updated order object with status: 'paused'.

caution

You can only pause an order that is in active status. Attempting to pause a pending, paused, completed, redeemed, or failed order returns a 400 error.

Resuming an Order

Resuming a paused order allows the AI agent to continue trading.

resumeAIOrder

const updatedOrder = await engine.resumeAIOrder('order_xyz789');

console.log('Status:', updatedOrder.status); // 'active'

Method Signature

resumeAIOrder(orderId: string): Promise<AIOrder>
ParameterTypeDescription
orderIdstringThe ID of the order to resume. Must be in paused status.

Returns: Promise<AIOrder> -- the updated order object with status: 'active'.

caution

You can only resume an order that is in paused status. The lock period timer continues regardless of whether the order is paused or active -- pausing does not extend the cycle duration.

Redeeming an Order

Redeeming an order withdraws the capital before the cycle ends. If the cycle has not yet completed, an early withdrawal penalty applies. See Early Withdrawal for penalty calculation details.

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

Method Signature

redeemAIOrder(orderId: string): Promise<AIRedemptionResult>
ParameterTypeDescription
orderIdstringThe ID of the order to redeem. Must be active or paused.

AIRedemptionResult Type

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

Managing an Active Order

Here is a full example showing an order management screen with pause/resume and redeem actions.

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

Next Steps