Files

1400 lines
72 KiB
React
Raw Permalink Normal View History

2026-06-25 14:00:20 +03:00
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>
);
}