geçenlerde birşeyler yapmaya çalıştığım ile ilgili bir paylaşım yapmıştım. başarı oranı pek tatmin edici olmadı açıkçası. farklı birşeyler denemeye karar verdim. henüz geliştirme aşamasındayım kendimce ama bu seviyesi de kullanılabilir (geliştirilecek şartları var hala) seviyede bir sinyal botu hazırladım (daha doğrusu hazırlattım yapay zekaya). kodlarını aşağıda paylaşıyorum. analiz kısmı için claude api ye ihtiyacınız var. sağladıktan sonra ayarlar kısmından api keyi girip kaydet demeniz gerekiyor. sonrasında sol sütundaki koinlerden istediğinizi seçip analizini yaptırabilirsiniz.
dediğim gibi geliştirmenizde fayda var. bu haliyle temel seviyede analiz yapıyor. ben denemek için işlemler alıyorum ufaktan ama daha yolu var bilginiz olsun.
şunu da belirteyim de bodoslama verdiği her sinyale işlem açmayın.
BOTUN VERDİĞİ SİNYALLER BİLGİ AMAÇLIDIR, KOİNİN DURUMUNU ARAŞTIRMADAN İŞLEME GİRMENİZ CİDDİ KAYIPLARA SEBEP OLABİLİR. <!DOCTYPE html>
<html lang="tr">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Binance Futures AI Analiz</title>
<style>
:root{--bg:#0a0e1a;--bg2:#0f1525;--bg3:#141c2e;--bg4:#1a2340;--border:#1e2d4a;--accent:#00d4ff;--accent2:#7c3aed;--green:#00e676;--green2:#69f0ae;--red:#ff1744;--red2:#ff6b6b;--yellow:#ffd600;--orange:#ff9100;--text:#e2e8f0;--text2:#8899bb;--text3:#4a6080;--mono:'Courier New',monospace;--r:8px;--r2:12px}
*{box-sizing:border-box;margin:0;padding:0}
body{background:var(--bg);color:var(--text);font-family:'Segoe UI',system-ui,sans-serif;font-size:13px;min-height:100vh}
.header{background:linear-gradient(135deg,#0f1525,#141c2e);border-bottom:1px solid var(--border);padding:10px 14px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:100;gap:10px;flex-wrap:wrap}
.hlogo{display:flex;align-items:center;gap:8px}
.hicon{width:28px;height:28px;background:linear-gradient(135deg,var(--accent),var(--accent2));border-radius:6px;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:900;color:#fff}
.htitle{font-size:13px;font-weight:700;line-height:1.2}
.hsub{font-size:10px;color:var(--text2)}
.btn{padding:6px 14px;border:none;border-radius:var(--r);font-size:12px;font-weight:600;cursor:pointer;transition:filter .2s;white-space:nowrap}
.btn-b{background:linear-gradient(135deg,#00b4d8,#0077b6);color:#fff}
.btn-ghost{background:var(--bg4);color:var(--text);border:1px solid var(--border)}
.btn:hover{filter:brightness(1.15)}
.btn:disabled{opacity:.6;cursor:not-allowed}
.main{padding:10px;max-width:1500px;margin:0 auto}
.layout-grid{display:flex;flex-direction:column;gap:10px}
@media(min-width:900px){.layout-grid{display:grid;grid-template-columns:300px 1fr;gap:10px;align-items:start}.sidebar-col{position:sticky;top:64px}}
.sbox{background:var(--bg2);border:1px solid var(--border);border-radius:var(--r2);margin-bottom:10px;overflow:hidden}
.shed{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;background:var(--bg3);border-bottom:1px solid var(--border);cursor:pointer;user-select:none;gap:8px}
.shed-left{display:flex;align-items:center;gap:8px;font-size:12px;font-weight:600;color:var(--text2);text-transform:uppercase;letter-spacing:.05em}
.chev{color:var(--text3);font-size:11px;transition:transform .25s;display:inline-block}
.chev.open{transform:rotate(180deg)}
.sbody{overflow:hidden;max-height:0;transition:max-height .3s ease}
.sbody.open{max-height:9999px}
.sbody.open.set-h{max-height:400px}
.sbody.open.coinlist-h{max-height:760px}
.chip{background:var(--bg4);border:1px solid var(--border);border-radius:4px;padding:3px 8px;font-size:10px;color:var(--text3)}
.field{display:flex;flex-direction:column;gap:4px;margin-bottom:10px}
.field label{font-size:11px;color:var(--text2);font-weight:600;text-transform:uppercase;letter-spacing:.04em}
.field input,.field select{background:var(--bg4);border:1px solid var(--border);border-radius:var(--r);color:var(--text);padding:8px 10px;font-size:12px;font-family:inherit;width:100%}
.field input:focus,.field select:focus{outline:none;border-color:var(--accent)}
.sgrid2{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.sact{display:flex;gap:8px;margin-top:6px;flex-wrap:wrap;align-items:center}
.cl-refresh-row{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 10px 0}
.cl-refresh-btn{display:flex;align-items:center;gap:5px;background:linear-gradient(135deg,#0077b6,#00b4d8);border:none;color:#fff;font-size:11px;font-weight:700;padding:6px 12px;border-radius:6px;cursor:pointer;transition:filter .2s}
.cl-refresh-btn:hover{filter:brightness(1.15)}
.cl-refresh-btn:disabled{opacity:.6;cursor:not-allowed}
.cl-refresh-btn.spinning span:first-child{display:inline-block;animation:spin .7s linear infinite}
.cl-updated{font-size:9px;color:var(--text3);font-family:var(--mono)}
.cl-sortbar{display:flex;gap:4px;padding:8px 10px 0}
.cl-sort-btn{flex:1;background:var(--bg4);border:1px solid var(--border);border-radius:6px;color:var(--text2);font-size:10px;font-weight:600;padding:5px 4px;cursor:pointer;text-transform:uppercase;letter-spacing:.03em;display:flex;align-items:center;justify-content:center;gap:3px}
.cl-sort-btn:hover{border-color:var(--accent)}
.cl-sort-btn.active{color:var(--accent);border-color:rgba(0,212,255,.4);background:rgba(0,212,255,.06)}
.sb-arrow{font-size:9px;opacity:.8}
.cl-head{display:grid;grid-template-columns:1.1fr 1fr 0.8fr 0.9fr;gap:4px;padding:8px 14px 4px;font-size:9px;color:var(--text3);text-transform:uppercase;letter-spacing:.04em}
.coinlist-wrap{max-height:600px;overflow-y:auto;padding:0 8px 8px}
.coinlist-wrap::-webkit-scrollbar{width:5px}
.coinlist-wrap::-webkit-scrollbar-thumb{background:var(--bg4);border-radius:3px}
.cl-row{display:grid;grid-template-columns:1.1fr 1fr 0.8fr 0.9fr;gap:4px;align-items:center;padding:8px 6px;border-radius:6px;cursor:pointer;font-size:11px;font-family:var(--mono);border:1px solid transparent}
.cl-row:hover{background:var(--bg4)}
.cl-row.active{background:rgba(0,212,255,.08);border-color:rgba(0,212,255,.35)}
.cl-sym{font-family:'Segoe UI',system-ui,sans-serif;font-weight:700;color:var(--text);font-size:12px}
.cl-price{color:var(--text2)}
.cl-chg{font-weight:700}
.cl-chg.up{color:var(--green)}
.cl-chg.down{color:var(--red)}
.cl-vol{color:var(--text3)}
.search-empty{padding:14px 12px;font-size:11px;color:var(--text3);text-align:center}
.ahead{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:10px;padding:14px 16px;background:linear-gradient(135deg,#0f1525,#141c2e);border-bottom:1px solid var(--border)}
.ahead-sym{font-size:20px;font-weight:800;letter-spacing:.02em}
.ahead-price{font-family:var(--mono);font-size:18px;font-weight:700;color:var(--accent)}
.ahead-chg{font-family:var(--mono);font-size:14px;font-weight:700;padding:3px 10px;border-radius:6px}
.ahead-chg.up{color:var(--green);background:rgba(0,230,118,.1)}
.ahead-chg.down{color:var(--red);background:rgba(255,23,68,.1)}
.apanel-body{padding:16px}
.dgrid{display:grid;grid-template-columns:repeat(auto-fit,minmax(130px,1fr));gap:10px;margin-bottom:14px}
.ditem{background:var(--bg4);border-radius:var(--r);padding:9px 11px}
.ditem-l{font-size:10px;color:var(--text3);text-transform:uppercase;letter-spacing:.04em;margin-bottom:3px}
.ditem-v{font-size:14px;font-weight:700;font-family:var(--mono)}
.ai-box{margin-bottom:14px;background:var(--bg4);border:1px solid var(--border);border-radius:var(--r);padding:14px}
.ai-box-hdr{display:flex;align-items:center;gap:10px;margin-bottom:10px;flex-wrap:wrap}
.ai-box-title{font-size:11px;font-weight:700;color:var(--accent);text-transform:uppercase;letter-spacing:.06em}
.ai-modal-pill{font-size:12px;font-weight:700;padding:3px 10px;border-radius:20px}
.ai-modal-pill.long{background:rgba(0,230,118,.15);color:var(--green);border:1px solid rgba(0,230,118,.3)}
.ai-modal-pill.short{background:rgba(255,23,68,.15);color:var(--red);border:1px solid rgba(255,23,68,.3)}
.ai-modal-pill.dikkat{background:rgba(255,145,0,.15);color:var(--orange);border:1px solid rgba(255,145,0,.3)}
.ai-modal-pill.notr{background:rgba(255,214,0,.1);color:var(--yellow);border:1px solid rgba(255,214,0,.25)}
.ai-modal-pill.loading{background:rgba(124,58,237,.12);color:#a78bfa;border:1px solid rgba(124,58,237,.25);animation:ab 1s infinite}
@keyframes ab{0%,100%{opacity:1}50%{opacity:.5}}
.ai-meta-box{background:var(--bg);border:1px solid var(--border);border-radius:6px;padding:10px;margin-bottom:10px;display:flex;flex-direction:column;gap:8px}
.ai-meta-action{font-size:13px;color:var(--text2);line-height:1.5}
.ai-meta-action strong{color:var(--text)}
.ai-levels-modal{display:grid;grid-template-columns:repeat(auto-fit,minmax(110px,1fr));gap:8px;margin-top:2px}
.lvl-box{background:var(--bg4);border:1px solid var(--border);border-radius:6px;padding:6px 9px;text-align:center}
.lvl-box-l{font-size:9px;color:var(--text3);text-transform:uppercase;letter-spacing:.04em;margin-bottom:2px}
.lvl-box-v{font-size:13px;font-weight:700;font-family:var(--mono)}
.lvl-box.entry .lvl-box-v{color:var(--accent)}
.lvl-box.stop .lvl-box-v{color:var(--red2)}
.lvl-box.tp .lvl-box-v{color:var(--green2)}
.ai-conf-row{display:flex;align-items:center;gap:6px;margin-top:2px}
.ai-conf-label{font-size:9px;color:var(--text3);text-transform:uppercase;letter-spacing:.04em;flex-shrink:0}
.ai-conf-track{flex:1;height:4px;background:var(--bg4);border-radius:2px;overflow:hidden}
.ai-conf-fill{height:100%;border-radius:2px;transition:width .4s}
.ai-conf-val{font-size:10px;font-weight:700;font-family:var(--mono);flex-shrink:0;min-width:30px;text-align:right}
.ai-toggle-row{display:flex;align-items:center;justify-content:space-between;cursor:pointer;user-select:none;padding:8px 10px;margin-top:10px;background:var(--bg);border:1px solid var(--border);border-radius:6px;font-size:11px;font-weight:600;color:var(--text2);text-transform:uppercase;letter-spacing:.04em}
.ai-toggle-row:hover{border-color:var(--accent)}
.ai-toggle-chev{font-size:10px;color:var(--text3);transition:transform .25s}
.ai-toggle-chev.open{transform:rotate(180deg)}
.ai-long-wrap{overflow:hidden;max-height:0;transition:max-height .3s ease}
.ai-long-wrap.open{max-height:2000px;margin-top:10px}
.ai-long-text{font-size:14px;color:var(--text);line-height:1.8;white-space:pre-wrap}
.ai-disclaimer{margin-top:10px;font-size:10px;line-height:1.5;color:var(--text3);background:rgba(255,214,0,.04);border:1px solid rgba(255,214,0,.12);border-radius:6px;padding:7px 9px}
.conflicts-box{background:rgba(255,214,0,.06);border:1px solid rgba(255,214,0,.2);border-radius:8px;padding:10px;margin-bottom:14px}
.conflicts-title{font-size:10px;font-weight:700;color:var(--yellow);text-transform:uppercase;letter-spacing:.05em;margin-bottom:6px}
.conflict-item{font-size:11px;color:var(--text2);padding:2px 0}
.ilist{display:flex;flex-direction:column;gap:5px}
.irow{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;background:var(--bg4);border-radius:6px;font-size:11px}
.iname{color:var(--text2)}
.ival{font-family:var(--mono);font-weight:600}
.ival.bull{color:var(--green)}.ival.bear{color:var(--red)}.ival.neutral{color:var(--yellow)}
.isec-title{font-size:10px;font-weight:700;color:var(--text3);text-transform:uppercase;padding:10px 0 4px;letter-spacing:.05em}
.ind-grid{display:grid;grid-template-columns:1fr 1fr;gap:10px}
@media(max-width:650px){.ind-grid{grid-template-columns:1fr}}
.ind-box{background:var(--bg3);border:1px solid var(--border);border-radius:10px;overflow:hidden;align-self:start}
.ind-box-hdr{display:flex;align-items:center;justify-content:space-between;padding:9px 12px;cursor:pointer;user-select:none;font-size:10px;font-weight:700;color:var(--text2);text-transform:uppercase;letter-spacing:.05em;background:var(--bg4)}
.ind-box-hdr:hover{color:var(--accent)}
.ind-chev{font-size:10px;color:var(--text3);transition:transform .25s}
.ind-chev.open{transform:rotate(180deg)}
.ind-box-body{overflow:hidden;max-height:0;transition:max-height .3s ease;display:flex;flex-direction:column;gap:5px;padding:0 8px}
.ind-box-body.open{max-height:1200px;padding:8px}
.modal-loading{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:50px 20px;color:var(--text2);font-size:12px}
.spin{display:inline-block;width:22px;height:22px;border:3px solid var(--bg4);border-top-color:var(--accent);border-radius:50%;animation:spin .6s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.modal-step{font-size:11px;color:var(--text3)}
.modal-step.active{color:var(--accent);font-weight:600}
.toast{position:fixed;bottom:20px;right:16px;background:var(--bg3);border:1px solid var(--border);border-radius:var(--r);padding:10px 14px;font-size:12px;color:var(--text);z-index:300;box-shadow:0 4px 20px rgba(0,0,0,.4);transform:translateY(60px);opacity:0;transition:all .3s;max-width:280px}
.toast.show{transform:translateY(0);opacity:1}
.toast.success{border-color:var(--green)}.toast.error{border-color:var(--red)}.toast.warn{border-color:var(--yellow)}
::-webkit-scrollbar{width:5px;height:5px}
::-webkit-scrollbar-track{background:var(--bg)}
::-webkit-scrollbar-thumb{background:var(--bg4);border-radius:3px}
</style>
</head>
<body>
<div class="header">
<div class="hlogo"><div class="hicon">₿</div><div><div class="htitle">Futures AI Analiz</div><div class="hsub">Binance USDT-M • Claude AI</div></div></div>
</div>
<div class="main">
<div class="layout-grid">
<div class="sidebar-col">
<div class="sbox">
<div class="shed" onclick="toggleSec('coinlist')"><div class="shed-left"><span>📋</span><span>Tüm Koinler</span><span class="chip" id="cl-count-chip">0</span></div><span class="chev open" id="chev-coinlist">▼</span></div>
<div class="sbody open coinlist-h" id="body-coinlist">
<div class="cl-refresh-row">
<button class="cl-refresh-btn" id="cl-refresh-btn" onclick="manualRefreshCoinList(event)"><span>↻</span> <span id="cl-refresh-label">Güncelle</span></button>
<span class="cl-updated" id="cl-updated">—</span>
</div>
<div class="cl-sortbar">
<button class="cl-sort-btn" id="sb-sort-name" onclick="setSidebarSort('name')">Koin <span class="sb-arrow">↕</span></button>
<button class="cl-sort-btn active" id="sb-sort-change" onclick="setSidebarSort('change')">24h% <span class="sb-arrow">↓</span></button>
<button class="cl-sort-btn" id="sb-sort-volume" onclick="setSidebarSort('volume')">Hacim <span class="sb-arrow">↕</span></button>
</div>
<div class="cl-head"><span>Koin</span><span>Fiyat</span><span>24h%</span><span>Hacim</span></div>
<div class="coinlist-wrap" id="coinlist-wrap"><div class="search-empty">Sembol listesi yükleniyor...</div></div>
</div>
</div>
</div>
<div class="content-col">
<div class="sbox">
<div class="shed" onclick="toggleSec('settings')"><div class="shed-left"><span>⚙️</span><span>Ayarlar</span></div><span class="chev" id="chev-settings">▼</span></div>
<div class="sbody set-h" id="body-settings">
<div style="padding:12px">
<div class="sgrid2">
<div class="field" style="grid-column:1/-1"><label>Claude API Key</label><input type="password" id="inp-apikey" placeholder="sk-ant-api03-..." autocomplete="off"></div>
<div class="field"><label>Claude Model</label><select id="inp-model"><option value="claude-sonnet-4-6" selected>Sonnet 4.6</option><option value="claude-haiku-4-5-20251001">Haiku 4.5 (Hızlı)</option></select></div>
<div class="field"><label>Kline Periyodu</label><select id="inp-tf"><option value="15m">15 Dakika</option><option value="1h" selected>1 Saat</option><option value="4h">4 Saat</option><option value="1d">1 Gün</option></select></div>
</div>
<div class="sact">
<button class="btn btn-b" onclick="saveSettings()">💾 Kaydet</button>
<button class="btn btn-ghost" onclick="loadSettings()">↺ Sıfırla</button>
<span class="chip">🔒 Yerel saklama</span>
</div>
</div>
</div>
</div>
<div class="sbox" id="apanel">
<div class="modal-loading"><div class="spin"></div><div class="modal-step active">Yükleniyor...</div></div>
</div>
</div>
</div>
</div>
<div class="toast" id="toast"></div>
<script>
const S={tickerMap:{},allSymbols:[],coinData:{},settings:{},sidebarSort:{key:'change',dir:'desc'},ws:null,apiReqs:0,activeSymbol:null,panelState:loadPanelState()};
function loadPanelState(){
var raw=localStorage.getItem('bfaa_panel_state');
var def={aiSummary:true,trend:true,momentum:true,hacim:true,volat:true};
if(!raw)return def;
try{var parsed=JSON.parse(raw);return Object.assign({},def,parsed);}catch(e){return def;}
}
function savePanelState(){localStorage.setItem('bfaa_panel_state',JSON.stringify(S.panelState));}
var FA='https://fapi.binance.com';
function toggleSec(id){var b=document.getElementById('body-'+id),c=document.getElementById('chev-'+id);if(!b||!c)return;if(b.classList.contains('open')){b.classList.remove('open');c.classList.remove('open');}else{b.classList.add('open');c.classList.add('open');}}
function toast(msg,type){var t=document.getElementById('toast');t.textContent=msg;t.className='toast '+(type||'');void t.offsetWidth;t.classList.add('show');setTimeout(function(){t.classList.remove('show');},3000);}
function fmtPrice(p){if(p===null||p===undefined||isNaN(p))return'\u2014';if(p>=1000)return p.toFixed(2);if(p>=1)return p.toFixed(4);if(p>=0.01)return p.toFixed(6);return p.toFixed(8);}
function fmtVol(v){if(v===null||v===undefined||isNaN(v))return'\u2014';if(v>=1e9)return(v/1e9).toFixed(2)+'B';if(v>=1e6)return(v/1e6).toFixed(2)+'M';if(v>=1e3)return(v/1e3).toFixed(1)+'K';return v.toFixed(0);}
function saveSettings(){
var s={apikey:document.getElementById('inp-apikey').value.trim(),model:document.getElementById('inp-model').value,tf:document.getElementById('inp-tf').value};
localStorage.setItem('bfaa_settings',JSON.stringify(s));
S.settings=s;
toast('Ayarlar kaydedildi','success');
}
function loadSettings(){
var raw=localStorage.getItem('bfaa_settings'),s=raw?JSON.parse(raw):{};
document.getElementById('inp-apikey').value=s.apikey||'';
document.getElementById('inp-model').value=s.model||'claude-sonnet-4-6';
document.getElementById('inp-tf').value=s.tf||'1h';
S.settings=s;
}
/* ===== Live ticker data ===== */
function startWS(){
if(S.ws)S.ws.close();
S.ws=new WebSocket('wss://fstream.binance.com/ws/!miniTicker@arr');
S.ws.onmessage=function(e){
try{
JSON.parse(e.data).forEach(function(t){
if(!t.s.endsWith('USDT'))return;
S.tickerMap[t.s]={price:parseFloat(t.c),change:parseFloat(t.P),volume:parseFloat(t.q)};
});
scheduleSidebarRender();
updateActiveHeaderLive();
}catch(x){}
};
S.ws.onclose=function(){setTimeout(startWS,5000);};
}
function updateActiveHeaderLive(){
if(!S.activeSymbol)return;
var t=S.tickerMap[S.activeSymbol];if(!t)return;
var pe=document.getElementById('ahead-price'),ce=document.getElementById('ahead-chg');
if(pe)pe.textContent=fmtPrice(t.price);
if(ce){ce.textContent=(t.change>=0?'+':'')+t.change.toFixed(2)+'%';ce.className='ahead-chg '+(t.change>=0?'up':'down');}
}
function fetchAllTickerSnapshot(){
return fetch(FA+'/fapi/v1/ticker/24hr').then(function(r){S.apiReqs++;return r.json();}).then(function(data){
(data||[]).forEach(function(t){
if(!t.symbol||!t.symbol.endsWith('USDT'))return;
S.tickerMap[t.symbol]={price:parseFloat(t.lastPrice),change:parseFloat(t.priceChangePercent),volume:parseFloat(t.quoteVolume)};
});
renderSidebarList();
updateActiveHeaderLive();
var upd=document.getElementById('cl-updated');if(upd)upd.textContent='G\xFCncellendi: '+new Date().toLocaleTimeString('tr-TR');
}).catch(function(e){console.error(e);});
}
function manualRefreshCoinList(e){
if(e)e.stopPropagation();
var btn=document.getElementById('cl-refresh-btn'),lbl=document.getElementById('cl-refresh-label');
if(btn.disabled)return;
btn.disabled=true;btn.classList.add('spinning');if(lbl)lbl.textContent='G\xFCncelleniyor...';
fetchAllTickerSnapshot().then(function(){
if(lbl)lbl.textContent='G\xFCncellendi \u2713';
toast('Koin listesi g\xFCncellendi','success');
}).catch(function(){
if(lbl)lbl.textContent='Hata';
}).finally(function(){
setTimeout(function(){btn.disabled=false;btn.classList.remove('spinning');if(lbl)lbl.textContent='G\xFCncelle';},900);
});
}
function fetchSymbolList(){
if(S.allSymbols&&S.allSymbols.length)return Promise.resolve(S.allSymbols);
return fetch(FA+'/fapi/v1/exchangeInfo').then(function(r){S.apiReqs++;return r.json();}).then(function(d){
S.allSymbols=(d.symbols||[]).filter(function(s){return s.contractType==='PERPETUAL'&&s.status==='TRADING'&&s.symbol.endsWith('USDT');}).map(function(s){return s.symbol;}).sort();
document.getElementById('cl-count-chip').textContent=S.allSymbols.length;
renderSidebarList();
return S.allSymbols;
}).catch(function(e){console.error(e);return [];});
}
var sidebarRenderTimer=null;
function scheduleSidebarRender(){
if(sidebarRenderTimer)return;
sidebarRenderTimer=setTimeout(function(){sidebarRenderTimer=null;renderSidebarList();},1500);
}
function setSidebarSort(key){
if(S.sidebarSort.key===key){S.sidebarSort.dir=S.sidebarSort.dir==='asc'?'desc':'asc';}
else{S.sidebarSort.key=key;S.sidebarSort.dir=key==='name'?'asc':'desc';}
updateSidebarSortUI();
renderSidebarList();
}
function updateSidebarSortUI(){
['name','change','volume'].forEach(function(k){
var btn=document.getElementById('sb-sort-'+k);if(!btn)return;
var isActive=S.sidebarSort.key===k;
btn.classList.toggle('active',isActive);
var arrow=btn.querySelector('.sb-arrow');
if(arrow)arrow.textContent=isActive?(S.sidebarSort.dir==='asc'?'\u2191':'\u2193'):'\u2195';
});
}
function renderSidebarList(){
var wrap=document.getElementById('coinlist-wrap');if(!wrap)return;
if(!S.allSymbols||!S.allSymbols.length)return;
var list=S.allSymbols.map(function(s){
var t=S.tickerMap[s];
return{symbol:s,price:t?t.price:null,change:t?t.change:null,volume:t?t.volume:null};
});
var k=S.sidebarSort.key,dir=S.sidebarSort.dir==='asc'?1:-1;
list.sort(function(a,b){
if(k==='name')return a.symbol.localeCompare(b.symbol)*dir;
var av=a[k]===null||a[k]===undefined?-Infinity:a[k];
var bv=b[k]===null||b[k]===undefined?-Infinity:b[k];
return (av-bv)*dir;
});
wrap.innerHTML=list.map(function(c){
var chgCls=c.change===null?'':(c.change>=0?'up':'down');
var activeCls=c.symbol===S.activeSymbol?' active':'';
return'<div class="cl-row'+activeCls+'" onclick="selectCoin(\''+c.symbol+'\')">'
+'<span class="cl-sym">'+c.symbol.replace('USDT','')+'</span>'
+'<span class="cl-price">'+(c.price!==null?fmtPrice(c.price):'\u2014')+'</span>'
+'<span class="cl-chg '+chgCls+'">'+(c.change!==null?(c.change>=0?'+':'')+c.change.toFixed(2)+'%':'\u2014')+'</span>'
+'<span class="cl-vol">'+(c.volume!==null?fmtVol(c.volume):'\u2014')+'</span>'
+'</div>';
}).join('');
}
/* ===== Indicator math (same proven logic) ===== */
function emaSeries(data,p){var k=2/(p+1),r=[data[0]];for(var i=1;i<data.length;i++)r.push(data[i]*k+r[i-1]*(1-k));return r;}
function rsi(closes,p){p=p||14;if(closes.length<p+1)return null;var g=0,l=0;for(var i=1;i<=p;i++){var d=closes[i]-closes[i-1];if(d>0)g+=d;else l-=d;}var ag=g/p,al=l/p;for(var i=p+1;i<closes.length;i++){var d=closes[i]-closes[i-1];ag=(ag*(p-1)+(d>0?d:0))/p;al=(al*(p-1)+(d<0?-d:0))/p;}if(al===0)return 100;return 100-100/(1+ag/al);}
function macd(closes){if(closes.length<26)return null;var e12=emaSeries(closes,12),e26=emaSeries(closes,26),ml=e12.map(function(v,i){return v-e26[i];}),sl=emaSeries(ml.slice(25),9),m=ml[ml.length-1],s=sl[sl.length-1];return{macd:m,signal:s,histogram:m-s};}
function macdPrev(closes){if(closes.length<27)return null;return macd(closes.slice(0,-1));}
function bollinger(closes,p,mult){p=p||20;mult=mult||2;if(closes.length<p)return null;var sl=closes.slice(-p),mean=sl.reduce(function(a,b){return a+b;},0)/p,std=Math.sqrt(sl.reduce(function(a,b){return a+(b-mean)*(b-mean);},0)/p);return{upper:mean+mult*std,middle:mean,lower:mean-mult*std,std:std,bandwidth:2*mult*std/mean};}
function calcAtr(highs,lows,closes,p){p=p||14;if(closes.length<p+1)return null;var trs=[];for(var i=1;i<closes.length;i++)trs.push(Math.max(highs[i]-lows[i],Math.abs(highs[i]-closes[i-1]),Math.abs(lows[i]-closes[i-1])));return trs.slice(-p).reduce(function(a,b){return a+b;},0)/p;}
function stochRsi(closes,rp,sp){rp=rp||14;sp=sp||14;if(closes.length<rp+sp)return null;var rv=[];for(var i=rp;i<closes.length;i++)rv.push(rsi(closes.slice(0,i+1),rp));var sl=rv.slice(-sp),mn=Math.min.apply(null,sl),mx=Math.max.apply(null,sl);if(mx===mn)return 50;return((rv[rv.length-1]-mn)/(mx-mn))*100;}
function cci(highs,lows,closes,p){p=p||20;if(closes.length<p)return null;var tp=closes.slice(-p).map(function(c,i){var idx=closes.length-p+i;return(highs[idx]+lows[idx]+c)/3;});var mean=tp.reduce(function(a,b){return a+b;},0)/p,md=tp.reduce(function(a,b){return a+Math.abs(b-mean);},0)/p;if(md===0)return 0;return(tp[tp.length-1]-mean)/(0.015*md);}
function williamsR(highs,lows,closes,p){p=p||14;if(closes.length<p)return null;var hh=Math.max.apply(null,highs.slice(-p)),ll=Math.min.apply(null,lows.slice(-p));if(hh===ll)return -50;return((hh-closes[closes.length-1])/(hh-ll))*-100;}
function vwap(highs,lows,closes,volumes){var cv=0,ctpv=0;for(var i=0;i<closes.length;i++){var tp=(highs[i]+lows[i]+closes[i])/3;ctpv+=tp*volumes[i];cv+=volumes[i];}return cv>0?ctpv/cv:closes[closes.length-1];}
function obv(closes,volumes){var o=0;var s=[0];for(var i=1;i<closes.length;i++){if(closes[i]>closes[i-1])o+=volumes[i];else if(closes[i]<closes[i-1])o-=volumes[i];s.push(o);}return{cur:o,series:s};}
function detectDiv(closes,highs,lows){var n=20;if(closes.length<n+14)return{bull:false,bear:false};var rv=[];for(var i=closes.length-n;i<closes.length;i++)rv.push(rsi(closes.slice(0,i+1),14)||50);var ls=lows.slice(-n),hs=highs.slice(-n),sl=[],sh=[];for(var i=2;i<n-1;i++){if(ls[i]<ls[i-1]&&ls[i]<ls[i+1])sl.push({price:ls[i],r:rv[i]});if(hs[i]>hs[i-1]&&hs[i]>hs[i+1])sh.push({price:hs[i],r:rv[i]});}var bull=false,bear=false;if(sl.length>=2){var l=sl[sl.length-1],p=sl[sl.length-2];if(l.price<p.price&&l.r>p.r+3)bull=true;}if(sh.length>=2){var l=sh[sh.length-1],p=sh[sh.length-2];if(l.price>p.price&&l.r<p.r-3)bear=true;}return{bull:bull,bear:bear};}
function candlePatterns(opens,highs,lows,closes){var pats=[],n=closes.length;if(n<3)return pats;var L={o:opens[n-1],h:highs[n-1],l:lows[n-1],c:closes[n-1]},P={o:opens[n-2],h:highs[n-2],l:lows[n-2],c:closes[n-2]},P2={o:opens[n-3],h:highs[n-3],l:lows[n-3],c:closes[n-3]};function body(c){return Math.abs(c.c-c.o);}function rng(c){return c.h-c.l;}function uw(c){return c.h-Math.max(c.o,c.c);}function lw(c){return Math.min(c.o,c.c)-c.l;}function bull(c){return c.c>c.o;}function bear(c){return c.c<c.o;}if(rng(L)>0&&body(L)/rng(L)<0.1)pats.push('Doji');if(lw(L)>body(L)*2&&uw(L)<body(L)*0.5)pats.push('Hammer');if(uw(L)>body(L)*2&&lw(L)<body(L)*0.5)pats.push('Shooting Star');if(bear(P)&&bull(L)&&L.o<P.c&&L.c>P.o)pats.push('Bull Engulfing');if(bull(P)&&bear(L)&&L.o>P.c&&L.c<P.o)pats.push('Bear Engulfing');if(bear(P2)&&body(P)<body(P2)*0.3&&bull(L)&&L.c>(P2.o+P2.c)/2)pats.push('Morning Star');if(bull(P2)&&body(P)<body(P2)*0.3&&bear(L)&&L.c<(P2.o+P2.c)/2)pats.push('Evening Star');var mw=Math.max(uw(L),lw(L));if(mw>body(L)*3)pats.push('Pin Bar');return pats;}
function pivot(h,l,c){var pp=(h+l+c)/3;return{pp:pp,r1:2*pp-l,r2:pp+(h-l),s1:2*pp-h,s2:pp-(h-l)};}
function computeScore(ind){
var score=50,signals=[],conflicts=[];
var ts=0;
if(ind.ema9&&ind.ema21&&ind.ema50){var bs=ind.ema9>ind.ema21&&ind.ema21>ind.ema50,brs=ind.ema9<ind.ema21&&ind.ema21<ind.ema50;if(bs){ts+=10;signals.push({l:'EMA Bull Stack',t:'trend',b:true});}else if(brs){ts-=10;signals.push({l:'EMA Bear Stack',t:'trend',b:false});}if(ind.ema9Slope>0){ts+=3;signals.push({l:'EMA Slope\u2191',t:'trend',b:true});}else if(ind.ema9Slope<0){ts-=3;signals.push({l:'EMA Slope\u2193',t:'trend',b:false});}if(ind.price>ind.ema50)ts+=4;else ts-=4;if(ind.price>ind.ema21)ts+=3;else ts-=3;if(ind.price>ind.ema9)ts+=2;else ts-=2;}
if(ind.macd){if(ind.macd.macd>ind.macd.signal){ts+=5;signals.push({l:'MACD Bull',t:'trend',b:true});}else{ts-=5;signals.push({l:'MACD Bear',t:'trend',b:false});}if(ind.macd.histogram>0&&ind.macdHistSlope>0){ts+=4;signals.push({l:'MACD G\xFC\xE7\u2191',t:'trend',b:true});}else if(ind.macd.histogram>0&&ind.macdHistSlope<0){ts+=1;conflicts.push('MACD zay\u0131fl\u0131yor');}else if(ind.macd.histogram<0&&ind.macdHistSlope<0)ts-=4;}
if(ind.conseBull>=3){ts+=3;signals.push({l:ind.conseBull+'x Bull',t:'trend',b:true});}if(ind.conseBear>=3){ts-=3;signals.push({l:ind.conseBear+'x Bear',t:'trend',b:false});}if(ind.hhPat){ts+=3;signals.push({l:'Higher High',t:'trend',b:true});}if(ind.llPat){ts-=3;signals.push({l:'Lower Low',t:'trend',b:false});}
score+=Math.max(-22,Math.min(22,ts));
var ms=0;
if(ind.rsi!==null&&ind.rsi!==undefined){if(ind.rsi>=80){ms-=15;signals.push({l:'RSI '+ind.rsi.toFixed(0)+' A\u015F\u0131r\u0131 OB',t:'mom',b:false});conflicts.push('RSI a\u015F\u0131r\u0131 al\u0131m (80+)');}else if(ind.rsi>=70){ms-=10;signals.push({l:'RSI '+ind.rsi.toFixed(0)+' OB',t:'mom',b:false});conflicts.push('RSI a\u015F\u0131r\u0131 al\u0131m');}else if(ind.rsi>=60){ms+=5;signals.push({l:'RSI '+ind.rsi.toFixed(0),t:'mom',b:true});}else if(ind.rsi>=50)ms+=2;else if(ind.rsi>=40)ms-=2;else if(ind.rsi<=20){ms+=15;signals.push({l:'RSI '+ind.rsi.toFixed(0)+' A\u015F\u0131r\u0131 OS',t:'mom',b:true});}else if(ind.rsi<=30){ms+=10;signals.push({l:'RSI '+ind.rsi.toFixed(0)+' OS',t:'mom',b:true});}}
if(ind.bullDiv){ms+=12;signals.push({l:'RSI Bull Div',t:'mom',b:true});}if(ind.bearDiv){ms-=12;signals.push({l:'RSI Bear Div',t:'mom',b:false});conflicts.push('Bearish divergence');}
if(ind.stochRsi!==null&&ind.stochRsi!==undefined){if(ind.stochRsi<10){ms+=8;signals.push({l:'StochRSI Dip',t:'mom',b:true});}else if(ind.stochRsi<20){ms+=5;signals.push({l:'StochRSI OS',t:'mom',b:true});}else if(ind.stochRsi>90){ms-=8;signals.push({l:'StochRSI Tepe',t:'mom',b:false});conflicts.push('StochRSI doygunluk');}else if(ind.stochRsi>80){ms-=5;signals.push({l:'StochRSI OB',t:'mom',b:false});}else if(ind.stochRsi>50)ms+=2;}
if(ind.cci!==null&&ind.cci!==undefined){if(ind.cci>200){ms-=6;signals.push({l:'CCI A\u015F\u0131r\u0131+',t:'mom',b:false});conflicts.push('CCI a\u015F\u0131r\u0131');}else if(ind.cci>100){ms+=4;signals.push({l:'CCI+',t:'mom',b:true});}else if(ind.cci<-200){ms+=6;signals.push({l:'CCI A\u015F\u0131r\u0131-',t:'mom',b:true});}else if(ind.cci<-100){ms-=4;signals.push({l:'CCI-',t:'mom',b:false});}}
if(ind.wr!==null&&ind.wr!==undefined){if(ind.wr>-10){ms-=5;signals.push({l:'W%R OB',t:'mom',b:false});}else if(ind.wr<-90){ms+=5;signals.push({l:'W%R OS',t:'mom',b:true});}else if(ind.wr>-30)ms+=3;else if(ind.wr<-70)ms-=3;}
if(ind.atrMom!==null&&ind.atrMom!==undefined){if(ind.atrMom>2&&ind.priceChange>0){ms+=4;signals.push({l:'ATR Mom\u2191',t:'mom',b:true});}else if(ind.atrMom>2&&ind.priceChange<0)ms-=4;}
score+=Math.max(-20,Math.min(20,ms));
var vs=0;
if(ind.volRatio!==null&&ind.volRatio!==undefined){if(ind.volRatio>3){vs+=10;signals.push({l:'Vol '+ind.volRatio.toFixed(1)+'x',t:'vol',b:ind.priceChange>=0});}else if(ind.volRatio>2){vs+=7;signals.push({l:'Vol '+ind.volRatio.toFixed(1)+'x',t:'vol',b:ind.priceChange>=0});}else if(ind.volRatio>1.5)vs+=4;else if(ind.volRatio>1.2)vs+=2;else if(ind.volRatio<0.6){vs-=5;signals.push({l:'D\xFC\u015Fk Hacim',t:'vol',b:false});}}
if(ind.volTrend==='bull-confirm'){vs+=5;signals.push({l:'Hacim Teyit',t:'vol',b:true});}else if(ind.volTrend==='bear-confirm'){vs-=5;signals.push({l:'Hacim D\xFC\u015F\xFC\u015F',t:'vol',b:false});}else if(ind.volTrend==='diverge'){vs-=3;conflicts.push('Hacim-fiyat uyu\u015Fmuyor');}
if(ind.vwap&&ind.price){var vd=(ind.price-ind.vwap)/ind.vwap*100;if(vd>5){vs-=3;conflicts.push('VWAP\'dan \xE7ok uzak');}else if(vd>0){vs+=4;signals.push({l:'> VWAP',t:'vol',b:true});}else if(vd<-5){vs+=3;signals.push({l:'VWAP Destek',t:'vol',b:true});}else{vs-=4;signals.push({l:'< VWAP',t:'vol',b:false});}}
if(ind.obvTrend==='up'){vs+=4;signals.push({l:'OBV\u2191',t:'vol',b:true});}else if(ind.obvTrend==='down'){vs-=4;signals.push({l:'OBV\u2193',t:'vol',b:false});}
if(ind.cvdBull===true){vs+=3;signals.push({l:'CVD Al\u0131\u015F',t:'vol',b:true});}else if(ind.cvdBull===false){vs-=3;signals.push({l:'CVD Sat\u0131\u015F',t:'vol',b:false});}
score+=Math.max(-18,Math.min(18,vs));
var fs=0;
if(ind.fundingRate!==null&&ind.fundingRate!==undefined){var fr=ind.fundingRate*100;if(fr>0.1){fs-=10;signals.push({l:'FR +'+fr.toFixed(3)+'%',t:'fund',b:false});conflicts.push('A\u015F\u0131r\u0131 y\xFCksek funding');}else if(fr>0.05){fs-=6;signals.push({l:'FR +'+fr.toFixed(3)+'%',t:'fund',b:false});conflicts.push('Y\xFCksek funding rate');}else if(fr>0.01)fs-=3;else if(fr<-0.1){fs+=10;signals.push({l:'FR '+fr.toFixed(3)+'%',t:'fund',b:true});}else if(fr<-0.05){fs+=6;signals.push({l:'FR '+fr.toFixed(3)+'%',t:'fund',b:true});}else if(fr<-0.01)fs+=3;else fs+=2;}
if(ind.lsRatio!==null&&ind.lsRatio!==undefined){if(ind.lsRatio>2){fs-=8;signals.push({l:'L/S '+ind.lsRatio.toFixed(2)+' A\u015F\u0131r\u0131',t:'oi',b:false});conflicts.push('A\u015F\u0131r\u0131 long y\u0131\u011F\u0131lmas\u0131');}else if(ind.lsRatio>1.5){fs-=5;signals.push({l:'L/S '+ind.lsRatio.toFixed(2),t:'oi',b:false});}else if(ind.lsRatio>1.2)fs-=2;else if(ind.lsRatio<0.5){fs+=8;signals.push({l:'L/S '+ind.lsRatio.toFixed(2),t:'oi',b:true});}else if(ind.lsRatio<0.7){fs+=5;signals.push({l:'L/S '+ind.lsRatio.toFixed(2),t:'oi',b:true});}}
if(ind.oiChange!==null&&ind.oiChange!==undefined){if(ind.oiChange>0.05&&ind.priceChange>0){fs+=6;signals.push({l:'OI+Fiyat\u2191',t:'oi',b:true});}else if(ind.oiChange>0.02&&ind.priceChange>0){fs+=3;signals.push({l:'OI\u2191',t:'oi',b:true});}else if(ind.oiChange>0.05&&ind.priceChange<0){fs-=5;conflicts.push('OI\u2191 fiyat\u2193');}}
score+=Math.max(-18,Math.min(18,fs));
var bs2=0;
if(ind.bb){var rng2=ind.bb.upper-ind.bb.lower,pos=rng2>0?(ind.price-ind.bb.lower)/rng2:0.5;if(pos<0.05){bs2+=8;signals.push({l:'BB Alt',t:'pat',b:true});}else if(pos<0.15){bs2+=5;signals.push({l:'BB Lower',t:'pat',b:true});}else if(pos>0.95){bs2-=8;signals.push({l:'BB \xDCst',t:'pat',b:false});conflicts.push('BB \xFCst band\u0131');}else if(pos>0.85){bs2-=5;signals.push({l:'BB Upper',t:'pat',b:false});}if(ind.bb.bandwidth<0.03)signals.push({l:'BB Squeeze',t:'pat',b:null});}
if(ind.atr&&ind.price){var ap=(ind.atr/ind.price)*100;if(ap>8){bs2-=3;conflicts.push('Y\xFCksek volatilite');signals.push({l:'ATR %'+ap.toFixed(1),t:'pat',b:null});}}
score+=Math.max(-12,Math.min(12,bs2));
var ps2=0;
if(ind.patterns){ind.patterns.forEach(function(p){if(['Bull Engulfing','Morning Star','Hammer'].indexOf(p)>=0){ps2+=6;signals.push({l:p,t:'pat',b:true});}else if(['Bear Engulfing','Evening Star','Shooting Star'].indexOf(p)>=0){ps2-=6;signals.push({l:p,t:'pat',b:false});conflicts.push(p);}else if(p==='Pin Bar')ps2+=3;else if(p==='Doji')signals.push({l:'Doji',t:'pat',b:null});});}
if(ind.pvt){if(ind.price>ind.pvt.r1){ps2-=3;conflicts.push('R1 \xFCzerinde');}else if(ind.price>ind.pvt.pp)ps2+=2;else if(ind.price<ind.pvt.s1){ps2+=3;signals.push({l:'S1 Alt\u0131',t:'pat',b:true});}}
score+=Math.max(-10,Math.min(10,ps2));
var emaBull=ind.ema9&&ind.ema21&&ind.ema9>ind.ema21&&ind.ema21>ind.ema50;
if(emaBull&&ind.rsi>=70)score-=8;if(ind.bearDiv&&emaBull)score-=6;if(ind.macd&&ind.macd.histogram>0&&ind.rsi>=70)score-=4;
score=Math.max(0,Math.min(100,Math.round(score)));
var bulls=signals.filter(function(s){return s.b===true;}).length,bears=signals.filter(function(s){return s.b===false;}).length;
if(bulls>=6&&score>50)score=Math.min(100,score+5);if(bears>=6&&score<50)score=Math.max(0,score-5);
if(conflicts.length>=3)score=Math.round(score*0.85+50*0.15);
return{score:Math.max(0,Math.min(100,Math.round(score))),signals:signals,conflicts:conflicts,bulls:bulls,bears:bears};
}
function scoreToType(score,conflicts){var hc=conflicts&&conflicts.length>=2;if(score>=80)return'sl';if(score>=60)return hc?'mx':'wl';if(score>=50)return hc?'mx':'wl';if(score>=42)return'nt';if(score>=30)return hc?'mx':'ws';if(score>=20)return'ws';return'ss';}
function fetchKlinesDirect(sym,tf){return fetch(FA+'/fapi/v1/klines?symbol='+sym+'&interval='+tf+'&limit=120').then(function(r){S.apiReqs++;return r.json();});}
function fetchOIDirect(sym){return fetch(FA+'/fapi/v1/openInterest?symbol='+sym).then(function(r){S.apiReqs++;return r.ok?r.json():null;}).catch(function(){return null;});}
function fetchFundingDirect(sym){return fetch(FA+'/fapi/v1/premiumIndex?symbol='+sym).then(function(r){S.apiReqs++;return r.ok?r.json():null;}).catch(function(){return null;});}
function fetchLSDirect(sym){return fetch(FA+'/futures/data/globalLongShortAccountRatio?symbol='+sym+'&period=1h&limit=1').then(function(r){S.apiReqs++;return r.json();}).then(function(d){return d[0]||null;}).catch(function(){return null;});}
function computeCoinResult(info,tf,klines,oi,funding,ls){
var sym=info.symbol;
var opens=klines.map(function(k){return parseFloat(k[1]);}),highs=klines.map(function(k){return parseFloat(k[2]);}),lows=klines.map(function(k){return parseFloat(k[3]);}),closes=klines.map(function(k){return parseFloat(k[4]);}),volumes=klines.map(function(k){return parseFloat(k[5]);});
var price=S.tickerMap[sym]?S.tickerMap[sym].price:info.price,change=S.tickerMap[sym]?S.tickerMap[sym].change:info.change;
var e9s=emaSeries(closes,9),e21s=emaSeries(closes,21),e50s=emaSeries(closes,50);
var ema9=e9s[e9s.length-1],ema21=e21s[e21s.length-1],ema50=e50s[e50s.length-1],ema9Slope=e9s[e9s.length-1]-e9s[e9s.length-4];
var mac=macd(closes),macP=macdPrev(closes),macdHistSlope=mac&&macP?mac.histogram-macP.histogram:0;
var r=rsi(closes,14);
var dv=detectDiv(closes,highs,lows),bullDiv=dv.bull,bearDiv=dv.bear;
var sr=stochRsi(closes,14,14),c20=cci(highs,lows,closes,20),wr=williamsR(highs,lows,closes,14);
var bb=bollinger(closes,20,2),at=calcAtr(highs,lows,closes,14),atrMom=at?Math.abs(closes[closes.length-1]-closes[closes.length-2])/at:null;
var vw=vwap(highs,lows,closes,volumes);
var obvd=obv(closes,volumes),obvLen=obvd.series.length,obvTrend=obvLen>=5?(obvd.series[obvLen-1]>obvd.series[obvLen-5]?'up':'down'):'neutral';
var cvd=0;for(var i=Math.max(0,closes.length-20);i<closes.length;i++)cvd+=closes[i]>=opens[i]?volumes[i]:-volumes[i];
var cvdBull=cvd>0?true:(cvd<0?false:null);
var volMA20=volumes.slice(-20).reduce(function(a,b){return a+b;},0)/20,volRatio=volumes[volumes.length-1]/volMA20;
var lc=closes.slice(-5),lv=volumes.slice(-5);
var volTrend;if(lc[4]>lc[0]&&lv[4]>lv[0])volTrend='bull-confirm';else if(lc[4]<lc[0]&&lv[4]>lv[0])volTrend='bear-confirm';else volTrend='diverge';
var cb=0,cbr=0;for(var i=closes.length-1;i>=Math.max(0,closes.length-6);i--){if(closes[i]>opens[i]){cb++;cbr=0;}else if(closes[i]<opens[i]){cbr++;cb=0;}else break;}
var hisl=highs.slice(-10),losl=lows.slice(-10);
var hhPat=highs[highs.length-1]>Math.max.apply(null,hisl.slice(0,-1)),llPat=lows[lows.length-1]<Math.min.apply(null,losl.slice(0,-1));
var pats=candlePatterns(opens,highs,lows,closes);
var pvt=pivot(highs[highs.length-2],lows[lows.length-2],closes[closes.length-2]);
var fundingRate=funding?parseFloat(funding.lastFundingRate):null;
var oiVal=oi?parseFloat(oi.openInterest):null,prevOi=S.coinData[sym]?S.coinData[sym].oi:oiVal;
var oiChange=oiVal!==null&&prevOi!==null?(oiVal-prevOi)/prevOi:null,lsRatio=ls?parseFloat(ls.longShortRatio):null;
var ind={price:price,priceChange:change,change:change,ema9:ema9,ema21:ema21,ema50:ema50,ema9Slope:ema9Slope,macd:mac,macdHistSlope:macdHistSlope,rsi:r,bullDiv:bullDiv,bearDiv:bearDiv,stochRsi:sr,cci:c20,wr:wr,bb:bb,atr:at,atrMom:atrMom,vwap:vw,obvTrend:obvTrend,cvdBull:cvdBull,volRatio:volRatio,volTrend:volTrend,conseBull:cb,conseBear:cbr,hhPat:hhPat,llPat:llPat,patterns:pats,pvt:pvt,fundingRate:fundingRate,oiChange:oiChange,lsRatio:lsRatio,oiVal:oiVal};
var sc=computeScore(ind);
var result=Object.assign({},info,{price:price,change:change,volume:S.tickerMap[sym]?S.tickerMap[sym].volume:info.volume,ind:ind,score:sc.score,signals:sc.signals,conflicts:sc.conflicts,bulls:sc.bulls,bears:sc.bears,signalType:scoreToType(sc.score,sc.conflicts),oi:oiVal,tf:tf,aiSignal:null,aiShort:null,aiAction:null,aiConfidence:null,aiLong:null,aiEntry:null,aiStop:null,aiTp1:null,aiTp2:null});
S.coinData[sym]=result;return result;
}
function analyzeCoinFast(info,tf){
var sym=info.symbol;
return Promise.all([fetchKlinesDirect(sym,tf),fetchOIDirect(sym),fetchFundingDirect(sym),fetchLSDirect(sym)]).then(function(res){
return computeCoinResult(info,tf,res[0],res[1],res[2],res[3]);
}).catch(function(e){console.error(e);return null;});
}
/* ===== Claude AI ===== */
function parseAIJson(clean){
try{return JSON.parse(clean);}catch(e1){}
var repaired=clean;
var lastBrace=repaired.lastIndexOf('}');
if(lastBrace===-1||lastBrace<repaired.length-1){
var quoteCount=(repaired.match(/(?:^|[^\\])"/g)||[]).length;
if(quoteCount%2===1)repaired+='"';
repaired=repaired.replace(/,\s*$/,'');
var openB=(repaired.match(/\{/g)||[]).length,closeB=(repaired.match(/\}/g)||[]).length;
while(closeB<openB){repaired+='}';closeB++;}
try{return JSON.parse(repaired);}catch(e2){}
}
var out={};
function grab(key){
var re=new RegExp('"'+key+'"\\s*:\\s*"([^"]*?)(?:"\\s*,|"\\s*\\}|$)','s');
var m=clean.match(re);
if(m)return m[1];
var re2=new RegExp('"'+key+'"\\s*:\\s*"([\\s\\S]*)$');
var m2=clean.match(re2);
return m2?m2[1]:'';
}
function grabNum(key){
var m=clean.match(new RegExp('"'+key+'"\\s*:\\s*([0-9.]+)'));
return m?parseFloat(m[1]):0;
}
out.signal=grab('signal')||'NOTR';
out.short=grab('short');
out.action=grab('action');
out.confidence=grabNum('confidence');
out.entry=grab('entry');
out.stop=grab('stop');
out.tp1=grab('tp1');
out.tp2=grab('tp2');
out.long=grab('long')+(clean.length>0&&!/"\s*\}\s*$/.test(clean)?' (analiz kesildi)':'');
return out;
}
function parseLvlNum(str){
if(str===null||str===undefined||str==='')return NaN;
var m=String(str).match(/-?\d+(\.\d+)?/);
return m?parseFloat(m[0]):NaN;
}
function fallbackLevels(coin,dir){
var atr=coin.ind.atr&&coin.ind.atr>0?coin.ind.atr:coin.price*0.012;
var p=coin.price,mult=1.6;
if(dir==='LONG'){
var stop=p-mult*atr,risk=p-stop;
return{entry:p,stop:stop,tp1:p+risk*1.5,tp2:p+risk*2.5};
}
if(dir==='SHORT'){
var stop2=p+mult*atr,risk2=stop2-p;
return{entry:p,stop:stop2,tp1:p-risk2*1.5,tp2:p-risk2*2.5};
}
return null;
}
function sanitizeAIResult(coin,ai){
var sig=ai.signal;
if(sig==='NOTR'){
ai.entry='';ai.stop='';ai.tp1='';ai.tp2='';
return ai;
}
var entry=parseLvlNum(ai.entry),stop=parseLvlNum(ai.stop),tp1=parseLvlNum(ai.tp1),tp2=parseLvlNum(ai.tp2);
var hasAll=!isNaN(entry)&&!isNaN(stop)&&!isNaN(tp1);
var dir=null;
if(sig==='LONG')dir='LONG';
else if(sig==='SHORT')dir='SHORT';
else if(sig==='DIKKAT'){
if(hasAll)dir=tp1>entry?'LONG':(tp1<entry?'SHORT':null);
if(!dir)dir=coin.score>=50?'LONG':'SHORT';
}
var ordered=dir==='LONG'?(stop<entry&&tp1>entry&&(isNaN(tp2)||tp2>=tp1)):(dir==='SHORT'?(stop>entry&&tp1<entry&&(isNaN(tp2)||tp2<=tp1)):false);
var autoNote='';
if(!hasAll||!ordered){
var fb=fallbackLevels(coin,dir);
if(fb){
ai.entry=fmtPrice(fb.entry);ai.stop=fmtPrice(fb.stop);ai.tp1=fmtPrice(fb.tp1);ai.tp2=fmtPrice(fb.tp2);
autoNote=' \u26A0\uFE0F AI seviyeleri mant\u0131ks\u0131z/eksikti, ATR bazl\u0131 seviyeler otomatik hesapland\u0131.';
}
}
var conflictCount=coin.conflicts?coin.conflicts.length:0;
if(conflictCount>=2&&ai.confidence>50){ai.confidence=Math.min(ai.confidence,45);autoNote+=' \u26A0\uFE0F \xC7eli\u015Fkili indikat\xF6rler nedeniyle g\xFCven skoru d\xFC\u015F\xFCr\xFCld\xFC.';}
if(conflictCount>=4&&sig!=='DIKKAT'){ai.signal='DIKKAT';autoNote+=' \u26A0\uFE0F \xC7ok say\u0131da \xE7eli\u015Fki nedeniyle sinyal D\u0130KKAT olarak i\u015Faretlendi (seviyeler korundu, temkinli olun).';}
if(autoNote)ai.long=(ai.long||'')+'\n\n'+autoNote.trim();
return ai;
}
function claudeAnalyze(coin){
if(!S.settings.apikey)return Promise.resolve(null);
var ind=coin.ind;
var prompt='Sen riskten kacinan, disiplinli bir kripto futures risk analistisin. Amacin par\u0131lt\u0131l\u0131 tahminler yapmak degil, ancak g\xFC\xE7l\xFC ve net teyitli kurulumlarda sinyal vermek. Yanlis veya erken sinyal vermek gercek para kaybettirir, bu yuzden supheci ol. Asagidaki verileri dikkatlice degerlendirip SADECE gecerli JSON don, JSON disinda hicbir metin yazma.\n\n'
+coin.symbol+' | Fiyat:'+coin.price+' USDT | 24s Degisim:%'+coin.change.toFixed(2)+' | Indikator Skoru:'+coin.score+'/100 ('+coin.signalType+')\n'
+'Bull sinyal:'+coin.bulls+' Bear sinyal:'+coin.bears+' Celiski sayisi:'+(coin.conflicts?coin.conflicts.length:0)+' Celiskiler:'+(coin.conflicts&&coin.conflicts.length?coin.conflicts.join(', '):'Yok')+'\n'
+'EMA9='+ind.ema9.toFixed(4)+' EMA21='+ind.ema21.toFixed(4)+' EMA50='+ind.ema50.toFixed(4)+' | EMA9 Egim:'+(ind.ema9Slope>0?'yukari':'asagi')
+' | MACD Histogram:'+(ind.macd?ind.macd.histogram.toFixed(5):'N/A')+' | Ardisik mum: '+ind.conseBull+'xBull '+ind.conseBear+'xBear'
+' | Higher High:'+(ind.hhPat?'evet':'hayir')+' Lower Low:'+(ind.llPat?'evet':'hayir')+'\n'
+'RSI(14)='+(ind.rsi?ind.rsi.toFixed(1):'N/A')+' BullDivergence:'+(ind.bullDiv?'VAR':'YOK')+' BearDivergence:'+(ind.bearDiv?'VAR':'YOK')
+' StochRSI='+(ind.stochRsi?ind.stochRsi.toFixed(1):'N/A')+' CCI='+(ind.cci?ind.cci.toFixed(1):'N/A')+' WilliamsR='+(ind.wr?ind.wr.toFixed(1):'N/A')+'\n'
+'Hacim oran(20MA):'+ind.volRatio.toFixed(2)+'x Trend:'+ind.volTrend+' | VWAP:'+(ind.vwap?ind.vwap.toFixed(4):'N/A')+' (fiyat '+(ind.price>ind.vwap?'ustunde':'altinda')+') | OBV:'+ind.obvTrend+' | CVD:'+(ind.cvdBull===true?'Alis':ind.cvdBull===false?'Satis':'Notr')+'\n'
+'Funding Rate='+(ind.fundingRate!==null?(ind.fundingRate*100).toFixed(4)+'%':'N/A')+' | Long/Short Oran='+(ind.lsRatio?ind.lsRatio.toFixed(2):'N/A')+' | OI Degisim:'+(ind.oiChange!==null?(ind.oiChange*100).toFixed(2)+'%':'N/A')+'\n'
+'Bollinger Bands:'+(ind.bb?ind.bb.lower.toFixed(4)+' - '+ind.bb.upper.toFixed(4)+' (orta '+ind.bb.middle.toFixed(4)+')':'N/A')+' | ATR(14)='+(ind.atr?ind.atr.toFixed(4):'N/A')+' (ATR/Fiyat %'+(ind.atr?(ind.atr/coin.price*100).toFixed(2):'N/A')+')\n'
+'Mum Formasyonlari:'+(ind.patterns&&ind.patterns.length?ind.patterns.join(', '):'Yok')+' | Pivot PP/R1/S1:'+(ind.pvt?ind.pvt.pp.toFixed(4)+' / '+ind.pvt.r1.toFixed(4)+' / '+ind.pvt.s1.toFixed(4):'N/A')+'\n\n'
+'KURALLAR (kesinlikle uy):\n'
+'1) 24 saatte zaten %'+Math.abs(coin.change).toFixed(1)+' hareket etmis bir coin icin, eger hareket yonunde RSI>=70 (LONG icin) veya RSI<=30 (SHORT icin) ise ve bearish/bullish divergence da varsa, bu zaten asiri uzamis bir hareket demektir - boyle durumda asla mevcut yonde LONG/SHORT onerme, bunun yerine DIKKAT veya NOTR ver.\n'
+'2) Celiski sayisi 2 veya daha fazlaysa (yukarida verildi) confidence en fazla 45 olabilir ve signal LONG/SHORT yerine DIKKAT veya NOTR olmali, cunku celiskili indikatorlerde net yon riskli.\n'
+'3) confidence sadece indikatorlerin GERCEKTEN birbirini teyit ettigi (ayni yonde EMA dizilimi + MACD + hacim teyidi + momentum + funding/OI uyumu gibi en az 4-5 farkli kategori ayni yonde) durumlarda 70 uzerine cikabilir. Tek 1-2 indikatore dayanan sinyallerde confidence 40-55 araliginda kalmali.\n'
+'4) stop seviyesi mutlaka ATR(14) bazli olmali: LONG icin stop = fiyat - (1.2 ile 2.0 arasi)*ATR, SHORT icin stop = fiyat + (1.2 ile 2.0 arasi)*ATR. Stop cok yakin olursa (gurultu ile tetiklenir) veya cok uzak olursa (risk/odul bozulur) kabul edilemez.\n'
+'5) tp1 mutlaka risk/odul orani en az 1:1.5, tp2 en az 1:2.5 olacak sekilde (entry-stop mesafesine gore) belirlenmeli ve mumkunse pivot/bollinger/swing seviyeleriyle ortusmeli.\n'
+'6) Eger yeterince guclu teyit yoksa LONG/SHORT yerine NOTR vermekten cekinme - yanlis sinyal vermek, sinyal vermemekten daha kotudur. Kaldiracli islemlerde kucuk bir ters hareket bile ciddi zarar yaratir, bu yuzden ihtiyatli ol.\n\n'
+'Su JSON formatinda don (kesinlikle sadece bunu don, baska hicbir sey yazma, aciklama ekleme):\n'
+'{\n'
+'"signal":"LONG veya SHORT veya NOTR veya DIKKAT",\n'
+'"short":"Tek cumle sinyal ozeti, max 12 kelime Turkce",\n'
+'"action":"Kisa islem onerisi, max 12 kelime, kaldiraci da belirt, ornek: Long ac, max 3-5x kaldirac, stop altinda hedef R1",\n'
+'"confidence":75,\n'
+'"entry":"Onerilen giris fiyati, tek sayisal deger, ornek: 2.4150",\n'
+'"stop":"Onerilen stop-loss fiyati, tek sayisal deger, kural 4teki ATR formulune gore",\n'
+'"tp1":"Birinci kar al hedefi, tek sayisal deger, kural 5teki R:R orani ile",\n'
+'"tp2":"Ikinci kar al hedefi (daha uzak), tek sayisal deger, kural 5teki R:R orani ile",\n'
+'"long":"Kisa ve oz bir Turkce ozet analiz, TAM OLARAK 4-5 cumle (daha fazla degil). Su sirayla deyin: (1) trend+momentum durumu tek cumlede (EMA/MACD/RSI uyumu), (2) hacim/funding/OI ne diyor tek cumlede, (3) giris/stop/TP mantigi neye dayaniyor (ATR, pivot, swing seviyesi) tek cumlede, (4) en buyuk risk veya invalidation senaryosu tek cumlede, (5) iste opsiyonel kisa pozisyon yonetimi notu. Gereksiz tekrar ve uzun aciklama yapma, sadece en onemli noktalari net ve oz sekilde ver. Asiri iyimser olma."\n'
+'}\n\n'
+'signal: LONG=net alis (sadece guclu teyit varsa), SHORT=net satis (sadece guclu teyit varsa), NOTR=belirsiz/yetersiz teyit bekle, DIKKAT=trend var ama ciddi risk/celiski/asiri uzama var\n'
+'entry/stop/tp1/tp2: NOTR disindaki sinyallerde mutlaka somut TEK sayisal deger ver (aralik degil), kural 4 ve 5e tam uy. NOTR ise bu alanlari bos string birak.';
return fetch('https://api.anthropic.com/v1/messages',{
method:'POST',
headers:{'Content-Type':'application/json','x-api-key':S.settings.apikey,'anthropic-version':'2023-06-01','anthropic-dangerous-direct-browser-access':'true'},
body:JSON.stringify({model:S.settings.model||'claude-sonnet-4-6',max_tokens:900,messages:[{role:'user',content:prompt}]})
}).then(function(res){
if(!res.ok)return res.json().then(function(e){throw new Error(e.error?e.error.message:res.status);});
return res.json();
}).then(function(data){
var raw=(data.content[0]?data.content[0].text:'')||'{}';
var clean=raw.replace(/```json|```/g,'').trim();
var parsed=parseAIJson(clean);
var result={signal:(parsed.signal||'NOTR').toUpperCase(),short:parsed.short||'',action:parsed.action||'',confidence:parsed.confidence||0,long:parsed.long||'',entry:parsed.entry||'',stop:parsed.stop||'',tp1:parsed.tp1||'',tp2:parsed.tp2||''};
return sanitizeAIResult(coin,result);
}).catch(function(e){
return{signal:'NOTR',short:'Analiz hatasi',action:'',confidence:0,long:'Hata: '+e.message,entry:'',stop:'',tp1:'',tp2:''};
});
}
/* ===== Rendering ===== */
function aiClass(sig){if(!sig)return'loading';if(sig==='LONG')return'long';if(sig==='SHORT')return'short';if(sig==='DIKKAT')return'dikkat';return'notr';}
function toggleAiLong(){
var wrap=document.getElementById('ai-long-wrap'),chev=document.getElementById('ai-toggle-chev'),lbl=document.getElementById('ai-toggle-label');
if(!wrap)return;
var open=wrap.classList.toggle('open');
if(chev)chev.classList.toggle('open',open);
if(lbl)lbl.textContent=open?'\u{1F4DD} AI \xD6zet Yorumunu Gizle':'\u{1F4DD} AI \xD6zet Yorumunu G\xF6ster';
S.panelState.aiSummary=open;savePanelState();
}
function toggleIndPanel(key){
var body=document.getElementById('indbody-'+key),chev=document.getElementById('indchev-'+key);
if(!body)return;
var open=body.classList.toggle('open');
if(chev)chev.classList.toggle('open',open);
S.panelState[key]=open;savePanelState();
}
function buildIndBox(key,title,rowsHtml){
var open=S.panelState[key]!==false;
return'<div class="ind-box" id="indbox-'+key+'">'
+'<div class="ind-box-hdr" onclick="toggleIndPanel(\''+key+'\')"><span>'+title+'</span><span class="ind-chev'+(open?' open':'')+'" id="indchev-'+key+'">\u25BC</span></div>'
+'<div class="ind-box-body'+(open?' open':'')+'" id="indbody-'+key+'">'+rowsHtml+'</div>'
+'</div>';
}
function modalLoadingHTML(step){
var steps=[['ind','\u{1F4CA} G\xFCncel veriler ve indikat\xF6rler taraniyor...'],['ai','\u{1F916} Claude AI analiz ediyor...']];
return'<div class="modal-loading"><div class="spin"></div>'
+steps.map(function(s){var idx=steps.findIndex(function(x){return x[0]===s[0];});var curIdx=steps.findIndex(function(x){return x[0]===step;});var cls=s[0]===step?'modal-step active':(idx<curIdx?'modal-step':'modal-step');return'<div class="'+cls+'">'+s[1]+'</div>';}).join('')
+'</div>';
}
function buildAnalysisHTML(coin){
var sym=coin.symbol;
var ind=coin.ind;
var rsiC=ind.rsi>=70?'bear':ind.rsi<=30?'bull':'neutral';
var macdC=ind.macd&&ind.macd.histogram>0?'bull':'bear';
var aiCls=aiClass(coin.aiSignal);
var aiIcon=coin.aiSignal==='LONG'?'\u{1F916} LONG \u25B2':coin.aiSignal==='SHORT'?'\u{1F916} SHORT \u25BC':coin.aiSignal==='DIKKAT'?'\u{1F916} \u26A0\uFE0F D\u0130KKAT':coin.aiSignal==='NOTR'?'\u{1F916} N\xD6TR':'\u{1F916} Bekliyor';
var conf=coin.aiConfidence||0;
var confColor=conf>=70?'var(--green)':conf>=45?'var(--yellow)':'var(--red2)';
var levelsHtml='';
if(coin.aiEntry||coin.aiStop||coin.aiTp1||coin.aiTp2){
levelsHtml=(coin.aiEntry?'<div class="lvl-box entry"><div class="lvl-box-l">Giri\u015F</div><div class="lvl-box-v">'+coin.aiEntry+'</div></div>':'')
+(coin.aiStop?'<div class="lvl-box stop"><div class="lvl-box-l">Stop</div><div class="lvl-box-v">'+coin.aiStop+'</div></div>':'')
+(coin.aiTp1?'<div class="lvl-box tp"><div class="lvl-box-l">TP1</div><div class="lvl-box-v">'+coin.aiTp1+'</div></div>':'')
+(coin.aiTp2?'<div class="lvl-box tp"><div class="lvl-box-l">TP2</div><div class="lvl-box-v">'+coin.aiTp2+'</div></div>':'');
}
return'<div class="ahead">'
+'<div style="display:flex;align-items:center;gap:10px;flex-wrap:wrap"><span class="ahead-sym">'+sym.replace('USDT','')+'/USDT</span>'
+'<span class="ahead-price" id="ahead-price">'+fmtPrice(coin.price)+'</span>'
+'<span class="ahead-chg '+(coin.change>=0?'up':'down')+'" id="ahead-chg">'+(coin.change>=0?'+':'')+coin.change.toFixed(2)+'%</span></div>'
+'<span class="chip">'+coin.tf+' grafik</span>'
+'</div>'
+'<div class="apanel-body">'
+'<div class="dgrid">'
+'<div class="ditem"><div class="ditem-l">Skor</div><div class="ditem-v">'+coin.score+'/100</div></div>'
+'<div class="ditem"><div class="ditem-l">\u0130nd. Sinyal</div><div class="ditem-v" style="font-size:11px">'+coin.signalType+'</div></div>'
+'<div class="ditem"><div class="ditem-l">Bull/Bear</div><div class="ditem-v"><span style="color:var(--green)">\u25B2'+(coin.bulls||0)+'</span> / <span style="color:var(--red)">\u25BC'+(coin.bears||0)+'</span></div></div>'
+'<div class="ditem"><div class="ditem-l">Funding</div><div class="ditem-v '+(ind.fundingRate&&ind.fundingRate<0?'bull':'bear')+'">'+(ind.fundingRate!==null&&ind.fundingRate!==undefined?(ind.fundingRate*100).toFixed(4)+'%':'N/A')+'</div></div>'
+'<div class="ditem"><div class="ditem-l">L/S Oran\u0131</div><div class="ditem-v">'+(ind.lsRatio?ind.lsRatio.toFixed(3):'N/A')+'</div></div>'
+'<div class="ditem"><div class="ditem-l">Hacim</div><div class="ditem-v">'+fmtVol(coin.volume)+'</div></div>'
+'</div>'
+'<div class="ai-box">'
+'<div class="ai-box-hdr">'
+'<div class="ai-box-title">\u{1F916} Claude AI Analizi</div>'
+'<span class="ai-modal-pill '+aiCls+'" id="mai-signal" data-sym="'+sym+'">'+aiIcon+'</span>'
+'</div>'
+'<div class="ai-meta-box">'
+'<div class="ai-meta-action" id="mai-action">'+(coin.aiAction?'\u{1F4A1} <strong>\u0130\u015Flem \xD6nerisi:</strong> '+coin.aiAction:'\u{1F4A1} <strong>\u0130\u015Flem \xD6nerisi:</strong> Bekleniyor...')+'</div>'
+'<div class="ai-levels-modal" id="mai-levels" style="display:'+(levelsHtml?'grid':'none')+'">'+levelsHtml+'</div>'
+'<div class="ai-conf-row"><span class="ai-conf-label">G\xFCven</span>'
+'<div class="ai-conf-track"><div class="ai-conf-fill" id="mai-conf-fill" style="width:'+conf+'%;background:'+confColor+'"></div></div>'
+'<span class="ai-conf-val" id="mai-conf-val" style="color:'+confColor+'">%'+conf+'</span>'
+'</div>'
+'</div>'
+'<div class="ai-toggle-row" onclick="toggleAiLong()"><span id="ai-toggle-label">\u{1F4DD} AI \xD6zet Yorumunu '+(S.panelState.aiSummary?'Gizle':'G\xF6ster')+'</span><span class="ai-toggle-chev'+(S.panelState.aiSummary?' open':'')+'" id="ai-toggle-chev">\u25BC</span></div>'
+'<div class="ai-long-wrap'+(S.panelState.aiSummary?' open':'')+'" id="ai-long-wrap"><div class="ai-long-text" id="mai-text">'+(coin.aiLong||'<span class="ai-streaming">Analiz bekleniyor...</span>')+'</div></div>'
+'<div class="ai-disclaimer">\u26A0\uFE0F Bu analiz yat\u0131r\u0131m tavsiyesi de\u011Fildir, olas\u0131l\u0131k tahminidir ve yanl\u0131\u015F olabilir. Kald\u0131ra\xE7l\u0131 i\u015Flemlerde k\xFC\xE7\xFCk bir ters hareket bile sermayenin b\xFCy\xFCk k\u0131sm\u0131n\u0131 kaybettirebilir \u2014 d\xFC\u015F\xFCk kald\u0131ra\xE7 ve uygun pozisyon b\xFCy\xFCkl\xFC\u011F\xFC kullan\u0131n, stop emrini mutlaka uygulay\u0131n.</div>'
+'</div>'
+(coin.conflicts&&coin.conflicts.length?'<div class="conflicts-box"><div class="conflicts-title">\u26A0\uFE0F \xC7eli\u015Fkiler</div>'+coin.conflicts.map(function(c){return'<div class="conflict-item">\u2022 '+c+'</div>';}).join('')+'</div>':'')
+'<div class="ind-grid">'
+buildIndBox('trend','Trend',
'<div class="irow"><span class="iname">EMA 9/21/50</span><span class="ival">'+ind.ema9.toFixed(4)+' / '+ind.ema21.toFixed(4)+' / '+ind.ema50.toFixed(4)+'</span></div>'
+'<div class="irow"><span class="iname">EMA Slope</span><span class="ival '+(ind.ema9Slope>0?'bull':'bear')+'">'+(ind.ema9Slope>0?'\u2191 Yukar\u0131':'\u2193 A\u015Fa\u011F\u0131')+'</span></div>'
+'<div class="irow"><span class="iname">MACD Hist</span><span class="ival '+macdC+'">'+(ind.macd?ind.macd.histogram.toFixed(6):'N/A')+'</span></div>'
+'<div class="irow"><span class="iname">Ard. Bull/Bear Mum</span><span class="ival">'+ind.conseBull+'\u{1F7E2} / '+ind.conseBear+'\u{1F534}</span></div>'
+'<div class="irow"><span class="iname">Higher High</span><span class="ival '+(ind.hhPat?'bull':'neutral')+'">'+(ind.hhPat?'\u2713 Evet':'Hay\u0131r')+'</span></div>'
+'<div class="irow"><span class="iname">Lower Low</span><span class="ival '+(ind.llPat?'bear':'neutral')+'">'+(ind.llPat?'\u26A0\uFE0F Evet':'Hay\u0131r')+'</span></div>')
+buildIndBox('momentum','Momentum',
'<div class="irow"><span class="iname">RSI (14)</span><span class="ival '+rsiC+'">'+(ind.rsi?ind.rsi.toFixed(2):'N/A')+'</span></div>'
+'<div class="irow"><span class="iname">Bullish Div</span><span class="ival '+(ind.bullDiv?'bull':'neutral')+'">'+(ind.bullDiv?'\u2713 VAR':'Yok')+'</span></div>'
+'<div class="irow"><span class="iname">Bearish Div</span><span class="ival '+(ind.bearDiv?'bear':'neutral')+'">'+(ind.bearDiv?'\u26A0\uFE0F VAR':'Yok')+'</span></div>'
+'<div class="irow"><span class="iname">StochRSI</span><span class="ival '+(ind.stochRsi<20?'bull':ind.stochRsi>80?'bear':'neutral')+'">'+(ind.stochRsi?ind.stochRsi.toFixed(1):'N/A')+'</span></div>'
+'<div class="irow"><span class="iname">CCI (20)</span><span class="ival '+(ind.cci>100?'bull':ind.cci<-100?'bear':'neutral')+'">'+(ind.cci?ind.cci.toFixed(1):'N/A')+'</span></div>'
+'<div class="irow"><span class="iname">Williams %R</span><span class="ival '+(ind.wr>-20?'bear':ind.wr<-80?'bull':'neutral')+'">'+(ind.wr?ind.wr.toFixed(1):'N/A')+'</span></div>'
+'<div class="irow"><span class="iname">ATR Mom</span><span class="ival">'+(ind.atrMom?ind.atrMom.toFixed(2):'N/A')+'x</span></div>')
+buildIndBox('hacim','Hacim',
'<div class="irow"><span class="iname">Hacim/20MA</span><span class="ival '+(ind.volRatio>1.5?'bull':'neutral')+'">'+(ind.volRatio?ind.volRatio.toFixed(2):'N/A')+'x</span></div>'
+'<div class="irow"><span class="iname">Hacim Trendi</span><span class="ival '+(ind.volTrend==='bull-confirm'?'bull':ind.volTrend==='bear-confirm'?'bear':'neutral')+'">'+ind.volTrend+'</span></div>'
+'<div class="irow"><span class="iname">VWAP</span><span class="ival '+(ind.price>ind.vwap?'bull':'bear')+'">'+(ind.vwap?ind.vwap.toFixed(4):'N/A')+'</span></div>'
+'<div class="irow"><span class="iname">OBV</span><span class="ival '+(ind.obvTrend==='up'?'bull':'bear')+'">'+ind.obvTrend+'</span></div>'
+'<div class="irow"><span class="iname">CVD</span><span class="ival '+(ind.cvdBull===true?'bull':ind.cvdBull===false?'bear':'neutral')+'">'+(ind.cvdBull===true?'Al\u0131\u015F':ind.cvdBull===false?'Sat\u0131\u015F':'N\xF6tr')+'</span></div>')
+buildIndBox('volat','Volatilite & Formasyon',
'<div class="irow"><span class="iname">BB</span><span class="ival">'+(ind.bb?ind.bb.lower.toFixed(4)+' \u2014 '+ind.bb.upper.toFixed(4):'N/A')+'</span></div>'
+'<div class="irow"><span class="iname">BB Bandwidth</span><span class="ival">'+(ind.bb?ind.bb.bandwidth.toFixed(4)+(ind.bb.bandwidth<0.03?' \u{1F525}':''):'N/A')+'</span></div>'
+'<div class="irow"><span class="iname">ATR</span><span class="ival">'+(ind.atr?ind.atr.toFixed(4):'N/A')+'</span></div>'
+'<div class="irow"><span class="iname">Formasyonlar</span><span class="ival">'+(ind.patterns&&ind.patterns.length?ind.patterns.join(', '):'Yok')+'</span></div>'
+'<div class="irow"><span class="iname">Pivot PP/R1/S1</span><span class="ival">'+(ind.pvt?ind.pvt.pp.toFixed(4)+' / <span class="bull">'+ind.pvt.r1.toFixed(4)+'</span> / <span class="bear">'+ind.pvt.s1.toFixed(4)+'</span>':'N/A')+'</span></div>')
+'</div>'
+'</div>';
}
function selectCoin(sym){
S.activeSymbol=sym;
renderSidebarList();
runAnalysis(sym);
}
function runAnalysis(sym){
var panel=document.getElementById('apanel');
panel.innerHTML=modalLoadingHTML('ind');
var tf=(S.settings.tf)||'1h';
var tickerPromise;
if(S.tickerMap[sym]){
tickerPromise=Promise.resolve({symbol:sym,price:S.tickerMap[sym].price,change:S.tickerMap[sym].change,volume:S.tickerMap[sym].volume});
}else{
tickerPromise=fetch(FA+'/fapi/v1/ticker/24hr?symbol='+sym).then(function(r){
if(!r.ok)throw new Error('Sembol bulunamadi');
return r.json();
}).then(function(t){
return{symbol:sym,price:parseFloat(t.lastPrice),change:parseFloat(t.priceChangePercent),volume:parseFloat(t.quoteVolume)};
});
}
tickerPromise.then(function(info){
return analyzeCoinFast(info,tf);
}).then(function(coin){
if(!coin)throw new Error('Indikator hesaplanamadi');
panel.innerHTML=buildAnalysisHTML(coin);
if(!S.settings.apikey){
var aiText2=document.getElementById('mai-text');if(aiText2)aiText2.innerHTML='API key girilmemi\u015F. Ayarlar b\xF6l\xFCm\xFCnden Claude API key girip kaydedin.';
return;
}
panel.querySelector('#mai-signal').textContent='\u{1F916} Bekleniyor';
panel.querySelector('#mai-text').innerHTML='<span class="ai-streaming">Claude analiz ediyor...</span>';
return claudeAnalyze(coin).then(function(ai){
if(ai){coin.aiSignal=ai.signal;coin.aiShort=ai.short;coin.aiAction=ai.action;coin.aiConfidence=ai.confidence;coin.aiLong=ai.long;coin.aiEntry=ai.entry;coin.aiStop=ai.stop;coin.aiTp1=ai.tp1;coin.aiTp2=ai.tp2;}
if(S.activeSymbol===sym){
panel.innerHTML=buildAnalysisHTML(coin);
}
});
}).catch(function(e){
panel.innerHTML='<div class="modal-loading"><span style="color:var(--red2)">\u26A0\uFE0F Hata: '+e.message+'</span></div>';
});
}
/* ===== Init ===== */
loadSettings();
startWS();
S.activeSymbol='BTCUSDT';
fetchSymbolList().then(function(){
return fetchAllTickerSnapshot();
}).then(function(){
renderSidebarList();
runAnalysis('BTCUSDT');
});
setInterval(fetchAllTickerSnapshot,20000);
</script>
</body>
</html>