mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-03 19:11:02 +08:00
## 功能描述 在创建和编辑 Trader 时,支持配置 AI 扫描决策间隔(scan_interval_minutes),允许用户自定义 AI 决策的频率。 ## 修改内容 ### 后端修改 (api/server.go) 1. **CreateTraderRequest** 添加 `ScanIntervalMinutes` 字段 2. **UpdateTraderRequest** 添加 `ScanIntervalMinutes` 字段和 `SystemPromptTemplate` 字段 3. **handleCreateTrader** 处理扫描间隔默认值(默认 3 分钟) 4. **handleUpdateTrader** 支持更新扫描间隔 5. **handleGetTraderConfig** 返回中添加 `scan_interval_minutes` 字段 ### 前端修改 #### web/src/types.ts - `CreateTraderRequest` 添加 `scan_interval_minutes?` 可选字段 - `TraderConfigData` 添加 `scan_interval_minutes` 必填字段 #### web/src/components/TraderConfigModal.tsx - 本地 `TraderConfigData` 接口添加 `scan_interval_minutes` - 初始状态设置默认值为 3 分钟 - 添加 UI 输入框(范围 1-60 分钟) - Label 优化为 "AI 扫描决策间隔 (分钟)" #### web/src/components/AITradersPage.tsx - `handleSaveEditTrader` 的更新请求中添加 `scan_interval_minutes` #### web/src/components/landing/CommunitySection.tsx - 修复 TypeScript 编译错误:定义 `CardProps` 接口 - 修正 `TestimonialCard` 组件的 prop 名称(author → authorName) ## 功能特性 - ✅ 支持 1-60 分钟的自定义间隔 - ✅ 默认值为 3 分钟 - ✅ UI 提示建议范围:3-10 分钟 - ✅ 创建和编辑时均支持配置 - ✅ 后端验证和处理默认值 ## 测试步骤 1. 创建新 Trader,设置自定义扫描间隔(如 10 分钟) 2. 验证 Trader 创建成功 3. 编辑现有 Trader,修改扫描间隔 4. 验证修改保存成功 5. 确认 AI 决策按照新的间隔执行
205 lines
4.3 KiB
TypeScript
205 lines
4.3 KiB
TypeScript
export interface SystemStatus {
|
|
trader_id: string;
|
|
trader_name: string;
|
|
ai_model: string;
|
|
is_running: boolean;
|
|
start_time: string;
|
|
runtime_minutes: number;
|
|
call_count: number;
|
|
initial_balance: number;
|
|
scan_interval: string;
|
|
stop_until: string;
|
|
last_reset_time: string;
|
|
ai_provider: string;
|
|
}
|
|
|
|
export interface AccountInfo {
|
|
total_equity: number;
|
|
wallet_balance: number;
|
|
unrealized_profit: number;
|
|
available_balance: number;
|
|
total_pnl: number;
|
|
total_pnl_pct: number;
|
|
total_unrealized_pnl: number;
|
|
initial_balance: number;
|
|
daily_pnl: number;
|
|
position_count: number;
|
|
margin_used: number;
|
|
margin_used_pct: number;
|
|
}
|
|
|
|
export interface Position {
|
|
symbol: string;
|
|
side: string;
|
|
entry_price: number;
|
|
mark_price: number;
|
|
quantity: number;
|
|
leverage: number;
|
|
unrealized_pnl: number;
|
|
unrealized_pnl_pct: number;
|
|
liquidation_price: number;
|
|
margin_used: number;
|
|
}
|
|
|
|
export interface DecisionAction {
|
|
action: string;
|
|
symbol: string;
|
|
quantity: number;
|
|
leverage: number;
|
|
price: number;
|
|
order_id: number;
|
|
timestamp: string;
|
|
success: boolean;
|
|
error?: string;
|
|
}
|
|
|
|
export interface AccountSnapshot {
|
|
total_balance: number;
|
|
available_balance: number;
|
|
total_unrealized_profit: number;
|
|
position_count: number;
|
|
margin_used_pct: number;
|
|
}
|
|
|
|
export interface DecisionRecord {
|
|
timestamp: string;
|
|
cycle_number: number;
|
|
input_prompt: string;
|
|
cot_trace: string;
|
|
decision_json: string;
|
|
account_state: AccountSnapshot;
|
|
positions: any[];
|
|
candidate_coins: string[];
|
|
decisions: DecisionAction[];
|
|
execution_log: string[];
|
|
success: boolean;
|
|
error_message?: string;
|
|
}
|
|
|
|
export interface Statistics {
|
|
total_cycles: number;
|
|
successful_cycles: number;
|
|
failed_cycles: number;
|
|
total_open_positions: number;
|
|
total_close_positions: number;
|
|
}
|
|
|
|
// AI Trading相关类型
|
|
export interface TraderInfo {
|
|
trader_id: string;
|
|
trader_name: string;
|
|
ai_model: string;
|
|
exchange_id?: string;
|
|
is_running?: boolean;
|
|
custom_prompt?: string;
|
|
}
|
|
|
|
export interface AIModel {
|
|
id: string;
|
|
name: string;
|
|
provider: string;
|
|
enabled: boolean;
|
|
apiKey?: string;
|
|
customApiUrl?: string;
|
|
customModelName?: string;
|
|
}
|
|
|
|
export interface Exchange {
|
|
id: string;
|
|
name: string;
|
|
type: 'cex' | 'dex';
|
|
enabled: boolean;
|
|
apiKey?: string;
|
|
secretKey?: string;
|
|
testnet?: boolean;
|
|
// Hyperliquid 特定字段
|
|
hyperliquidWalletAddr?: string;
|
|
// Aster 特定字段
|
|
asterUser?: string;
|
|
asterSigner?: string;
|
|
asterPrivateKey?: string;
|
|
}
|
|
|
|
export interface CreateTraderRequest {
|
|
name: string;
|
|
ai_model_id: string;
|
|
exchange_id: string;
|
|
initial_balance: number;
|
|
scan_interval_minutes?: number;
|
|
btc_eth_leverage?: number;
|
|
altcoin_leverage?: number;
|
|
trading_symbols?: string;
|
|
custom_prompt?: string;
|
|
override_base_prompt?: boolean;
|
|
system_prompt_template?: string;
|
|
is_cross_margin?: boolean;
|
|
use_coin_pool?: boolean;
|
|
use_oi_top?: boolean;
|
|
}
|
|
|
|
export interface UpdateModelConfigRequest {
|
|
models: {
|
|
[key: string]: {
|
|
enabled: boolean;
|
|
api_key: string;
|
|
custom_api_url?: string;
|
|
custom_model_name?: string;
|
|
};
|
|
};
|
|
}
|
|
|
|
export interface UpdateExchangeConfigRequest {
|
|
exchanges: {
|
|
[key: string]: {
|
|
enabled: boolean;
|
|
api_key: string;
|
|
secret_key: string;
|
|
testnet?: boolean;
|
|
// Hyperliquid 特定字段
|
|
hyperliquid_wallet_addr?: string;
|
|
// Aster 特定字段
|
|
aster_user?: string;
|
|
aster_signer?: string;
|
|
aster_private_key?: string;
|
|
};
|
|
};
|
|
}
|
|
|
|
// Competition related types
|
|
export interface CompetitionTraderData {
|
|
trader_id: string;
|
|
trader_name: string;
|
|
ai_model: string;
|
|
exchange: string;
|
|
total_equity: number;
|
|
total_pnl: number;
|
|
total_pnl_pct: number;
|
|
position_count: number;
|
|
margin_used_pct: number;
|
|
is_running: boolean;
|
|
}
|
|
|
|
export interface CompetitionData {
|
|
traders: CompetitionTraderData[];
|
|
count: number;
|
|
}
|
|
|
|
// Trader Configuration Data for View Modal
|
|
export interface TraderConfigData {
|
|
trader_id?: string;
|
|
trader_name: string;
|
|
ai_model: string;
|
|
exchange_id: string;
|
|
btc_eth_leverage: number;
|
|
altcoin_leverage: number;
|
|
trading_symbols: string;
|
|
custom_prompt: string;
|
|
override_base_prompt: boolean;
|
|
is_cross_margin: boolean;
|
|
use_coin_pool: boolean;
|
|
use_oi_top: boolean;
|
|
initial_balance: number;
|
|
scan_interval_minutes: number;
|
|
is_running: boolean;
|
|
}
|