diff --git a/src/web/bot.html b/src/web/bot.html
index c468540..fd800e1 100644
--- a/src/web/bot.html
+++ b/src/web/bot.html
@@ -532,10 +532,84 @@ async function loadKlines() {
document.getElementById('ohlc-l').textContent = fmt(last.low);
document.getElementById('ohlc-c').textContent = fmt(last.close);
}
+ drawSupportResistance(candles);
updateChartOverlays();
} catch(e) {}
}
+// ── Support / Resistance ──────────────────────────
+let srLines = [];
+
+function drawSupportResistance(candles) {
+ // önceki çizgileri temizle
+ srLines.forEach(l => candleSeries.removePriceLine(l));
+ srLines = [];
+
+ if (candles.length < 10) return;
+
+ const left = 5, right = 5; // her yönde kaç mum komşu bakılacak
+ const pivotHighs = [], pivotLows = [];
+
+ for (let i = left; i < candles.length - right; i++) {
+ const c = candles[i];
+ let isHigh = true, isLow = true;
+ for (let j = i - left; j <= i + right; j++) {
+ if (j === i) continue;
+ if (candles[j].high >= c.high) isHigh = false;
+ if (candles[j].low <= c.low) isLow = false;
+ }
+ if (isHigh) pivotHighs.push(c.high);
+ if (isLow) pivotLows.push(c.low);
+ }
+
+ // yakın seviyeleri cluster'la: fiyat aralığının %0.3'ü içindeki pivotları birleştir
+ const currentPrice = candles[candles.length - 1].close;
+ const threshold = currentPrice * 0.003;
+
+ function cluster(pivots) {
+ const sorted = [...pivots].sort((a, b) => a - b);
+ const groups = [];
+ for (const p of sorted) {
+ const last = groups[groups.length - 1];
+ if (last && p - last[last.length - 1] <= threshold) {
+ last.push(p);
+ } else {
+ groups.push([p]);
+ }
+ }
+ // her grubun ortalamasını al, en az 2 pivot olan seviyeleri döndür
+ return groups
+ .filter(g => g.length >= 2)
+ .map(g => g.reduce((s, v) => s + v, 0) / g.length);
+ }
+
+ const resistances = cluster(pivotHighs);
+ const supports = cluster(pivotLows);
+
+ // mevcut fiyata yakın en fazla 4 direnç + 4 destek çiz
+ const near = levels => levels
+ .map(p => ({ p, dist: Math.abs(p - currentPrice) }))
+ .sort((a, b) => a.dist - b.dist)
+ .slice(0, 4)
+ .map(x => x.p);
+
+ near(resistances).forEach(price => {
+ srLines.push(candleSeries.createPriceLine({
+ price, color: 'rgba(231,76,60,0.55)', lineWidth: 1,
+ lineStyle: LightweightCharts.LineStyle.Dashed,
+ axisLabelVisible: false, title: 'R',
+ }));
+ });
+
+ near(supports).forEach(price => {
+ srLines.push(candleSeries.createPriceLine({
+ price, color: 'rgba(46,204,113,0.55)', lineWidth: 1,
+ lineStyle: LightweightCharts.LineStyle.Dashed,
+ axisLabelVisible: false, title: 'S',
+ }));
+ });
+}
+
let klineWs = null;
function startKlineWs() {
if (klineWs) klineWs.close();