mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-12 15:26:55 +08:00
feat: add debate arena and fix multiple issues
- Add AI debate arena for multi-AI trading decisions - Fix debate consensus calculation and display - Fix vote parsing to support both <decision> and <final_vote> tags - Fix JSON field name compatibility (stop_loss/stop_loss_pct) - Fix symbol validation to prevent AI hallucinating invalid symbols - Fix Bybit position side display (was uppercase, now lowercase for consistency) - Fix NOFX logo navigation to home page - Add detailed logging for debugging trade execution
This commit is contained in:
@@ -22,6 +22,12 @@ import type {
|
||||
BacktestRunMetadata,
|
||||
Strategy,
|
||||
StrategyConfig,
|
||||
DebateSession,
|
||||
DebateSessionWithDetails,
|
||||
CreateDebateRequest,
|
||||
DebateMessage,
|
||||
DebateVote,
|
||||
DebatePersonalityInfo,
|
||||
} from '../types'
|
||||
import { CryptoService } from './crypto'
|
||||
import { httpClient } from './httpClient'
|
||||
@@ -67,7 +73,7 @@ export const api = {
|
||||
async getTraders(): Promise<TraderInfo[]> {
|
||||
const result = await httpClient.get<TraderInfo[]>(`${API_BASE}/my-traders`)
|
||||
if (!result.success) throw new Error('获取trader列表失败')
|
||||
return result.data!
|
||||
return Array.isArray(result.data) ? result.data : []
|
||||
},
|
||||
|
||||
// 获取公开的交易员列表(无需认证)
|
||||
@@ -155,7 +161,7 @@ export const api = {
|
||||
async getModelConfigs(): Promise<AIModel[]> {
|
||||
const result = await httpClient.get<AIModel[]>(`${API_BASE}/models`)
|
||||
if (!result.success) throw new Error('获取模型配置失败')
|
||||
return result.data!
|
||||
return Array.isArray(result.data) ? result.data : []
|
||||
},
|
||||
|
||||
// 获取系统支持的AI模型列表(无需认证)
|
||||
@@ -623,9 +629,10 @@ export const api = {
|
||||
|
||||
// Strategy APIs
|
||||
async getStrategies(): Promise<Strategy[]> {
|
||||
const result = await httpClient.get<Strategy[]>(`${API_BASE}/strategies`)
|
||||
const result = await httpClient.get<{ strategies: Strategy[] }>(`${API_BASE}/strategies`)
|
||||
if (!result.success) throw new Error('获取策略列表失败')
|
||||
return result.data!
|
||||
const strategies = result.data?.strategies
|
||||
return Array.isArray(strategies) ? strategies : []
|
||||
},
|
||||
|
||||
async getStrategy(strategyId: string): Promise<Strategy> {
|
||||
@@ -685,4 +692,71 @@ export const api = {
|
||||
if (!result.success) throw new Error('复制策略失败')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
// Debate Arena APIs
|
||||
async getDebates(): Promise<DebateSession[]> {
|
||||
const result = await httpClient.get<DebateSession[]>(`${API_BASE}/debates`)
|
||||
if (!result.success) throw new Error('获取辩论列表失败')
|
||||
return Array.isArray(result.data) ? result.data : []
|
||||
},
|
||||
|
||||
async getDebate(debateId: string): Promise<DebateSessionWithDetails> {
|
||||
const result = await httpClient.get<DebateSessionWithDetails>(`${API_BASE}/debates/${debateId}`)
|
||||
if (!result.success) throw new Error('获取辩论详情失败')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async createDebate(request: CreateDebateRequest): Promise<DebateSessionWithDetails> {
|
||||
const result = await httpClient.post<DebateSessionWithDetails>(`${API_BASE}/debates`, request)
|
||||
if (!result.success) throw new Error('创建辩论失败')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async startDebate(debateId: string): Promise<void> {
|
||||
const result = await httpClient.post(`${API_BASE}/debates/${debateId}/start`)
|
||||
if (!result.success) throw new Error('启动辩论失败')
|
||||
},
|
||||
|
||||
async cancelDebate(debateId: string): Promise<void> {
|
||||
const result = await httpClient.post(`${API_BASE}/debates/${debateId}/cancel`)
|
||||
if (!result.success) throw new Error('取消辩论失败')
|
||||
},
|
||||
|
||||
async executeDebate(debateId: string, traderId: string): Promise<DebateSessionWithDetails> {
|
||||
const result = await httpClient.post<{ message: string; session: DebateSessionWithDetails }>(
|
||||
`${API_BASE}/debates/${debateId}/execute`,
|
||||
{ trader_id: traderId }
|
||||
)
|
||||
if (!result.success) throw new Error('执行交易失败')
|
||||
return result.data!.session
|
||||
},
|
||||
|
||||
async deleteDebate(debateId: string): Promise<void> {
|
||||
const result = await httpClient.delete(`${API_BASE}/debates/${debateId}`)
|
||||
if (!result.success) throw new Error('删除辩论失败')
|
||||
},
|
||||
|
||||
async getDebateMessages(debateId: string): Promise<DebateMessage[]> {
|
||||
const result = await httpClient.get<DebateMessage[]>(`${API_BASE}/debates/${debateId}/messages`)
|
||||
if (!result.success) throw new Error('获取辩论消息失败')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async getDebateVotes(debateId: string): Promise<DebateVote[]> {
|
||||
const result = await httpClient.get<DebateVote[]>(`${API_BASE}/debates/${debateId}/votes`)
|
||||
if (!result.success) throw new Error('获取辩论投票失败')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
async getDebatePersonalities(): Promise<DebatePersonalityInfo[]> {
|
||||
const result = await httpClient.get<DebatePersonalityInfo[]>(`${API_BASE}/debates/personalities`)
|
||||
if (!result.success) throw new Error('获取AI性格列表失败')
|
||||
return result.data!
|
||||
},
|
||||
|
||||
// SSE stream for live debate updates
|
||||
createDebateStream(debateId: string): EventSource {
|
||||
const token = localStorage.getItem('auth_token')
|
||||
return new EventSource(`${API_BASE}/debates/${debateId}/stream?token=${token}`)
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user