@import url(‘
https://fonts.googleapis.com/css2?family=DM+Mono:wght@400;500&family=Syne:wght@400;500;600;700&display=swap’);
#sai-wrap *{box-sizing:border-box;margin:0;padding:0;}
#sai-wrap{
–bg:#0a0e1a;–surface:#111827;–card:#161d2e;–border:#1e2d45;
–text:#e8edf5;–muted:#6b7a99;–accent:#3b82f6;–green:#10b981;
–red:#ef4444;–amber:#f59e0b;
–font:’Syne’,sans-serif;–mono:’DM Mono’,monospace;
background:var(–bg);color:var(–text);font-family:var(–font);
min-height:100vh;padding:0;
}
#sai-wrap .sai-hdr{display:flex;align-items:center;gap:12px;padding:12px 16px;background:var(–surface);border-bottom:1px solid var(–border);position:sticky;top:0;z-index:100;flex-wrap:wrap;}
#sai-wrap .sai-logo{font-size:16px;font-weight:700;letter-spacing:-.5px;color:var(–text);white-space:nowrap;}
#sai-wrap .sai-logo span{color:var(–accent);}
#sai-wrap .sai-srch{position:relative;flex:1;min-width:200px;max-width:480px;}
#sai-wrap .sai-srch input{width:100%;background:var(–card);border:1px solid var(–border);border-radius:8px;padding:8px 12px 8px 32px;color:var(–text);font-family:var(–font);font-size:13px;outline:none;transition:border .2s;}
#sai-wrap .sai-srch input:focus{border-color:var(–accent);}
#sai-wrap .sai-srch input::placeholder{color:var(–muted);}
#sai-wrap .si{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(–muted);font-size:14px;pointer-events:none;}
#sai-wrap .sai-dd{position:absolute;top:calc(100% + 4px);left:0;right:0;background:var(–surface);border:1px solid var(–border);border-radius:8px;z-index:500;display:none;overflow:hidden;box-shadow:0 8px 28px rgba(0,0,0,.55);max-height:300px;overflow-y:auto;}
#sai-wrap .sai-dd.open{display:block;}
#sai-wrap .ddi{padding:9px 13px;cursor:pointer;display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid var(–border);font-size:12px;}
#sai-wrap .ddi:last-child{border-bottom:none;}
#sai-wrap .ddi:hover{background:var(–card);}
#sai-wrap .ddi .ds{font-weight:700;color:var(–accent);font-size:13px;margin-right:8px;}
#sai-wrap .ddi .dn{color:var(–muted);}
#sai-wrap .ddi .de{font-size:10px;color:var(–muted);background:var(–card);padding:2px 6px;border-radius:4px;border:1px solid var(–border);}
#sai-wrap .cur-sw{display:flex;gap:3px;background:var(–card);border-radius:8px;padding:3px;border:1px solid var(–border);}
#sai-wrap .cur-btn{padding:5px 12px;border-radius:6px;font-size:11px;font-weight:700;cursor:pointer;border:none;font-family:var(–font);background:transparent;color:var(–muted);transition:all .15s;}
#sai-wrap .cur-btn.on{background:var(–accent);color:#fff;}
#sai-wrap .wbtn{padding:6px 13px;border-radius:7px;font-size:11px;cursor:pointer;font-family:var(–font);font-weight:600;border:1px solid rgba(59,130,246,.3);background:rgba(59,130,246,.1);color:#3b82f6;transition:all .15s;}
#sai-wrap .wbtn.added{border-color:rgba(16,185,129,.3);background:rgba(16,185,129,.1);color:#10b981;}
#sai-wrap .sai-body{display:flex;min-height:calc(100vh – 52px);}
#sai-wrap .sai-sb{width:190px;background:var(–surface);border-right:1px solid var(–border);overflow-y:auto;flex-shrink:0;}
#sai-wrap .sai-content{flex:1;overflow-y:auto;padding:16px 18px;}
#sai-wrap .slbl{padding:10px 12px 4px;font-size:9px;letter-spacing:1.5px;color:var(–muted);text-transform:uppercase;font-weight:600;}
#sai-wrap .wit{padding:9px 12px;cursor:pointer;border-bottom:1px solid var(–border);transition:background .12s;}
#sai-wrap .wit:hover,#sai-wrap .wit.active{background:var(–card);}
#sai-wrap .wit .wr{display:flex;justify-content:space-between;}
#sai-wrap .wit .ws{font-size:12px;font-weight:700;}
#sai-wrap .wit .wn{font-size:10px;color:var(–muted);margin-top:1px;}
#sai-wrap .wit .wp{font-family:var(–mono);font-size:11px;text-align:right;}
#sai-wrap .wit .wc{font-family:var(–mono);font-size:10px;}
#sai-wrap .up{color:#10b981;}#sai-wrap .dn{color:#ef4444;}
#sai-wrap .hero{display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:14px;flex-wrap:wrap;gap:10px;}
#sai-wrap .hsym{font-size:24px;font-weight:700;letter-spacing:-1px;}
#sai-wrap .hnm{font-size:11px;color:var(–muted);margin-top:2px;}
#sai-wrap .hprice{text-align:right;}
#sai-wrap .hpbig{font-size:24px;font-weight:700;font-family:var(–mono);}
#sai-wrap .hpchg{font-size:12px;font-family:var(–mono);margin-top:2px;}
#sai-wrap .hlive{font-size:10px;color:var(–muted);margin-top:3px;}
#sai-wrap .ldot{width:6px;height:6px;border-radius:50%;background:#10b981;display:inline-block;animation:lp 2s infinite;margin-right:4px;}
@keyframes lp{0%,100%{opacity:1}50%{opacity:.25}}
#sai-wrap .sigbox{background:var(–card);border:1px solid var(–border);border-radius:12px;padding:13px 15px;margin-bottom:14px;display:flex;gap:14px;align-items:flex-start;}
#sai-wrap .sbadge{padding:7px 16px;border-radius:8px;font-size:13px;font-weight:700;letter-spacing:1px;white-space:nowrap;}
#sai-wrap .sbuy{background:rgba(16,185,129,.15);color:#10b981;border:1px solid rgba(16,185,129,.3);}
#sai-wrap .ssell{background:rgba(239,68,68,.15);color:#ef4444;border:1px solid rgba(239,68,68,.3);}
#sai-wrap .shold{background:rgba(245,158,11,.15);color:#f59e0b;border:1px solid rgba(245,158,11,.3);}
#sai-wrap .sload{background:rgba(107,122,153,.1);color:var(–muted);border:1px solid var(–border);}
#sai-wrap .sigtxt{flex:1;font-size:11px;color:var(–muted);line-height:1.6;}
#sai-wrap .cbwrap{margin-top:7px;}
#sai-wrap .cblbl{font-size:9px;color:var(–muted);margin-bottom:3px;}
#sai-wrap .cbbar{height:3px;background:var(–border);border-radius:2px;width:88px;}
#sai-wrap .cbfill{height:100%;border-radius:2px;transition:width .6s;}
#sai-wrap .mets{display:grid;grid-template-columns:repeat(4,1fr);gap:9px;margin-bottom:14px;}
#sai-wrap .mc{background:var(–card);border:1px solid var(–border);border-radius:10px;padding:10px 12px;}
#sai-wrap .ml{font-size:9px;letter-spacing:1px;color:var(–muted);text-transform:uppercase;margin-bottom:4px;}
#sai-wrap .mv{font-size:14px;font-weight:700;font-family:var(–mono);}
#sai-wrap .chcard{background:var(–card);border:1px solid var(–border);border-radius:12px;padding:13px 15px;margin-bottom:14px;}
#sai-wrap .chtop{display:flex;justify-content:space-between;align-items:center;margin-bottom:10px;}
#sai-wrap .chtit{font-size:11px;color:var(–muted);}
#sai-wrap .tfs{display:flex;gap:3px;}
#sai-wrap .tf{padding:3px 9px;border-radius:6px;font-size:10px;cursor:pointer;background:transparent;border:1px solid var(–border);color:var(–muted);font-family:var(–font);transition:all .12s;}
#sai-wrap .tf.on{background:var(–accent);color:#fff;border-color:var(–accent);}
#sai-wrap .chwrap{position:relative;height:175px;}
#sai-wrap .sec{font-size:9px;letter-spacing:1.5px;color:var(–muted);text-transform:uppercase;margin-bottom:9px;font-weight:600;}
#sai-wrap .predgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-bottom:14px;}
#sai-wrap .pcard{background:var(–card);border:1px solid var(–border);border-radius:10px;padding:10px 12px;}
#sai-wrap .plbl{font-size:9px;letter-spacing:1px;color:var(–muted);text-transform:uppercase;margin-bottom:4px;}
#sai-wrap .pprice{font-size:13px;font-weight:700;font-family:var(–mono);}
#sai-wrap .pdelta{font-size:10px;font-family:var(–mono);margin-top:2px;}
#sai-wrap .pbar{height:3px;background:var(–border);border-radius:2px;margin-top:7px;}
#sai-wrap .pbfill{height:100%;border-radius:2px;}
#sai-wrap .indgrid{display:grid;grid-template-columns:repeat(3,1fr);gap:9px;margin-bottom:20px;}
#sai-wrap .icard{background:var(–card);border:1px solid var(–border);border-radius:10px;padding:10px 12px;}
#sai-wrap .iname{font-size:10px;color:var(–muted);margin-bottom:3px;}
#sai-wrap .ival{font-size:13px;font-weight:700;font-family:var(–mono);}
#sai-wrap .ipill{font-size:9px;margin-top:4px;padding:2px 7px;border-radius:4px;display:inline-block;}
#sai-wrap .pbull{background:rgba(16,185,129,.15);color:#10b981;}
#sai-wrap .pbear{background:rgba(239,68,68,.15);color:#ef4444;}
#sai-wrap .pneu{background:rgba(107,122,153,.12);color:var(–muted);}
#sai-wrap .sk{background:linear-gradient(90deg,var(–card) 25%,var(–border) 50%,var(–card) 75%);background-size:200% 100%;animation:sk 1.4s infinite;border-radius:6px;}
@keyframes sk{0%{background-position:200% 0}100%{background-position:-200% 0}}
#sai-wrap .rbtn{padding:5px 11px;border-radius:7px;font-size:11px;cursor:pointer;font-family:var(–font);border:1px solid var(–border);background:transparent;color:var(–muted);margin-left:8px;}
#sai-wrap .cadnote{font-size:9px;color:var(–muted);margin-top:2px;}
#sai-wrap .disc{font-size:10px;color:var(–muted);padding:8px 18px;background:var(–surface);border-top:1px solid var(–border);text-align:center;}
#sai-wrap .splash{display:flex;align-items:center;justify-content:center;height:65vh;flex-direction:column;gap:12px;}
#sai-wrap .splash-ico{font-size:36px;}
#sai-wrap .splash-title{font-size:18px;font-weight:600;}
#sai-wrap .splash-sub{font-size:12px;color:var(–muted);text-align:center;max-width:380px;line-height:1.7;}
#sai-wrap .splash-btns{display:flex;gap:8px;flex-wrap:wrap;justify-content:center;margin-top:10px;}
#sai-wrap .splash-btn{padding:7px 16px;background:var(–card);border:1px solid var(–border);color:var(–muted);border-radius:6px;cursor:pointer;font-size:12px;font-family:var(–font);transition:all .15s;}
#sai-wrap .splash-btn:hover{border-color:var(–accent);color:var(–accent);}
STOCKAI Predictor
📈
AI-Powered Stock Analysis
Search any stock worldwide. Live prices, AI buy/sell/hold signals, price predictions from today through next year — in USD and CAD.
⚠ For informational purposes only. Not financial advice. AI predictions are estimates only. Always consult a qualified financial advisor.
https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.4.1/chart.umd.js
const sai = (function(){
let AV = localStorage.getItem(‘spp_av’) || ”;
let CL = localStorage.getItem(‘spp_cl’) || ”;
let CUR = ‘USD’, CADR = 1.37;
let WL = JSON.parse(localStorage.getItem(‘spp_wl’) || ‘[“AAPL”,”NVDA”,”TSLA”,”SHOP.TO”,”RY.TO”]’);
let SYM = null, PC = null, CD = null;
const TICKS = [
{s:’AAPL’,n:’Apple Inc.’,e:’NASDAQ’},{s:’NVDA’,n:’NVIDIA Corporation’,e:’NASDAQ’},{s:’MSFT’,n:’Microsoft Corporation’,e:’NASDAQ’},
{s:’GOOGL’,n:’Alphabet Inc.’,e:’NASDAQ’},{s:’AMZN’,n:’Amazon.com Inc.’,e:’NASDAQ’},{s:’META’,n:’Meta Platforms’,e:’NASDAQ’},
{s:’TSLA’,n:’Tesla Inc.’,e:’NASDAQ’},{s:’AVGO’,n:’Broadcom Inc.’,e:’NASDAQ’},{s:’LLY’,n:’Eli Lilly’,e:’NYSE’},
{s:’JPM’,n:’JPMorgan Chase’,e:’NYSE’},{s:’V’,n:’Visa Inc.’,e:’NYSE’},{s:’XOM’,n:’Exxon Mobil’,e:’NYSE’},
{s:’UNH’,n:’UnitedHealth Group’,e:’NYSE’},{s:’MA’,n:’Mastercard’,e:’NYSE’},{s:’HD’,n:’The Home Depot’,e:’NYSE’},
{s:’PG’,n:’Procter & Gamble’,e:’NYSE’},{s:’JNJ’,n:’Johnson & Johnson’,e:’NYSE’},{s:’COST’,n:’Costco Wholesale’,e:’NASDAQ’},
{s:’ABBV’,n:’AbbVie Inc.’,e:’NYSE’},{s:’BAC’,n:’Bank of America’,e:’NYSE’},{s:’WMT’,n:’Walmart Inc.’,e:’NYSE’},
{s:’NFLX’,n:’Netflix Inc.’,e:’NASDAQ’},{s:’ORCL’,n:’Oracle Corporation’,e:’NYSE’},{s:’CRM’,n:’Salesforce’,e:’NYSE’},
{s:’AMD’,n:’Advanced Micro Devices’,e:’NASDAQ’},{s:’ADBE’,n:’Adobe Inc.’,e:’NASDAQ’},{s:’INTC’,n:’Intel Corporation’,e:’NASDAQ’},
{s:’CSCO’,n:’Cisco Systems’,e:’NASDAQ’},{s:’PEP’,n:’PepsiCo Inc.’,e:’NASDAQ’},{s:’DIS’,n:’Walt Disney’,e:’NYSE’},
{s:’KO’,n:’Coca-Cola’,e:’NYSE’},{s:’NKE’,n:’Nike Inc.’,e:’NYSE’},{s:’GS’,n:’Goldman Sachs’,e:’NYSE’},
{s:’MS’,n:’Morgan Stanley’,e:’NYSE’},{s:’BRK-B’,n:’Berkshire Hathaway B’,e:’NYSE’},{s:’PYPL’,n:’PayPal’,e:’NASDAQ’},
{s:’T’,n:’AT&T Inc.’,e:’NYSE’},{s:’VZ’,n:’Verizon’,e:’NYSE’},{s:’SHOP’,n:’Shopify (USD)’,e:’NYSE’},
{s:’QQQ’,n:’Invesco QQQ ETF’,e:’NASDAQ’},{s:’SPY’,n:’SPDR S&P 500 ETF’,e:’NYSE’},{s:’IWM’,n:’iShares Russell 2000′,e:’NYSE’},
{s:’GLD’,n:’SPDR Gold Shares’,e:’NYSE’},{s:’VTI’,n:’Vanguard Total Market’,e:’NYSE’},{s:’TLT’,n:’iShares 20Y Treasury’,e:’NASDAQ’},
{s:’ASML’,n:’ASML Holding’,e:’NASDAQ’},{s:’TSM’,n:’Taiwan Semiconductor’,e:’NYSE’},{s:’NVO’,n:’Novo Nordisk’,e:’NYSE’},
{s:’SAP’,n:’SAP SE’,e:’NYSE’},{s:’TM’,n:’Toyota Motor’,e:’NYSE’},{s:’SONY’,n:’Sony Group’,e:’NYSE’},
{s:’BABA’,n:’Alibaba Group’,e:’NYSE’},{s:’HSBC’,n:’HSBC Holdings’,e:’NYSE’},
{s:’SHOP.TO’,n:’Shopify Inc.’,e:’TSX’},{s:’RY.TO’,n:’Royal Bank of Canada’,e:’TSX’},{s:’TD.TO’,n:’TD Bank’,e:’TSX’},
{s:’BNS.TO’,n:’Bank of Nova Scotia’,e:’TSX’},{s:’BMO.TO’,n:’Bank of Montreal’,e:’TSX’},{s:’ENB.TO’,n:’Enbridge Inc.’,e:’TSX’},
{s:’CNR.TO’,n:’Canadian National Railway’,e:’TSX’},{s:’CP.TO’,n:’Canadian Pacific’,e:’TSX’},{s:’CNQ.TO’,n:’Canadian Natural Resources’,e:’TSX’},
{s:’ABX.TO’,n:’Barrick Gold’,e:’TSX’},{s:’MFC.TO’,n:’Manulife Financial’,e:’TSX’},{s:’SU.TO’,n:’Suncor Energy’,e:’TSX’},
{s:’TRI.TO’,n:’Thomson Reuters’,e:’TSX’},{s:’ATD.TO’,n:’Alimentation Couche-Tard’,e:’TSX’},{s:’L.TO’,n:’Loblaw Companies’,e:’TSX’},
{s:’DOL.TO’,n:’Dollarama Inc.’,e:’TSX’},{s:’WPM.TO’,n:’Wheaton Precious Metals’,e:’TSX’},{s:’AEM.TO’,n:’Agnico Eagle Mines’,e:’TSX’},
{s:’CCO.TO’,n:’Cameco Corporation’,e:’TSX’},{s:’SLF.TO’,n:’Sun Life Financial’,e:’TSX’},{s:’FFH.TO’,n:’Fairfax Financial’,e:’TSX’},
];
function fx(p){ return CUR===’CAD’ ? +(p*CADR).toFixed(2) : +p.toFixed(2); }
function fp(p){ return ‘$’+fx(p).toFixed(2)+(CUR===’CAD’?’ CAD’:’ USD’); }
function fv(n){ if(!n)return’—’;if(n>1e9)return(n/1e9).toFixed(1)+’B’;if(n>1e6)return(n/1e6).toFixed(1)+’M’;if(n>1e3)return(n/1e3).toFixed(1)+’K’;return”+n; }
async function fetchRate(){
if(!AV) return;
try{
const r = await fetch(‘
https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=USD&to_currency=CAD&apikey=’+AV);
const d = await r.json();
const rate = parseFloat(d[‘Realtime Currency Exchange Rate’]?.[‘5. Exchange Rate’]);
if(rate && !isNaN(rate)) CADR = rate;
}catch(e){}
}
async function fetchQ(sym){
if(!AV) return null;
try{
const r = await fetch(‘
https://www.alphavantage.co/query?function=GLOBAL_QUOTE&symbol=’+sym+’&apikey=’+AV);
const d = await r.json();
const q = d[‘Global Quote’];
if(!q||!q[’05. price’]) return null;
return{
name: sym, ex: sym.endsWith(‘.TO’)?’TSX’:’US’,
price: +parseFloat(q[’05. price’]).toFixed(2),
chg: +parseFloat(q[’09. change’]).toFixed(2),
pct: +parseFloat(q[’10. change percent’]).toFixed(2),
open: +parseFloat(q[’02. open’]).toFixed(2),
high: +parseFloat(q[’03. high’]).toFixed(2),
low: +parseFloat(q[’04. low’]).toFixed(2),
vol: fv(parseInt(q[’06. volume’])),
high52: +parseFloat(q[’03. high’]).toFixed(2),
low52: +parseFloat(q[’04. low’]).toFixed(2)
};
}catch(e){ return null; }
}
async function fetchHist(sym){
if(!AV) return null;
try{
const r = await fetch(‘
https://www.alphavantage.co/query?function=TIME_SERIES_DAILY&symbol=’+sym+’&outputsize=compact&apikey=’+AV);
const d = await r.json();
const ts = d[‘Time Series (Daily)’];
if(!ts) return null;
const e = Object.entries(ts).slice(0,100).reverse();
return{ prices: e.map(x=>+parseFloat(x[1][‘4. close’]).toFixed(2)), labels: e.map(x=>x[0]) };
}catch(e){ return null; }
}
async function fetchRSI(sym){
if(!AV) return null;
try{
const r = await fetch(‘
https://www.alphavantage.co/query?function=RSI&symbol=’+sym+’&interval=daily&time_period=14&series_type=close&apikey=’+AV);
const d = await r.json();
const v = d[‘Technical Analysis: RSI’];
if(!v) return null;
return parseFloat(Object.values(v)[0][‘RSI’]).toFixed(1);
}catch(e){ return null; }
}
async function fetchMACD(sym){
if(!AV) return null;
try{
const r = await fetch(‘
https://www.alphavantage.co/query?function=MACD&symbol=’+sym+’&interval=daily&series_type=close&apikey=’+AV);
const d = await r.json();
const v = d[‘Technical Analysis: MACD’];
if(!v) return null;
const e = Object.values(v)[0];
return{ macd: parseFloat(e[‘MACD’]).toFixed(3), signal: parseFloat(e[‘MACD_Signal’]).toFixed(3) };
}catch(e){ return null; }
}
async function getAI(sym, q, rsi, macd, hist){
if(CL){
try{
const recent = hist ? hist.prices.slice(-20).join(‘, ‘) : ‘N/A’;
const prompt = ‘You are a financial analyst AI. Analyze and respond ONLY with valid JSON, no markdown.\n\nStock: ‘+sym+’\nPrice: $’+q.price+’\nChange: ‘+q.chg+’ (‘+q.pct+’%)\nRSI(14): ‘+rsi+’\nMACD: ‘+(macd?macd.macd:’N/A’)+’ Signal: ‘+(macd?macd.signal:’N/A’)+’\nRecent 20-day closes: ‘+recent+’\n\nJSON format:\n{“signal”:”BUY”|”SELL”|”HOLD”,”confidence”:0-100,”reason”:”2-3 sentence analysis”,”predictions”:{“today”:number,”tomorrow”:number,”week”:number,”month”:number,”quarter”:number,”year”:number},”rsi_signal”:”Oversold”|”Neutral”|”Overbought”,”macd_signal”:”Bullish”|”Bearish”|”Neutral”,”trend”:”Uptrend”|”Downtrend”|”Sideways”}’;
const resp = await fetch(‘
https://api.anthropic.com/v1/messages’,{
method:’POST’,
headers:{‘Content-Type’:’application/json’,’x-api-key’:CL,’anthropic-version’:’2023-06-01′},
body:JSON.stringify({model:’claude-sonnet-4-20250514′,max_tokens:800,messages:[{role:’user’,content:prompt}]})
});
const data = await resp.json();
const txt = data.content[0].text.replace(/“`json|“`/g,”).trim();
return JSON.parse(txt);
}catch(e){}
}
return localSig(q, rsi, macd);
}
function localSig(q, rsi, macd){
const r = parseFloat(rsi)||50;
const bull = parseFloat((macd&&macd.macd)||0) > parseFloat((macd&&macd.signal)||0);
const score = (r<35?3:r70?-3:r>60?-1:0)+(bull?2:-2)+(q.chg>=0?1:-1);
const sig = score>=3?’BUY’:score=0?1:-1; const p = q.price;
return{
signal:sig, confidence:Math.min(91,58+Math.abs(score)*5),
reason:’RSI at ‘+r+(r65?’ is overbought, caution advised.’:’ is neutral.’)+’ MACD is ‘+(bull?’bullish, supporting buying interest.’:’bearish, indicating selling pressure.’)+’ Price is ‘+(q.chg>=0?’up today, adding momentum.’:’down today, showing weakness.’),
predictions:{
today:+(p*(1+t*0.003+Math.random()*0.005-0.002)).toFixed(2),
tomorrow:+(p*(1+t*0.007+Math.random()*0.01-0.004)).toFixed(2),
week:+(p*(1+t*0.022+Math.random()*0.025-0.01)).toFixed(2),
month:+(p*(1+t*0.055+Math.random()*0.05-0.02)).toFixed(2),
quarter:+(p*(1+t*0.12+Math.random()*0.12-0.04)).toFixed(2),
year:+(p*(1+t*0.26+Math.random()*0.25-0.08)).toFixed(2)
},
rsi_signal:r65?’Overbought’:’Neutral’,
macd_signal:bull?’Bullish’:’Bearish’,
trend:q.chg>=0?’Uptrend’:’Downtrend’
};
}
async function load(sym){
if(!AV){
const k = prompt(‘Enter your Alpha Vantage API key to load live data (free at alphavantage.co):’);
if(k){ AV=k.trim(); localStorage.setItem(‘spp_av’,AV); fetchRate(); }
else return;
}
SYM=sym; renderWL(); updWBtn(); showSkel(sym);
const [q,hist,rsi,macd] = await Promise.all([fetchQ(sym),fetchHist(sym),fetchRSI(sym),fetchMACD(sym)]);
if(!q){
document.getElementById(‘sai-main’).innerHTML=’
Could not load ‘+sym+’. Check your API key or try another ticker.
‘;
return;
}
const ai = await getAI(sym,q,rsi,macd,hist);
CD={sym,q,hist,rsi,macd,ai};
renderFull(sym,q,hist,rsi,macd,ai);
}
function showSkel(sym){
document.getElementById(‘sai-main’).innerHTML=
‘
‘+
‘
Fetching live data and running AI analysis…
‘+
‘
‘;
}
function renderFull(sym,q,hist,rsi,macd,ai){
const sc=ai.signal===’BUY’?’sbuy’:ai.signal===’SELL’?’ssell’:’shold’;
const sc2=ai.signal===’BUY’?’#10b981′:ai.signal===’SELL’?’#ef4444′:’#f59e0b’;
const rn=parseFloat(rsi)||50;
const mb=parseFloat((macd&&macd.macd)||0)>parseFloat((macd&&macd.signal)||0);
const isTSX=sym.endsWith(‘.TO’);
const preds=[
{l:’Today close’,v:ai.predictions.today},{l:’Tomorrow’,v:ai.predictions.tomorrow},
{l:’Next week’,v:ai.predictions.week},{l:’Next month’,v:ai.predictions.month},
{l:’Next quarter’,v:ai.predictions.quarter},{l:’Next year’,v:ai.predictions.year}
];
const inR=q.high52>q.low52?((q.price-q.low52)/(q.high52-q.low52)*100).toFixed(0):’50’;
let h=’
‘+sym+’
‘;
h+=’
‘+(q.name||sym)+’ · ‘+(q.ex||”)+
‘
‘;
h+=’
‘+fp(q.price)+’
‘;
h+=’
=0?’up’:’dn’)+’”>’+(q.chg>=0?’+’:”)+fx(q.chg).toFixed(2)+’ (‘+q.pct+’%)
‘;
if(CUR===’CAD’&&!isTSX) h+=’
USD ‘+q.price.toFixed(2)+’ × ‘+CADR.toFixed(4)+’
‘;
h+=’
Live · 15min delay
‘;
h+=’
‘+ai.signal+’
‘;
h+=’
Confidence: ‘+ai.confidence+’%
‘;
h+=’
‘;
h+=’
‘+ai.reason+(CL?’ · Claude AI‘:”)+’
‘;
h+=’
‘;
h+=’
Open
‘+fp(q.open||q.price)+’
‘;
h+=’
High / Low
‘+fp(q.high||q.price)+’ / ‘+fp(q.low||q.price)+’
‘;
h+=’
‘;
h+=’
52W Range
‘+fp(q.low52)+’ – ‘+fp(q.high52)+’
‘;
h+=’
Price history (‘+CUR+’)‘;
h+=’
‘;
h+=’
‘;
h+=’
AI price predictions (‘+CUR+’)
‘;
preds.forEach(p=>{
const diff=(p.v-q.price)/q.price*100;
const up=diff>=0;
h+=’
‘+p.l+’
‘+fp(p.v)+’
‘;
h+=’
‘+(up?’+’:”)+diff.toFixed(2)+’%
‘;
h+=’
‘;
});
h+=’
Technical indicators
‘;
h+=’
RSI (14)
<div class="ival" style="color:'+(rn65?’#ef4444′:’var(–text)’)+’”>’+rn+’
<div class="ipill '+(rn65?’pbear’:’pneu’)+’”>’+ai.rsi_signal+’
‘;
h+=’