Dev backtest (#1134)

This commit is contained in:
Rick
2025-11-28 21:34:27 +08:00
committed by GitHub
parent 04f006abad
commit 11b6c6ba3e
39 changed files with 9293 additions and 125 deletions

View File

@@ -0,0 +1,177 @@
import { useState } from 'react'
import type { DecisionRecord } from '../types'
import { t, type Language } from '../i18n/translations'
interface DecisionCardProps {
decision: DecisionRecord
language: Language
}
export function DecisionCard({ decision, language }: DecisionCardProps) {
const [showInputPrompt, setShowInputPrompt] = useState(false)
const [showCoT, setShowCoT] = useState(false)
return (
<div
className="rounded p-5 transition-all duration-300 hover:translate-y-[-2px]"
style={{
border: '1px solid #2B3139',
background: '#1E2329',
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.3)',
}}
>
<div className="flex items-start justify-between mb-3">
<div>
<div className="font-semibold" style={{ color: '#EAECEF' }}>
{t('cycle', language)} #{decision.cycle_number}
</div>
<div className="text-xs" style={{ color: '#848E9C' }}>
{new Date(decision.timestamp).toLocaleString()}
</div>
</div>
<div
className="px-3 py-1 rounded text-xs font-bold"
style={
decision.success
? { background: 'rgba(14, 203, 129, 0.1)', color: '#0ECB81' }
: { background: 'rgba(246, 70, 93, 0.1)', color: '#F6465D' }
}
>
{t(decision.success ? 'success' : 'failed', language)}
</div>
</div>
{decision.input_prompt && (
<div className="mb-3">
<button
onClick={() => setShowInputPrompt(!showInputPrompt)}
className="flex items-center gap-2 text-sm transition-colors"
style={{ color: '#60a5fa' }}
>
<span className="font-semibold">
📥 {t('inputPrompt', language)}
</span>
<span className="text-xs">
{showInputPrompt ? t('collapse', language) : t('expand', language)}
</span>
</button>
{showInputPrompt && (
<div
className="mt-2 rounded p-4 text-sm font-mono whitespace-pre-wrap max-h-96 overflow-y-auto"
style={{
background: '#0B0E11',
border: '1px solid #2B3139',
color: '#EAECEF',
}}
>
{decision.input_prompt}
</div>
)}
</div>
)}
{decision.cot_trace && (
<div className="mb-3">
<button
onClick={() => setShowCoT(!showCoT)}
className="flex items-center gap-2 text-sm transition-colors"
style={{ color: '#F0B90B' }}
>
<span className="font-semibold">
📤 {t('aiThinking', language)}
</span>
<span className="text-xs">
{showCoT ? t('collapse', language) : t('expand', language)}
</span>
</button>
{showCoT && (
<div
className="mt-2 rounded p-4 text-sm font-mono whitespace-pre-wrap max-h-96 overflow-y-auto"
style={{
background: '#0B0E11',
border: '1px solid #2B3139',
color: '#EAECEF',
}}
>
{decision.cot_trace}
</div>
)}
</div>
)}
{decision.decisions && decision.decisions.length > 0 && (
<div className="space-y-2 mb-3">
{decision.decisions.map((action, index) => (
<div
key={`${action.symbol}-${index}`}
className="flex items-center gap-2 text-sm rounded px-3 py-2"
style={{ background: '#0B0E11' }}
>
<span
className="font-mono font-bold"
style={{ color: '#EAECEF' }}
>
{action.symbol}
</span>
<span
className="px-2 py-0.5 rounded text-xs font-bold"
style={
action.action.includes('open')
? {
background: 'rgba(96, 165, 250, 0.1)',
color: '#60a5fa',
}
: action.action.includes('close')
? {
background: 'rgba(14, 203, 129, 0.1)',
color: '#0ECB81',
}
: {
background: 'rgba(248, 113, 113, 0.1)',
color: '#F87171',
}
}
>
{action.action}
</span>
{action.reasoning && (
<span
className="text-xs"
style={{ color: '#848E9C', flex: 1 }}
>
{action.reasoning}
</span>
)}
</div>
))}
</div>
)}
{decision.execution_log && decision.execution_log.length > 0 && (
<div
className="rounded p-3 text-xs font-mono space-y-1"
style={{ background: '#0B0E11', border: '1px solid #2B3139' }}
>
{decision.execution_log.map((log, index) => (
<div key={`${log}-${index}`} style={{ color: '#EAECEF' }}>
{log}
</div>
))}
</div>
)}
{decision.error_message && (
<div
className="rounded p-3 mt-3 text-sm"
style={{
background: 'rgba(246, 70, 93, 0.1)',
border: '1px solid rgba(246, 70, 93, 0.4)',
color: '#F6465D',
}}
>
{decision.error_message}
</div>
)}
</div>
)
}