Feature: Add multi-language support and UI improvements

- Add language context and translation system (Chinese/English)
- Enhance UI components with i18n support
- Update AILearning, EquityChart, and CompetitionPage
- Add language toggle in header
- Improve user experience with localized text
This commit is contained in:
tinkle
2025-10-28 22:25:36 +08:00
parent 4502ec4579
commit 641b772465
7 changed files with 484 additions and 103 deletions

View File

@@ -1,5 +1,7 @@
import { useEffect, useState } from 'react';
import useSWR from 'swr';
import { useLanguage } from '../contexts/LanguageContext';
import { t } from '../i18n/translations';
interface TradeOutcome {
symbol: string;
@@ -52,6 +54,7 @@ interface DecisionRecord {
const fetcher = (url: string) => fetch(url).then(res => res.json());
export default function AILearning({ traderId }: AILearningProps) {
const { language } = useLanguage();
const { data: performance, error } = useSWR<PerformanceAnalysis>(
`http://localhost:8080/api/performance?trader_id=${traderId}`,
fetcher,
@@ -68,7 +71,7 @@ export default function AILearning({ traderId }: AILearningProps) {
if (error) {
return (
<div className="rounded p-6" style={{ background: '#1E2329', border: '1px solid #2B3139' }}>
<div style={{ color: '#F6465D' }}> AI学习数据失败</div>
<div style={{ color: '#F6465D' }}>{t('loadingError', language)}</div>
</div>
);
}
@@ -76,7 +79,7 @@ export default function AILearning({ traderId }: AILearningProps) {
if (!performance) {
return (
<div className="rounded p-6" style={{ background: '#1E2329', border: '1px solid #2B3139' }}>
<div style={{ color: '#848E9C' }}>📊 ...</div>
<div style={{ color: '#848E9C' }}>📊 {t('loading', language)}</div>
</div>
);
}
@@ -86,10 +89,10 @@ export default function AILearning({ traderId }: AILearningProps) {
<div className="rounded p-6" style={{ background: '#1E2329', border: '1px solid #2B3139' }}>
<div className="flex items-center gap-2 mb-2">
<span className="text-xl">🧠</span>
<h2 className="text-lg font-bold" style={{ color: '#EAECEF' }}>AI </h2>
<h2 className="text-lg font-bold" style={{ color: '#EAECEF' }}>{t('aiLearning', language)}</h2>
</div>
<div style={{ color: '#848E9C' }}>
{t('noCompleteData', language)}
</div>
</div>
);
@@ -115,9 +118,9 @@ export default function AILearning({ traderId }: AILearningProps) {
🧠
</div>
<div>
<h2 className="text-2xl font-bold" style={{ color: '#EAECEF' }}>AI Learning & Reflection</h2>
<h2 className="text-2xl font-bold" style={{ color: '#EAECEF' }}>{t('aiLearning', language)}</h2>
<p className="text-sm" style={{ color: '#848E9C' }}>
{performance.total_trades} trades analyzed · Real-time evolution
{t('tradesAnalyzed', language, { count: performance.total_trades })}
</p>
</div>
</div>
@@ -150,10 +153,10 @@ export default function AILearning({ traderId }: AILearningProps) {
</div>
<div>
<h3 className="text-base font-bold" style={{ color: '#C4B5FD' }}>
Latest Reflection
{t('latestReflection', language)}
</h3>
<p className="text-xs" style={{ color: '#94A3B8' }}>
Cycle #{latestDecisions[0].cycle_number} · {new Date(latestDecisions[0].timestamp).toLocaleTimeString()}
{t('cycle', language)} #{latestDecisions[0].cycle_number} · {new Date(latestDecisions[0].timestamp).toLocaleTimeString()}
</p>
</div>
</div>
@@ -171,7 +174,7 @@ export default function AILearning({ traderId }: AILearningProps) {
{latestDecisions[0].cot_trace && (
<details className="mt-4">
<summary className="cursor-pointer text-sm font-semibold flex items-center gap-2 hover:opacity-80 transition-opacity" style={{ color: '#A78BFA' }}>
<span>📋 Full Chain of Thought</span>
<span>{t('fullCoT', language)}</span>
</summary>
<div className="mt-3 rounded-xl p-4 text-xs leading-relaxed whitespace-pre-wrap max-h-80 overflow-y-auto" style={{
background: 'rgba(0, 0, 0, 0.5)',
@@ -195,7 +198,7 @@ export default function AILearning({ traderId }: AILearningProps) {
border: '1px solid rgba(99, 102, 241, 0.2)',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)'
}}>
<div className="text-xs font-semibold mb-2" style={{ color: '#94A3B8' }}>Total Trades</div>
<div className="text-xs font-semibold mb-2" style={{ color: '#94A3B8' }}>{t('totalTrades', language)}</div>
<div className="text-3xl font-bold mono" style={{ color: '#E0E7FF' }}>
{performance.total_trades}
</div>
@@ -209,7 +212,7 @@ export default function AILearning({ traderId }: AILearningProps) {
border: `1px solid ${(performance.win_rate || 0) >= 50 ? 'rgba(14, 203, 129, 0.3)' : 'rgba(246, 70, 93, 0.3)'}`,
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)'
}}>
<div className="text-xs font-semibold mb-2" style={{ color: '#94A3B8' }}>Win Rate</div>
<div className="text-xs font-semibold mb-2" style={{ color: '#94A3B8' }}>{t('winRate', language)}</div>
<div className="text-3xl font-bold mono" style={{
color: (performance.win_rate || 0) >= 50 ? '#10B981' : '#F87171'
}}>
@@ -226,7 +229,7 @@ export default function AILearning({ traderId }: AILearningProps) {
border: '1px solid rgba(14, 203, 129, 0.2)',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)'
}}>
<div className="text-xs font-semibold mb-2" style={{ color: '#94A3B8' }}>Avg Win</div>
<div className="text-xs font-semibold mb-2" style={{ color: '#94A3B8' }}>{t('avgWin', language)}</div>
<div className="text-3xl font-bold mono" style={{ color: '#10B981' }}>
+{(performance.avg_win || 0).toFixed(2)}%
</div>
@@ -238,7 +241,7 @@ export default function AILearning({ traderId }: AILearningProps) {
border: '1px solid rgba(246, 70, 93, 0.2)',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.1)'
}}>
<div className="text-xs font-semibold mb-2" style={{ color: '#94A3B8' }}>Avg Loss</div>
<div className="text-xs font-semibold mb-2" style={{ color: '#94A3B8' }}>{t('avgLoss', language)}</div>
<div className="text-3xl font-bold mono" style={{ color: '#F87171' }}>
{(performance.avg_loss || 0).toFixed(2)}%
</div>
@@ -258,9 +261,9 @@ export default function AILearning({ traderId }: AILearningProps) {
<div className="relative flex items-center justify-between">
<div>
<div className="text-sm font-semibold mb-1" style={{ color: '#FCD34D' }}>Profit Factor</div>
<div className="text-sm font-semibold mb-1" style={{ color: '#FCD34D' }}>{t('profitFactor', language)}</div>
<div className="text-xs" style={{ color: '#94A3B8' }}>
Avg Win ÷ Avg Loss
{t('avgWinDivLoss', language)}
</div>
</div>
<div className="text-5xl font-bold mono" style={{
@@ -276,10 +279,10 @@ export default function AILearning({ traderId }: AILearningProps) {
color: (performance.profit_factor || 0) >= 2.0 ? '#10B981' :
(performance.profit_factor || 0) >= 1.5 ? '#F0B90B' : '#94A3B8'
}}>
{(performance.profit_factor || 0) >= 2.0 && '🔥 Excellent - Strong profitability'}
{(performance.profit_factor || 0) >= 1.5 && (performance.profit_factor || 0) < 2.0 && '✓ Good - Stable profits'}
{(performance.profit_factor || 0) >= 1.0 && (performance.profit_factor || 0) < 1.5 && '⚠️ Fair - Needs optimization'}
{(performance.profit_factor || 0) > 0 && (performance.profit_factor || 0) < 1.0 && '❌ Poor - Losses exceed gains'}
{(performance.profit_factor || 0) >= 2.0 && t('excellent', language)}
{(performance.profit_factor || 0) >= 1.5 && (performance.profit_factor || 0) < 2.0 && t('good', language)}
{(performance.profit_factor || 0) >= 1.0 && (performance.profit_factor || 0) < 1.5 && t('fair', language)}
{(performance.profit_factor || 0) > 0 && (performance.profit_factor || 0) < 1.0 && t('poor', language)}
</div>
</div>
</div>
@@ -298,7 +301,7 @@ export default function AILearning({ traderId }: AILearningProps) {
}}>
<div className="flex items-center gap-2 mb-3">
<span className="text-xl">🏆</span>
<span className="text-xs font-semibold" style={{ color: '#6EE7B7' }}>Best Performer</span>
<span className="text-xs font-semibold" style={{ color: '#6EE7B7' }}>{t('bestPerformer', language)}</span>
</div>
<div className="text-2xl font-bold mono mb-1" style={{ color: '#10B981' }}>
{performance.best_symbol}
@@ -306,7 +309,7 @@ export default function AILearning({ traderId }: AILearningProps) {
{symbolStats[performance.best_symbol] && (
<div className="text-sm font-semibold" style={{ color: '#6EE7B7' }}>
{symbolStats[performance.best_symbol].total_pn_l > 0 ? '+' : ''}
{symbolStats[performance.best_symbol].total_pn_l.toFixed(2)}% P&L
{symbolStats[performance.best_symbol].total_pn_l.toFixed(2)}% {t('pnl', language)}
</div>
)}
</div>
@@ -320,7 +323,7 @@ export default function AILearning({ traderId }: AILearningProps) {
}}>
<div className="flex items-center gap-2 mb-3">
<span className="text-xl">📉</span>
<span className="text-xs font-semibold" style={{ color: '#FCA5A5' }}>Worst Performer</span>
<span className="text-xs font-semibold" style={{ color: '#FCA5A5' }}>{t('worstPerformer', language)}</span>
</div>
<div className="text-2xl font-bold mono mb-1" style={{ color: '#F87171' }}>
{performance.worst_symbol}
@@ -328,7 +331,7 @@ export default function AILearning({ traderId }: AILearningProps) {
{symbolStats[performance.worst_symbol] && (
<div className="text-sm font-semibold" style={{ color: '#FCA5A5' }}>
{symbolStats[performance.worst_symbol].total_pn_l > 0 ? '+' : ''}
{symbolStats[performance.worst_symbol].total_pn_l.toFixed(2)}% P&L
{symbolStats[performance.worst_symbol].total_pn_l.toFixed(2)}% {t('pnl', language)}
</div>
)}
</div>
@@ -345,7 +348,7 @@ export default function AILearning({ traderId }: AILearningProps) {
}}>
<div className="p-5 border-b" style={{ borderColor: 'rgba(99, 102, 241, 0.2)', background: 'rgba(30, 35, 41, 0.6)' }}>
<h3 className="font-bold flex items-center gap-2" style={{ color: '#E0E7FF' }}>
📊 Symbol Performance
{t('symbolPerformance', language)}
</h3>
</div>
<div className="overflow-x-auto">
@@ -411,11 +414,11 @@ export default function AILearning({ traderId }: AILearningProps) {
<div className="flex items-center gap-2">
<span className="text-xl">📜</span>
<div>
<h3 className="font-bold text-sm" style={{ color: '#FCD34D' }}>Trade History</h3>
<h3 className="font-bold text-sm" style={{ color: '#FCD34D' }}>{t('tradeHistory', language)}</h3>
<p className="text-xs" style={{ color: '#94A3B8' }}>
{performance?.recent_trades && performance.recent_trades.length > 0
? `Recent ${performance.recent_trades.length} completed trades`
: 'Completed trades will appear here'}
? t('completedTrades', language, { count: performance.recent_trades.length })
: t('completedTradesWillAppear', language)}
</p>
</div>
</div>
@@ -459,7 +462,7 @@ export default function AILearning({ traderId }: AILearningProps) {
background: 'rgba(240, 185, 11, 0.2)',
color: '#FCD34D'
}}>
Latest
{t('latest', language)}
</span>
)}
</div>
@@ -473,13 +476,13 @@ export default function AILearning({ traderId }: AILearningProps) {
{/* 价格信息 */}
<div className="grid grid-cols-2 gap-2 mb-3 text-xs">
<div>
<div style={{ color: '#94A3B8' }}>Entry</div>
<div style={{ color: '#94A3B8' }}>{t('entry', language)}</div>
<div className="font-mono font-semibold" style={{ color: '#CBD5E1' }}>
{trade.open_price.toFixed(4)}
</div>
</div>
<div className="text-right">
<div style={{ color: '#94A3B8' }}>Exit</div>
<div style={{ color: '#94A3B8' }}>{t('exit', language)}</div>
<div className="font-mono font-semibold" style={{ color: '#CBD5E1' }}>
{trade.close_price.toFixed(4)}
</div>
@@ -508,7 +511,7 @@ export default function AILearning({ traderId }: AILearningProps) {
background: 'rgba(248, 113, 113, 0.2)',
color: '#FCA5A5'
}}>
Stop Loss
{t('stopLoss', language)}
</span>
)}
</div>
@@ -531,7 +534,7 @@ export default function AILearning({ traderId }: AILearningProps) {
) : (
<div className="p-6 text-center">
<div className="text-4xl mb-2 opacity-50">📜</div>
<div style={{ color: '#94A3B8' }}>No completed trades yet</div>
<div style={{ color: '#94A3B8' }}>{t('noCompletedTrades', language)}</div>
</div>
)}
</div>
@@ -556,23 +559,23 @@ export default function AILearning({ traderId }: AILearningProps) {
💡
</div>
<div>
<h3 className="font-bold mb-3 text-base" style={{ color: '#FCD34D' }}>How AI Learns & Evolves</h3>
<h3 className="font-bold mb-3 text-base" style={{ color: '#FCD34D' }}>{t('howAILearns', language)}</h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 text-sm">
<div className="flex items-start gap-2">
<span style={{ color: '#F0B90B' }}></span>
<span style={{ color: '#CBD5E1' }}>Analyzes last 20 trading cycles before each decision</span>
<span style={{ color: '#CBD5E1' }}>{t('aiLearningPoint1', language)}</span>
</div>
<div className="flex items-start gap-2">
<span style={{ color: '#F0B90B' }}></span>
<span style={{ color: '#CBD5E1' }}>Identifies best & worst performing symbols</span>
<span style={{ color: '#CBD5E1' }}>{t('aiLearningPoint2', language)}</span>
</div>
<div className="flex items-start gap-2">
<span style={{ color: '#F0B90B' }}></span>
<span style={{ color: '#CBD5E1' }}>Optimizes position sizing based on win rate</span>
<span style={{ color: '#CBD5E1' }}>{t('aiLearningPoint3', language)}</span>
</div>
<div className="flex items-start gap-2">
<span style={{ color: '#F0B90B' }}></span>
<span style={{ color: '#CBD5E1' }}>Avoids repeating past mistakes</span>
<span style={{ color: '#CBD5E1' }}>{t('aiLearningPoint4', language)}</span>
</div>
</div>
</div>

View File

@@ -2,8 +2,11 @@ import useSWR from 'swr';
import { api } from '../lib/api';
import type { CompetitionData } from '../types';
import { ComparisonChart } from './ComparisonChart';
import { useLanguage } from '../contexts/LanguageContext';
import { t } from '../i18n/translations';
export function CompetitionPage() {
const { language } = useLanguage();
const { data: competition } = useSWR<CompetitionData>(
'competition',
api.getCompetition,
@@ -57,18 +60,18 @@ export function CompetitionPage() {
</div>
<div>
<h1 className="text-2xl font-bold flex items-center gap-2" style={{ color: '#EAECEF' }}>
AI Competition
{t('aiCompetition', language)}
<span className="text-xs font-normal px-2 py-1 rounded" style={{ background: 'rgba(240, 185, 11, 0.15)', color: '#F0B90B' }}>
{competition.count} traders
{competition.count} {t('traders', language)}
</span>
</h1>
<p className="text-xs" style={{ color: '#848E9C' }}>
Qwen vs DeepSeek · Live Battle
{t('liveBattle', language)}
</p>
</div>
</div>
<div className="text-right">
<div className="text-xs mb-1" style={{ color: '#848E9C' }}>🥇 Leader</div>
<div className="text-xs mb-1" style={{ color: '#848E9C' }}>{t('leader', language)}</div>
<div className="text-lg font-bold" style={{ color: '#F0B90B' }}>{leader?.trader_name}</div>
<div className="text-sm font-semibold" style={{ color: leader.total_pnl >= 0 ? '#0ECB81' : '#F6465D' }}>
{leader.total_pnl >= 0 ? '+' : ''}{leader.total_pnl_pct.toFixed(2)}%
@@ -82,10 +85,10 @@ export function CompetitionPage() {
<div className="binance-card p-5 animate-slide-in" style={{ animationDelay: '0.1s' }}>
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-bold flex items-center gap-2" style={{ color: '#EAECEF' }}>
📈 Performance Comparison
{t('performanceComparison', language)}
</h2>
<div className="text-xs" style={{ color: '#848E9C' }}>
Real-time PnL %
{t('realTimePnL', language)}
</div>
</div>
<ComparisonChart traders={sortedTraders} />
@@ -95,10 +98,10 @@ export function CompetitionPage() {
<div className="binance-card p-5 animate-slide-in" style={{ animationDelay: '0.1s' }}>
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-bold flex items-center gap-2" style={{ color: '#EAECEF' }}>
🥇 Leaderboard
{t('leaderboard', language)}
</h2>
<div className="text-xs px-2 py-1 rounded" style={{ background: 'rgba(240, 185, 11, 0.1)', color: '#F0B90B', border: '1px solid rgba(240, 185, 11, 0.2)' }}>
LIVE
{t('live', language)}
</div>
</div>
<div className="space-y-2">
@@ -134,7 +137,7 @@ export function CompetitionPage() {
<div className="flex items-center gap-3">
{/* Total Equity */}
<div className="text-right">
<div className="text-xs" style={{ color: '#848E9C' }}>Equity</div>
<div className="text-xs" style={{ color: '#848E9C' }}>{t('equity', language)}</div>
<div className="text-sm font-bold mono" style={{ color: '#EAECEF' }}>
{trader.total_equity.toFixed(2)}
</div>
@@ -142,7 +145,7 @@ export function CompetitionPage() {
{/* P&L */}
<div className="text-right min-w-[90px]">
<div className="text-xs" style={{ color: '#848E9C' }}>P&L</div>
<div className="text-xs" style={{ color: '#848E9C' }}>{t('pnl', language)}</div>
<div
className="text-lg font-bold mono"
style={{ color: trader.total_pnl >= 0 ? '#0ECB81' : '#F6465D' }}
@@ -157,7 +160,7 @@ export function CompetitionPage() {
{/* Positions */}
<div className="text-right">
<div className="text-xs" style={{ color: '#848E9C' }}>Pos</div>
<div className="text-xs" style={{ color: '#848E9C' }}>{t('pos', language)}</div>
<div className="text-sm font-bold mono" style={{ color: '#EAECEF' }}>
{trader.position_count}
</div>
@@ -191,7 +194,7 @@ export function CompetitionPage() {
{competition.traders.length === 2 && (
<div className="binance-card p-5 animate-slide-in" style={{ animationDelay: '0.3s' }}>
<h2 className="text-lg font-bold mb-4 flex items-center gap-2" style={{ color: '#EAECEF' }}>
Head-to-Head Battle
{t('headToHead', language)}
</h2>
<div className="grid grid-cols-2 gap-4">
{sortedTraders.map((trader, index) => {
@@ -228,12 +231,12 @@ export function CompetitionPage() {
</div>
{isWinning && gap > 0 && (
<div className="text-xs font-semibold" style={{ color: '#0ECB81' }}>
Leading by {gap.toFixed(2)}%
{t('leadingBy', language, { gap: gap.toFixed(2) })}
</div>
)}
{!isWinning && gap < 0 && (
<div className="text-xs font-semibold" style={{ color: '#F6465D' }}>
Behind by {Math.abs(gap).toFixed(2)}%
{t('behindBy', language, { gap: Math.abs(gap).toFixed(2) })}
</div>
)}
</div>

View File

@@ -11,6 +11,8 @@ import {
} from 'recharts';
import useSWR from 'swr';
import { api } from '../lib/api';
import { useLanguage } from '../contexts/LanguageContext';
import { t } from '../i18n/translations';
interface EquityPoint {
timestamp: string;
@@ -25,6 +27,7 @@ interface EquityChartProps {
}
export function EquityChart({ traderId }: EquityChartProps) {
const { language } = useLanguage();
const [displayMode, setDisplayMode] = useState<'dollar' | 'percent'>('dollar');
const { data: history, error } = useSWR<EquityPoint[]>(
@@ -49,7 +52,7 @@ export function EquityChart({ traderId }: EquityChartProps) {
<div className="flex items-center gap-3 p-4 rounded" style={{ background: 'rgba(246, 70, 93, 0.1)', border: '1px solid rgba(246, 70, 93, 0.2)' }}>
<div className="text-2xl"></div>
<div>
<div className="font-semibold" style={{ color: '#F6465D' }}></div>
<div className="font-semibold" style={{ color: '#F6465D' }}>{t('loadingError', language)}</div>
<div className="text-sm" style={{ color: '#848E9C' }}>{error.message}</div>
</div>
</div>
@@ -60,11 +63,11 @@ export function EquityChart({ traderId }: EquityChartProps) {
if (!history || history.length === 0) {
return (
<div className="binance-card p-6">
<h3 className="text-lg font-semibold mb-6" style={{ color: '#EAECEF' }}>线</h3>
<h3 className="text-lg font-semibold mb-6" style={{ color: '#EAECEF' }}>{t('accountEquityCurve', language)}</h3>
<div className="text-center py-16" style={{ color: '#848E9C' }}>
<div className="text-6xl mb-4 opacity-50">📊</div>
<div className="text-lg font-semibold mb-2"></div>
<div className="text-sm">线</div>
<div className="text-lg font-semibold mb-2">{t('noHistoricalData', language)}</div>
<div className="text-sm">{t('dataWillAppear', language)}</div>
</div>
</div>
);
@@ -153,7 +156,7 @@ export function EquityChart({ traderId }: EquityChartProps) {
{/* Header */}
<div className="flex items-center justify-between mb-4">
<div>
<h3 className="text-lg font-bold mb-2" style={{ color: '#EAECEF' }}>线</h3>
<h3 className="text-lg font-bold mb-2" style={{ color: '#EAECEF' }}>{t('accountEquityCurve', language)}</h3>
<div className="flex items-baseline gap-4">
<span className="text-3xl font-bold mono" style={{ color: '#EAECEF' }}>
{account?.total_equity.toFixed(2) || '0.00'}
@@ -239,7 +242,7 @@ export function EquityChart({ traderId }: EquityChartProps) {
stroke="#474D57"
strokeDasharray="3 3"
label={{
value: displayMode === 'dollar' ? '初始' : '0%',
value: displayMode === 'dollar' ? t('initialBalance', language).split(' ')[0] : '0%',
fill: '#848E9C',
fontSize: 12,
}}
@@ -259,27 +262,27 @@ export function EquityChart({ traderId }: EquityChartProps) {
{/* Footer Stats */}
<div className="mt-3 grid grid-cols-4 gap-3 pt-3" style={{ borderTop: '1px solid #2B3139' }}>
<div className="p-2 rounded transition-all hover:bg-opacity-50" style={{ background: 'rgba(240, 185, 11, 0.05)' }}>
<div className="text-xs mb-1 uppercase tracking-wider" style={{ color: '#848E9C' }}></div>
<div className="text-xs mb-1 uppercase tracking-wider" style={{ color: '#848E9C' }}>{t('initialBalance', language)}</div>
<div className="text-sm font-bold mono" style={{ color: '#EAECEF' }}>
{initialBalance.toFixed(2)} USDT
</div>
</div>
<div className="p-2 rounded transition-all hover:bg-opacity-50" style={{ background: 'rgba(240, 185, 11, 0.05)' }}>
<div className="text-xs mb-1 uppercase tracking-wider" style={{ color: '#848E9C' }}></div>
<div className="text-xs mb-1 uppercase tracking-wider" style={{ color: '#848E9C' }}>{t('currentEquity', language)}</div>
<div className="text-sm font-bold mono" style={{ color: '#EAECEF' }}>
{currentValue.raw_equity.toFixed(2)} USDT
</div>
</div>
<div className="p-2 rounded transition-all hover:bg-opacity-50" style={{ background: 'rgba(240, 185, 11, 0.05)' }}>
<div className="text-xs mb-1 uppercase tracking-wider" style={{ color: '#848E9C' }}></div>
<div className="text-sm font-bold mono" style={{ color: '#EAECEF' }}>{history.length} </div>
<div className="text-xs mb-1 uppercase tracking-wider" style={{ color: '#848E9C' }}>{t('historicalCycles', language)}</div>
<div className="text-sm font-bold mono" style={{ color: '#EAECEF' }}>{history.length} {t('cycles', language)}</div>
</div>
<div className="p-2 rounded transition-all hover:bg-opacity-50" style={{ background: 'rgba(240, 185, 11, 0.05)' }}>
<div className="text-xs mb-1 uppercase tracking-wider" style={{ color: '#848E9C' }}></div>
<div className="text-xs mb-1 uppercase tracking-wider" style={{ color: '#848E9C' }}>{t('displayRange', language)}</div>
<div className="text-sm font-bold mono" style={{ color: '#EAECEF' }}>
{history.length > MAX_DISPLAY_POINTS
? `最近 ${MAX_DISPLAY_POINTS}`
: '全部数据'
? `${t('recent', language)} ${MAX_DISPLAY_POINTS}`
: t('allData', language)
}
</div>
</div>