import React, { useState, useEffect, useMemo, useCallback } from 'react'; import { ArrowUp, ArrowDown, Activity, Clock, Zap, TrendingUp, TrendingDown, RefreshCw, Wifi, WifiOff, Layers, Box, AlertTriangle, BookOpen, Info, Flame, Globe, BarChart2, Battery, BatteryCharging, Gauge, HelpCircle, Target, Skull } from 'lucide-react'; // --- AYARLAR --- const SYMBOL = 'BTCUSDT'; const API_BASE = 'https://api.binance.com/api/v3'; // --- YARDIMCI FONKSİYONLAR --- const formatCurrency = (value) => { if (!value) return '---'; return new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 2 }).format(value); }; const calculateDistance = (current, target) => { if (!current || !target) return 0; const diff = Math.abs(current - target); return (diff / current) * 100; }; // EMA Hesaplama const calculateEMA = (closes, period) => { if (closes.length < period) return null; const k = 2 / (period + 1); let ema = closes.slice(0, period).reduce((a, b) => a + b, 0) / period; for (let i = period; i < closes.length; i++) { ema = (closes[i] * k) + (ema * (1 - k)); } return ema; }; // ATR (Average True Range) const calculateATR = (candles, period = 14) => { if (candles.length <= period) return 0; let trs = []; for(let i = 1; i < candles.length; i++) { const high = parseFloat(candles[i][2]); const low = parseFloat(candles[i][3]); const prevClose = parseFloat(candles[i-1][4]); const tr = Math.max(high - low, Math.abs(high - prevClose), Math.abs(low - prevClose)); trs.push(tr); } const last14TR = trs.slice(-period); return last14TR.reduce((a, b) => a + b, 0) / period; }; const getActiveSession = () => { const hour = new Date().getUTCHours(); if (hour >= 0 && hour < 8) return { name: 'ASIA SESSION', color: 'text-yellow-500', desc: 'Genelde range (yatay) oluşur. Likidite avı (Sweep) yaygındır.' }; if (hour >= 8 && hour < 13) return { name: 'LONDON OPEN', color: 'text-blue-400', desc: 'Hacim artışı ile gerçek trendin başlama olasılığı artar.' }; if (hour >= 13 && hour < 16) return { name: 'NY & LONDON OVERLAP', color: 'text-purple-400', desc: 'Volatilite zirve yapar. Gün içi ana hareketler genellikle burada gerçekleşir.' }; if (hour >= 16 && hour < 21) return { name: 'NY SESSION (PM)', color: 'text-emerald-400', desc: 'Trend devamı veya gün sonu pozisyon kapama hareketleri.' }; return { name: 'MARKET CLOSE/THIN', color: 'text-neutral-500', desc: 'Düşük likidite nedeniyle spread açılabilir, dikkat.' }; }; // --- STİL MANTIĞI --- const getStatusStyles = (distance, type, isConfluence) => { let styles = { rowBorder: 'border-l-2 border-transparent hover:bg-neutral-900/30', badge: 'text-neutral-600 font-normal', text: 'text-neutral-500', label: 'IDLE', barColor: 'bg-neutral-800' }; if (isConfluence) { styles.text = 'text-amber-200 font-bold'; styles.confluenceBadge = 'bg-purple-900/50 text-purple-200 border border-purple-500/30 px-1.5 rounded text-[9px] ml-2 animate-pulse'; } else if (type.includes('resistance')) { styles.text = 'text-red-400'; } else if (type.includes('support')) { styles.text = 'text-emerald-400'; } else if (type.includes('trap')) { styles.text = 'text-orange-400'; // Trap zone rengi farklı olsun } else { styles.text = 'text-indigo-400'; // Trend target rengi } if (distance < 0.35) { return { ...styles, rowBorder: 'border-l-2 border-amber-500 bg-amber-500/10', badge: 'bg-amber-500 text-black animate-pulse shadow-[0_0_10px_rgba(245,158,11,0.5)]', label: '⚡ BÖLGEDE', barColor: 'bg-amber-500' }; } else if (distance < 1.5) { return { ...styles, rowBorder: 'border-l-2 border-neutral-700 bg-neutral-900/50', badge: 'bg-neutral-800 text-amber-200 border border-amber-500/30', label: '👁️ İZLEMEDE', barColor: 'bg-amber-500/50' }; } return styles; }; export default function BarbarDashboard() { const [price, setPrice] = useState(null); const [levels, setLevels] = useState([]); const [yearlyOpen, setYearlyOpen] = useState(null); const [lastTouch, setLastTouch] = useState({}); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [tooltips, setTooltips] = useState({ yearly: false, trend: false, vitals: false }); const [session, setSession] = useState(getActiveSession()); const [trend, setTrend] = useState({ ema200: null, bias: 'NEUTRAL' }); const [vitals, setVitals] = useState({ atr: 0, dailyRange: 0, rangePercent: 0, rvol: 0 }); const toggleTooltip = (key, state) => setTooltips(prev => ({ ...prev, [key]: state })); // --- API VERİ ÇEKME --- const fetchMarketData = useCallback(async () => { try { setLoading(true); setError(null); const [weeklyRes, monthlyRes, yearlyRes, dailyRes, fourHourRes] = await Promise.all([ fetch(`${API_BASE}/klines?symbol=${SYMBOL}&interval=1w&limit=2`), fetch(`${API_BASE}/klines?symbol=${SYMBOL}&interval=1M&limit=2`), fetch(`${API_BASE}/klines?symbol=${SYMBOL}&interval=1M&limit=12`), fetch(`${API_BASE}/klines?symbol=${SYMBOL}&interval=1d&limit=30`), fetch(`${API_BASE}/klines?symbol=${SYMBOL}&interval=4h&limit=250`) ]); const weeklyData = await weeklyRes.json(); const monthlyData = await monthlyRes.json(); const yearlyData = await yearlyRes.json(); const dailyData = await dailyRes.json(); const fourHourData = await fourHourRes.json(); if (!Array.isArray(weeklyData)) throw new Error("API Error"); // 1. High/Low const prevWeek = weeklyData[weeklyData.length - 2]; const prevMonth = monthlyData[monthlyData.length - 2]; // 2. Yearly Open const currentYear = new Date().getFullYear(); const januaryCandle = yearlyData.find(k => new Date(k[0]).getFullYear() === currentYear && new Date(k[0]).getMonth() === 0); const yOpen = januaryCandle ? parseFloat(januaryCandle[1]) : parseFloat(yearlyData[0][1]); setYearlyOpen(yOpen); // 3. Monday Range let mondayHigh = null; let mondayLow = null; for (let i = dailyData.length - 1; i >= 0; i--) { const d = new Date(dailyData[i][0]); if (d.getDay() === 1) { mondayHigh = parseFloat(dailyData[i][2]); mondayLow = parseFloat(dailyData[i][3]); break; } } // 4. Trend (4H EMA 200) const closes4h = fourHourData.map(c => parseFloat(c[4])); const ema200 = calculateEMA(closes4h, 200); const lastPrice = parseFloat(fourHourData[fourHourData.length - 1][4]); let trendBias = 'NÖTR'; if (ema200) trendBias = lastPrice > ema200 ? 'YÜKSELİŞ (BULL)' : 'DÜŞÜŞ (BEAR)'; setTrend({ ema200, bias: trendBias }); // 5. Vitals (ATR) const atrValue = calculateATR(dailyData, 14); const currentDailyCandle = dailyData[dailyData.length - 1]; const currentHigh = parseFloat(currentDailyCandle[2]); const currentLow = parseFloat(currentDailyCandle[3]); const currentRange = currentHigh - currentLow; const rangeUsagePercent = (currentRange / atrValue) * 100; // 6. RVOL const currentVol = parseFloat(currentDailyCandle[5]); const avgVol = dailyData.slice(dailyData.length - 11, dailyData.length - 1) .reduce((acc, c) => acc + parseFloat(c[5]), 0) / 10; const rvol = currentVol / avgVol; setVitals({ atr: atrValue, dailyRange: currentRange, rangePercent: rangeUsagePercent, rvol: rvol }); // --- SEVİYE HESAPLAMALARI --- const pwh = parseFloat(prevWeek[2]); const pwl = parseFloat(prevWeek[3]); const wRange = pwh - pwl; const pmh = parseFloat(prevMonth[2]); const pml = parseFloat(prevMonth[3]); const mRange = pmh - pml; // --- SECRET SAUCE COEFFICIENTS --- // Gizli Katsayılar: 0.13 (Trap/Sweep) ve 0.618 (Trend/Target) const COEFF_TRAP = 0.13; const COEFF_TREND = 0.618; let rawLevels = [ // Weekly Levels { id: 'w_ext_trend_res', label: 'EXT. II (TREND)', price: pwh + (wRange * COEFF_TREND), type: 'extension_trend_res', group: 'Weekly' }, { id: 'w_ext_trap_res', label: 'EXT. I (TRAP)', price: pwh + (wRange * COEFF_TRAP), type: 'extension_trap_res', group: 'Weekly' }, { id: 'pwh', label: 'PWH (HIGH)', price: pwh, type: 'resistance', group: 'Weekly' }, { id: 'pwl', label: 'PWL (LOW)', price: pwl, type: 'support', group: 'Weekly' }, { id: 'w_ext_trap_sup', label: 'EXT. I (TRAP)', price: pwl - (wRange * COEFF_TRAP), type: 'extension_trap_sup', group: 'Weekly' }, { id: 'w_ext_trend_sup', label: 'EXT. II (TREND)', price: pwl - (wRange * COEFF_TREND), type: 'extension_trend_sup', group: 'Weekly' }, // Monthly Levels { id: 'm_ext_trend_res', label: 'EXT. II (TREND)', price: pmh + (mRange * COEFF_TREND), type: 'extension_trend_res', group: 'Monthly' }, { id: 'm_ext_trap_res', label: 'EXT. I (TRAP)', price: pmh + (mRange * COEFF_TRAP), type: 'extension_trap_res', group: 'Monthly' }, { id: 'pmh', label: 'PMH (HIGH)', price: pmh, type: 'resistance', group: 'Monthly' }, { id: 'pml', label: 'PML (LOW)', price: pml, type: 'support', group: 'Monthly' }, { id: 'm_ext_trap_sup', label: 'EXT. I (TRAP)', price: pml - (mRange * COEFF_TRAP), type: 'extension_trap_sup', group: 'Monthly' }, { id: 'm_ext_trend_sup', label: 'EXT. II (TREND)', price: pml - (mRange * COEFF_TREND), type: 'extension_trend_sup', group: 'Monthly' }, ]; if (mondayHigh) { rawLevels.push( { id: 'mon_high', label: 'MONDAY HIGH', price: mondayHigh, type: 'resistance', group: 'Weekly' }, { id: 'mon_low', label: 'MONDAY LOW', price: mondayLow, type: 'support', group: 'Weekly' } ); } const levelsWithConfluence = rawLevels.map(lvl => { const isConfluence = rawLevels.some(other => other.id !== lvl.id && Math.abs((lvl.price - other.price) / lvl.price) < 0.003 ); return { ...lvl, isConfluence }; }); setLevels(levelsWithConfluence.sort((a, b) => b.price - a.price)); setLoading(false); } catch (err) { console.error(err); setError("Veri Akışı Kesildi. API Bağlantısı Yok."); setLoading(false); } }, []); // --- POLLING --- useEffect(() => { fetchMarketData(); const interval = setInterval(async () => { setSession(getActiveSession()); try { const res = await fetch(`${API_BASE}/ticker/price?symbol=${SYMBOL}`); const data = await res.json(); if (data?.price) setPrice(parseFloat(data.price)); } catch (e) {} }, 3000); return () => clearInterval(interval); }, [fetchMarketData]); // Last Touch Logic useEffect(() => { if (!price || levels.length === 0) return; const now = new Date(); levels.forEach(lvl => { if (calculateDistance(price, lvl.price) < 0.05) { setLastTouch(prev => ({ ...prev, [lvl.id]: now })); } }); }, [price, levels]); const yearlyStatus = useMemo(() => { if (!price || !yearlyOpen) return {}; const isBullish = price > yearlyOpen; return { isBullish, color: isBullish ? 'text-emerald-500' : 'text-red-500', text: isBullish ? 'BULLISH BIAS' : 'BEARISH BIAS', bg: isBullish ? 'bg-emerald-500/10 border-emerald-500/20' : 'bg-red-500/10 border-red-500/20', }; }, [price, yearlyOpen]); // --- RENDER --- const renderTableSection = (title, groupLevels, icon) => (

