{"id":76669,"date":"2026-10-27T23:27:47","date_gmt":"2026-10-27T23:27:47","guid":{"rendered":"https:\/\/www.stocktargetadvisor.com\/blog\/?page_id=76669"},"modified":"2026-10-28T05:22:28","modified_gmt":"2026-10-28T05:22:28","slug":"stock-research-tool","status":"publish","type":"page","link":"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/","title":{"rendered":"Stock Analysis Tool"},"content":{"rendered":"<p>Research U.S. and Canadian stocks using published analyst sentiment, market context, financial statements and source-linked firm ratings. Availability varies by listing.<\/p>\n<div id=\"sta-target-tool\"><style>#sta-target-tool{max-width:1100px;margin:0 auto 60px;color:#17324e;font:16px\/1.65 system-ui,sans-serif}#sta-target-tool *{box-sizing:border-box}#sta-target-tool .hero{background:linear-gradient(120deg,#0d2039,#15548b);color:#fff;padding:38px;border-radius:16px}#sta-target-tool h2{color:inherit;font-size:34px;line-height:1.2;margin:12px 0}#sta-target-tool h3{color:inherit}#sta-target-tool .tag{font-size:12px;letter-spacing:.13em;text-transform:uppercase;font-weight:800}#sta-target-tool .panel{padding:26px;border:1px solid #d8e2eb;border-radius:12px;margin-top:22px;background:#f6f9fc}#sta-target-tool label{display:block;font-weight:700;margin:12px 0 5px}#sta-target-tool input,#sta-target-tool select{width:100%;padding:12px;border:1px solid #adc0d0;border-radius:7px;background:#fff;font:inherit}#sta-target-tool button{padding:12px 19px;background:#1068ab;color:#fff;border:0;border-radius:7px;cursor:pointer;font:inherit;font-weight:700;margin-top:15px}#sta-target-tool button:disabled{opacity:.6}#sta-target-tool .row{display:grid;grid-template-columns:1fr 1fr;gap:20px}#sta-target-tool .metrics{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}#sta-target-tool .metric{padding:20px;background:white;border:1px solid #d8e2eb;border-radius:10px}#sta-target-tool .metric strong{display:block;font-size:25px;margin:10px 0}#sta-target-tool .small{font-size:13px;color:#526c80}#sta-target-tool .scroll{overflow:auto}#sta-target-tool table{width:100%;border-collapse:collapse;font-size:14px}#sta-target-tool th,#sta-target-tool td{padding:12px;text-align:left;vertical-align:top;border-bottom:1px solid #d8e2eb}#sta-target-tool a{color:#065d9f;text-decoration:underline}#sta-target-tool summary{font-weight:700;cursor:pointer}#sta-target-tool [hidden]{display:none!important}@media(max-width:650px){#sta-target-tool .row,#sta-target-tool .metrics{grid-template-columns:1fr}#sta-target-tool .hero{padding:24px}}#sta-target-tool #stat-results{padding:0;border:0;background:transparent}#sta-target-tool .dash-heading{display:flex;justify-content:space-between;align-items:center;gap:20px;background:linear-gradient(125deg,#071e36,#145489);padding:30px 32px;color:#fff;border-radius:16px;margin-bottom:18px}#sta-target-tool .dash-heading h2{font-size:46px;margin:9px 0 2px;letter-spacing:-1px}#sta-target-tool .dash-heading p{margin:0;color:#c4d9ec}#sta-target-tool .dash-eyebrow{font-size:10px;font-weight:800;letter-spacing:.16em;color:#a9cfef}#sta-target-tool .dash-badge{border:1px solid #ffffff38;background:#ffffff12;border-radius:10px;text-align:right;padding:12px 18px;font-size:20px;font-weight:800}#sta-target-tool .dash-badge span{display:block;font-size:11px;font-weight:500;color:#c4d9ec}#sta-target-tool .dash-kpis{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-bottom:18px}#sta-target-tool .dash-kpi{padding:20px 17px;background:#fff;border:1px solid #dde6ef;border-top:3px solid #1478e8;border-radius:10px;box-shadow:0 5px 18px #123c6208}#sta-target-tool .dash-kpi>span{font-size:11px;text-transform:uppercase;letter-spacing:.06em;font-weight:750;color:#526c80}#sta-target-tool .dash-kpi strong{display:block;font-size:25px;color:#102f4d;letter-spacing:-.6px;margin:8px 0;line-height:1.25;overflow-wrap:anywhere}#sta-target-tool .dash-kpi small{display:block;font-size:11px;color:#647b8c}#sta-target-tool .dash-grid{display:grid;grid-template-columns:1fr 1fr;gap:18px;margin:18px 0}#sta-target-tool .dash-card{border:1px solid #dde6ef;border-radius:12px;background:white;padding:22px;min-width:0}#sta-target-tool .dash-section-head{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:15px}#sta-target-tool .dash-section-head h3{margin:0;font-size:18px;line-height:1.3}#sta-target-tool .dash-section-head>span{font-size:10px;letter-spacing:.07em;color:#60788b;font-weight:750;background:#edf4fa;border-radius:5px;padding:4px 7px}#sta-target-tool .dash-muted{font-size:11px;color:#60788b;line-height:1.6;margin:12px 0 0}#sta-target-tool .dash-range{position:relative;height:40px;margin:24px 0 10px}#sta-target-tool .dash-range-track{position:absolute;left:8%;right:8%;height:8px;top:16px;border-radius:8px;background:linear-gradient(90deg,#d7e8fa,#1478e8)}#sta-target-tool .dash-dot{position:absolute;top:10px;width:20px;height:20px;border:3px solid white;box-shadow:0 0 0 1px #9db8d0;border-radius:50%;transform:translateX(-50%)}#sta-target-tool .dash-dot-mean{background:#1478e8;z-index:2}#sta-target-tool .dash-dot-median{background:#123858;top:29px;width:11px;height:11px;border-width:2px}#sta-target-tool .dash-range-labels{display:flex;justify-content:space-between;gap:8px}#sta-target-tool .dash-range-labels>span{font-size:9px;letter-spacing:.08em;color:#60788b}#sta-target-tool .dash-range-labels strong{display:block;font-size:16px;color:#123858;letter-spacing:0;margin-top:4px}#sta-target-tool .dash-sentiment{display:flex;height:30px;border-radius:7px;overflow:hidden;margin:26px 0 18px;background:#edf2f7}#sta-target-tool .dash-sentiment span{display:flex;align-items:center;justify-content:center;color:white;font-weight:800;font-size:12px}#sta-target-tool .green{background:#14966c}#sta-target-tool .red{background:#d65360}#sta-target-tool .slate{background:#7b91a6}#sta-target-tool .blue{background:#1478e8}#sta-target-tool .navy{background:#123858}#sta-target-tool .dash-key{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px}#sta-target-tool .dash-votes{display:grid;grid-template-columns:repeat(3,1fr);gap:10px}#sta-target-tool .dash-votes>span{font-size:11px;color:#60788b}#sta-target-tool .dash-votes strong{display:block;font-size:21px;color:#17324e;margin:3px 0}#sta-target-tool .dash-votes small{font-size:11px;color:#60788b;font-weight:500}#sta-target-tool .dash-coverage{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:25px;padding:22px 26px;border:1px solid #d8e6f3;background:#edf5fc;border-radius:12px}#sta-target-tool .dash-coverage>div>span{display:block;font-size:11px;color:#526c80}#sta-target-tool .dash-coverage strong{display:block;font-size:24px;color:#123858;margin:4px 0}#sta-target-tool .dash-coverage small{display:block;font-size:10px;color:#60788b}#sta-target-tool .dash-meter{height:5px;background:#ceddeb;border-radius:5px;overflow:hidden;margin-top:11px}#sta-target-tool .dash-meter>span{display:block;height:100%;background:#1478e8}#sta-target-tool .dash-history{width:100%;height:auto;display:block}#sta-target-tool .dash-history text{font:11px system-ui;fill:#60788b}#sta-target-tool .dash-revisions{font-size:12px}#sta-target-tool .dash-revisions th,#sta-target-tool .dash-revisions td{padding:10px 5px;white-space:nowrap}#sta-target-tool .dash-positive{color:#0b8059;font-weight:800}#sta-target-tool .dash-negative{color:#be3d4b;font-weight:800}#sta-target-tool .dash-audit{margin:18px 0;font-size:12px}#sta-target-tool .sta-published-analysis{padding:26px;background:#f5f9fd;border:1px solid #dce6ef;border-radius:14px;margin:22px 0}#sta-target-tool .sta-published-analysis>.metric strong,#sta-target-tool .sta-published-analysis li strong{display:inline;font-size:15px}#sta-target-tool .sta-published-analysis li{font-size:13px;margin-bottom:14px;line-height:1.65}#sta-target-tool .sta-published-analysis h3{margin-top:0}#sta-target-tool .sta-scorecard .metrics{grid-template-columns:1fr 1fr}#sta-target-tool details.dash-card{margin:18px 0}#sta-target-tool .hero{padding:28px 32px}#sta-target-tool .hero p{margin-bottom:0}#sta-target-tool .panel#stat-form{background:#f6f9fc}#sta-target-tool .dash-heading+.dash-kpis{margin-top:0}@media(max-width:760px){#sta-target-tool .dash-kpis{grid-template-columns:1fr 1fr}#sta-target-tool .dash-grid{grid-template-columns:1fr}#sta-target-tool .dash-coverage{grid-template-columns:1fr;gap:16px}#sta-target-tool .dash-heading{padding:24px}#sta-target-tool .dash-heading h2{font-size:36px}#sta-target-tool .dash-card{padding:18px}#sta-target-tool .dash-kpi strong{font-size:22px}#sta-target-tool .sta-published-analysis{padding:18px}#sta-target-tool .sta-scorecard .metrics{grid-template-columns:1fr}}<\/style>\n<section class=\"hero\"><span class=\"tag\">STA Research \u00b7 Published-source consensus<\/span><h2>STA Target Tool<\/h2><p>Ask about a stock\u2019s target and analyst outlook. Explore ratings compiled from STA\u2019s published research, with a source for every record.<\/p><\/section>\n<form class=\"panel\" id=\"stat-form\"><label for=\"stat-question\">Your question or ticker<\/label><input id=\"stat-question\" placeholder=\"What is the target for Tesla stock?\" maxlength=\"180\" required><p class=\"small\">Enter a company, ticker or simple stock question. Choose a listing when names overlap; add :CA for Canada. Search uses company and ticker matching, not generative AI.<\/p><div><label for=\"stat-days\">Ratings lookback<\/label><select id=\"stat-days\"><option value=\"90\" selected>90 days \u2014 recent updates<\/option><option value=\"180\">180 days<\/option><option value=\"365\">12 months<\/option><\/select><\/div><button id=\"stat-submit\">Find Target<\/button><p id=\"stat-status\" role=\"status\" aria-live=\"polite\"><\/p><\/form>\n<section id=\"stat-results\" class=\"panel\" hidden aria-label=\"Search results\"><\/section>\n<details class=\"panel\"><summary>Coverage and calculation method<\/summary><p id=\"stat-coverage\">Loading local index status\u2026<\/p><p>The index scans published STA posts and pages. It extracts explicit company\/ticker\/firm rating sentences and clearly labelled ratings tables. Narrative-only forecasts, unrecognised layouts, ambiguous targets and Weiss Ratings are excluded. Each source is refreshed when it is edited or unpublished.<\/p><p>One latest recognised rating and one latest valid target per firm are used within the selected lookback. A newer rating-only update can retain that firm\u2019s earlier target, with its own date shown. Withdrawn coverage blocks older values. Duplicates are removed; conflicting values on the same report date are excluded. Broker-brand aliases are normalised where known. Different listings and currencies are never averaged together. Ticker plus listing is the primary identifier; the company name is a secondary display label. Company-name differences are flagged for review and do not change the ticker assignment. Currency remains separate for each calculation.<\/p><p>Dates use the date in the report title when available; otherwise the publication date, labelled as such. Figures remain historical observations. The tool does not adjust old targets for stock splits or currency conversions. The selected lookback is not proof that a target remains active.<\/p><p>Calculations use all available valid values within the selected window, taking each firm\u2019s latest rating and latest target once. The default is 90 days to emphasise recent updates. Mean target is a simple arithmetic average. A single-firm target or rating is shown as such, not described as a consensus; small samples are labelled. No value is invented when none is available. The analyst score maps Strong Buy to 5; Buy, Outperform, Overweight and Positive to 4; Hold, Neutral, Market Perform, Sector Perform and Equal Weight to 3; Underperform, Underweight and Reduce to 2; Sell and Strong Sell to 1. Unsupported ratings are displayed but not scored. Scores of 4.5+, 3.5+, 2.5+, 1.5+ and below 1.5 map to Strong Buy, Buy, Hold, Underperform and Sell.<\/p><p>No live stock-price feed is connected. Analyst targets are forecasts, not guaranteed returns.<\/p><\/details><\/div>\n<script>(function(){'use strict';const root=document.getElementById('sta-target-tool');if(!root)return;const api=\"https:\\\/\\\/www.stocktargetadvisor.com\\\/blog\\\/wp-json\\\/sta-target\\\/v1\\\/\",$=s=>root.querySelector(s),out=$('#stat-results'),status=$('#stat-status');let last=null;const esc=s=>String(s==null?'':s).replace(\/[&<>\"']\/g,c=>({'&':'&amp;','<':'&lt;','>':'&gt;','\"':'&quot;',\"'\":'&#39;'}[c]));const money=(n,c)=>n==null?'\u2014':new Intl.NumberFormat('en-CA',{style:'currency',currency:c}).format(n);async function get(path){const response=await fetch(api+path,{credentials:'same-origin'});const data=await response.json();if(!response.ok)throw Error(data.message||'Search is unavailable.');return data}function coverage(s){return(s.complete?'Index build complete':'Index build in progress')+' \u00b7 '+(s.scanned||0)+' published pages scanned \u00b7 '+(s.sources||0)+' source pages with extracted records \u00b7 '+(s.records||0)+' stored records.'}get('status').then(s=>$('#stat-coverage').textContent=coverage(s)).catch(()=>$('#stat-coverage').textContent='Local index status is unavailable.');function record(r,field,c){if(!r)return'\u2014';return'<strong>'+esc(field==='target'?money(r.target,c):r.rating)+'<\/strong><br><span class=\"small\">'+esc(r.report_date)+' \u00b7 '+esc(r.date_basis)+'<\/span><br><span class=\"small\">Source label: '+esc(r.company)+'<\/span><br><a href=\"'+esc(r.source_url)+'\" target=\"_blank\" rel=\"noopener\">Source<\/a><details><summary>Evidence<\/summary>'+esc(r.evidence)+'<\/details>'}function analystScorecard(d,ret){const scored=d.firms.filter(f=>f.rating_record&&f.rating_record.rating_score!=null),bull=scored.filter(f=>Number(f.rating_record.rating_score)>=4).length,bear=scored.filter(f=>Number(f.rating_record.rating_score)<=2).length,neutral=scored.length-bull-bear,n=scored.length,balance=n?(bull-bear)\/n:null,label=balance==null?'Insufficient data':balance>=0.6?'Bullish':balance>=0.2?'Slightly Bullish':balance<=-0.6?'Bearish':balance<=-0.2?'Slightly Bearish':'Neutral';const good=[],bad=[],notes=[];if(bull)good.push(bull+' of '+n+' rated firms have a Buy-equivalent or stronger outlook.');if(bear)bad.push(bear+' of '+n+' rated firms have an Underperform-equivalent or weaker outlook.');if(neutral)notes.push(neutral+' of '+n+' rated firms have a Hold-equivalent outlook.');if(d.target_count>=2&&d.average>0){const spread=100*(d.high-d.low)\/d.average;if(spread>=40)bad.push('Targets are widely dispersed: the high-to-low spread is '+spread.toFixed(1)+'% of the average, indicating substantial disagreement.');else notes.push('The high-to-low target spread is '+spread.toFixed(1)+'% of the average; this describes agreement, not forecast accuracy.');}if(n<3)notes.push(n===1?'Only one rated firm is available; this is not a consensus.':'Fewer than three rated firms are available; sentiment has limited coverage.');if(d.target_count<3)notes.push(d.target_count+' target firm'+(d.target_count===1?'':'s')+' available; the target estimate has limited coverage.');const dates=d.firms.flatMap(f=>[f.rating_record,f.target_record]).filter(Boolean).map(r=>r.report_date).sort();if(dates.length){const age=Math.floor((Date.now()-Date.parse(dates[dates.length-1]+'T00:00:00Z'))\/86400000);if(age>60)notes.push('The newest included record is more than 60 days old.');}if(d.identity_excluded)notes.push('Source company-name variations are flagged below; check the evidence against the ticker.');if(d.conflicts_excluded)notes.push(d.conflicts_excluded+' conflicting fields were excluded.');const list=(items,empty)=>'<ul>'+ (items.length?items.map(t=>'<li>'+esc(t)+'<\/li>').join(''):'<li>'+empty+'<\/li>')+'<\/ul>';return '<section aria-label=\"Bullish and bearish analyst scorecard\" class=\"sta-scorecard\"><h3>Analyst Sentiment<\/h3><p><strong>'+label+'<\/strong>'+(balance==null?'':' \u00b7 Balance score '+(balance>0?'+':'')+(balance*100).toFixed(0)+' \/ 100')+'<\/p><p>'+bull+' bullish \u00b7 '+neutral+' neutral \u00b7 '+bear+' bearish analyst ratings<\/p><div class=\"metrics\"><div class=\"metric\"><h4>What to like<\/h4>'+list(good,'No bullish factors identified in the available analyst data.')+'<\/div><div class=\"metric\"><h4>What not to like<\/h4>'+list(bad,'No bearish factors identified in the available analyst data. This does not mean the stock has no risks.')+'<\/div><\/div><h4>Coverage and context<\/h4>'+list(notes,'See the dated source records below.')+'<details><summary>How this sentiment is calculated<\/summary><p>One latest rating per firm in the selected lookback. Buy, Outperform and Overweight equivalents count as bullish; Hold equivalents as neutral; Underperform and Sell equivalents as bearish. Balance = (bullish firms \u2212 bearish firms) \u00f7 all scored firms \u00d7 100. Scores of +60 or higher are Bullish; +20 to below +60 Slightly Bullish; above \u221220 to below +20 Neutral; above \u221260 to \u221220 Slightly Bearish; \u221260 or lower Bearish. Target upside and target dispersion are context only and do not change this rating.<\/p><p>This is an analyst-data scorecard inspired by STA\u2019s earlier presentation, not the legacy fundamental score. Cash flow, profitability, valuation, debt and technical trends are not assessed here. Missing inputs are not treated as positive or negative. Small samples can produce extreme scores. This is not a buy or sell recommendation.<\/p><\/details><\/section>';}function dashboard(d,ret,price,date){const z=d.dashboard||{history:[],windows:[],source_count:0,latest:null,firms:d.firms.length},ratings=d.firms.map(f=>f.rating_record).filter(Boolean),bull=ratings.filter(r=>r.rating_score>=4).length,bear=ratings.filter(r=>r.rating_score<=2).length,neutral=ratings.length-bull-bear,n=ratings.length,span=d.average>0?100*(d.high-d.low)\/d.average:null,coveragePct=z.firms?Math.round(100*d.target_count\/z.firms):0,latest=z.latest||'Unavailable',head='<div class=\"dash-heading\"><div><span class=\"dash-eyebrow\">STA RESEARCH \/ STOCK INTELLIGENCE<\/span><h2>'+esc(d.symbol)+'<\/h2><p>'+esc(d.company)+'<\/p><\/div><div class=\"dash-badge\">'+esc(d.currency)+'<span>'+d.days+'-day lookback<\/span><\/div><\/div>',kpi=(name,value,sub)=>'<div class=\"dash-kpi\"><span>'+name+'<\/span><strong>'+value+'<\/strong><small>'+sub+'<\/small><\/div>';let range='<p class=\"dash-muted\">No valid target values in this window.<\/p>';if(d.average!=null){const pos=v=>d.high===d.low?50:8+84*(v-d.low)\/(d.high-d.low);range='<div class=\"dash-range\" role=\"img\" aria-label=\"Target range '+money(d.low,d.currency)+' to '+money(d.high,d.currency)+', mean '+money(d.average,d.currency)+', median '+money(d.median,d.currency)+'\"><div class=\"dash-range-track\"><\/div><span class=\"dash-dot dash-dot-mean\" style=\"left:'+pos(d.average)+'%\" title=\"Mean '+money(d.average,d.currency)+'\"><\/span><span class=\"dash-dot dash-dot-median\" style=\"left:'+pos(d.median)+'%\" title=\"Median '+money(d.median,d.currency)+'\"><\/span><\/div><div class=\"dash-range-labels\"><span>LOW<strong>'+money(d.low,d.currency)+'<\/strong><\/span><span>MEDIAN<strong>'+money(d.median,d.currency)+'<\/strong><\/span><span>HIGH<strong>'+money(d.high,d.currency)+'<\/strong><\/span><\/div><p class=\"dash-muted\"><i class=\"dash-key blue\"><\/i> Mean <i class=\"dash-key navy\"><\/i> Median \u00b7 '+d.target_count+' target firm'+(d.target_count===1?' \u2014 single firm, not a consensus':'s')+'<\/p>';}\nconst sentiment=n?'<div class=\"dash-sentiment\" role=\"img\" aria-label=\"'+bull+' bullish, '+neutral+' neutral and '+bear+' bearish firms\">'+[[bull,'green'],[neutral,'slate'],[bear,'red']].map(([v,c])=>v?'<span class=\"'+c+'\" style=\"width:'+(100*v\/n)+'%\" title=\"'+v+' firms\">'+(100*v\/n>=12?v:'')+'<\/span>':'').join('')+'<\/div><div class=\"dash-votes\">'+[['Bullish',bull,'green'],['Neutral',neutral,'slate'],['Bearish',bear,'red']].map(([label,v,c])=>'<span><i class=\"dash-key '+c+'\"><\/i>'+label+'<strong>'+v+' <small>'+Math.round(100*v\/n)+'%<\/small><\/strong><\/span>').join('')+'<\/div>':'<p class=\"dash-muted\">No scored analyst ratings available.<\/p>';\nlet history='<p class=\"dash-muted\">At least two dated target snapshots are needed for a history chart.<\/p>';const h=z.history||[];if(h.length>=2){const vals=h.map(p=>p.average),lo=Math.min(...vals),hi=Math.max(...vals),pad=(hi-lo)*0.2||Math.max(1,hi*0.04),bottom=lo-pad,top=hi+pad,t0=Date.parse(h[0].date),t1=Date.parse(h[h.length-1].date),x=p=>66+550*(Date.parse(p.date)-t0)\/(t1-t0||1),y=p=>180-145*(p.average-bottom)\/(top-bottom),points=h.map(p=>x(p)+','+y(p)).join(' ');history='<svg class=\"dash-history\" viewBox=\"0 0 660 230\" role=\"img\" aria-label=\"Available target average history in '+esc(d.currency)+'\"><title>Article-derived target snapshots. Firm coverage changes over time.<\/title>'+[bottom,(top+bottom)\/2,top].map(v=>{const yy=180-145*(v-bottom)\/(top-bottom);return '<line x1=\"66\" y1=\"'+yy+'\" x2=\"616\" y2=\"'+yy+'\" stroke=\"#e2e8f0\"\/><text x=\"58\" y=\"'+(yy+4)+'\" text-anchor=\"end\">'+v.toFixed(0)+'<\/text>'}).join('')+'<polyline points=\"'+points+'\" fill=\"none\" stroke=\"#1478e8\" stroke-width=\"3\"\/>'+h.map(p=>'<circle cx=\"'+x(p)+'\" cy=\"'+y(p)+'\" r=\"4\" fill=\"#1478e8\"><title>'+esc(p.date)+' \u00b7 '+money(p.average,d.currency)+' \u00b7 '+p.firms+' firms<\/title><\/circle>').join('')+'<text x=\"66\" y=\"211\">'+esc(h[0].date)+'<\/text><text x=\"616\" y=\"211\" text-anchor=\"end\">'+esc(h[h.length-1].date)+'<\/text><\/svg><details><summary>View exact snapshots<\/summary><table><thead><tr><th>Date<\/th><th>Mean target<\/th><th>Firms<\/th><\/tr><\/thead><tbody>'+h.map(p=>'<tr><td>'+esc(p.date)+'<\/td><td>'+money(p.average,d.currency)+'<\/td><td>'+p.firms+'<\/td><\/tr>').join('')+'<\/tbody><\/table><\/details>';}\nconst activity=(z.windows||[]).map(w=>'<tr><th>'+w.days+'d<\/th><td class=\"dash-positive\">'+w.target_up+'<\/td><td class=\"dash-negative\">'+w.target_down+'<\/td><td class=\"dash-positive\">'+w.rating_up+'<\/td><td class=\"dash-negative\">'+w.rating_down+'<\/td><\/tr>').join('');return head+'<div class=\"dash-kpis\">'+kpi(d.target_count===1?'Single-firm target':'Average target',money(d.average,d.currency),d.target_count+' firms \u00b7 '+(d.target_count<3?'limited sample':'latest per firm'))+kpi('Analyst rating',esc(d.rating),d.rating_count+' firms'+(d.score!=null?' \u00b7 '+d.score.toFixed(2)+'\/5':''))+kpi('Latest update',esc(latest),z.source_count+' source articles in this window')+'<\/div><div class=\"dash-grid\"><section class=\"dash-card\"><div class=\"dash-section-head\"><h3>Target range<\/h3><span>'+esc(d.currency)+'<\/span><\/div>'+range+'<\/section><section class=\"dash-card\"><div class=\"dash-section-head\"><h3>Analyst sentiment<\/h3><span>'+n+' FIRMS<\/span><\/div>'+sentiment+'<p class=\"dash-muted\">Each firm counts once. Buy equivalents are bullish; Hold neutral; Underperform\/Sell bearish.<\/p><\/section><\/div><div class=\"dash-coverage\"><div><span>Firms with valid targets<\/span><strong>'+d.target_count+' \/ '+z.firms+'<\/strong><div class=\"dash-meter\"><span style=\"width:'+coveragePct+'%\"><\/span><\/div><\/div><div><span>Target dispersion<\/span><strong>'+(span==null?'Unavailable':span.toFixed(1)+'%')+'<\/strong><small>High\u2013low spread \u00f7 mean; not a confidence score<\/small><\/div><\/div><div class=\"dash-grid dash-history-grid\"><section class=\"dash-card\"><div class=\"dash-section-head\"><h3>Target history<\/h3><span>'+esc(d.currency)+'<\/span><\/div>'+history+'<p class=\"dash-muted\">Available mean target, not share price. Snapshots use only records within the selected lookback; changing coverage can move the average. Up to 12 dated snapshots.<\/p><\/section><section class=\"dash-card\"><div class=\"dash-section-head\"><h3>Observed revisions<\/h3><span>COUNT<\/span><\/div><div class=\"scroll\"><table class=\"dash-revisions\"><thead><tr><th>Window<\/th><th>Target \u2191<\/th><th>Target \u2193<\/th><th>Rating \u2191<\/th><th>Rating \u2193<\/th><\/tr><\/thead><tbody>'+activity+'<\/tbody><\/table><\/div><p class=\"dash-muted\">Counts explicit revision language when no prior value is available; otherwise compares consecutive values from the same firm within the selected lookback. Each firm\/date\/field counts once. Zero means none found in available records. Rating comparisons use the normalised scale.<\/p><\/section><\/div>';}\nlet marketSequence=0;\nfunction marketMessage(state){return ({not_configured:'Market context is not connected yet.',unsupported_listing:'Market context is not available for this Canadian listing.',access_denied:'This dataset is not included in the connected data plan.',authentication_failed:'The data connection needs attention.',rate_limited:'Market context is temporarily at its request limit. Please try again shortly.',busy:'Market context is being refreshed. Please try again shortly.',no_data:'No matching data was returned.',temporarily_unavailable:'Market context is temporarily unavailable.'})[state]||'Market context is unavailable.';}\nasync function loadMarketContext(symbol){\nconst sequence=++marketSequence,slot=$('#stat-market-context');if(!slot)return;\nslot.innerHTML='<section class=\"dash-card\" aria-label=\"Market context\"><h3>Market context<\/h3><p role=\"status\">Loading RSI and annual-report context\u2026<\/p><\/section>';\ntry{const m=await get('market-context?'+new URLSearchParams({symbol}));if(sequence!==marketSequence||!slot.isConnected||last.symbol!==symbol)return;\nif(m.state!=='ok'){slot.innerHTML='<section class=\"dash-card\" aria-label=\"Market context\"><h3>Market context<\/h3><p>'+esc(marketMessage(m.state))+'<\/p><\/section>';return;}\nconst r=m.rsi||{},f=m.filing||{};\nlet html='<section class=\"dash-card\" aria-label=\"Market context\"><h3>Technical momentum \u00b7 RSI<\/h3>';\nif(r.state==='ok'){\nconst v=Number(r.value),label=v>=70?'Overbought range':v<=30?'Oversold range':v>50?'Above the midpoint':v<50?'Below the midpoint':'At the midpoint';\nhtml+='<p><strong style=\"font-size:2rem\">'+v.toFixed(2)+'<\/strong> \/ 100 \u00b7 '+label+'<\/p><p>14 trading periods \u00b7 daily closing prices \u00b7 split adjusted \u00b7 data dated '+esc(r.date)+'<\/p><p class=\"small\">RSI measures price momentum. Readings above 70 or below 30 are conventional overbought or oversold levels; they do not establish fair value or predict a reversal.<\/p>';\n}else html+='<p>'+esc(marketMessage(r.state))+'<\/p>';\nhtml+='<h3>Company-reported risks \u00b7 10-K<\/h3>';\nif(f.state==='ok'){\nhtml+='<p>Filed '+esc(f.filing_date)+' \u00b7 reporting period ended '+esc(f.period_end)+'<\/p><details><summary>Read risk-factor excerpt<\/summary><p style=\"white-space:pre-line\">'+esc(f.excerpt)+'<\/p>'+(f.truncated?'<p>Excerpt shortened; see the filing for the full section.<\/p>':'')+'<\/details>';\nif(f.url&&\/^https:\\\/\\\/(www\\.)?sec\\.gov\\\/\/i.test(f.url))html+='<p><a href=\"'+esc(f.url)+'\" target=\"_blank\" rel=\"noopener noreferrer\">Read the original SEC filing<\/a><\/p>';\nhtml+='<p class=\"small\">Company disclosure text, not an STA risk rating. The filing date above shows its age.<\/p>';\n}else html+='<p>'+esc(marketMessage(f.state))+'<\/p>';\nhtml+='<p><strong>Financial statements<\/strong> appear below when supported. RSI and risk disclosures are separate from fundamental scoring.<\/p><p class=\"small\">Source: Massive REST API \u00b7 retrieved '+esc(m.retrieved_at)+' \u00b7 responses may be cached for up to six hours.<\/p><\/section>';\nslot.innerHTML=html;\n}catch(e){if(sequence===marketSequence&&slot.isConnected)slot.innerHTML='<section class=\"dash-card\"><h3>Market context<\/h3><p>Market context could not be loaded. Analyst results remain available.<\/p><\/section>';}\n}\n\nfunction fundamentalModel(d,now=Date.now()){\nconst p=d.periods||[],a=p[0],b=p[1],checks=[],groups=['Growth','Profitability','Cash generation','Financial strength'];\nconst unavailable=reason=>({available:false,reason,checks});\nif(d.currency!=='USD')return unavailable('The model currently supports USD statements only.');\nconst sic=String(d.sic||'');if(!\/^\\d{4}$\/.test(sic))return unavailable('Industry classification is missing; the general-company model has been withheld.');\nif((Number(sic)>=6000&&Number(sic)<7000)||(Number(sic)>=4900&&Number(sic)<5000))return unavailable('Financial, real-estate and utility companies need a sector-specific model. Their statement figures remain available below.');\nif(!a||!b)return unavailable('Two comparable annual periods are needed.');\nconst day=86400000,end=Date.parse(a.end+'T00:00:00Z'),oldEnd=Date.parse(b.end+'T00:00:00Z'),start=Date.parse(a.start+'T00:00:00Z'),oldStart=Date.parse(b.start+'T00:00:00Z');\nif(![end,oldEnd,start,oldStart].every(Number.isFinite)||end>now||now-end>550*day)return unavailable('The latest annual period is missing, invalid or too old for this model.');\nif(end-oldEnd<330*day||end-oldEnd>400*day||Math.abs((end-start)-(oldEnd-oldStart))>14*day)return unavailable('The annual periods are not sufficiently comparable.');\nconst val=(p,g,k)=>{const v=p?.statements?.[g]?.[k]?.value;return typeof v==='number'&&Number.isFinite(v)?v:null;},ratio=(x,y)=>x!==null&&y!==null&&y>0&&Number.isFinite(x\/y)?x\/y:null;\nconst add=(group,name,value,positive,negative,description,format='percent')=>checks.push({group,name,value,signal:value===null?null:positive(value)?1:negative(value)?-1:0,description,format});\nconst revenue=val(a,'income','revenue'),priorRevenue=val(b,'income','revenue'),eps=val(a,'income','eps'),priorEps=val(b,'income','eps'),profit=val(a,'income','net_income'),op=val(a,'income','operating_income'),assets=val(a,'balance','assets'),priorAssets=val(b,'balance','assets'),cfo=val(a,'cash_flow','operating_cash'),fcf=val(a,'cash_flow','free_cash_flow');\nadd('Growth','Revenue growth',ratio(revenue,priorRevenue)===null?null:revenue\/priorRevenue-1,x=>x>=0.05,x=>x<0,'At least 5%: positive; 0% to below 5%: neutral; below 0%: negative. Prior revenue must be positive.');\nadd('Growth','Diluted EPS growth',ratio(eps,priorEps)===null?null:eps\/priorEps-1,x=>x>=0.05,x=>x<0,'At least 5%: positive; 0% to below 5%: neutral; below 0%: negative. Prior EPS must be positive; loss-to-profit changes are left unscored.');\nadd('Profitability','Operating margin',ratio(op,revenue),x=>x>=0.10,x=>x<0,'Operating income \/ revenue. At least 10%: positive; 0% to below 10%: neutral; below 0%: negative.');\nadd('Profitability','Return on average assets',ratio(profit,assets!==null&&priorAssets!==null&&assets>0&&priorAssets>0?(assets+priorAssets)\/2:null),x=>x>=0.05,x=>x<0,'Net income \/ average of the two year-end total-assets figures. At least 5%: positive; 0% to below 5%: neutral; below 0%: negative.');\nconst equity=val(a,'balance','equity'),priorEquity=val(b,'balance','equity'),averageAssets=assets!==null&&priorAssets!==null&&assets>0&&priorAssets>0?(assets+priorAssets)\/2:null;\nadd('Profitability','Return on average equity',ratio(profit,equity!==null&&priorEquity!==null&&equity>0&&priorEquity>0?(equity+priorEquity)\/2:null),x=>x>=0.15,x=>x<0,'Net income \/ average year-end stockholders equity. At least 15%: positive; 0% to below 15%: neutral; below 0%: negative. Both equity balances must be positive. Buybacks and leverage can inflate this ratio.');\nadd('Profitability','Gross profit \/ average assets',ratio(val(a,'income','gross_profit'),averageAssets),x=>x>=0.20,x=>x<0,'Gross profit \/ average year-end total assets. At least 20%: positive; 0% to below 20%: neutral; below 0%: negative. This is an absolute threshold, not a peer ranking.');\nadd('Cash generation','Operating cash flow',cfo,x=>x>0,x=>x<0,'Positive operating cash flow is a positive factor; zero is neutral; negative operating cash flow is a negative factor.','usd');\nadd('Cash generation','Free cash flow',fcf,x=>x>0,x=>x<0,'Operating cash flow minus property, plant and equipment purchases. Positive is a positive factor; zero neutral; negative a negative factor.','usd');\nadd('Cash generation','Free-cash-flow margin',ratio(fcf,revenue),x=>x>=0.05,x=>x<0,'Operating cash flow minus property, plant and equipment purchases, divided by revenue. At least 5%: positive; 0% to below 5%: neutral; below 0%: negative.');\nadd('Cash generation','Cash conversion',ratio(cfo,profit),x=>x>=1,x=>x<0.8,'Operating cash flow \/ net income. At least 1.0x: positive; 0.8x to below 1.0x: neutral; below 0.8x: negative. Net income must be positive.','multiple');\nadd('Financial strength','Current ratio',ratio(val(a,'balance','current_assets'),val(a,'balance','current_liabilities')),x=>x>=1.5,x=>x<1,'Current assets \/ current liabilities. At least 1.5x: positive; 1.0x to below 1.5x: neutral; below 1.0x: negative.','multiple');\nadd('Financial strength','Liabilities \/ assets',ratio(val(a,'balance','liabilities'),assets),x=>x<=0.5,x=>x>0.7,'Total liabilities \/ total assets. Up to 50%: positive; above 50% to 70%: neutral; above 70%: negative. This includes all liabilities, not just debt.');\nconst covered=checks.filter(c=>c.signal!==null),categories=groups.map(name=>{const list=covered.filter(c=>c.group===name);return {name,count:list.length,balance:list.length?list.reduce((s,c)=>s+c.signal,0)\/list.length:null};});\nif(covered.length<9||categories.some(c=>!c.count))return unavailable('At least nine of twelve checks, including every category, are required. Available checks are shown without an overall score.');\nconst score=Math.round(50+50*categories.reduce((s,c)=>s+c.balance,0)\/4),label=score>=65?'Bullish':score<=35?'Bearish':'Neutral';\nreturn {available:true,score,label,checks,categories,covered:covered.length,end:a.end,start:a.start,previousEnd:b.end};\n}\nfunction fundamentalScorecard(d){\nconst m=fundamentalModel(d),tone=m.available?(m.label==='Bullish'?'#166534':m.label==='Bearish'?'#991b1b':'#475569'):'#475569',icon=m.available?(m.label==='Bullish'?'\ud83d\udc02':m.label==='Bearish'?'\ud83d\udc3b':'\u2696'):'\u2014';\nconst format=c=>c.value===null?'Unavailable':c.format==='usd'?new Intl.NumberFormat('en-US',{style:'currency',currency:'USD',notation:'compact',maximumFractionDigits:2}).format(c.value):c.format==='multiple'?c.value.toFixed(2)+'x':(100*c.value).toFixed(1)+'%',state=c=>c.signal===null?'Not scored':c.signal>0?'Positive':c.signal<0?'Negative':'Neutral';\nlet html='<section class=\"dash-card\" aria-label=\"STA fundamental score\"><h3>STA Fundamental Signal<\/h3><p style=\"font-size:1.7rem;color:'+tone+'\"><span aria-hidden=\"true\">'+icon+'<\/span> <strong>'+(m.available?m.label+' \u00b7 '+m.score+' \/ 100':'Score unavailable')+'<\/strong><\/p>';\nif(m.available)html+='<p>Based on the annual period ended '+esc(m.end)+' compared with '+esc(m.previousEnd)+' \u00b7 '+m.covered+' of 12 checks available.<\/p><div style=\"height:12px;background:#e2e8f0;border-radius:6px;overflow:hidden\" aria-hidden=\"true\"><div style=\"width:'+m.score+'%;height:100%;background:'+tone+'\"><\/div><\/div>';\nelse html+='<p>'+esc(m.reason)+'<\/p>';\nconst list=(sign,empty)=>{const rows=m.checks.filter(c=>c.signal===sign);return rows.length?'<ul style=\"list-style:none;padding-left:0\">'+rows.map(c=>'<li style=\"margin-bottom:14px\"><span aria-hidden=\"true\">'+(sign>0?'\ud83d\udc02':'\ud83d\udc3b')+'<\/span> <strong>'+esc(c.name)+': '+format(c)+'<\/strong><br><span class=\"small\">'+esc(c.description)+'<\/span><\/li>').join('')+'<\/ul>':'<p>'+empty+'<\/p>';};\nif(m.checks.length)html+='<div style=\"display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:24px\"><div><h4 style=\"color:#166534\">What to like<\/h4>'+list(1,'No positive checks identified in the available inputs.')+'<\/div><div><h4 style=\"color:#991b1b\">What not to like<\/h4>'+list(-1,'No negative checks identified; this does not establish the absence of risk.')+'<\/div><\/div><details><summary>All checks and calculation method<\/summary><div class=\"scroll\"><table style=\"width:100%\"><thead><tr><th>Category<\/th><th>Check<\/th><th>Value<\/th><th>Assessment<\/th><\/tr><\/thead><tbody>'+m.checks.map(c=>'<tr><td>'+esc(c.group)+'<\/td><td>'+esc(c.name)+'<\/td><td>'+format(c)+'<\/td><td>'+state(c)+'<\/td><\/tr>').join('')+'<\/tbody><\/table><\/div><ul>'+m.checks.map(c=>'<li><strong>'+esc(c.name)+':<\/strong> '+esc(c.description)+'<\/li>').join('')+'<\/ul><p>Each check is +1 positive, 0 neutral or \u22121 negative. Within each category, average the available checks. Each of the four categories has 25% weight. Score = 50 + 50 \u00d7 average category balance, rounded to a whole number. 65\u2013100 is Bullish, 36\u201364 Neutral, 0\u201335 Bearish. Missing inputs do not count as zero. At least nine of twelve checks and all four categories are required.<\/p><p>Growth, Profitability, Cash generation and Financial strength are assessed using STA-defined thresholds. These thresholds are not industry-relative benchmarks or a CFA Institute scoring methodology. The model excludes financial, real-estate and utility SIC groups and withholds scores when annual periods are more than 550 days old or not comparable.<\/p><p>This is a descriptive annual financial-health screen, not a valuation, price forecast or buy\/sell recommendation. It does not assess share price, quarterly developments, one-off accounting items or the complete filing notes. Analyst ratings and RSI do not contribute to this score.<\/p><\/details>';\nhtml+='<details><summary>Original STA factors and data coverage<\/summary><p>This version uses the original STA report as a basis: revenue growth, returns on equity and assets, gross profit relative to assets, positive cash flow and positive free cash flow. It adds profitability, earnings growth, liquidity and liabilities checks. Category weights keep related checks from gaining extra overall weight.<\/p><p>Not scored yet: market capitalization, risk-adjusted returns, dividend returns, capital utilization\/ROIC, volatility, total returns, and valuation relative to earnings, book value or cash flow. These need price history, dividends, invested-capital inputs or peer comparisons.<\/p><p>The original weights and peer rankings have not been recovered. This is a new transparent STA model, not a recreation of the old numeric score. Superior and overpriced labels are withheld until the relevant benchmarks are connected.<\/p><\/details>';return html+'<p class=\"small\">Uses the dated SEC statement figures and filing sources below. Annual results can lag current conditions.<\/p><\/section>';\n}\n\n\nlet statementSequence=0;\nasync function loadStatements(symbol){\nconst sequence=++statementSequence,slot=$('#stat-financial-statements');if(!slot)return;\nslot.innerHTML='<section class=\"dash-card\"><h3>Financial statements<\/h3><p>Loading annual financial statements\u2026<\/p><\/section>';\ntry{const d=await get('financial-statements?'+new URLSearchParams({symbol}));if(sequence!==statementSequence||!slot.isConnected||last.symbol!==symbol)return;\nif(d.state!=='ok'){const message=d.state==='sec_unavailable'?'SEC financial statements could not be retrieved. Please try again shortly.':d.state==='no_standard_statements'?'Comparable annual US-GAAP statements are not available for this company.':marketMessage(d.state);slot.innerHTML='<section class=\"dash-card\" aria-label=\"Financial statements\"><h3>Financial statements<\/h3><p>'+esc(message)+'<\/p><\/section>';return;}\nconst periods=d.periods,fmt=(cell,unit)=>cell==null?'\u2014':new Intl.NumberFormat('en-US',{minimumFractionDigits:unit==='USD\/shares'?2:0,maximumFractionDigits:unit==='USD\/shares'?2:0}).format(unit==='USD\/shares'?cell.value:cell.value\/1000000);\nlet html=fundamentalScorecard(d)+'<section class=\"dash-card\" aria-label=\"Financial statements\"><h3>Financial statements \u00b7 '+esc(d.company)+'<\/h3><p>Annual SEC filing extracts \u00b7 USD millions, except per-share amounts. Balance sheets are as of the period end; income and cash flow cover the dates shown.<\/p>';\nfor(const [group,title] of [['income','Income statement'],['balance','Balance sheet'],['cash_flow','Cash-flow statement']]){\nhtml+='<details '+(group==='income'?'open':'')+'><summary>'+title+'<\/summary><div class=\"scroll\"><table><thead><tr><th scope=\"col\">Metric<\/th>'+periods.map(p=>'<th scope=\"col\">'+esc(p.end)+'<\/th>').join('')+'<\/tr><\/thead><tbody>';\nfor(const [key,def] of Object.entries(d.definitions[group]))html+='<tr><th scope=\"row\">'+esc(def.label)+'<\/th>'+periods.map(p=>{const cell=p.statements[group][key];return '<td title=\"'+esc(cell?cell.tag:'Not reported in the supported standard fields')+'\">'+fmt(cell,def.unit)+'<\/td>';}).join('')+'<\/tr>';\nhtml+='<\/tbody><\/table><\/div><\/details>';\n}\nhtml+='<details><summary>Reporting periods and sources<\/summary><ul>'+periods.map(p=>'<li>'+esc(p.start)+' to '+esc(p.end)+' \u00b7 filed '+esc(p.filed)+' \u00b7 <a href=\"'+esc(p.url)+'\" target=\"_blank\" rel=\"noopener noreferrer\">SEC filing<\/a><\/li>').join('')+'<\/ul><p>Figures for each period come from the same filing; prior periods may reflect later restatements. A dash means unavailable, not zero. These are selected standard line items, not the complete statements or footnotes. Free cash flow is operating cash flow minus property, plant and equipment purchases.<\/p><p>Source: SEC Company Facts \u00b7 retrieved '+esc(d.retrieved_at)+' \u00b7 cached for up to 24 hours. Currently supports annual USD US-GAAP filings; Canadian listings and custom reporting tags are not covered.<\/p><\/details><\/section>';\nslot.innerHTML=html;\n}catch(e){if(sequence===statementSequence&&slot.isConnected)slot.innerHTML='<section class=\"dash-card\"><h3>Financial statements<\/h3><p>Statements could not be loaded. Analyst results remain available.<\/p><\/section>';}\n}\n\n\nfunction loadAccuracyTrial(symbol,currency){\n const enabled=false;if(!enabled)return;\n const box=document.createElement('section');box.className='dash-card';box.id='stat-accuracy-trial';box.innerHTML='<span class=\"dash-eyebrow\">ADMIN PREVIEW \u00b7 RECENT PERFORMANCE<\/span><h3>Analyst accuracy \u00b7 recent performance<\/h3><p>By default, calculate progress since each update using the available STA targets from the last 180 days and subsequent completed daily prices. Coverage grows as more STA records are published. Optional fixed periods: 30, 60 or 90 days. This measures short-term progress against the stated target, not whether an annual forecast succeeded.<\/p><label for=\"stat-accuracy-days\">Evaluation period<\/label><select id=\"stat-accuracy-days\"><option value=\"0\">Available data \u2014 since each update<\/option><option value=\"30\">30 days<\/option><option value=\"60\">60 days<\/option><option value=\"90\">90 days<\/option><\/select><button type=\"button\" id=\"stat-accuracy-calculate\">Calculate analyst accuracy<\/button><div class=\"stat-accuracy-output\" aria-live=\"polite\"><\/div><details><summary>How accuracy is measured<\/summary><p>Target accuracy = max(0, 100 \u2212 100 \u00d7 |ending close \u2212 target| \/ target). This measures closeness, not the percentage of winning recommendations. Direction success compares the target-implied direction with the price move. Target reached means the daily trading range included the target. Prices and targets are adjusted to the same split basis; dividends are excluded.<\/p><p>The trial uses targets issued in the last 180 days and the selected 30-, 60- or 90-day period. Fixed-period observations must complete the full selected period. Since-update snapshots use all available subsequent completed daily price bars, with at least one trading session required, use varying observation lengths, and must not be treated as completed or directly comparable forecast rankings. Entry is the next trading day open after the recorded report\/publication date; exit is the last available close on or before the selected end date. Duplicate targets, conflicting entries, retrospective report dates and insufficient price histories are excluded. Fixed-period calculations exclude overlapping windows for the same firm. Available-data mode includes distinct target changes even when observation windows overlap; those observations are correlated. Brokerage-level results are provisional below five completed forecasts. Named analysts cannot be ranked without their identities.<\/p><\/details>';\n \n if(!symbol.endsWith(':CA')){const check=document.createElement('button');check.type='button';check.textContent='Test historical price connection';const details=document.createElement('p');details.className='small';box.append(check,details);check.onclick=async()=>{check.disabled=true;details.textContent='Testing historical prices and split data\u2026';try{const response=await fetch(\"https:\\\/\\\/www.stocktargetadvisor.com\\\/blog\\\/wp-json\\\/sta-target\\\/v1\\\/accuracy-data-check\"+'?'+new URLSearchParams({symbol}),{credentials:'same-origin',headers:{'X-WP-Nonce':\"\"}});const x=await response.json();if(!response.ok)throw Error(x.message||'Connection test failed.');details.textContent='Historical prices: '+x.prices+' \u00b7 '+x.daily_bars+' daily bars'+(x.first_date?' ('+x.first_date+' to '+x.last_date+')':'')+' \u00b7 Split history: '+x.split_history+' \u00b7 Adjustment checks: '+(Object.values(x.checks).every(Boolean)?'passed':'failed')+'.';}catch(error){details.textContent=error.message;}finally{check.disabled=false;}};}\n\n const anchor=$('#stat-financial-statements');anchor.after(box);const button=box.querySelector('button'),result=box.querySelector('.stat-accuracy-output');\n button.onclick=async()=>{button.disabled=true;result.textContent='Checking completed observations and historical prices\u2026';try{\n const response=await fetch(\"https:\\\/\\\/www.stocktargetadvisor.com\\\/blog\\\/wp-json\\\/sta-target\\\/v1\\\/analyst-accuracy\"+'?'+new URLSearchParams({symbol,currency,days:box.querySelector('#stat-accuracy-days').value}),{credentials:'same-origin',headers:{'X-WP-Nonce':\"\"}});let a;try{a=await response.json();}catch(error){throw Error('The server returned a temporary response error. Please try Calculate analyst accuracy again.');}if(!response.ok)throw Error(a.message||'Accuracy trial unavailable.');\n result.innerHTML='<p>'+esc(a.message||a.state)+'<\/p><p class=\"small\">'+Number(a.evaluated||0)+(a.days===0?' in-progress snapshots \u00b7 ':' completed observations \u00b7 ')+Number(a.pending||0)+' in progress \u00b7 '+Number(a.excluded||0)+' excluded<\/p>';\n if(a.firms&&a.firms.length){const best=a.firms[0].accuracy,leaders=a.firms.filter(f=>f.accuracy===best),names=leaders.map(f=>f.firm).join(' \/ ');result.innerHTML+='<div style=\"background:#eef5fc;border-left:4px solid #1672aa;padding:18px;margin:16px 0;border-radius:6px\"><span class=\"dash-eyebrow\">'+(leaders.length>1?'JOINT TOP BROKERAGES':'TOP BROKERAGE FOR THIS STOCK')+'<\/span><h4 style=\"margin:8px 0;font-size:22px\">'+esc(names)+'<\/h4><p style=\"margin:6px 0\"><strong>'+best+'% target-closeness score<\/strong><\/p><p class=\"small\">'+leaders.map(f=>esc(f.firm)+': '+f.completed+' observation'+(f.completed===1?'':'s')).join(' \u00b7 ')+'<\/p><p class=\"small\">Provisional leader among evaluated brokerages for '+esc(symbol)+' only, based on available STA targets and the selected observation period. This is not an overall analyst ranking or a percentage of successful recommendations.<\/p><\/div>';}\n if(a.firms&&a.firms.length)result.innerHTML+='<div class=\"scroll\"><table><thead><tr><th>Brokerage<\/th><th>Target closeness score<\/th><th>Direction success<\/th><th>Target reached<\/th><th>Observations<\/th><th>Status<\/th><\/tr><\/thead><tbody>'+a.firms.map(f=>'<tr><td>'+esc(f.firm)+'<\/td><td>'+f.accuracy+'%<\/td><td>'+(f.direction_success==null?'\u2014':f.direction_success+'%')+'<\/td><td>'+f.target_reached+'%<\/td><td>'+f.completed+'<\/td><td>'+esc(f.status)+'<\/td><\/tr>').join('')+'<\/tbody><\/table><\/div><details><summary>Forecast evidence<\/summary>'+a.forecasts.map(f=>'<p><strong>'+esc(f.firm)+'<\/strong> \u00b7 '+esc(f.date)+' \u2192 '+esc(f.end_date)+'<br>Original target '+money(f.original_target,a.currency)+' \u00b7 split-aligned target '+money(f.adjusted_target,a.currency)+' \u00b7 ending close '+money(f.ending_close,a.currency)+'<br><a href=\"'+esc(f.source_url)+'\">STA source article<\/a><\/p>').join('')+'<\/details>';\n }catch(error){result.textContent=error.message;}finally{button.disabled=false;}};\n box.querySelector('#stat-accuracy-days').onchange=()=>{result.textContent='Period changed. Select Calculate analyst accuracy to refresh the results.';};\n}\n\nfunction render(d,price,date){last=d;let ret=null;let targetDates=d.firms.filter(f=>f.target_record).map(f=>f.target_record.report_date).sort();out.innerHTML=dashboard(d,ret,price,date)+(d.currencies.length>1?'<label for=\"stat-currency\">Target currency<\/label><select id=\"stat-currency\">'+d.currencies.map(c=>'<option '+(c===d.currency?'selected':'')+'>'+esc(c)+'<\/option>').join('')+'<\/select><p class=\"small\">Targets in different currencies are analysed separately.<\/p>':'')+'<details class=\"dash-card\"><summary>Analyst rationale and scoring method<\/summary>'+analystScorecard(d,ret)+'<\/details>'+'<div id=\"stat-market-context\"><\/div><div id=\"stat-financial-statements\"><\/div><h3>Latest rating and target per firm<\/h3><div class=\"scroll\"><table><thead><tr><th>Firm<\/th><th>Latest rating<\/th><th>Latest target ('+esc(d.currency)+')<\/th><th>Notes<\/th><\/tr><\/thead><tbody>'+d.firms.map(f=>'<tr><td>'+esc(f.firm)+'<\/td><td>'+record(f.rating_record,'rating',d.currency)+'<\/td><td>'+record(f.target_record,'target',d.currency)+'<\/td><td>'+esc(Object.keys(f.conflicts).length?'Same-date conflict excluded':f.withdrawn_date?'Coverage withdrawal recorded '+f.withdrawn_date:'Latest update '+f.latest_update)+'<\/td><\/tr>').join('')+'<\/tbody><\/table><\/div>';out.hidden=false;const cur=$('#stat-currency');if(cur)cur.onchange=()=>{run(d.symbol,cur.value)}}async function run(q,currency){const price=null,date='';$('#stat-submit').disabled=true;status.textContent='Searching the compiled STA ratings index\u2026';out.hidden=true;try{const d=await get('search?'+new URLSearchParams({q,days:$('#stat-days').value,currency:currency||''}));if(d.candidates){out.innerHTML='<h2>'+esc(d.message)+'<\/h2>'+d.candidates.map((c,i)=>'<button type=\"button\" data-choice=\"'+i+'\">'+esc(c.symbol)+' \u00b7 '+esc(c.company)+'<\/button> ').join('')+'<p class=\"small\">'+esc(coverage(d.status))+'<\/p>';out.hidden=false;out.querySelectorAll('[data-choice]').forEach(b=>b.onclick=()=>{const c=d.candidates[Number(b.dataset.choice)];$('#stat-question').value=c.symbol;run(c.symbol,'')});status.textContent='Search complete.'}else{render(d,price,date);loadAccuracyTrial(d.symbol,d.currency);loadMarketContext(d.symbol);loadStatements(d.symbol);status.textContent='Search complete for '+d.symbol+'.'}}catch(e){status.textContent=e.message}finally{$('#stat-submit').disabled=false}}$('#stat-form').addEventListener('submit',e=>{e.preventDefault();run($('#stat-question').value,'')})})();<\/script>\n\n<style>#sta-target-tool #sta-user-price,#sta-target-tool #stat-results>.dash-grid,#sta-target-tool #stat-results>.dash-coverage,#sta-target-tool #stat-results>.dash-history-grid,#sta-target-tool #stat-accuracy-trial{display:none!important}<\/style>\n<style>#sta-target-tool #sta-user-price{margin:18px 0 20px;padding:22px 26px;border:1px solid #cbdceb;border-left:4px solid #126dad;border-radius:12px;background:#f7fbff}#sta-target-tool #sta-user-price h3{margin:0 0 8px;font-size:21px}#sta-target-tool #sta-user-price p{margin:0 0 14px;color:#4a6074}#sta-target-tool #sta-user-price .sta-user-line{display:flex;gap:18px;align-items:flex-end;flex-wrap:wrap}#sta-target-tool #sta-user-price label{display:block;flex:0 1 260px;margin:0;font-weight:600}#sta-target-tool #sta-user-price input{display:block;box-sizing:border-box;width:100%;margin-top:5px;padding:9px 11px;border:1px solid #b9c9d8;border-radius:6px}#sta-target-tool #sta-user-price .sta-user-output{flex:1;min-width:220px;padding:10px 14px;border-radius:8px;background:#fff}#sta-target-tool #sta-user-price .sta-user-output strong{display:block;font-size:24px}#sta-target-tool #sta-user-price .sta-user-output small{display:block;margin-top:5px}#sta-target-tool #sta-target-ranking{margin-top:18px;padding-top:16px;border-top:1px solid #cbdceb}#sta-target-tool #sta-target-ranking h4{font-size:18px;margin:0 0 6px}#sta-target-tool #sta-target-ranking .sta-rank-note{font-size:13px;margin:8px 0;color:#4a6074}#sta-target-tool #sta-target-ranking .sta-rank-scroll{overflow-x:auto}#sta-target-tool #sta-target-ranking table{width:100%;border-collapse:collapse;background:#fff;font-size:14px}#sta-target-tool #sta-target-ranking th,#sta-target-tool #sta-target-ranking td{padding:9px 11px;text-align:left;border-bottom:1px solid #e2eaf1}#sta-target-tool #sta-target-ranking th{background:#eaf3fc;color:#234563}#sta-target-tool #sta-target-ranking tbody tr:first-child td{font-weight:700;color:#075a3b}<\/style>\n<p><script>(function(){'use strict';var root=document.getElementById('sta-target-tool');if(!root)return;function num(v){var x=parseFloat(String(v||'').replace(\/[^0-9.]\/g,''));return Number.isFinite(x)?x:NaN;}function element(tag,cls,txt){var e=document.createElement(tag);if(cls)e.className=cls;if(txt!==undefined)e.textContent=txt;return e;}function install(){var result=root.querySelector('#stat-results');if(!result||result.querySelector('#sta-user-price'))return;var kpis=result.querySelector('.dash-kpis'),badge=result.querySelector('.dash-badge'),consensus=result.querySelector('.dash-kpi strong');if(!kpis||!badge||!consensus)return;var badgeText=badge.textContent.trim().toUpperCase(),currency=badgeText.startsWith('CAD')?'CAD':badgeText.startsWith('USD')?'USD':null,target=num(consensus.textContent);if(!currency||!Number.isFinite(target)||target<=0)return;var country=currency==='CAD'?'Canadian':'U.S.',format=new Intl.NumberFormat(currency==='CAD'?'en-CA':'en-US',{style:'currency',currency:currency}),box=element('section');box.id='sta-user-price';box.appendChild(element('h3','', 'Optional: Compare with a current share price'));box.appendChild(element('p','', 'Enter a current share price from your preferred source. This is your input, not a live quote or a historical analyst accuracy score.'));var line=element('div','sta-user-line'),label=element('label','', 'Current share price ('+currency+')'),input=element('input'),output=element('div','sta-user-output'),value=element('strong','', '\u2014'),note=element('small','', 'Enter a price to calculate.');input.type='number';input.min='0.0001';input.step='any';input.inputMode='decimal';input.placeholder='Enter a price (optional)';input.setAttribute('aria-label','Current share price in '+currency);label.appendChild(input);output.setAttribute('aria-live','polite');output.appendChild(element('span','', 'Consensus upside \/ downside'));output.appendChild(value);output.appendChild(note);line.appendChild(label);line.appendChild(output);box.appendChild(line);var ranking=element('div');ranking.id='sta-target-ranking';ranking.appendChild(element('h4','',country+' analyst target proximity ranking'));ranking.appendChild(element('p','sta-rank-note','Ranked by distance from your entered '+currency+' share price. This is not analyst forecast accuracy.'));var scroll=element('div','sta-rank-scroll'),detail=element('p','sta-rank-note','Enter a current '+currency+' price to rank available analyst targets.');ranking.appendChild(scroll);ranking.appendChild(detail);box.appendChild(ranking);var rows=Array.from(result.querySelectorAll(':scope > .scroll table tbody tr'));var firms=rows.map(function(tr){var cells=tr.querySelectorAll('th,td');return{name:cells[0]?cells[0].textContent.trim():'',target:cells[2]?num(cells[2].textContent):NaN};}).filter(function(f){return f.name&&Number.isFinite(f.target)&&f.target>0;});function draw(price){scroll.replaceChildren();if(!Number.isFinite(price)||price<=0){detail.textContent='Enter a current '+currency+' price to rank available analyst targets.';return;}if(!firms.length){detail.textContent='No numeric analyst targets available for this listing.';return;}var sorted=firms.map(function(f){return{name:f.name,target:f.target,difference:Math.abs(f.target-price),percent:Math.abs(f.target-price)\/price*100};}).sort(function(a,b){return a.difference-b.difference||a.name.localeCompare(b.name);});var table=element('table'),thead=element('thead'),head=element('tr');['Rank','Analyst','Target','Distance','Distance %'].forEach(function(h){head.appendChild(element('th','',h));});thead.appendChild(head);table.appendChild(thead);var tbody=element('tbody');sorted.forEach(function(f,i){var tr=element('tr');[String(i+1),f.name,format.format(f.target),format.format(f.difference),f.percent.toFixed(1)+'%'].forEach(function(t){tr.appendChild(element('td','',t));});tbody.appendChild(tr);});table.appendChild(tbody);scroll.appendChild(table);detail.textContent=sorted.length+' published analyst targets compared with your input price of '+format.format(price)+'. Rankings reflect proximity only, not directional accuracy or investment performance.';}input.addEventListener('input',function(){var price=Number(input.value);if(!input.value||!Number.isFinite(price)||price<=0){value.textContent='\u2014';note.textContent='Enter a positive share price.';draw(NaN);return;}var upside=(target\/price-1)*100;value.textContent=(upside>=0?'+':'')+upside.toFixed(1)+'%';draw(price);if(firms.length){var closest=firms.reduce(function(a,b){return Math.abs(b.target-price)<Math.abs(a.target-price)?b:a;});note.textContent='Closest target: '+closest.name+' ('+format.format(closest.target)+'). This is target proximity, not forecast accuracy.';}else{note.textContent='Based on the available consensus target.';}});kpis.after(box);draw(NaN);}var observer=new MutationObserver(install);observer.observe(root,{childList:true,subtree:true});install();})();<\/script><br \/>\n<script>(function(){function updateLabel(){var label=document.querySelector(\"#sta-target-tool label[for=stat-question]\");if(label&&label.textContent!==\"Stock Ticker\")label.textContent=\"Stock Ticker\";var input=document.getElementById(\"stat-question\");if(input)input.setAttribute(\"aria-label\",\"Stock Ticker\");}if(document.readyState===\"loading\")document.addEventListener(\"DOMContentLoaded\",updateLabel);else updateLabel();var root=document.getElementById(\"sta-target-tool\");if(root)new MutationObserver(updateLabel).observe(root,{childList:true,subtree:true});})();<\/script><\/p>\n<style>\n#sta-target-tool .sta-ca-score{margin:20px 0;padding:22px;border:1px solid #cbdceb;border-left:4px solid #1471ae;border-radius:12px;background:#f6faff;color:#18334a}\n#sta-target-tool .sta-ca-score h3{margin:0 0 6px;font-size:22px}#sta-target-tool .sta-ca-score p{margin:6px 0 14px;font-size:13px;color:#486276}\n#sta-target-tool .sta-ca-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin:16px 0}\n#sta-target-tool .sta-ca-tile{padding:15px;background:#fff;border:1px solid #dae6f0;border-radius:9px}\n#sta-target-tool .sta-ca-tile span{display:block;font-size:13px;color:#456176}#sta-target-tool .sta-ca-tile strong{display:block;font-size:24px;margin:5px 0}\n#sta-target-tool .sta-ca-score label{font-weight:700;font-size:14px}#sta-target-tool .sta-ca-score input{display:block;max-width:240px;width:100%;padding:10px;margin-top:6px;border:1px solid #b9cddd;border-radius:6px}\n#sta-target-tool .sta-ca-score table{border-collapse:collapse;width:100%;background:#fff;font-size:13px}#sta-target-tool .sta-ca-score th,#sta-target-tool .sta-ca-score td{padding:9px;border-bottom:1px solid #e1eaf2;text-align:left}#sta-target-tool .sta-ca-score th{background:#e9f3fc}\n#sta-target-tool .sta-ca-score .sta-ca-foot{font-size:12px;margin:14px 0 0;color:#526778}\n<\/style>\n<p><script>(function(){'use strict';var root=document.getElementById('sta-target-tool');if(!root)return;\nfunction n(t){var v=parseFloat(String(t||'').replace(\/[^0-9.]\/g,''));return isFinite(v)?v:NaN}\nfunction clamp(v){return Math.max(0,Math.min(100,v))}\nfunction rating(t){t=String(t||'').toLowerCase();if(\/strong buy|conviction buy\/.test(t))return 5;if(\/buy|outperform|overweight|positive|accumulate\/.test(t))return 4;if(\/hold|neutral|equal.weight|market perform|sector perform|perform|peer perform\/.test(t))return 3;if(\/underperform|underweight|reduce\/.test(t))return 2;if(\/sell\/.test(t))return 1;return NaN}\nfunction install(){var res=root.querySelector('#stat-results');if(!res||res.querySelector('#sta-ca-analysis'))return;var badge=res.querySelector('.dash-badge');if(!badge||!\/^CAD\/i.test(badge.textContent.trim()))return;var trs=[].slice.call(res.querySelectorAll(':scope > .scroll table tbody tr'));if(!trs.length)return;\nvar records=trs.map(function(tr){var c=tr.querySelectorAll('td'),ratingText=c[1]?c[1].querySelector('strong')?.textContent:'',targetText=c[2]?c[2].querySelector('strong')?.textContent:'',evidence=c[1]?c[1].querySelector('details')?.textContent||'':'';return{r:rating(ratingText),t:n(targetText),e:evidence}});\nvar rs=records.filter(function(x){return isFinite(x.r)}),ts=records.filter(function(x){return isFinite(x.t)&&x.t>0}).map(function(x){return x.t}),mean=ts.length?ts.reduce(function(a,b){return a+b},0)\/ts.length:NaN;\nvar consensus=rs.length?clamp((rs.reduce(function(a,b){return a+b.r},0)\/rs.length-1)*25):NaN;\nvar revisions=records.map(function(x){var e=x.e.toLowerCase();return \/(?:raised|increased|lifted|hiked|boosted) (?:its |the )?(?:price )?target|target (?:raised|increased|lifted|boosted)|target up\/.test(e)?1:\/(?:lowered|reduced|cut|trimmed|slashed) (?:its |the )?(?:price )?target|target (?:lowered|reduced|cut)|target down\/.test(e)?-1:0}).filter(Boolean);\nvar movements=records.map(function(x){var e=x.e.toLowerCase();return \/upgrad(?:e|ed)\/.test(e)?1:\/downgrad(?:e|ed)\/.test(e)?-1:0}).filter(Boolean);\nvar agreement=ts.length>=2&&mean>0?clamp(100-(Math.sqrt(ts.reduce(function(a,b){return a+Math.pow(b-mean,2)},0)\/ts.length)\/mean)*200):NaN;\nvar box=document.createElement('section');box.id='sta-ca-analysis';box.className='sta-ca-score';box.innerHTML=decodeURIComponent('%3Ch3%3ESTA%20Canadian%20Analyst-Based%20Stock%20Score%3C%2Fh3%3E%3Cp%3EIndependent%20STA%20calculation%20based%20on%20published%20analyst%20opinions.%20This%20is%20not%20financial-statement%20fundamental%20analysis%20or%20price-based%20technical%20analysis.%3C%2Fp%3E%3Clabel%3ECurrent%20share%20price%20(CAD)%20%E2%80%94%20optional%3Cinput%20id%3D%22sta-ca-current%22%20type%3D%22number%22%20min%3D%220.0001%22%20step%3D%22any%22%20placeholder%3D%22Enter%20CAD%20price%22%3E%3C%2Flabel%3E%3Cdiv%20class%3D%22sta-ca-grid%22%3E%3Cdiv%20class%3D%22sta-ca-tile%20sta-ca-signal%22%3E%3Cspan%3ESTA%20Market%20Signal%3C%2Fspan%3E%3Cstrong%20id%3D%22sta-ca-signal%22%3E%E2%80%94%3C%2Fstrong%3E%3Cspan%20id%3D%22sta-ca-signal-note%22%3EAnalyst-derived%20direction%3C%2Fspan%3E%3C%2Fdiv%3E%3Cdiv%20class%3D%22sta-ca-tile%22%3E%3Cspan%3ESTA%20analyst%20score%3C%2Fspan%3E%3Cstrong%20id%3D%22sta-ca-total%22%3E%E2%80%94%3C%2Fstrong%3E%3Cspan%20id%3D%22sta-ca-label%22%3EEnter%20a%20price%20to%20include%20valuation%3C%2Fspan%3E%3C%2Fdiv%3E%3Cdiv%20class%3D%22sta-ca-tile%22%3E%3Cspan%3EConsensus%20analyst%20target%3C%2Fspan%3E%3Cstrong%20id%3D%22sta-ca-target%22%3E%E2%80%94%3C%2Fstrong%3E%3Cspan%20id%3D%22sta-ca-upside%22%3EEnter%20a%20current%20price%20for%20implied%20upside%3C%2Fspan%3E%3C%2Fdiv%3E%3C%2Fdiv%3E%3Ctable%3E%3Cthead%3E%3Ctr%3E%3Cth%3EFactor%3C%2Fth%3E%3Cth%3EScore%3C%2Fth%3E%3Cth%3EWeight%3C%2Fth%3E%3C%2Ftr%3E%3C%2Fthead%3E%3Ctbody%20id%3D%22sta-ca-factors%22%3E%3C%2Ftbody%3E%3C%2Ftable%3E%3Cp%20class%3D%22sta-ca-foot%22%20id%3D%22sta-ca-coverage%22%3E%3C%2Fp%3E%3Cp%20class%3D%22sta-ca-foot%22%3EScoring%3A%20consensus%20rating%2025%25%2C%20implied%20valuation%2020%25%2C%20target%20revisions%2015%25%2C%20rating%20momentum%2010%25%2C%20analyst%20agreement%2010%25%2C%20bullish%20rating%20breadth%2010%25%2C%20target%20support%20breadth%2010%25.%20Missing%20factors%20are%20excluded%20and%20the%20remaining%20weights%20are%20normalized%3B%20the%20score%20is%20unavailable%20with%20fewer%20than%20three%20measurable%20factors.%20A%20higher%20target%20represents%20analyst%20opinion%2C%20not%20guaranteed%20upside.%20Each%20published%20firm%20row%20is%20counted%20once%20within%20the%20selected%20lookback%3B%20similarly%20named%20firms%20may%20appear%20separately.%20Scores%20and%20thresholds%20are%20experimental%20and%20have%20not%20been%20validated%20against%20realized%20returns.%3C%2Fp%3E');\nvar first=res.querySelector('[aria-label=\"Market context\"]');if(first){first.before(box)}else{res.appendChild(box)}\nvar unavailable=[].slice.call(res.querySelectorAll('.dash-card')).filter(function(e){return \/not available for this Canadian listing\/.test(e.textContent)});unavailable.forEach(function(e){e.style.display='none'});\nfunction fmt(v){return isFinite(v)?Math.round(v)+'\/100':'Not available'}function redraw(){var raw=box.querySelector('#sta-ca-current').value,price=raw?Number(raw):NaN,upside=isFinite(price)&&price>0&&isFinite(mean)?(mean\/price-1)*100:NaN;\nvar valuation=isFinite(upside)?clamp(50+1.25*upside):NaN,rev=revisions.length?clamp(50+50*revisions.reduce(function(a,b){return a+b},0)\/revisions.length):NaN,mom=movements.length?clamp(50+50*movements.reduce(function(a,b){return a+b},0)\/movements.length):NaN;\nvar bullishBreadth=rs.length?clamp(rs.filter(function(x){return x.r>=4}).length\/rs.length*100):NaN,targetSupport=isFinite(price)&&price>0&&ts.length?clamp(ts.filter(function(x){return x>price}).length\/ts.length*100):NaN;\nvar factors=[['Analyst consensus',consensus,25,rs.length+' rated firms'],['Implied valuation',valuation,20,isFinite(upside)?upside.toFixed(1)+'% upside\/downside':'Enter current price'],['Target revisions',rev,15,revisions.length+' detected changes'],['Rating momentum',mom,10,movements.length+' detected changes'],['Analyst agreement',agreement,10,ts.length+' numeric targets'],['Bullish rating breadth',bullishBreadth,10,rs.length+' rated firms'],['Targets above share price',targetSupport,10,isFinite(price)?ts.length+' targets':'Enter current price']];\nvar present=factors.filter(function(f){return isFinite(f[1])}),weight=present.reduce(function(a,f){return a+f[2]},0),score=present.length>=3?present.reduce(function(a,f){return a+f[1]*f[2]},0)\/weight:NaN;\nbox.querySelector('#sta-ca-total').textContent=fmt(score);box.querySelector('#sta-ca-label').textContent=!isFinite(score)?'Insufficient coverage':'Based on available analyst inputs';var signal=!isFinite(score)?'Insufficient data':score>=80?'Strong Bullish':score>=65?'Bullish':score>=45?'Neutral':score>=30?'Bearish':'Strong Bearish';box.querySelector('#sta-ca-signal').textContent=signal;box.querySelector('#sta-ca-signal-note').textContent=present.length+' of 7 metrics available';box.querySelector('.sta-ca-signal').style.borderLeft='4px solid '+(!isFinite(score)?'#8393a0':score>=65?'#16966b':score>=45?'#ca9b35':'#b44343');\nbox.querySelector('#sta-ca-target').textContent=isFinite(mean)?'C$'+mean.toFixed(2):'\u2014';box.querySelector('#sta-ca-upside').textContent=isFinite(upside)?(upside>=0?'+':'')+upside.toFixed(1)+'% analyst-implied':'Enter a current CAD price';\nvar tbody=box.querySelector('#sta-ca-factors');tbody.replaceChildren();factors.forEach(function(f){var tr=document.createElement('tr');[f[0]+' ('+f[3]+')',fmt(f[1]),f[2]+'%'].forEach(function(s){var td=document.createElement('td');td.textContent=s;tr.appendChild(td)});tbody.appendChild(tr)});\nbox.querySelector('#sta-ca-coverage').textContent=present.length+' of 7 factors measurable \u00b7 '+rs.length+' rated firms \u00b7 '+ts.length+' target prices. This is an analyst-derived indicator only; no unsupported inputs are imputed.'}\nbox.querySelector('#sta-ca-current').addEventListener('input',redraw);redraw()}\nvar observer=new MutationObserver(install);observer.observe(root,{childList:true,subtree:true});install()})();<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Research U.S. and Canadian stocks using published analyst sentiment, market context, financial statements and source-linked firm ratings. Availability varies by listing.<\/p>\n","protected":false},"author":3,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-76669","page","type-page","status-publish","hentry"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v19.4 (Yoast SEO v21.4) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Stock Analysis Tool | Stock Target Advisor<\/title>\n<meta name=\"robots\" content=\"noindex, follow\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Stock Analysis Tool\" \/>\n<meta property=\"og:description\" content=\"Research U.S. and Canadian stocks using published analyst sentiment, market context, financial statements and source-linked firm ratings. Availability varies by listing.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/\" \/>\n<meta property=\"og:site_name\" content=\"Stock Target Advisor\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/StockTargetAdvisor\/\" \/>\n<meta property=\"article:modified_time\" content=\"2026-10-28T05:22:28+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.stocktargetadvisor.com\/blog\/wp-content\/uploads\/2019\/11\/Stock-Target-Advisor.png\" \/>\n\t<meta property=\"og:image:width\" content=\"291\" \/>\n\t<meta property=\"og:image:height\" content=\"59\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@AdvisorTarget\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"1 minute\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/\",\"url\":\"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/\",\"name\":\"Stock Analysis Tool | Stock Target Advisor\",\"isPartOf\":{\"@id\":\"https:\/\/www.stocktargetadvisor.com\/blog\/#website\"},\"datePublished\":\"2026-10-27T23:27:47+00:00\",\"dateModified\":\"2026-10-28T05:22:28+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.stocktargetadvisor.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Stock Analysis Tool\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.stocktargetadvisor.com\/blog\/#website\",\"url\":\"https:\/\/www.stocktargetadvisor.com\/blog\/\",\"name\":\"Stock Target Advisor\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.stocktargetadvisor.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.stocktargetadvisor.com\/blog\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.stocktargetadvisor.com\/blog\/#organization\",\"name\":\"Stock Target Advisor\",\"alternateName\":\"STA\",\"url\":\"https:\/\/www.stocktargetadvisor.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.stocktargetadvisor.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"http:\/\/stocktargetadvisor.com\/wp-content\/uploads\/2019\/10\/STAlogo.jpeg\",\"contentUrl\":\"http:\/\/stocktargetadvisor.com\/wp-content\/uploads\/2019\/10\/STAlogo.jpeg\",\"width\":\"225\",\"height\":\"225\",\"caption\":\"Stock Target Advisor\"},\"image\":{\"@id\":\"https:\/\/www.stocktargetadvisor.com\/blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/StockTargetAdvisor\/\",\"https:\/\/twitter.com\/AdvisorTarget\"]}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Stock Analysis Tool | Stock Target Advisor","robots":{"index":"noindex","follow":"follow"},"og_locale":"en_US","og_type":"article","og_title":"Stock Analysis Tool","og_description":"Research U.S. and Canadian stocks using published analyst sentiment, market context, financial statements and source-linked firm ratings. Availability varies by listing.","og_url":"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/","og_site_name":"Stock Target Advisor","article_publisher":"https:\/\/www.facebook.com\/StockTargetAdvisor\/","article_modified_time":"2026-10-28T05:22:28+00:00","og_image":[{"width":291,"height":59,"url":"https:\/\/www.stocktargetadvisor.com\/blog\/wp-content\/uploads\/2019\/11\/Stock-Target-Advisor.png","type":"image\/png"}],"twitter_card":"summary_large_image","twitter_site":"@AdvisorTarget","twitter_misc":{"Est. reading time":"1 minute"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/","url":"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/","name":"Stock Analysis Tool | Stock Target Advisor","isPartOf":{"@id":"https:\/\/www.stocktargetadvisor.com\/blog\/#website"},"datePublished":"2026-10-27T23:27:47+00:00","dateModified":"2026-10-28T05:22:28+00:00","breadcrumb":{"@id":"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.stocktargetadvisor.com\/blog\/stock-research-tool\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.stocktargetadvisor.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Stock Analysis Tool"}]},{"@type":"WebSite","@id":"https:\/\/www.stocktargetadvisor.com\/blog\/#website","url":"https:\/\/www.stocktargetadvisor.com\/blog\/","name":"Stock Target Advisor","description":"","publisher":{"@id":"https:\/\/www.stocktargetadvisor.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.stocktargetadvisor.com\/blog\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.stocktargetadvisor.com\/blog\/#organization","name":"Stock Target Advisor","alternateName":"STA","url":"https:\/\/www.stocktargetadvisor.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.stocktargetadvisor.com\/blog\/#\/schema\/logo\/image\/","url":"http:\/\/stocktargetadvisor.com\/wp-content\/uploads\/2019\/10\/STAlogo.jpeg","contentUrl":"http:\/\/stocktargetadvisor.com\/wp-content\/uploads\/2019\/10\/STAlogo.jpeg","width":"225","height":"225","caption":"Stock Target Advisor"},"image":{"@id":"https:\/\/www.stocktargetadvisor.com\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/StockTargetAdvisor\/","https:\/\/twitter.com\/AdvisorTarget"]}]}},"_links":{"self":[{"href":"https:\/\/www.stocktargetadvisor.com\/blog\/wp-json\/wp\/v2\/pages\/76669","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.stocktargetadvisor.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.stocktargetadvisor.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.stocktargetadvisor.com\/blog\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/www.stocktargetadvisor.com\/blog\/wp-json\/wp\/v2\/comments?post=76669"}],"version-history":[{"count":8,"href":"https:\/\/www.stocktargetadvisor.com\/blog\/wp-json\/wp\/v2\/pages\/76669\/revisions"}],"predecessor-version":[{"id":76708,"href":"https:\/\/www.stocktargetadvisor.com\/blog\/wp-json\/wp\/v2\/pages\/76669\/revisions\/76708"}],"wp:attachment":[{"href":"https:\/\/www.stocktargetadvisor.com\/blog\/wp-json\/wp\/v2\/media?parent=76669"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}