Refactor: Improve AI decision system and Sharpe ratio calculation

Major improvements:
- Use period-level Sharpe ratio (range -2 to +2) instead of annualized
- Save full user prompt in decision logs for debugging
- Format complete market data (3m + 4h candles) for AI analysis
- Prevent position stacking with duplicate position checks
- Update Sharpe ratio interpretation thresholds
Market data enhancements:
- Display full technical indicators in user prompt
- Include 3-minute and 4-hour timeframe data
- Add OI (Open Interest) change and funding rate signals
Risk control:
- Block opening duplicate positions (same symbol + direction)
- Suggest close action first before opening new position
- Prevent margin usage from exceeding limits
UI improvements:
- Update multi-language translations
- Refine AI learning dashboard display
Co-Authored-By: tinkle-community <tinklefund@gmail.com>
This commit is contained in:
tinkle-community
2025-10-29 04:44:17 +08:00
parent d2ccf516a1
commit ceaedca253
6 changed files with 104 additions and 461 deletions
+21 -1
View File
@@ -559,6 +559,7 @@ function StatCard({
// Decision Card Component with CoT Trace - Binance Style
function DecisionCard({ decision, language }: { decision: DecisionRecord; language: Language }) {
const [showInput, setShowInput] = useState(false);
const [showCoT, setShowCoT] = useState(false);
return (
@@ -582,6 +583,25 @@ function DecisionCard({ decision, language }: { decision: DecisionRecord; langua
</div>
</div>
{/* AI Input Prompt - Collapsible */}
{decision.input_prompt && (
<div className="mb-3">
<button
onClick={() => setShowInput(!showInput)}
className="flex items-center gap-2 text-sm transition-colors"
style={{ color: '#8B5CF6' }}
>
<span className="font-semibold">📥 {t('inputPrompt', language)}</span>
<span className="text-xs">{showInput ? t('collapse', language) : t('expand', language)}</span>
</button>
{showInput && (
<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>
)}
{/* AI Chain of Thought - Collapsible */}
{decision.cot_trace && (
<div className="mb-3">
@@ -590,7 +610,7 @@ function DecisionCard({ decision, language }: { decision: DecisionRecord; langua
className="flex items-center gap-2 text-sm transition-colors"
style={{ color: '#F0B90B' }}
>
<span className="font-semibold">{t('aiThinking', language)}</span>
<span className="font-semibold">📤 {t('aiThinking', language)}</span>
<span className="text-xs">{showCoT ? t('collapse', language) : t('expand', language)}</span>
</button>
{showCoT && (
+2 -64
View File
@@ -47,6 +47,7 @@ interface AILearningProps {
interface DecisionRecord {
timestamp: string;
cycle_number: number;
input_prompt: string;
cot_trace: string;
success: boolean;
}
@@ -104,9 +105,6 @@ export default function AILearning({ traderId }: AILearningProps) {
(a, b) => (b.total_pn_l || 0) - (a.total_pn_l || 0)
);
// 提取AI的最新反思(从CoT trace中)
const latestReflection = extractReflectionFromCoT(latestDecisions?.[0]?.cot_trace);
return (
<div className="space-y-6">
{/* 标题区 - 更简洁 */}
@@ -128,68 +126,8 @@ export default function AILearning({ traderId }: AILearningProps) {
{/* 主要内容:现代化网格布局 */}
<div className="grid grid-cols-1 lg:grid-cols-12 gap-6">
{/* 左侧大区域:AI反思 + 核心指标 (5列) */}
{/* 左侧大区域:核心指标 (5列) */}
<div className="lg:col-span-5 space-y-6">
{/* AI最新反思 - 渐变卡片 */}
{latestReflection && latestDecisions && latestDecisions.length > 0 && (
<div className="rounded-2xl p-6 relative overflow-hidden" style={{
background: 'linear-gradient(135deg, #1E1B4B 0%, #312E81 50%, #1E293B 100%)',
border: '1px solid rgba(139, 92, 246, 0.2)',
boxShadow: '0 10px 40px rgba(139, 92, 246, 0.15)'
}}>
{/* 背景装饰 */}
<div className="absolute top-0 right-0 w-64 h-64 rounded-full opacity-10" style={{
background: 'radial-gradient(circle, #8B5CF6 0%, transparent 70%)',
filter: 'blur(40px)'
}} />
<div className="relative">
<div className="flex items-center gap-3 mb-4">
<div className="w-10 h-10 rounded-lg flex items-center justify-center text-xl" style={{
background: 'rgba(139, 92, 246, 0.2)',
border: '1px solid rgba(139, 92, 246, 0.3)'
}}>
🎯
</div>
<div>
<h3 className="text-base font-bold" style={{ color: '#C4B5FD' }}>
{t('latestReflection', language)}
</h3>
<p className="text-xs" style={{ color: '#94A3B8' }}>
{t('cycle', language)} #{latestDecisions[0].cycle_number} · {new Date(latestDecisions[0].timestamp).toLocaleTimeString()}
</p>
</div>
</div>
<div className="rounded-xl p-4 text-sm leading-relaxed whitespace-pre-wrap" style={{
background: 'rgba(0, 0, 0, 0.4)',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(139, 92, 246, 0.1)',
color: '#DDD6FE',
fontFamily: 'ui-sans-serif, system-ui'
}}>
{latestReflection}
</div>
{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>{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)',
border: '1px solid rgba(139, 92, 246, 0.15)',
color: '#A5B4FC',
fontFamily: 'ui-monospace, monospace'
}}>
{latestDecisions[0].cot_trace}
</div>
</details>
)}
</div>
</div>
)}
{/* 核心指标网格 - 玻璃态设计 */}
<div className="grid grid-cols-2 gap-4">
{/* 总交易数 */}
+2
View File
@@ -47,6 +47,7 @@ export const translations = {
cycle: 'Cycle',
success: 'Success',
failed: 'Failed',
inputPrompt: 'Input Prompt',
aiThinking: 'AI Chain of Thought',
collapse: 'Collapse',
expand: 'Expand',
@@ -164,6 +165,7 @@ export const translations = {
cycle: '周期',
success: '成功',
failed: '失败',
inputPrompt: '输入提示',
aiThinking: '💭 AI思维链分析',
collapse: '▼ 收起',
expand: '▶ 展开',