{icon} {title.toUpperCase()} PLAN

FRAME: {title === 'Weekly' ? 'WEEKLY' : 'MONTHLY'}
{groupLevels.map((lvl) => { const distance = calculateDistance(price, lvl.price); const status = getStatusStyles(distance, lvl.type, lvl.isConfluence); const isMainLevel = lvl.id.includes('pwh') || lvl.id.includes('pwl') || lvl.id.includes('pmh') || lvl.id.includes('pml') || lvl.id.includes('mon_'); return ( ); })}
Level Price Dist. Status
{lvl.label} {lvl.type.includes('trap') && } {lvl.type.includes('trend') && } {lvl.isConfluence && ( )}
{isMainLevel && ( {lvl.id.includes('mon') ? 'WEEKLY PIVOT' : 'LIQUIDITY POOL'} )}
{formatCurrency(lvl.price)}
%{distance.toFixed(2)}
{status.label} {lastTouch[lvl.id] &&
TOUCHED
}
); const renderProtocol = () => (

EXECUTION PROTOCOL: ORDERFLOW CONFIRMATION

Seviye testi sırasında kör emir atma. CVD Uyumsuzluklarını (Absorption) ve Open Interest (OI) değişimini mutlaka kontrol et.
ÖNEMLİ: 🔥 İşaretli seviyeler (Confluence) çakışma bölgesidir. Yüksek volatilite bekle.

); const renderVitals = () => { // Vitals Color Logic const rangeColor = vitals.rangePercent > 100 ? 'text-red-500 animate-pulse' : vitals.rangePercent > 80 ? 'text-yellow-500' : 'text-emerald-500'; const rvolColor = vitals.rvol > 1.5 ? 'text-amber-500' : 'text-neutral-500'; return (
toggleTooltip('vitals', true)} onMouseLeave={() => toggleTooltip('vitals', false)} onClick={() => toggleTooltip('vitals', !tooltips.vitals)} > {tooltips.vitals && (
Menzil & Hacim (TR) Günlük menzil (ATR) %100'ü aştıysa hareketin "şiştiği" (overextended) anlamına gelebilir. Bu durumda trend tersine dönüş sinyalleri veya yatay konsolidasyon beklenebilir.
)}
MARKET VITALS
DAILY RANGE
%{vitals.rangePercent.toFixed(0)} / ATR
RVOL
{vitals.rvol.toFixed(2)}x
{vitals.rangePercent > 100 ? '⚠️ Range Extended. Confluence bölgesindeysen Uyumsuzluk (Divergence) ara.' : 'Range Available. Hareket alanı mevcut.'}
); }; const renderBottomPanel = () => (
{/* Glossary */}
GLOSSARY (TR)
{[ { term: 'EXT. I (TRAP)', desc: 'Tuzak Bölgesi. Stop avı / SFP beklenir. (Dönüş)' }, { term: 'EXT. II (TREND)', desc: 'Trend Genişlemesi. Fiyatın buraya akması beklenir.' }, { term: 'Monday Range', desc: 'Haftalık Yön (Bias). Pivot.' }, { term: 'Confluence (🔥)', desc: 'Kesişim. Yüksek Olasılık.' }, ].map((item) => (
{item.term} {item.desc}
))}
{/* Session Monitor */}
ACTIVE SESSION
{session.name}
{session.desc}
{/* Trend Monitor */}
toggleTooltip('trend', true)} onMouseLeave={() => toggleTooltip('trend', false)} onClick={() => toggleTooltip('trend', !tooltips.trend)} > {tooltips.trend && (
Dinamik Trend (EMA 200) Fiyatın ortalamaya göre konumu, piyasanın "en az direnç yolunu" (path of least resistance) gösterir. Trend yönünde işlem aramak momentum avantajı sağlar.
)}
4H TREND BIAS (EMA 200)
{trend.bias}
EMA 200: {trend.ema200 ? formatCurrency(trend.ema200) : 'HESAPLANIYOR...'}
Dinamik Trend Filtresi
{/* Vitals Monitor (NEW) */} {renderVitals()}
); if (loading && !price) return (
ALGORİTMALAR HESAPLANIYOR...
); if (error) return (

{error}

); const weeklyLevels = levels.filter(l => l.group === 'Weekly'); const monthlyLevels = levels.filter(l => l.group === 'Monthly'); return (
{/* HEADER */}

BARBARIANS.PLAN

LIVE FEED • {session.name}
{SYMBOL}
yearlyOpen ? 'text-neutral-100' : 'text-neutral-300'}`}> {formatCurrency(price)}
{/* MAIN CONTENT */}
{renderTableSection('Weekly', weeklyLevels, )} {renderTableSection('Monthly', monthlyLevels, )}
{renderProtocol()} {renderBottomPanel()}
{/* YEARLY OPEN STICKY FOOTER */} {yearlyOpen && (
{/* Left: Yearly Context */}
toggleTooltip('yearly', true)} onMouseLeave={() => toggleTooltip('yearly', false)} onClick={() => toggleTooltip('yearly', !tooltips.yearly)} > YEARLY CONTEXT (TR) {tooltips.yearly && (

Yıllık Açılış Önemi

Kurumsal pivot seviyesi. Üstü alıcı (Boğa), altı satıcı (Ayı) kontrolü demektir.

)}
{formatCurrency(yearlyOpen)} {yearlyStatus.text} {yearlyStatus.isBullish ? : }
{/* Right: Legend */}
CONFLUENCE R: RESISTANCE S: SUPPORT
)}
); }