创建订单
创建 AI 交易订单遵循逐步构建的流程:选择策略、链、等级、周期和交易对,然后设置投资金额并提交。本页介绍 createAIOrder API 方法、CreateAIOrderRequest 类型,以及完整的端到端示例。
构建流程
1. Select Strategy ──> useAIStrategies / getAIStrategies
2. Select Chain ──> OneChainSelector
3. Select Tier ──> OneTierSelector
4. Select Cycle ──> OneCycleSelector
5. Select Pair ──> OnePairSelector
6. Set Amount ──> Text input (validated against min/max)
7. Create Order ──> createAIOrder(request)
createAIOrder API
方法签名
createAIOrder(request: CreateAIOrderRequest): Promise<AIOrder>
CreateAIOrderRequest 类型
interface CreateAIOrderRequest {
/** The strategy ID to use for this order. */
strategyId: string;
/** Chain ID where the order will be executed. */
chainId: number;
/** Tier ID within the selected strategy. */
tierId: string;
/** Investment cycle duration in days. */
cycleDays: number;
/** Trading pair symbol, e.g. "BTC_USDT". */
pair: string;
/** Investment amount in the quote currency (e.g. USDT). */
amount: number;
/** Optional wallet address to fund from. Uses default wallet if omitted. */
walletAddress?: string;
/** Optional metadata attached to the order. */
metadata?: Record<string, string>;
}
AIOrder 类型
interface AIOrder {
/** Unique order identifier. */
id: string;
/** The strategy used for this order. */
strategyId: string;
/** Strategy name (denormalised for display). */
strategyName: string;
/** Chain ID. */
chainId: number;
/** Tier ID. */
tierId: string;
/** Trading pair symbol. */
pair: string;
/** Investment amount in quote currency. */
amount: number;
/** Investment cycle duration in days. */
cycleDays: number;
/** Investor share rate at the time of order creation. */
shareRate: number;
/** Current order status. */
status: AIOrderStatus;
/** Current net asset value (NAV) of the order. */
currentNav: number;
/** Unrealised profit/loss amount. */
unrealisedPnl: number;
/** Unrealised profit/loss percentage. */
unrealisedPnlPercent: number;
/** ISO 8601 timestamp when the order was created. */
createdAt: string;
/** ISO 8601 timestamp when the lock period ends. */
expiresAt: string;
/** ISO 8601 timestamp when the order was completed or redeemed, or null. */
closedAt: string | null;
/** Wallet address that funded the order. */
walletAddress: string;
/** Optional metadata. */
metadata?: Record<string, string>;
}
AIOrderStatus 枚举
type AIOrderStatus =
| 'pending' // Order submitted, awaiting activation
| 'active' // AI agent is actively trading
| 'paused' // Trading temporarily paused by user
| 'completed' // Cycle ended, profits distributed
| 'redeemed' // User withdrew before cycle end
| 'failed'; // Order failed to activate
基本订单创建
import { OneEngineClient } from '@one_deploy/sdk';
import { setAITradingAccessToken } from '@one_deploy/sdk';
// Set token before making AI trading calls
setAITradingAccessToken(userToken);
const engine = new OneEngineClient({
apiKey: process.env.ONE_API_KEY!,
projectId: process.env.ONE_PROJECT_ID!,
});
const order = await engine.createAIOrder({
strategyId: 'strat_abc123',
chainId: 8453, // Base
tierId: 'tier_gold',
cycleDays: 30,
pair: 'ETH_USDT',
amount: 500,
});
console.log('Order ID:', order.id);
console.log('Status:', order.status); // 'pending'
console.log('Share rate:', order.shareRate); // 0.70
console.log('Expires at:', order.expiresAt);
完整构建流程示例
以下示例展示了一个完整的 React Native 页面,引导用户逐步完成构建流程的每一步。
import { useState } from 'react';
import {
setAITradingAccessToken,
useAIStrategies,
OneChainSelector,
OneTierSelector,
OneCycleSelector,
OnePairSelector,
OneEngineClient,
DEFAULT_SHARE_RATES,
} from '@one_deploy/sdk';
import type {
AIStrategy,
Tier,
TradingPair,
AIOrder,
CreateAIOrderRequest,
} from '@one_deploy/sdk';
// Initialise the engine client
const engine = new OneEngineClient({
apiKey: 'YOUR_API_KEY',
projectId: 'YOUR_PROJECT_ID',
});
type BuilderStep = 'strategy' | 'chain' | 'tier' | 'cycle' | 'pair' | 'amount' | 'confirm';
function CreateOrderScreen() {
const [step, setStep] = useState<BuilderStep>('strategy');
const [strategy, setStrategy] = useState<AIStrategy | null>(null);
const [chainId, setChainId] = useState<number | null>(null);
const [tier, setTier] = useState<Tier | null>(null);
const [cycleDays, setCycleDays] = useState<number | null>(null);
const [pair, setPair] = useState<TradingPair | null>(null);
const [amount, setAmount] = useState<string>('');
const [order, setOrder] = useState<AIOrder | null>(null);
const [error, setError] = useState<string | null>(null);
const [submitting, setSubmitting] = useState(false);
const { strategies, isLoading } = useAIStrategies();
// Step 1: Select Strategy
const renderStrategyStep = () => (
<FlatList
data={strategies}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<Pressable
onPress={() => {
setStrategy(item);
setStep('chain');
}}
>
<View style={styles.card}>
<Text style={styles.name}>{item.name}</Text>
<Text>{item.category} -- {item.riskLevel} risk</Text>
<Text>APY: {item.expectedApy}%</Text>
</View>
</Pressable>
)}
/>
);
// Step 2: Select Chain
const renderChainStep = () => (
<OneChainSelector
supportedChains={strategy!.supportedChains}
onSelect={(id) => {
setChainId(id);
setStep('tier');
}}
/>
);
// Step 3: Select Tier
const renderTierStep = () => (
<OneTierSelector
tiers={strategy!.tiers}
onSelect={(selectedTier) => {
setTier(selectedTier);
setStep('cycle');
}}
/>
);
// Step 4: Select Cycle
const renderCycleStep = () => (
<OneCycleSelector
strategyId={strategy!.id}
onSelect={(days) => {
setCycleDays(days);
setStep('pair');
}}
/>
);
// Step 5: Select Pair
const renderPairStep = () => (
<OnePairSelector
strategyId={strategy!.id}
chainId={chainId!}
onSelect={(selectedPair) => {
setPair(selectedPair);
setStep('amount');
}}
/>
);
// Step 6: Set Amount
const renderAmountStep = () => (
<View style={styles.amountContainer}>
<Text>Enter investment amount ({pair!.quoteAsset}):</Text>
<TextInput
style={styles.input}
value={amount}
onChangeText={setAmount}
keyboardType="decimal-pad"
placeholder={`Min: ${strategy!.minInvestment}`}
/>
<Text style={styles.shareInfo}>
Share rate: {((DEFAULT_SHARE_RATES[cycleDays!] ?? 0) * 100).toFixed(0)}%
</Text>
<Pressable
onPress={() => setStep('confirm')}
disabled={!amount || parseFloat(amount) < strategy!.minInvestment}
>
<Text style={styles.button}>Review Order</Text>
</Pressable>
</View>
);
// Step 7: Confirm and Submit
const handleSubmit = async () => {
setSubmitting(true);
setError(null);
try {
const request: CreateAIOrderRequest = {
strategyId: strategy!.id,
chainId: chainId!,
tierId: tier!.id,
cycleDays: cycleDays!,
pair: pair!.symbol,
amount: parseFloat(amount),
};
const result = await engine.createAIOrder(request);
setOrder(result);
} catch (err) {
setError(err instanceof Error ? err.message : 'Order creation failed');
} finally {
setSubmitting(false);
}
};
const renderConfirmStep = () => (
<View style={styles.confirm}>
<Text style={styles.heading}>Order Summary</Text>
<Text>Strategy: {strategy!.name}</Text>
<Text>Chain ID: {chainId}</Text>
<Text>Tier: {tier!.name}</Text>
<Text>Cycle: {cycleDays} days</Text>
<Text>Pair: {pair!.symbol}</Text>
<Text>Amount: {amount} {pair!.quoteAsset}</Text>
<Text>
Share rate: {((DEFAULT_SHARE_RATES[cycleDays!] ?? 0) * 100).toFixed(0)}%
</Text>
{error && <Text style={styles.error}>{error}</Text>}
{order ? (
<View style={styles.success}>
<Text>Order created successfully.</Text>
<Text>Order ID: {order.id}</Text>
<Text>Status: {order.status}</Text>
<Text>Expires: {new Date(order.expiresAt).toLocaleDateString()}</Text>
</View>
) : (
<Pressable onPress={handleSubmit} disabled={submitting}>
<Text style={styles.button}>
{submitting ? 'Submitting...' : 'Confirm Order'}
</Text>
</Pressable>
)}
</View>
);
// Render current step
if (isLoading) return <ActivityIndicator />;
switch (step) {
case 'strategy': return renderStrategyStep();
case 'chain': return renderChainStep();
case 'tier': return renderTierStep();
case 'cycle': return renderCycleStep();
case 'pair': return renderPairStep();
case 'amount': return renderAmountStep();
case 'confirm': return renderConfirmStep();
}
}
验证规则
在调用 createAIOrder 之前,请确保请求通过以下验证:
| 字段 | 规则 |
|---|---|
strategyId | 必须引用一个活跃策略(isActive: true) |
chainId | 必须在策略的 supportedChains 数组中 |
tierId | 必须是策略 tiers 数组中的有效等级 ID |
cycleDays | 必须在策略的 availableCycles 数组中 |
pair | 必须在策略的 supportedPairs 中,且在所选链上处于活跃状态 |
amount | 必须 >= strategy.minInvestment 且 <= strategy.maxInvestment(如已设置) |
如果任何验证失败,API 将返回 400 错误并附带描述性消息。