Files
ahad-quant/ahad_quant_dashboard.jsx
2026-06-25 14:00:20 +03:00

1400 lines
72 KiB
React
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useState, useEffect, useCallback } from "react";
import {
AreaChart, Area, XAxis, YAxis, Tooltip, ResponsiveContainer,
BarChart, Bar, LineChart, Line, ReferenceLine
} from "recharts";
// ── Constants ─────────────────────────────────────────────────────────────────
const COINS = ["BTC","ETH","SOL","BNB","DOGE","AVAX","LINK","ARB","OP","APT",
"SUI","INJ","TIA","WLD","NEAR","FET","AAVE","DOT","ADA","XRP",
"LTC","BCH","CRV","ONDO","ENA","JUP","RENDER"];
const EXCHANGES = ["Bybit","Binance","OKX","Gate.io","KuCoin","Bitget","HTX","MEXC","BingX"];
const GRID_STRATEGIES = ["neutral","long","short","trend","reverse"];
const DCA_STRATEGIES = ["classic","aggressive","safe","trend","reverse"];
const REGIMES = ["BULL","BEAR","SIDEWAYS"];
// ── Palette ────────────────────────────────────────────────────────────────────
const C = {
bg:"#020b14", surface:"#05111f", card:"#071626",
border:"#0c2035", border2:"#102840",
accent:"#00d4aa", blue:"#1a8cff", purple:"#9b5de5",
danger:"#ff3358", warn:"#ffb700", success:"#00e676",
text:"#b8cfe8", muted:"#3a5872", dim:"#102030",
glow:"#00d4aa33",
};
// ── CSS ────────────────────────────────────────────────────────────────────────
const CSS = `
@import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Rajdhani:wght@300;400;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap');
*{box-sizing:border-box;margin:0;padding:0}
body{background:${C.bg}}
::-webkit-scrollbar{width:3px;height:3px}
::-webkit-scrollbar-track{background:${C.bg}}
::-webkit-scrollbar-thumb{background:${C.border2};border-radius:2px}
@keyframes blink{0%,100%{opacity:1}50%{opacity:0.15}}
@keyframes pulse-ring{0%,100%{box-shadow:0 0 0 0 ${C.glow},0 0 8px ${C.accent}44}50%{box-shadow:0 0 0 6px transparent,0 0 20px ${C.accent}66}}
@keyframes slidein{from{transform:translateY(-6px);opacity:0}to{transform:translateY(0);opacity:1}}
@keyframes pump-flash{0%,100%{background:rgba(255,179,0,.06)}50%{background:rgba(255,179,0,.15)}}
@keyframes danger-flash{0%,100%{background:rgba(255,51,88,.06)}50%{background:rgba(255,51,88,.14)}}
@keyframes hum{0%{opacity:.6}50%{opacity:1}100%{opacity:.6}}
@keyframes spin{from{transform:rotate(0deg)}to{transform:rotate(360deg)}}
@keyframes bar-grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
.live-dot{animation:blink 1.3s ease-in-out infinite}
.pulse{animation:pulse-ring 2.5s ease-in-out infinite}
.pump{animation:pump-flash 2s ease-in-out infinite}
.dump{animation:danger-flash 2s ease-in-out infinite}
.hum{animation:hum 3s ease-in-out infinite}
.spin{animation:spin 8s linear infinite}
.new-signal{animation:slidein .3s ease-out}
.nav-btn:hover{background:rgba(0,212,170,.07)!important;border-left-color:${C.accent}55!important}
input[type=range]{-webkit-appearance:none;appearance:none;height:3px;background:${C.dim};border-radius:2px;outline:none}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:12px;height:12px;border-radius:50%;background:${C.accent};cursor:pointer;box-shadow:0 0 6px ${C.accent}99}
input[type=number]{background:${C.dim};border:1px solid ${C.border2};color:${C.text};padding:3px 8px;border-radius:4px;font-family:'JetBrains Mono';font-size:11px;width:70px;outline:none}
input[type=number]:focus{border-color:${C.accent}88}
select{background:${C.dim};border:1px solid ${C.border2};color:${C.text};padding:3px 8px;border-radius:4px;font-family:'JetBrains Mono';font-size:11px;outline:none;cursor:pointer}
select:focus{border-color:${C.accent}88}
button{cursor:pointer;font-family:'Rajdhani';letter-spacing:1px}
button:hover{filter:brightness(1.15)}
`;
// ── Helpers ────────────────────────────────────────────────────────────────────
const rand = (a,b) => Math.random()*(b-a)+a;
const pick = arr => arr[Math.floor(Math.random()*arr.length)];
const fmt2 = n => n.toFixed(2);
const fmtK = n => n >= 1000 ? `${(n/1000).toFixed(1)}K` : n.toFixed(0);
function genEquity(n=80){
let v=10000;
const now=Date.now();
return Array.from({length:n},(_,i)=>{
v*=(1+rand(-0.0045,0.006));
const d=new Date(now-(n-i)*3600000);
return{t:`${d.getMonth()+1}/${d.getDate()} ${d.getHours()}h`,v:Math.round(v*100)/100};
});
}
function genSignal(){
const coin=pick(COINS),dir=Math.random()>.5?"LONG":"SHORT";
const conf=+(rand(0.71,0.935)).toFixed(3);
return{
id:Date.now()+Math.random(),coin,dir,conf,
time:new Date().toLocaleTimeString("fr-FR",{hour:"2-digit",minute:"2-digit",second:"2-digit"}),
regime:pick(REGIMES),exec:conf>0.80
};
}
// ── Atom components ────────────────────────────────────────────────────────────
function Badge({text,color=C.accent,small}){
return(
<span style={{background:`${color}1a`,color,border:`1px solid ${color}44`,
borderRadius:3,padding:small?"1px 5px":"2px 7px",
fontSize:small?8:9,fontFamily:"JetBrains Mono",fontWeight:600,letterSpacing:.8,whiteSpace:"nowrap"}}>
{text}
</span>
);
}
function Toggle({on,toggle,label,color=C.accent}){
return(
<div onClick={toggle} style={{display:"flex",alignItems:"center",gap:10,cursor:"pointer",userSelect:"none"}}>
<div style={{width:38,height:20,borderRadius:10,
background:on?color:C.dim,position:"relative",
transition:"background .3s",border:`1px solid ${on?color:C.border2}`}}>
<div style={{position:"absolute",top:2,left:on?18:2,width:14,height:14,
borderRadius:7,background:"white",transition:"left .25s",
boxShadow:on?`0 0 6px ${color}99`:""}}/>
</div>
{label&&<span style={{color:on?color:C.muted,fontFamily:"Rajdhani",
fontSize:12,letterSpacing:.5,transition:"color .3s"}}>{label}</span>}
</div>
);
}
function KPI({label,value,sub,color=C.text,glow}){
return(
<div style={{background:C.card,border:`1px solid ${glow?color+"44":C.border}`,
borderRadius:8,padding:"14px 18px",
...(glow?{boxShadow:`0 0 16px ${color}22`}:{})}}>
<div style={{color:C.muted,fontSize:9,fontFamily:"Rajdhani",
letterSpacing:2.5,textTransform:"uppercase",marginBottom:5}}>{label}</div>
<div style={{color,fontSize:20,fontFamily:"JetBrains Mono",
fontWeight:600,lineHeight:1.1}}>{value}</div>
{sub&&<div style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani",marginTop:4}}>{sub}</div>}
</div>
);
}
function SectionTitle({children}){
return(
<div style={{color:C.muted,fontSize:9,fontFamily:"Rajdhani",
letterSpacing:2.5,textTransform:"uppercase",marginBottom:14,
display:"flex",alignItems:"center",gap:8}}>
<div style={{width:16,height:1,background:C.accent,opacity:.5}}/>
{children}
<div style={{flex:1,height:1,background:C.border}}/>
</div>
);
}
function Panel({children,style={},accentColor}){
return(
<div style={{background:C.card,border:`1px solid ${accentColor?accentColor+"33":C.border}`,
borderRadius:8,padding:18,...style}}>
{children}
</div>
);
}
function Row({l,v,color,mono=true}){
return(
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",
marginBottom:8,paddingBottom:7,borderBottom:`1px solid ${C.border}22`}}>
<span style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani",letterSpacing:.5}}>{l}</span>
<span style={{color:color||C.text,fontSize:11,fontFamily:mono?"JetBrains Mono":"Rajdhani"}}>{v}</span>
</div>
);
}
// Confidence arc SVG
function ConfArc({value,size=140}){
const r=50,cx=size/2,cy=size/2;
const circ=2*Math.PI*r;
const arc=circ*0.75; // 270° arc
const filled=arc*value;
const color=value>0.85?C.success:value>0.72?C.accent:C.warn;
return(
<svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
<circle cx={cx} cy={cy} r={r} fill="none" stroke={C.dim} strokeWidth={7}
strokeDasharray={`${arc} ${circ}`}
strokeDashoffset={-circ*0.125}
strokeLinecap="round"/>
<circle cx={cx} cy={cy} r={r} fill="none" stroke={color} strokeWidth={7}
strokeDasharray={`${filled} ${circ-filled}`}
strokeDashoffset={-circ*0.125}
strokeLinecap="round"
style={{filter:`drop-shadow(0 0 6px ${color})`,transition:"stroke-dasharray .8s ease,stroke .5s"}}/>
<text x={cx} y={cy-6} textAnchor="middle" fill={C.text} fontSize={18}
fontFamily="JetBrains Mono" fontWeight="600">{(value*100).toFixed(1)}%</text>
<text x={cx} y={cy+12} textAnchor="middle" fill={C.muted} fontSize={8}
fontFamily="Rajdhani" letterSpacing={2}>CONFIDENCE</text>
<text x={cx} y={cy+24} textAnchor="middle"
fill={value>=0.72?C.success:C.warn} fontSize={8} fontFamily="Rajdhani">
{value>=0.72?"▶ SIGNAL VALID":"⏸ BELOW THRESHOLD"}
</text>
</svg>
);
}
// Signal feed row
function SigRow({s}){
const isL=s.dir==="LONG",col=isL?C.success:C.danger;
return(
<div className="new-signal" style={{
display:"grid",gridTemplateColumns:"54px 46px 90px 60px 1fr 52px",
alignItems:"center",gap:6,
padding:"5px 10px",borderBottom:`1px solid ${C.border}18`,
background:s.exec?`${col}08`:"transparent"}}>
<span style={{color:C.text,fontFamily:"JetBrains Mono",fontSize:11,fontWeight:600}}>{s.coin}</span>
<Badge text={s.dir} color={col} small/>
<div style={{display:"flex",alignItems:"center",gap:4}}>
<div style={{flex:1,height:2,background:C.dim,borderRadius:2}}>
<div style={{width:`${s.conf*100}%`,height:"100%",
background:s.conf>0.85?C.success:C.accent,borderRadius:2,transition:"width .5s"}}/>
</div>
<span style={{color:C.muted,fontSize:8,fontFamily:"JetBrains Mono"}}>{(s.conf*100).toFixed(1)}%</span>
</div>
<Badge text={s.regime} small
color={s.regime==="BULL"?C.success:s.regime==="BEAR"?C.danger:C.warn}/>
<span style={{color:C.muted,fontSize:9,fontFamily:"JetBrains Mono"}}>{s.time}</span>
<span style={{color:s.exec?C.success:C.muted,fontSize:8,fontFamily:"Rajdhani",
letterSpacing:.5,textAlign:"right"}}>{s.exec?"▶ EXEC":"— SKIP"}</span>
</div>
);
}
// Position card
function PosCard({p,onClose}){
const isL=p.dir==="LONG",col=isL?C.success:C.danger;
const pnlColor=p.pnl>=0?C.success:C.danger;
return(
<div style={{border:`1px solid ${col}28`,borderRadius:7,padding:12,
marginBottom:8,background:`${col}05`}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:8}}>
<div style={{display:"flex",gap:8,alignItems:"center"}}>
<span style={{color:C.text,fontFamily:"Orbitron",fontSize:13,fontWeight:700}}>{p.coin}</span>
<Badge text={p.dir} color={col}/>
<span style={{color:C.muted,fontFamily:"Rajdhani",fontSize:10}}>{p.age}</span>
</div>
<div style={{display:"flex",alignItems:"center",gap:10}}>
<span style={{color:pnlColor,fontFamily:"JetBrains Mono",fontSize:14,fontWeight:600}}>
{p.pnl>=0?"+":""}{fmt2(p.pnl)} USDT
</span>
{onClose&&<button onClick={()=>onClose(p.coin)}
style={{background:`${C.danger}18`,border:`1px solid ${C.danger}44`,
color:C.danger,padding:"3px 9px",borderRadius:4,fontSize:10}}>
CLOSE
</button>}
</div>
</div>
<div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:6,marginBottom:6}}>
{[["Entry",`$${p.entry.toLocaleString()}`],["Current",`$${p.current.toLocaleString()}`],
["SL",`$${p.sl.toLocaleString()}`],["TP",`$${p.tp.toLocaleString()}`]].map(([l,v])=>(
<div key={l}>
<div style={{color:C.muted,fontSize:7,fontFamily:"Rajdhani",letterSpacing:1.5,marginBottom:1}}>{l}</div>
<div style={{color:l==="SL"?C.danger:l==="TP"?C.success:C.text,fontSize:10,fontFamily:"JetBrains Mono"}}>{v}</div>
</div>
))}
</div>
<div style={{display:"flex",alignItems:"center",gap:6}}>
<span style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",letterSpacing:1}}>CONF</span>
<div style={{flex:1,height:2,background:C.dim,borderRadius:2}}>
<div style={{width:`${p.conf*100}%`,height:"100%",background:C.accent,borderRadius:2}}/>
</div>
<span style={{color:C.muted,fontSize:8,fontFamily:"JetBrains Mono"}}>{(p.conf*100).toFixed(0)}%</span>
<span style={{color:C.muted,fontSize:8,fontFamily:"JetBrains Mono",marginLeft:6}}>
Lev {p.lev}x
</span>
</div>
</div>
);
}
// ── Main Component ─────────────────────────────────────────────────────────────
export default function AHAD QUANT(){
const [tab,setTab]=useState("overview");
const [clock,setClock]=useState(new Date());
// Bot toggles
const [botOn,setBotOn]=useState(true);
const [gridOn,setGridOn]=useState(false);
const [dcaOn,setDcaOn]=useState(false);
const [pumpOn,setPumpOn]=useState(true);
const [paperMode,setPaperMode]=useState(true);
const [exchange,setExchange]=useState("Bybit");
const [retrainOn,setRetrainOn]=useState(false);
const [regimeFilter,setRegimeFilter]=useState(false);
// Config
const [cfg,setCfg]=useState({
leverage:5,risk:3,sl:1.5,tp:2.2,maxPos:5,maxLoss:5,minConf:72,
cbLosses:3,gridLevels:10,gridUsdt:200,gridCoin:"BTC",gridStrategy:"neutral",
dcaBase:50,dcaSafety:30,dcaMaxSafety:5,dcaDev:1.5,dcaTp:2,dcaCoin:"BTC",
pumpVol:5,pumpPrice:3,pumpLev:5,pumpRisk:5,
retrainInterval:24,retrainMinAcc:55,
maxHold:3,compound:true
});
const setC=useCallback((k,v)=>setCfg(p=>({...p,[k]:v})),[]);
// Live data
const [balance,setBalance]=useState(10847.23);
const [dailyPnL,setDailyPnL]=useState(234.56);
const [equity,setEquity]=useState(()=>genEquity());
const [signals,setSignals]=useState(()=>[...Array(6)].map(genSignal));
const [positions,setPositions]=useState([
{coin:"BTC",dir:"LONG",entry:67420,current:67892,size:0.015,
pnl:45.23,conf:0.847,age:"2h 14m",sl:66408,tp:68904,lev:5},
{coin:"ETH",dir:"SHORT",entry:3521.4,current:3534.2,size:0.12,
pnl:-12.45,conf:0.781,age:"45m",sl:3573.6,tp:3443.2,lev:5},
]);
const [regime,setRegime]=useState("BULL");
const [confidence,setConfidence]=useState(0.847);
const [cbLosses,setCbLosses]=useState(1);
const [winRate,setWinRate]=useState(74.6);
const [totalTrades,setTotalTrades]=useState(312);
const [accuracy,setAccuracy]=useState(74.6);
const [pumpAlerts,setPumpAlerts]=useState([
{coin:"SUI",type:"PUMP",pct:"+8.3%",vol:"12.4x",time:"2m ago",act:true},
{coin:"INJ",type:"PUMP",pct:"+5.1%",vol:"6.8x",time:"8m ago",act:true},
{coin:"DOGE",type:"DUMP",pct:"-4.2%",vol:"3.1x",time:"23m ago",act:false},
]);
// Clock
useEffect(()=>{
const iv=setInterval(()=>setClock(new Date()),1000);
return()=>clearInterval(iv);
},[]);
// Live simulation
useEffect(()=>{
const iv=setInterval(()=>{
setBalance(b=>+Math.max(9000,b+rand(-8,14)).toFixed(2));
setDailyPnL(p=>+(p+rand(-4,5.5)).toFixed(2));
setConfidence(+(rand(0.71,0.94)).toFixed(3));
setPositions(prev=>prev.map(p=>({
...p,
current:+(p.current*(1+rand(-0.0006,0.0007))).toFixed(p.coin==="BTC"?0:1),
pnl:+(p.pnl+rand(-2.5,3)).toFixed(2),
})));
setEquity(prev=>{
const last=prev[prev.length-1];
const nv=Math.max(9200,last.v*(1+rand(-0.0012,0.0017)));
const d=new Date();
return[...prev.slice(-79),{t:`${d.getHours()}:${String(d.getMinutes()).padStart(2,"0")}`,v:Math.round(nv*100)/100}];
});
if(Math.random()>.5)setSignals(prev=>[genSignal(),...prev.slice(0,29)]);
if(Math.random()>.85)setRegime(pick(REGIMES));
},1800);
return()=>clearInterval(iv);
},[]);
const closePos=useCallback((coin)=>{
setPositions(p=>p.filter(x=>x.coin!==coin));
},[]);
// Derived
const totalPnL=equity.length?equity[equity.length-1].v-10000:0;
const dailyColor=dailyPnL>=0?C.success:C.danger;
const regimeColor=regime==="BULL"?C.success:regime==="BEAR"?C.danger:C.warn;
const regimeIcon=regime==="BULL"?"↗":regime==="BEAR"?"↘":"→";
// ── Tab: Overview ──────────────────────────────────────────────────────────
function TabOverview(){
return(
<div style={{display:"flex",flexDirection:"column",gap:14}}>
{/* KPIs */}
<div style={{display:"grid",gridTemplateColumns:"repeat(4,1fr)",gap:12}}>
<KPI label="Portfolio Balance" glow
value={`$${balance.toLocaleString("en-US",{minimumFractionDigits:2})}`}
sub={paperMode?"📄 Paper Mode":"💰 Live Trading"} color={C.accent}/>
<KPI label="Daily P&L"
value={`${dailyPnL>=0?"+":""}$${fmt2(dailyPnL)}`}
sub={`${(dailyPnL/balance*100).toFixed(2)}% today`} color={dailyColor}/>
<KPI label="Total Profit"
value={`${totalPnL>=0?"+":""}$${Math.round(totalPnL).toLocaleString()}`}
sub={`${((totalPnL/10000)*100).toFixed(2)}% from start`}
color={totalPnL>=0?C.success:C.danger}/>
<KPI label="Win Rate · Accuracy"
value={`${winRate.toFixed(1)}%`}
sub={`AI: ${accuracy.toFixed(1)}% · ${totalTrades} trades`} color={C.blue}/>
</div>
{/* Equity + Regime + Status */}
<div style={{display:"grid",gridTemplateColumns:"1fr 220px",gap:12}}>
<Panel>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12}}>
<SectionTitle>EQUITY CURVE · 80H</SectionTitle>
<span style={{color:totalPnL>=0?C.success:C.danger,fontFamily:"JetBrains Mono",fontSize:12}}>
{totalPnL>=0?"+":""}${totalPnL.toFixed(2)} ({((totalPnL/10000)*100).toFixed(2)}%)
</span>
</div>
<ResponsiveContainer width="100%" height={150}>
<AreaChart data={equity} margin={{top:0,right:0,left:-28,bottom:0}}>
<defs>
<linearGradient id="gEq" x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={C.accent} stopOpacity={.35}/>
<stop offset="95%" stopColor={C.accent} stopOpacity={0}/>
</linearGradient>
</defs>
<XAxis dataKey="t" tick={{fill:C.muted,fontSize:7,fontFamily:"JetBrains Mono"}}
tickLine={false} axisLine={false} interval={15}/>
<YAxis tick={{fill:C.muted,fontSize:7,fontFamily:"JetBrains Mono"}}
tickLine={false} axisLine={false}/>
<Tooltip contentStyle={{background:C.surface,border:`1px solid ${C.accent}44`,
borderRadius:6,fontFamily:"JetBrains Mono",fontSize:10,color:C.text}}/>
<ReferenceLine y={10000} stroke={C.muted} strokeDasharray="3 3" strokeOpacity={.4}/>
<Area type="monotone" dataKey="v" stroke={C.accent} strokeWidth={1.5}
fill="url(#gEq)" dot={false}/>
</AreaChart>
</ResponsiveContainer>
</Panel>
<div style={{display:"flex",flexDirection:"column",gap:12}}>
{/* Regime */}
<Panel style={{flex:1,display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center"}}>
<div style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",letterSpacing:2.5,marginBottom:12}}>MARKET REGIME · HMM</div>
<div className="pulse" style={{width:72,height:72,borderRadius:"50%",
border:`2.5px solid ${regimeColor}`,display:"flex",alignItems:"center",
justifyContent:"center",marginBottom:10}}>
<span style={{fontSize:28}}>{regimeIcon}</span>
</div>
<span style={{color:regimeColor,fontFamily:"Orbitron",fontSize:15,
fontWeight:700,letterSpacing:3}}>{regime}</span>
<span style={{color:C.muted,fontSize:8,fontFamily:"JetBrains Mono",marginTop:4}}>
{regimeFilter?"Filter: ON":"Filter: OFF"}
</span>
</Panel>
{/* Bot Status */}
<Panel>
<div style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",
letterSpacing:2.5,marginBottom:10}}>MODULE STATUS</div>
{[
{l:"AI Bot",on:botOn,color:C.accent},
{l:"Grid Bot",on:gridOn,color:C.blue},
{l:"DCA Bot",on:dcaOn,color:C.warn},
{l:"Pump Scanner",on:pumpOn,color:C.success},
{l:"Auto-Retrain",on:retrainOn,color:C.purple},
].map(({l,on,color})=>(
<div key={l} style={{display:"flex",justifyContent:"space-between",
alignItems:"center",marginBottom:7}}>
<span style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani"}}>{l}</span>
<div style={{display:"flex",alignItems:"center",gap:5}}>
<div className={on?"live-dot":""} style={{width:5,height:5,borderRadius:"50%",
background:on?color:C.dim,...(on?{boxShadow:`0 0 5px ${color}`}:{})}}/>
<span style={{color:on?color:C.muted,fontSize:8,fontFamily:"JetBrains Mono"}}>
{on?"RUN":"OFF"}
</span>
</div>
</div>
))}
</Panel>
</div>
</div>
{/* Positions + Signals */}
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:12}}>
<Panel>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12}}>
<SectionTitle>OPEN POSITIONS · {positions.length}/{cfg.maxPos}</SectionTitle>
<button onClick={()=>setPositions([])}
style={{background:`${C.danger}15`,border:`1px solid ${C.danger}44`,
color:C.danger,padding:"4px 12px",borderRadius:4,fontSize:10}}>
CLOSE ALL
</button>
</div>
{positions.length===0?(
<div style={{color:C.muted,textAlign:"center",padding:30,
fontFamily:"JetBrains Mono",fontSize:11}}>No active positions</div>
):positions.map(p=><PosCard key={p.coin} p={p} onClose={closePos}/>)}
</Panel>
<Panel>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12}}>
<SectionTitle>SIGNAL STREAM · LIVE</SectionTitle>
<div style={{display:"flex",alignItems:"center",gap:5}}>
<div className="live-dot" style={{width:5,height:5,borderRadius:"50%",
background:C.success,boxShadow:`0 0 5px ${C.success}`}}/>
<span style={{color:C.success,fontSize:8,fontFamily:"JetBrains Mono"}}>STREAMING</span>
</div>
</div>
<div style={{display:"grid",gridTemplateColumns:"54px 46px 90px 60px 1fr 52px",
gap:6,marginBottom:6,padding:"0 10px"}}>
{["COIN","DIR","CONF","REGIME","TIME","STATUS"].map(h=>(
<span key={h} style={{color:C.muted,fontSize:7,fontFamily:"Rajdhani",letterSpacing:1.5}}>{h}</span>
))}
</div>
<div style={{maxHeight:210,overflowY:"auto"}}>
{signals.map(s=><SigRow key={s.id} s={s}/>)}
</div>
</Panel>
</div>
{/* Pump + Risk preview */}
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:12}}>
<Panel>
<SectionTitle>PUMP SCANNER · ALERTS</SectionTitle>
{pumpAlerts.map((a,i)=>(
<div key={i} className={a.act?(a.type==="PUMP"?"pump":"dump"):""}
style={{display:"flex",justifyContent:"space-between",alignItems:"center",
padding:"9px 12px",borderRadius:6,marginBottom:6,
border:`1px solid ${a.act?(a.type==="PUMP"?C.warn:C.danger):C.border}44`}}>
<div style={{display:"flex",gap:10,alignItems:"center"}}>
<span style={{color:C.text,fontFamily:"Orbitron",fontSize:12,fontWeight:700}}>{a.coin}</span>
<Badge text={a.type} color={a.type==="PUMP"?C.warn:C.danger}/>
<span style={{color:a.type==="PUMP"?C.warn:C.danger,fontFamily:"JetBrains Mono",fontSize:14,fontWeight:600}}>{a.pct}</span>
</div>
<div style={{textAlign:"right"}}>
<div style={{color:C.text,fontSize:10,fontFamily:"JetBrains Mono"}}>Vol: {a.vol}</div>
<div style={{color:C.muted,fontSize:9,fontFamily:"JetBrains Mono"}}>{a.time}</div>
</div>
</div>
))}
</Panel>
<Panel>
<SectionTitle>RISK MANAGER</SectionTitle>
{/* Circuit breaker */}
<div style={{marginBottom:14}}>
<div style={{display:"flex",justifyContent:"space-between",marginBottom:6}}>
<span style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani"}}>Circuit Breaker</span>
<span style={{color:cbLosses>=cfg.cbLosses?C.danger:C.warn,
fontFamily:"JetBrains Mono",fontSize:10}}>
{cbLosses}/{cfg.cbLosses} losses
</span>
</div>
<div style={{display:"flex",gap:4}}>
{[...Array(cfg.cbLosses)].map((_,i)=>(
<div key={i} style={{flex:1,height:6,borderRadius:3,
background:i<cbLosses?`${C.danger}cc`:C.dim,transition:"background .3s"}}/>
))}
</div>
</div>
{/* Daily loss */}
{(()=>{
const used=Math.max(0,Math.abs(Math.min(0,dailyPnL))/balance*100);
const pct=Math.min(used/cfg.maxLoss*100,100);
return(
<div style={{marginBottom:14}}>
<div style={{display:"flex",justifyContent:"space-between",marginBottom:6}}>
<span style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani"}}>Daily Loss Used</span>
<span style={{color:pct>75?C.danger:C.text,fontFamily:"JetBrains Mono",fontSize:10}}>
{used.toFixed(2)}% / {cfg.maxLoss}%
</span>
</div>
<div style={{height:5,background:C.dim,borderRadius:3,overflow:"hidden"}}>
<div style={{width:`${pct}%`,height:"100%",borderRadius:3,
background:pct>75?C.danger:pct>50?C.warn:C.success,transition:"width .5s"}}/>
</div>
</div>
);
})()}
<Row l="Risk/Trade" v={`${cfg.risk}% of equity`}/>
<Row l="SL / TP" v={`${cfg.sl}% / ${cfg.tp}%`}/>
<Row l="Leverage" v={`${cfg.leverage}x`}/>
<Row l="Min Confidence" v={`${cfg.minConf}%`}/>
</Panel>
</div>
</div>
);
}
// ── Tab: AI Bot ────────────────────────────────────────────────────────────
function TabAIBot(){
return(
<div style={{display:"flex",flexDirection:"column",gap:14}}>
<div style={{display:"grid",gridTemplateColumns:"260px 1fr",gap:14}}>
{/* Left: controls + confidence */}
<div style={{display:"flex",flexDirection:"column",gap:12}}>
<Panel accentColor={C.accent}>
<SectionTitle>AI BOT CONTROL</SectionTitle>
<div style={{display:"flex",justifyContent:"center",marginBottom:16}}>
<ConfArc value={confidence}/>
</div>
<div style={{display:"flex",flexDirection:"column",gap:10,marginBottom:14}}>
<Toggle on={botOn} toggle={()=>setBotOn(!botOn)} label="Bot Active" color={C.accent}/>
<Toggle on={paperMode} toggle={()=>setPaperMode(!paperMode)}
label={paperMode?"Paper Mode":"Live Mode"} color={paperMode?C.blue:C.danger}/>
<Toggle on={regimeFilter} toggle={()=>setRegimeFilter(!regimeFilter)}
label="Regime Filter (HMM)" color={C.purple}/>
<Toggle on={retrainOn} toggle={()=>setRetrainOn(!retrainOn)}
label="Auto-Retrain" color={C.purple}/>
</div>
<div style={{borderTop:`1px solid ${C.border}`,paddingTop:12}}>
<Row l="Model" v="Ensemble"/>
<Row l="Components" v="LGB+XGB+RF"/>
<Row l="Features" v="62 engineered"/>
<Row l="Min Confidence" v={`${cfg.minConf}%`}/>
<Row l="Accuracy" v={`${accuracy.toFixed(1)}%`} color={C.blue}/>
<Row l="Win Rate" v={`${winRate.toFixed(1)}%`} color={winRate>60?C.success:C.warn}/>
</div>
<div style={{display:"flex",gap:8,marginTop:12}}>
<button style={{flex:1,background:`${C.danger}15`,border:`1px solid ${C.danger}44`,
color:C.danger,padding:"7px 0",borderRadius:5,fontSize:11}}>
STOP BOT
</button>
<button style={{flex:1,background:`${C.accent}15`,border:`1px solid ${C.accent}44`,
color:C.accent,padding:"7px 0",borderRadius:5,fontSize:11}}>
RESTART
</button>
</div>
</Panel>
</div>
{/* Right: positions + signal stream */}
<div style={{display:"flex",flexDirection:"column",gap:12}}>
<Panel>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12}}>
<SectionTitle>OPEN POSITIONS · {positions.length}/{cfg.maxPos}</SectionTitle>
<button onClick={()=>setPositions([])}
style={{background:`${C.danger}15`,border:`1px solid ${C.danger}44`,
color:C.danger,padding:"4px 12px",borderRadius:4,fontSize:10}}>
CLOSE ALL
</button>
</div>
{positions.length===0
?<div style={{color:C.muted,textAlign:"center",padding:24,fontFamily:"JetBrains Mono",fontSize:11}}>
No active positions
</div>
:positions.map(p=><PosCard key={p.coin} p={p} onClose={closePos}/>)}
</Panel>
<Panel style={{flex:1}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:12}}>
<SectionTitle>LIVE SIGNAL STREAM</SectionTitle>
<div style={{display:"flex",alignItems:"center",gap:5}}>
<div className="live-dot" style={{width:5,height:5,borderRadius:"50%",
background:botOn?C.success:C.dim,...(botOn?{boxShadow:`0 0 5px ${C.success}`}:{})}}/>
<span style={{color:botOn?C.success:C.muted,fontSize:8,fontFamily:"JetBrains Mono"}}>
{botOn?"LIVE":"PAUSED"}
</span>
</div>
</div>
<div style={{display:"grid",gridTemplateColumns:"54px 46px 90px 60px 1fr 52px",
gap:6,marginBottom:6,padding:"0 10px"}}>
{["COIN","DIR","CONF","REGIME","TIME","STATUS"].map(h=>(
<span key={h} style={{color:C.muted,fontSize:7,fontFamily:"Rajdhani",letterSpacing:1.5}}>{h}</span>
))}
</div>
<div style={{maxHeight:240,overflowY:"auto"}}>
{signals.map(s=><SigRow key={s.id} s={s}/>)}
</div>
</Panel>
</div>
</div>
</div>
);
}
// ── Tab: Grid Bot ──────────────────────────────────────────────────────────
function TabGrid(){
const lower=65000,upper=70000,cur=67892,levels=cfg.gridLevels;
const step=(upper-lower)/levels;
const gridLines=[...Array(levels+1)].map((_,i)=>lower+i*step);
const gridPnL=12.4,filledCount=4;
return(
<div style={{display:"grid",gridTemplateColumns:"280px 1fr",gap:14}}>
<div style={{display:"flex",flexDirection:"column",gap:12}}>
<Panel accentColor={C.blue}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16}}>
<SectionTitle>GRID BOT</SectionTitle>
<Toggle on={gridOn} toggle={()=>setGridOn(!gridOn)} color={C.blue}/>
</div>
<Row l="Coin" v={cfg.gridCoin+"/USDT"}/>
<Row l="Strategy" v={cfg.gridStrategy}/>
<Row l="Range" v={`$${(lower/1000).toFixed(0)}K $${(upper/1000).toFixed(0)}K`}/>
<Row l="Grid Levels" v={cfg.gridLevels}/>
<Row l="Total USDT" v={`$${cfg.gridUsdt}`}/>
<Row l="Per Grid" v={`$${(cfg.gridUsdt/cfg.gridLevels).toFixed(1)}`}/>
<Row l="Leverage" v="3x"/>
<div style={{borderTop:`1px solid ${C.border}`,marginTop:10,paddingTop:10}}>
<div style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",letterSpacing:2,marginBottom:8}}>RUNTIME STATS</div>
<Row l="Filled Orders" v={`${filledCount} / ${levels}`} color={C.success}/>
<Row l="Grid P&L" v={`+$${gridPnL.toFixed(2)}`} color={C.success}/>
<Row l="Est. Daily" v="~1.2%"/>
</div>
<div style={{marginTop:12}}>
<div style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",letterSpacing:1.5,marginBottom:8}}>STRATEGY</div>
<div style={{display:"flex",flexWrap:"wrap",gap:5}}>
{GRID_STRATEGIES.map(s=>(
<button key={s} onClick={()=>setC("gridStrategy",s)}
style={{background:cfg.gridStrategy===s?`${C.blue}22`:C.dim,
border:`1px solid ${cfg.gridStrategy===s?C.blue:C.border}`,
color:cfg.gridStrategy===s?C.blue:C.muted,
padding:"3px 10px",borderRadius:4,fontSize:10}}>
{s}
</button>
))}
</div>
</div>
</Panel>
</div>
<Panel>
<SectionTitle>GRID VISUALIZATION · {cfg.gridCoin}/USDT</SectionTitle>
<div style={{position:"relative",height:380}}>
{gridLines.map((price,i)=>{
const pct=(price-lower)/(upper-lower)*100;
const above=price>cur;
const filled=!above&&i%3===0;
return(
<div key={i} style={{position:"absolute",left:0,right:0,bottom:`${pct}%`,
display:"flex",alignItems:"center",gap:8}}>
<div style={{flex:1,height:1,
background:filled?`${C.success}55`:above?`${C.danger}22`:`${C.border}55`}}/>
<div style={{display:"flex",alignItems:"center",gap:6}}>
{filled&&<Badge text="FILLED" color={C.success} small/>}
{above&&<Badge text="SELL" color={C.danger} small/>}
{!filled&&!above&&<Badge text="BUY" color={C.success} small/>}
<span style={{color:filled?C.success:above?C.danger:C.muted,
fontSize:9,fontFamily:"JetBrains Mono",width:80,textAlign:"right"}}>
${price.toLocaleString()}
</span>
</div>
</div>
);
})}
{/* Current price */}
<div style={{position:"absolute",left:0,right:0,
bottom:`${(cur-lower)/(upper-lower)*100}%`,
display:"flex",alignItems:"center",gap:8}}>
<div style={{flex:1,height:2,background:C.accent,
boxShadow:`0 0 8px ${C.accent}`}}/>
<div style={{display:"flex",alignItems:"center",gap:6}}>
<div className="hum" style={{background:`${C.accent}22`,border:`1px solid ${C.accent}`,
borderRadius:3,padding:"2px 8px"}}>
<span style={{color:C.accent,fontSize:10,fontFamily:"JetBrains Mono",fontWeight:600}}>
CURRENT ${cur.toLocaleString()}
</span>
</div>
</div>
</div>
</div>
</Panel>
</div>
);
}
// ── Tab: DCA Bot ───────────────────────────────────────────────────────────
function TabDCA(){
const safeties=[...Array(cfg.dcaMaxSafety)].map((_,i)=>({
lv:i+1,
price:Math.round(67420*(1-cfg.dcaMaxSafety*cfg.dcaDev/100+i*cfg.dcaDev/100)),
size:+(cfg.dcaSafety*Math.pow(1.5,i)).toFixed(0),
filled:i<2
}));
const totalInvested=cfg.dcaBase+safeties.filter(s=>s.filled).reduce((a,b)=>a+b.size,0);
return(
<div style={{display:"grid",gridTemplateColumns:"280px 1fr",gap:14}}>
<Panel accentColor={C.warn}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16}}>
<SectionTitle>DCA BOT</SectionTitle>
<Toggle on={dcaOn} toggle={()=>setDcaOn(!dcaOn)} color={C.warn}/>
</div>
<Row l="Coin" v={cfg.dcaCoin+"/USDT"}/>
<Row l="Strategy" v="Classic"/>
<Row l="Base Order" v={`$${cfg.dcaBase}`}/>
<Row l="Safety Order" v={`$${cfg.dcaSafety}`}/>
<Row l="Max Safety Orders" v={cfg.dcaMaxSafety}/>
<Row l="Price Deviation" v={`${cfg.dcaDev}%`}/>
<Row l="Take Profit" v={`${cfg.dcaTp}%`}/>
<div style={{borderTop:`1px solid ${C.border}`,marginTop:10,paddingTop:10}}>
<Row l="Total Invested" v={`$${totalInvested.toFixed(0)}`} color={C.warn}/>
<Row l="Safety Filled" v={`${safeties.filter(s=>s.filled).length}/${cfg.dcaMaxSafety}`} color={C.warn}/>
<Row l="Avg Entry" v="$66,405"/>
<Row l="Current PnL" v="+$8.20" color={C.success}/>
</div>
<div style={{marginTop:12}}>
<div style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",letterSpacing:1.5,marginBottom:8}}>STRATEGY</div>
<div style={{display:"flex",flexWrap:"wrap",gap:5}}>
{DCA_STRATEGIES.map(s=>(
<button key={s} onClick={()=>setC("dcaStrategy",s)}
style={{background:C.dim,border:`1px solid ${C.border}`,
color:C.muted,padding:"3px 10px",borderRadius:4,fontSize:10}}>
{s}
</button>
))}
</div>
</div>
</Panel>
<Panel>
<SectionTitle>ORDER LADDER · {cfg.dcaCoin}/USDT</SectionTitle>
{/* Header */}
<div style={{display:"grid",gridTemplateColumns:"55px 110px 90px 100px 90px 70px",
gap:0,marginBottom:8,padding:"0 4px"}}>
{["LEVEL","PRICE","SIZE (USDT)","CUM. SIZE","DEVIATION","STATUS"].map(h=>(
<span key={h} style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",
letterSpacing:1.5,paddingBottom:6,borderBottom:`1px solid ${C.border}`}}>{h}</span>
))}
</div>
{/* Base */}
<div style={{display:"grid",gridTemplateColumns:"55px 110px 90px 100px 90px 70px",
gap:0,background:`${C.success}06`,padding:"8px 4px",borderRadius:4,marginBottom:2}}>
{["BASE",`$67,420`,`$${cfg.dcaBase}`,`$${cfg.dcaBase}`,"—",
<Badge key="s" text="FILLED" color={C.success} small/>].map((v,i)=>(
<span key={i} style={{color:i===5?undefined:C.text,fontSize:10,
fontFamily:"JetBrains Mono",display:"flex",alignItems:"center"}}>{v}</span>
))}
</div>
{safeties.map((so)=>(
<div key={so.lv} style={{display:"grid",gridTemplateColumns:"55px 110px 90px 100px 90px 70px",
gap:0,padding:"8px 4px",borderRadius:4,marginBottom:2,
background:so.filled?`${C.success}06`:"transparent"}}>
{[`SO${so.lv}`,`$${so.price.toLocaleString()}`,`$${so.size}`,
`$${cfg.dcaBase+safeties.slice(0,so.lv).reduce((a,b)=>a+b.size,0)}`,
`-${(so.lv*cfg.dcaDev).toFixed(1)}%`,
<Badge key="s" text={so.filled?"FILLED":"PENDING"}
color={so.filled?C.success:C.muted} small/>
].map((v,i)=>(
<span key={i} style={{color:i===5?undefined:so.filled?C.text:C.muted,fontSize:10,
fontFamily:"JetBrains Mono",display:"flex",alignItems:"center"}}>{v}</span>
))}
</div>
))}
{/* TP line */}
<div style={{marginTop:16,padding:"10px 12px",background:`${C.success}0a`,
border:`1px solid ${C.success}33`,borderRadius:6,
display:"flex",justifyContent:"space-between",alignItems:"center"}}>
<span style={{color:C.success,fontFamily:"Rajdhani",fontSize:11,letterSpacing:1}}>
TAKE PROFIT TARGET
</span>
<span style={{color:C.success,fontFamily:"JetBrains Mono",fontSize:12,fontWeight:600}}>
$67,734 (+{cfg.dcaTp}% from avg)
</span>
</div>
</Panel>
</div>
);
}
// ── Tab: Pump Scanner ──────────────────────────────────────────────────────
function TabPump(){
return(
<div style={{display:"grid",gridTemplateColumns:"260px 1fr",gap:14}}>
<Panel accentColor={C.success}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",marginBottom:16}}>
<SectionTitle>PUMP SCANNER</SectionTitle>
<Toggle on={pumpOn} toggle={()=>setPumpOn(!pumpOn)} color={C.success}/>
</div>
<Row l="Volume Threshold" v={`${cfg.pumpVol}x avg`}/>
<Row l="Price Spike" v={`>${cfg.pumpPrice}%`}/>
<Row l="Leverage" v={`${cfg.pumpLev}x`}/>
<Row l="Risk/Trade" v={`${cfg.pumpRisk}% equity`}/>
<Row l="Scan Interval" v="3s"/>
<Row l="Scanning" v={`${COINS.length} pairs`}/>
<Row l="Announcements" v="Monitoring"/>
<div style={{borderTop:`1px solid ${C.border}`,marginTop:10,paddingTop:10}}>
<div style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",letterSpacing:2,marginBottom:8}}>TODAY STATS</div>
<Row l="Pumps Detected" v="7" color={C.warn}/>
<Row l="Trades Entered" v="3" color={C.success}/>
<Row l="Scanner P&L" v="+$89.20" color={C.success}/>
</div>
<div style={{marginTop:12}}>
<button onClick={()=>setPumpAlerts([])}
style={{width:"100%",background:`${C.muted}22`,border:`1px solid ${C.border}`,
color:C.muted,padding:"7px 0",borderRadius:5,fontSize:10}}>
CLEAR ALERTS
</button>
</div>
</Panel>
<Panel>
<SectionTitle>LIVE ALERTS · {pumpAlerts.length} ACTIVE</SectionTitle>
{pumpAlerts.length===0
?<div style={{color:C.muted,textAlign:"center",padding:50,
fontFamily:"JetBrains Mono",fontSize:12}}>Market calm no alerts</div>
:pumpAlerts.map((a,i)=>(
<div key={i} className={a.act?(a.type==="PUMP"?"pump":"dump"):""}
style={{padding:18,marginBottom:10,borderRadius:8,
border:`1px solid ${a.act?(a.type==="PUMP"?C.warn:C.danger):C.border}44`}}>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"flex-start",marginBottom:10}}>
<div style={{display:"flex",gap:10,alignItems:"center"}}>
<span style={{color:C.text,fontFamily:"Orbitron",fontSize:20,fontWeight:700}}>{a.coin}</span>
<Badge text={a.type} color={a.type==="PUMP"?C.warn:C.danger}/>
{a.act&&<div className="live-dot" style={{width:6,height:6,borderRadius:"50%",
background:a.type==="PUMP"?C.warn:C.danger}}/>}
</div>
<span style={{color:a.type==="PUMP"?C.warn:C.danger,
fontFamily:"JetBrains Mono",fontSize:28,fontWeight:700}}>{a.pct}</span>
</div>
<div style={{display:"grid",gridTemplateColumns:"repeat(3,1fr)",gap:10}}>
{[["VOLUME MULT",a.vol,C.text],
["TIME",a.time,C.muted],
["STATUS",a.act?"ACTIVE":"EXPIRED",a.act?C.success:C.muted]
].map(([l,v,c])=>(
<div key={l}>
<div style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",
letterSpacing:1.5,marginBottom:3}}>{l}</div>
<div style={{color:c,fontFamily:"JetBrains Mono",fontSize:14}}>{v}</div>
</div>
))}
</div>
</div>
))}
</Panel>
</div>
);
}
// ── Tab: Risk Manager ──────────────────────────────────────────────────────
function TabRisk(){
const used=Math.max(0,Math.abs(Math.min(0,dailyPnL))/balance*100);
const perfData=[
{n:"Mon",pnl:145},{n:"Tue",pnl:-42},{n:"Wed",pnl:234},{n:"Thu",pnl:89},
{n:"Fri",pnl:-28},{n:"Sat",pnl:312},{n:"Sun",pnl:178}
];
return(
<div style={{display:"flex",flexDirection:"column",gap:14}}>
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:12}}>
{/* Circuit Breaker */}
<Panel>
<SectionTitle>CIRCUIT BREAKER</SectionTitle>
<div style={{display:"flex",gap:6,marginBottom:12}}>
{[...Array(cfg.cbLosses)].map((_,i)=>(
<div key={i} style={{flex:1,height:44,borderRadius:6,
background:i<cbLosses?`${C.danger}88`:C.dim,
border:`1px solid ${i<cbLosses?C.danger:C.border}`,
display:"flex",alignItems:"center",justifyContent:"center",transition:"all .3s"}}>
<span style={{fontSize:18,color:i<cbLosses?C.danger:C.muted}}>
{i<cbLosses?"✗":"○"}
</span>
</div>
))}
</div>
<div style={{color:cbLosses>=cfg.cbLosses?C.danger:C.muted,
fontSize:10,fontFamily:"Rajdhani",marginBottom:10}}>
{cbLosses>=cfg.cbLosses?"⚠ ACTIVE — Trading paused for 1h":`${cfg.cbLosses-cbLosses} loss(es) until pause`}
</div>
<Row l="Consecutive Losses" v={`${cbLosses}/${cfg.cbLosses}`} color={cbLosses>0?C.warn:C.text}/>
<Row l="Cooldown Period" v="3600s (1h)"/>
<Row l="Status" v={cbLosses>=cfg.cbLosses?"TRIGGERED":"MONITORING"}
color={cbLosses>=cfg.cbLosses?C.danger:C.success}/>
</Panel>
{/* Daily Loss */}
<Panel>
<SectionTitle>DAILY LOSS LIMIT</SectionTitle>
<div style={{position:"relative",height:22,background:C.dim,
borderRadius:11,overflow:"hidden",marginBottom:12}}>
<div style={{position:"absolute",inset:0,
width:`${Math.min(used/cfg.maxLoss*100,100)}%`,
background:used/cfg.maxLoss>0.8?C.danger:used/cfg.maxLoss>0.5?C.warn:C.success,
borderRadius:11,transition:"width .5s"}}/>
<div style={{position:"absolute",inset:0,display:"flex",
alignItems:"center",justifyContent:"center"}}>
<span style={{color:"white",fontSize:10,fontFamily:"JetBrains Mono",fontWeight:600}}>
{used.toFixed(2)}% / {cfg.maxLoss}%
</span>
</div>
</div>
<Row l="Used Today" v={`$${Math.abs(Math.min(0,dailyPnL)).toFixed(2)}`} color={C.danger}/>
<Row l="Max Allowed" v={`${cfg.maxLoss}% = $${(balance*cfg.maxLoss/100).toFixed(0)}`}/>
<Row l="Remaining" v={`$${Math.max(0,balance*cfg.maxLoss/100-Math.abs(Math.min(0,dailyPnL))).toFixed(2)}`} color={C.success}/>
<Row l="Reset" v="00:00 UTC"/>
</Panel>
{/* Performance */}
<Panel>
<SectionTitle>PERFORMANCE</SectionTitle>
<Row l="Total Trades" v={totalTrades}/>
<Row l="Win Rate" v={`${winRate.toFixed(1)}%`} color={winRate>60?C.success:C.warn}/>
<Row l="AI Accuracy" v={`${accuracy.toFixed(1)}%`} color={C.blue}/>
<Row l="Avg Win" v="+$23.4" color={C.success}/>
<Row l="Avg Loss" v="-$14.2" color={C.danger}/>
<Row l="Profit Factor" v="1.65" color={C.success}/>
<Row l="Sharpe Ratio" v="2.14" color={C.success}/>
<Row l="Max Drawdown" v="-8.3%" color={C.danger}/>
</Panel>
</div>
{/* Risk params + Weekly chart */}
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:12}}>
<Panel>
<SectionTitle>RISK PARAMETERS</SectionTitle>
<Row l="Risk per Trade" v={`${cfg.risk}% of equity`}/>
<Row l="Stop Loss" v={`${cfg.sl}%`} color={C.danger}/>
<Row l="Take Profit" v={`${cfg.tp}%`} color={C.success}/>
<Row l="R:R Ratio" v={`1:${(cfg.tp/cfg.sl).toFixed(2)}`} color={C.blue}/>
<Row l="Leverage" v={`${cfg.leverage}x`} color={C.warn}/>
<Row l="Max Positions" v={cfg.maxPos}/>
<Row l="Max Margin Usage" v="20%"/>
<Row l="Max Hold Duration" v={`${cfg.maxHold} candles (${cfg.maxHold}h)`}/>
<Row l="Compound Mode" v={cfg.compound?"ON":"OFF"} color={cfg.compound?C.success:C.muted}/>
<Row l="Capital Cap" v="$1,000,000"/>
</Panel>
<Panel>
<SectionTitle>DAILY P&L · 7 DAYS</SectionTitle>
<ResponsiveContainer width="100%" height={200}>
<BarChart data={perfData} margin={{top:4,right:0,left:-20,bottom:0}}>
<XAxis dataKey="n" tick={{fill:C.muted,fontSize:9,fontFamily:"JetBrains Mono"}}
tickLine={false} axisLine={false}/>
<YAxis tick={{fill:C.muted,fontSize:9,fontFamily:"JetBrains Mono"}}
tickLine={false} axisLine={false}/>
<Tooltip contentStyle={{background:C.surface,border:`1px solid ${C.border}`,
borderRadius:6,fontFamily:"JetBrains Mono",fontSize:10,color:C.text}}/>
<ReferenceLine y={0} stroke={C.border} strokeOpacity={.6}/>
<Bar dataKey="pnl" fill={C.accent}
radius={[3,3,0,0]}
label={false}/>
</BarChart>
</ResponsiveContainer>
</Panel>
</div>
</div>
);
}
// ── Tab: AI Model ──────────────────────────────────────────────────────────
function TabModel(){
const features=[
{n:"rsi_14",v:.124},{n:"funding_rate",v:.098},{n:"volume_ma_ratio",v:.087},
{n:"oi_change_pct",v:.076},{n:"price_momentum_7",v:.065},{n:"cvd_20",v:.058},
{n:"atr_14",v:.051},{n:"btc_correlation_20",v:.043},{n:"fear_greed_index",v:.039},
{n:"order_flow_ratio",v:.033},{n:"obi_proxy",v:.029},{n:"price_skewness_24",v:.025},
];
const maxV=features[0].v;
return(
<div style={{display:"flex",flexDirection:"column",gap:14}}>
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:14}}>
<Panel>
<SectionTitle>ENSEMBLE MODEL</SectionTitle>
<Row l="Type" v="XGBoost + LightGBM + RF"/>
<Row l="Accuracy" v={`${accuracy.toFixed(1)}%`} color={C.blue}/>
<Row l="Walk-forward" v="4-window validated"/>
<Row l="Features" v="62 engineered"/>
<Row l="Training Data" v="12 months · 27 coins"/>
<Row l="HPO Trials" v="200+ (Optuna)"/>
<Row l="Min Confidence" v={`${cfg.minConf}%`}/>
<Row l="Last Retrain" v="4h ago"/>
<Row l="Next Auto-Retrain" v="20h"/>
<Row l="Min Retrain Acc." v={`${cfg.retrainMinAcc}%`}/>
<div style={{borderTop:`1px solid ${C.border}`,marginTop:12,paddingTop:12}}>
<div style={{display:"flex",gap:8,marginBottom:8}}>
<Toggle on={retrainOn} toggle={()=>setRetrainOn(!retrainOn)}
label="Auto-Retrain" color={C.purple}/>
</div>
</div>
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr",gap:8,marginTop:8}}>
<button style={{background:`${C.blue}15`,border:`1px solid ${C.blue}44`,
color:C.blue,padding:"8px 0",borderRadius:5,fontSize:11}}>
RETRAIN NOW
</button>
<button style={{background:`${C.accent}15`,border:`1px solid ${C.accent}44`,
color:C.accent,padding:"8px 0",borderRadius:5,fontSize:11}}>
BACKTEST
</button>
<button style={{background:`${C.warn}15`,border:`1px solid ${C.warn}44`,
color:C.warn,padding:"8px 0",borderRadius:5,fontSize:11}}>
DOWNLOAD DATA
</button>
<button style={{background:`${C.muted}22`,border:`1px solid ${C.border}`,
color:C.muted,padding:"8px 0",borderRadius:5,fontSize:11}}>
VIEW LOGS
</button>
</div>
</Panel>
<Panel>
<SectionTitle>FEATURE IMPORTANCE · TOP 12</SectionTitle>
{features.map(({n,v},i)=>(
<div key={n} style={{marginBottom:8}}>
<div style={{display:"flex",justifyContent:"space-between",marginBottom:2}}>
<span style={{color:C.muted,fontSize:9,fontFamily:"JetBrains Mono"}}>{n}</span>
<span style={{color:C.text,fontSize:9,fontFamily:"JetBrains Mono"}}>{(v*100).toFixed(1)}%</span>
</div>
<div style={{height:4,background:C.dim,borderRadius:2}}>
<div style={{width:`${v/maxV*100}%`,height:"100%",borderRadius:2,
background:i===0?C.accent:i<3?C.blue:C.muted,
opacity:Math.max(0.3,1-i*.06)}}/>
</div>
</div>
))}
</Panel>
</div>
<Panel>
<SectionTitle>TRADING UNIVERSE · {COINS.length} COINS</SectionTitle>
<div style={{display:"flex",flexWrap:"wrap",gap:7}}>
{COINS.map(coin=>{
const hasPos=positions.some(p=>p.coin===coin);
return(
<div key={coin} style={{
background:hasPos?`${C.accent}18`:C.dim,
border:`1px solid ${hasPos?C.accent:C.border}`,
borderRadius:5,padding:"4px 11px",
...(hasPos?{boxShadow:`0 0 8px ${C.accent}33`}:{})}}>
<span style={{color:hasPos?C.accent:C.muted,
fontFamily:"JetBrains Mono",fontSize:11}}>{coin}</span>
</div>
);
})}
</div>
</Panel>
</div>
);
}
// ── Tab: Config ────────────────────────────────────────────────────────────
function TabConfig(){
function CfgSlider({label,field,min,max,step=1,suffix=""}){
return(
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",
marginBottom:11,paddingBottom:10,borderBottom:`1px solid ${C.border}22`}}>
<span style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani",flex:1}}>{label}</span>
<div style={{display:"flex",alignItems:"center",gap:8}}>
<input type="range" min={min} max={max} step={step} value={cfg[field]}
onChange={e=>setC(field,parseFloat(e.target.value))} style={{width:90}}/>
<span style={{color:C.accent,fontFamily:"JetBrains Mono",fontSize:11,
minWidth:46,textAlign:"right"}}>{cfg[field]}{suffix}</span>
</div>
</div>
);
}
return(
<div style={{display:"grid",gridTemplateColumns:"1fr 1fr 1fr",gap:14}}>
{/* Bot Config */}
<div style={{display:"flex",flexDirection:"column",gap:12}}>
<Panel>
<SectionTitle>EXCHANGE & MODE</SectionTitle>
<div style={{marginBottom:14}}>
<div style={{color:C.muted,fontSize:8,fontFamily:"Rajdhani",
letterSpacing:2,marginBottom:8}}>EXCHANGE</div>
<div style={{display:"flex",flexWrap:"wrap",gap:5}}>
{EXCHANGES.map(ex=>(
<button key={ex} onClick={()=>setExchange(ex)}
style={{background:exchange===ex?`${C.accent}1a`:C.dim,
border:`1px solid ${exchange===ex?C.accent:C.border}`,
color:exchange===ex?C.accent:C.muted,
padding:"4px 10px",borderRadius:4,fontSize:10}}>
{ex}
</button>
))}
</div>
</div>
<div style={{marginBottom:14}}>
<Toggle on={paperMode} toggle={()=>setPaperMode(!paperMode)}
label={paperMode?"📄 Paper Mode (Simulation)":"💰 Live Trading"} color={paperMode?C.blue:C.danger}/>
</div>
<div style={{marginBottom:6}}>
<Toggle on={cfg.compound} toggle={()=>setC("compound",!cfg.compound)}
label="Compound Mode" color={C.accent}/>
</div>
</Panel>
<Panel>
<SectionTitle>BOT PARAMETERS</SectionTitle>
<CfgSlider label="Leverage" field="leverage" min={1} max={20} suffix="x"/>
<CfgSlider label="Risk per Trade" field="risk" min={0.5} max={10} step={0.5} suffix="%"/>
<CfgSlider label="Stop Loss" field="sl" min={0.5} max={5} step={0.1} suffix="%"/>
<CfgSlider label="Take Profit" field="tp" min={0.5} max={10} step={0.1} suffix="%"/>
<CfgSlider label="Max Positions" field="maxPos" min={1} max={10}/>
<CfgSlider label="Max Daily Loss" field="maxLoss" min={1} max={20} suffix="%"/>
<CfgSlider label="Min Confidence" field="minConf" min={60} max={95} suffix="%"/>
<CfgSlider label="Max Hold (candles)" field="maxHold" min={1} max={24}/>
</Panel>
</div>
{/* Grid + DCA */}
<div style={{display:"flex",flexDirection:"column",gap:12}}>
<Panel accentColor={C.blue}>
<SectionTitle>GRID BOT</SectionTitle>
<div style={{marginBottom:12}}>
<Toggle on={gridOn} toggle={()=>setGridOn(!gridOn)} label="Grid Bot" color={C.blue}/>
</div>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",
marginBottom:11,paddingBottom:10,borderBottom:`1px solid ${C.border}22`}}>
<span style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani"}}>Coin</span>
<select value={cfg.gridCoin} onChange={e=>setC("gridCoin",e.target.value)}>
{["BTC","ETH","SOL","BNB"].map(c=><option key={c}>{c}</option>)}
</select>
</div>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",
marginBottom:11,paddingBottom:10,borderBottom:`1px solid ${C.border}22`}}>
<span style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani"}}>Strategy</span>
<select value={cfg.gridStrategy} onChange={e=>setC("gridStrategy",e.target.value)}>
{GRID_STRATEGIES.map(s=><option key={s}>{s}</option>)}
</select>
</div>
<CfgSlider label="Grid Levels" field="gridLevels" min={5} max={50}/>
<CfgSlider label="Total USDT" field="gridUsdt" min={50} max={5000} step={50} suffix=" $"/>
</Panel>
<Panel accentColor={C.warn}>
<SectionTitle>DCA BOT</SectionTitle>
<div style={{marginBottom:12}}>
<Toggle on={dcaOn} toggle={()=>setDcaOn(!dcaOn)} label="DCA Bot" color={C.warn}/>
</div>
<div style={{display:"flex",justifyContent:"space-between",alignItems:"center",
marginBottom:11,paddingBottom:10,borderBottom:`1px solid ${C.border}22`}}>
<span style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani"}}>Coin</span>
<select value={cfg.dcaCoin} onChange={e=>setC("dcaCoin",e.target.value)}>
{["BTC","ETH","SOL","BNB"].map(c=><option key={c}>{c}</option>)}
</select>
</div>
<CfgSlider label="Base Order" field="dcaBase" min={10} max={1000} step={10} suffix=" $"/>
<CfgSlider label="Safety Order" field="dcaSafety" min={10} max={1000} step={10} suffix=" $"/>
<CfgSlider label="Max Safety Orders" field="dcaMaxSafety" min={1} max={10}/>
<CfgSlider label="Price Deviation" field="dcaDev" min={0.5} max={5} step={0.1} suffix="%"/>
<CfgSlider label="Take Profit" field="dcaTp" min={0.5} max={10} step={0.1} suffix="%"/>
</Panel>
</div>
{/* Pump + Model */}
<div style={{display:"flex",flexDirection:"column",gap:12}}>
<Panel accentColor={C.success}>
<SectionTitle>PUMP SCANNER</SectionTitle>
<div style={{marginBottom:12}}>
<Toggle on={pumpOn} toggle={()=>setPumpOn(!pumpOn)} label="Pump Scanner" color={C.success}/>
</div>
<CfgSlider label="Volume Multiplier" field="pumpVol" min={2} max={20} step={0.5} suffix="x"/>
<CfgSlider label="Price Spike" field="pumpPrice" min={1} max={15} suffix="%"/>
<CfgSlider label="Leverage" field="pumpLev" min={1} max={20} suffix="x"/>
<CfgSlider label="Risk per Trade" field="pumpRisk" min={1} max={20} suffix="%"/>
</Panel>
<Panel accentColor={C.purple}>
<SectionTitle>AI MODEL</SectionTitle>
<div style={{marginBottom:12}}>
<Toggle on={retrainOn} toggle={()=>setRetrainOn(!retrainOn)}
label="Auto-Retrain" color={C.purple}/>
</div>
<div style={{marginBottom:12}}>
<Toggle on={regimeFilter} toggle={()=>setRegimeFilter(!regimeFilter)}
label="Regime Filter (HMM)" color={C.purple}/>
</div>
<CfgSlider label="Retrain Interval" field="retrainInterval" min={1} max={168} suffix="h"/>
<CfgSlider label="Min Retrain Acc." field="retrainMinAcc" min={50} max={90} suffix="%"/>
</Panel>
<Panel>
<SectionTitle>CIRCUIT BREAKER</SectionTitle>
<CfgSlider label="Max Consecutive Losses" field="cbLosses" min={1} max={10}/>
<div style={{marginTop:6}}>
<Row l="Cooldown" v="3600s (1h)"/>
<Row l="Status" v={cbLosses>=cfg.cbLosses?"TRIGGERED":"MONITORING"}
color={cbLosses>=cfg.cbLosses?C.danger:C.success}/>
</div>
</Panel>
</div>
</div>
);
}
// ── Nav items ──────────────────────────────────────────────────────────────
const nav=[
{id:"overview",label:"OVERVIEW",dot:null},
{id:"aibot",label:"AI BOT",dot:botOn?C.accent:null},
{id:"grid",label:"GRID BOT",dot:gridOn?C.blue:null},
{id:"dca",label:"DCA BOT",dot:dcaOn?C.warn:null},
{id:"pump",label:"PUMP SCAN",dot:pumpOn?C.success:null},
{id:"risk",label:"RISK MGR",dot:cbLosses>0?C.warn:null},
{id:"model",label:"AI MODEL",dot:retrainOn?C.purple:null},
{id:"config",label:"CONFIG",dot:null},
];
// ── Final render ───────────────────────────────────────────────────────────
return(
<div style={{background:C.bg,minHeight:"100vh",color:C.text,fontFamily:"Rajdhani, sans-serif"}}>
<style>{CSS}</style>
{/* ── Top Bar ─────────────────────────────────────────────────────── */}
<div style={{background:C.surface,borderBottom:`1px solid ${C.border}`,
padding:"0 24px",height:52,display:"flex",alignItems:"center",
justifyContent:"space-between",position:"sticky",top:0,zIndex:100}}>
{/* Logo */}
<div style={{display:"flex",alignItems:"center",gap:12}}>
<span style={{fontFamily:"Orbitron",fontSize:17,fontWeight:900,
color:C.accent,letterSpacing:2,textShadow:`0 0 20px ${C.accent}66`}}>
DEEP<span style={{color:C.text}}>ALPHA</span>
</span>
<div style={{background:`${C.accent}18`,border:`1px solid ${C.accent}44`,
borderRadius:3,padding:"1px 9px"}}>
<span style={{color:C.accent,fontSize:8,fontFamily:"JetBrains Mono",letterSpacing:2}}>
PRO V11
</span>
</div>
</div>
{/* Center stats */}
<div style={{display:"flex",gap:24,alignItems:"center"}}>
<div style={{textAlign:"center"}}>
<div style={{color:C.muted,fontSize:7,fontFamily:"Rajdhani",letterSpacing:2}}>BALANCE</div>
<div style={{color:C.accent,fontFamily:"JetBrains Mono",fontSize:14,fontWeight:600}}>
${balance.toLocaleString("en-US",{minimumFractionDigits:2})}
</div>
</div>
<div style={{textAlign:"center"}}>
<div style={{color:C.muted,fontSize:7,fontFamily:"Rajdhani",letterSpacing:2}}>DAILY P&L</div>
<div style={{color:dailyColor,fontFamily:"JetBrains Mono",fontSize:14,fontWeight:600}}>
{dailyPnL>=0?"+":""}${fmt2(dailyPnL)}
</div>
</div>
<div style={{textAlign:"center"}}>
<div style={{color:C.muted,fontSize:7,fontFamily:"Rajdhani",letterSpacing:2}}>REGIME</div>
<div style={{color:regimeColor,fontFamily:"Orbitron",fontSize:12,fontWeight:700}}>
{regimeIcon} {regime}
</div>
</div>
<div style={{textAlign:"center"}}>
<div style={{color:C.muted,fontSize:7,fontFamily:"Rajdhani",letterSpacing:2}}>POSITIONS</div>
<div style={{color:C.text,fontFamily:"JetBrains Mono",fontSize:14}}>
{positions.length}<span style={{color:C.muted}}>/{cfg.maxPos}</span>
</div>
</div>
</div>
{/* Right status */}
<div style={{display:"flex",alignItems:"center",gap:16}}>
<div style={{background:paperMode?`${C.blue}18`:`${C.danger}18`,
border:`1px solid ${paperMode?C.blue:C.danger}44`,
borderRadius:4,padding:"3px 10px"}}>
<span style={{color:paperMode?C.blue:C.danger,fontSize:10,fontFamily:"Rajdhani",letterSpacing:1}}>
{paperMode?"📄 PAPER":"💰 LIVE"}
</span>
</div>
<div style={{fontSize:10,fontFamily:"Rajdhani",color:C.muted}}>
{exchange.toUpperCase()}
</div>
<div style={{display:"flex",alignItems:"center",gap:6}}>
<div className={botOn?"live-dot":""} style={{width:7,height:7,borderRadius:"50%",
background:botOn?C.success:C.danger,
...(botOn?{boxShadow:`0 0 8px ${C.success}`}:{})}}/>
<span style={{color:botOn?C.success:C.danger,fontSize:10,fontFamily:"JetBrains Mono"}}>
{botOn?"ACTIVE":"STOPPED"}
</span>
</div>
<span style={{color:C.muted,fontFamily:"JetBrains Mono",fontSize:10}}>
{clock.toLocaleTimeString("fr-FR")}
</span>
</div>
</div>
{/* ── Body ────────────────────────────────────────────────────────── */}
<div style={{display:"flex"}}>
{/* Sidebar */}
<div style={{width:168,background:C.surface,borderRight:`1px solid ${C.border}`,
minHeight:"calc(100vh - 52px)",padding:"12px 0",flexShrink:0,position:"sticky",
top:52,height:"calc(100vh - 52px)",overflowY:"auto"}}>
{nav.map(item=>(
<div key={item.id} className="nav-btn" onClick={()=>setTab(item.id)}
style={{display:"flex",alignItems:"center",gap:10,padding:"10px 16px",
cursor:"pointer",margin:"1px 8px",borderRadius:6,
background:tab===item.id?`${C.accent}12`:"transparent",
borderLeft:tab===item.id?`2px solid ${C.accent}`:"2px solid transparent",
transition:"all .2s",userSelect:"none"}}>
{item.dot&&<div style={{width:5,height:5,borderRadius:"50%",
background:item.dot,boxShadow:`0 0 5px ${item.dot}`,flexShrink:0}}/>}
{!item.dot&&<div style={{width:5,height:5,borderRadius:"50%",
background:"transparent",flexShrink:0}}/>}
<span style={{color:tab===item.id?C.accent:C.muted,
fontSize:11,fontFamily:"Rajdhani",letterSpacing:1.5,fontWeight:tab===item.id?600:400}}>
{item.label}
</span>
</div>
))}
{/* Quick toggles */}
<div style={{borderTop:`1px solid ${C.border}`,margin:"14px 10px 0",paddingTop:14}}>
<div style={{color:C.dim,fontSize:7,letterSpacing:2.5,fontFamily:"Rajdhani",
marginBottom:10,paddingLeft:6}}>QUICK CONTROLS</div>
{[
{l:"AI Bot",on:botOn,f:()=>setBotOn(!botOn),c:C.accent},
{l:"Grid",on:gridOn,f:()=>setGridOn(!gridOn),c:C.blue},
{l:"DCA",on:dcaOn,f:()=>setDcaOn(!dcaOn),c:C.warn},
{l:"Pump",on:pumpOn,f:()=>setPumpOn(!pumpOn),c:C.success},
].map(({l,on,f,c})=>(
<div key={l} onClick={f} style={{display:"flex",justifyContent:"space-between",
alignItems:"center",padding:"6px 6px",cursor:"pointer",borderRadius:4,
transition:"background .15s"}}>
<span style={{color:C.muted,fontSize:10,fontFamily:"Rajdhani"}}>{l}</span>
<div style={{width:30,height:16,borderRadius:8,
background:on?c:C.dim,position:"relative",transition:"background .3s"}}>
<div style={{position:"absolute",top:2,left:on?14:2,width:12,height:12,
borderRadius:6,background:"white",transition:"left .25s"}}/>
</div>
</div>
))}
</div>
{/* System info */}
<div style={{borderTop:`1px solid ${C.border}`,margin:"14px 10px 0",paddingTop:14}}>
<div style={{color:C.dim,fontSize:7,letterSpacing:2.5,fontFamily:"Rajdhani",
marginBottom:8,paddingLeft:6}}>SYSTEM</div>
<div style={{padding:"0 6px"}}>
{[["CPU","12%"],["RAM","2.1GB"],["Uptime","4h 23m"],["Loop","60s"]].map(([l,v])=>(
<div key={l} style={{display:"flex",justifyContent:"space-between",marginBottom:5}}>
<span style={{color:C.muted,fontSize:9,fontFamily:"Rajdhani"}}>{l}</span>
<span style={{color:C.text,fontSize:9,fontFamily:"JetBrains Mono"}}>{v}</span>
</div>
))}
</div>
</div>
</div>
{/* Main content */}
<div style={{flex:1,padding:18,overflowY:"auto",maxHeight:"calc(100vh - 52px)"}}>
{tab==="overview" && <TabOverview/>}
{tab==="aibot" && <TabAIBot/>}
{tab==="grid" && <TabGrid/>}
{tab==="dca" && <TabDCA/>}
{tab==="pump" && <TabPump/>}
{tab==="risk" && <TabRisk/>}
{tab==="model" && <TabModel/>}
{tab==="config" && <TabConfig/>}
</div>
</div>
</div>
);
}