Suros for Excel

Add-in version 2.5. Last updated 14 October 2026.

Suros for Excel puts twenty-one worksheet functions under the SU namespace and a Suros tab on the ribbon, reading the same delayed prices, reported statements, consensus estimates, peers and screens the terminal reads. It is not in AppSource: you load the manifest yourself, paste an API key into the task pane, and every cell stays a formula that fetches again when you recalculate.

Install it

Save surossystems.com/excel/manifest.xml to your machine. That one file is the whole install; the code it names is served from this site, so it updates without you doing anything.

What you are installing: when you add it, Excel names the publisher, Suros Systems, and the one permission the add-in asks for, to read and change the workbook. It reads the cell you have selected, writes the formulas and template sheets you ask for, and recalculates when you press Refresh. Every address in the manifest is on https://surossystems.com, and the add-in itself is plain JavaScript served from this site, in surossystems.com/excel/, where you can read it. There is no program to download or run.

Excel on the web

  1. Open a workbook at office.com.
  2. On the Home tab choose Add-ins, then More Add-ins.
  3. Open the My Add-ins tab and choose Upload My Add-in.
  4. Browse to manifest.xml and upload it.
  5. An SUROS tab appears on the ribbon.

Excel on Windows

  1. Put manifest.xml in a folder of its own, for example C:\suros-addin.
  2. Right click that folder, choose Properties, then Sharing, then Share, and copy the network path it gives you, which looks like \\MACHINE\suros-addin.
  3. In Excel go to File, Options, Trust Center, Trust Center Settings, Trusted Add-in Catalogs.
  4. Paste the network path, press Add catalog, tick Show in Menu, press OK.
  5. Restart Excel. On the Home tab choose Add-ins, More Add-ins, Shared Folder, then SUROS, then Add.

Excel on Mac

  1. Copy manifest.xml into ~/Library/Containers/com.microsoft.Excel/Data/Documents/wef, creating the wef folder if it is not there.
  2. Restart Excel. The SUROS tab appears on the ribbon.

Then connect it

  1. On the Suros tab press Suros pane.
  2. Paste your API key and press Save key. It is stored by Office on that machine and never written into the workbook, so sharing the file does not share the key.
  3. Press Test connection. It calls the quote endpoint and reports the price it got back and how much of your rate limit is left, or the exact reason it failed.
  4. Type =SU.PRICE("AAPL") in a cell.

The API key

API keys come with a subscription: any paid plan can make one, and an account without a subscription cannot. Keys are made on the account page. A key starts with ss_ and is shown once, when it is created. It is a bearer credential: treat it like a password, and revoke it from the same page if it leaks. An individual account holds one active key at a time; revoke it to make another. An organisation's allowance is set by its contract.

The tier follows the account behind the key on every request, and sets one number: how many requests a minute that key may make. If the subscription lapses or is cancelled, the key is refused with 403 and subscription required; it is kept, and works again as soon as the account subscribes again.

TierWho gets itRequests a minute
standardThe Equities analyst and Commodity trader plans60
proA pro plan, the beta, or membership of an organisation on a pro plan600

One formula is one request. A spilled range is still one request, so =SU.SCREEN("world","quality","",200) costs the same as =SU.PRICE("AAPL"). A watchlist of 200 rows with five SU.PRICE columns is a thousand requests and will hit the standard limit; a preset block is one.

Every answer carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset. Over the limit the endpoint returns 429 and the cell reads #N/A with the reason, never a stale number. Wait a minute and recalculate. The pane's Read key status button reads /api/v1/me with the key itself, so it can show the key's name, tier, limit and today's request count whether or not the browser is signed in.

The functions

HISTORY, SCREEN, SEARCH, PEERS, YIELDS, FEDPATH, STAKES, SUPPLY, INSIDERS, INSIDERBUYS, INSIDER, HOLDERS and MANAGER spill a range with a header row. FUND, EST and SHORTS spill too: one field spills a one-cell range, which behaves like a value in arithmetic and anywhere else, and a preset or a holder list spills the whole block. PRICE, SYMBOL, EARNINGS, FEARGREED and POSITIONING return one value. Leave the cells below and to the right of a spilling formula free or Excel shows #SPILL!.

Tickers take the terminal's form: AAPL, EQNR.OL, SAP.DE, NESN.SW, VOLV-B.ST. Nordic share classes use a dash. A sheet that still holds an older form such as VOLVA.ST can wrap it in SU.SYMBOL.

SU.PRICE(symbol, [field])

The last price, or another field off the same quote. delayMin says how many minutes the exchange holds the quote back (0 where it is real time) and asOf is the time of the last trade, in UTC.

ArgumentTakes
symbolA ticker in the terminal's form: AAPL, EQNR.OL, 7203.T.
fieldOptional. price, change, changePct, prevClose, currency, name, type, time, delayMin or asOf. Defaults to price.
=SU.PRICE("EQNR.OL","changePct")

SU.HISTORY(symbol, [range], [interval], [columns], [adjust])

Candles, spilled oldest first under a header row.

ArgumentTakes
symbolA ticker.
rangeOptional. 1d, 5d, 1mo, 3mo, 6mo, 1y, 2y, 5y, 10y, ytd, max. Defaults to 1y.
intervalOptional. 1m, 2m, 5m, 15m, 30m, 60m, 90m, 1h, 1d, 5d, 1wk, 1mo, 3mo. Defaults to 1d. How far back an intraday interval reaches is the upstream feed's rule, not ours: a range it will not serve at that interval comes back as #N/A saying no candles arrived.
columnsOptional. Any of date, open, high, low, close, volume, comma separated. Defaults to all six.
adjustOptional. total adjusts for splits and dividends, split for splits only, none is the raw print. Defaults to total on daily and slower bars, none intraday.
=SU.HISTORY("AAPL","5y","1wk","date,close","total")

SU.FUND(symbol, field, [period])

One figure off the fundamentals payload, or a preset block. That payload carries two things: the statements as filed, and a current block of vendor statistics. period decides which is read, because the same name can appear on both. =SU.FUND("AAPL","revenue","ttm") is the filed trailing twelve month figure; =SU.FUND("AAPL","revenue","key") is the vendor's current one. Ask for a current-only field without key and the cell says so rather than guessing.

ArgumentTakes
symbolA ticker.
fieldA statement field, a current key field, or a preset name. Statement fields are revenue, costOfRevenue, grossProfit, rnd, sga, operatingIncome, ebit, ebitda, interestExpense, pretaxIncome, taxProvision, netIncome, epsDiluted, sharesDiluted, totalAssets, totalEquity, totalDebt, cash, currentAssets, currentLiabilities, minorityInterest, operatingCashflow, capex, depreciation, freeCashflow, dividendsPaid, buybacks and sbc. Current key fields include marketCap, enterpriseValue, trailingPE, forwardPE, pegRatio, priceToBook, priceToSales, dividendYield, returnOnEquity, currentRatio, debtToEquity, sector, industry, country, employees, sharesOutstanding, floatShares, sharesShort and shortRatio. beta is on the same block but is not a vendor statistic: it is Suros's own beta, regressed on one year of daily closes against the index published for the listing's exchange, and it is #N/A where no index is published for that market. The vendor's own figure is vendorBeta; it does not name the index or window behind it, so it does not compare with beta.
periodOptional. ttm, a year label such as 2025, an annual offset where 0 is the newest reported year, a quarter such as q0, or key for the current block. Defaults to ttm.
=SU.FUND("AAPL","freeCashflow",0)

SU.EST(symbol, period, [field])

One consensus figure, or a preset block. Read the limits section before you build on it.

ArgumentTakes
symbolA ticker.
period0q the current quarter, +1q the next, 0y the current year, +1y the next; next for the next earnings date; h0 to h3 for a reported quarter against its estimate, newest first, as far back as the feed reports; r0 to r3 for a month of analyst recommendations, newest first.
fieldOptional, and it depends on the period. On 0q, +1q, 0y and +1y: eps, epsLow, epsHigh, epsN, epsGrowth, epsYearAgo, revenue, revenueLow, revenueHigh, revenueN, revenueGrowth, revenueYearAgo, epsTrendCurrent, epsTrend7, epsTrend30, epsTrend60, epsTrend90, up7, down7, up30, down30, endDate, growth. On next: date, dateEnd, estimated. On hN: period, date, epsEstimate, epsActual, surprisePct. On rN: period, strongBuy, buy, hold, sell, strongSell. Defaults to eps.
=SU.EST("AAPL","+1y","eps")

SU.SCREEN(scope, [filters], [columns], [limit], [sort], [offset])

The screener, spilled. Filter field names are the screener's own ids, not the output column names, and an id the endpoint does not know is rejected with the reason in the cell.

ArgumentTakes
scopeworld, an index (sp500, ndx, dji, rut, sxxp, sx5e, ukx, dax, cac, aex, ibex, smi, omxs30, omxc25, omxh25, n225, hsi, kospi200, asx200, nifty, sensex, sti) or an exchange (nasdaq, nyse, amex, oslo, stockholm, copenhagen, helsinki, xetra, lse, euronext, amsterdam, six, milan, madrid, tsx, tokyo, hkex, seoul, taiwan, singapore, asx, nse, bse, telaviv, mexico, saopaulo).
filtersOptional. A preset name, or a JSON array of {"field":…,"op":…,"value":…} objects. Operators are gt, lt, gte, lte, between, eq, ne, in, nempty, match. Empty means no filter.
columnsOptional. Display names symbol, name, company, price, change, changePct, volume, relVolume, mcap, ccy, exchange, sector, industry, type, isin, figi, mic, the text columns country, capBasis, statementsCurrency and beta_benchmark, or any screener field id such as price_earnings_ttm or Perf.Y. name is the ticker root the screener stores; company is the company name. Asking for beta_1_year adds beta_benchmark, the index that beta was measured against. Defaults to the preset's own columns, otherwise symbol, company, price, changePct, mcap.
limitOptional. 1 to 200 rows. Defaults to 100.
sortOptional. A field then a direction in one string, "market_cap_basic desc" or "changePct asc". Defaults to the preset's own sort, otherwise market cap descending.
offsetOptional. Matching rows to skip, 0 to 5000. Use it to page past the 200 row cap.
=SU.SCREEN("sp500","[{""field"":""market_cap_basic"",""op"":""gt"",""value"":1e10}]","symbol,company,price,changePct,mcap",50)

Double quotes inside an Excel string argument are doubled. That is Excel's rule, not ours.

SU.SEARCH(query, [count], [columns])

Finds the exact ticker the other functions want.

ArgumentTakes
queryPart of a company name, or a ticker.
countOptional. 1 to 40 rows. Defaults to 10.
columnsOptional. A preset name, or any of symbol, name, type, exchange, exchangeCode, currency, sector, industry, isin, figi, lei. Defaults to symbol, name, exchange, currency.
=SU.SEARCH("equinor",10,"ids")

SU.PEERS(symbol, [limit], [columns])

Comparable companies, matched on industry first, then sector, then exchange, and ordered by how close they are in size.

ArgumentTakes
symbolA ticker.
limitOptional. 1 to 20 rows, which is as many as the endpoint builds. Defaults to 10.
columnsOptional. A preset name, or any of symbol, name, sector, industry, mcap, ccy, exchange, score. score is the size match, 1 being closest. Defaults to symbol, name, sector, mcap.
=SU.PEERS("AAPL",20,"comps")

SU.SYMBOL(symbol)

The canonical form of a renamed ticker. VOLVA.ST comes back as VOLV-A.ST; a ticker that was never renamed comes back as it went in.

=SU.SYMBOL("VOLVA.ST")
=SU.FUND(SU.SYMBOL(A2),"revenue","ttm")

SU.EARNINGS(symbol, [field])

The next earnings report, and the last one.

ArgumentTakes
symbolA ticker.
fieldOptional. date of the next report; status, which is projected until the company sets the date, then confirmed, then reported; time, before open or after close, and #N/A when the company has not said; calendarQuarter, the calendar quarter the report falls in, which is not the fiscal quarter for a company whose year does not end in December; estimate, TRUE while the date is projected; and the last reported quarter as lastReported, lastEps, lastEpsEstimate, lastEpsSurprisePct, lastRevenue, lastRevenueEstimate and lastRevenueSurprisePct. Defaults to date.
=SU.EARNINGS("AAPL","status")

SU.YIELDS([tenors], [days])

The US Treasury constant-maturity curve in percent: a date column, then one column per tenor, oldest first.

ArgumentTakes
tenorsOptional. Any of 1M, 3M, 6M, 1Y, 2Y, 3Y, 5Y, 7Y, 10Y, 20Y, 30Y, comma separated. Defaults to all eleven.
daysOptional. Trading days, 1 to 1300. Defaults to 1, the latest curve. A day a tenor did not print reads #N/A.
=SU.YIELDS("2Y,10Y,30Y",20)

This product uses the FRED® API but is not endorsed or certified by the Federal Reserve Bank of St. Louis.

SU.FEDPATH([columns])

The policy rate fed funds futures price into each upcoming meeting: date, the rate going in (start) and coming out (end), the move (moveBp) and the move from today (cumBp), in basis points.

=SU.FEDPATH("date,end,cumBp")

SU.FEARGREED([field])

Suros's own fear and greed index, 0 extreme fear to 100 extreme greed: seven market inputs, each ranked against its own last 252 sessions and averaged. field is score (the default), rating, asOf, prevClose, prevWeek, prevMonth or prevYear.

=SU.FEARGREED("rating")

SU.POSITIONING(market, [group], [field])

Weekly positioning in 25 financial futures. market is an id such as ZN, ES, 6E or BTC; group is dealer, am (asset managers), lev (leveraged funds, the default), other or small; field is net (the default), long, short, chg (the weekly change in net), pct (where net sits in its last three years, 0 to 100) or share (net as a percent of open interest).

=SU.POSITIONING("ZN","lev","net")

SU.SHORTS(symbol, [field])

Disclosed short positions from the national register that covers the listing. Norway, Sweden, the Netherlands, Germany, France, Finland, Poland, Belgium, Ireland, Denmark and Austria publish named holders; the UK, Hong Kong and Australia publish totals. A US listing gives fails to deliver: shares sold that were not delivered on settlement day, which is not short interest. field is total (the default, a percent of shares, or shares where the register publishes totals), chg30, chg90, unit, register, asOf, or holders to spill the named positions.

=SU.SHORTS("EQNR.OL","holders")

SU.STAKES(symbol, [columns])

Holders of five percent or more of a US registrant, from beneficial ownership filings. Columns from name, stance (active or passive), form, filed, pct, shares, pctChg and accession. Defaults to name, stance, filed, pct and shares.

=SU.STAKES("AAPL")

SU.SUPPLY(symbol, [side], [columns])

Customers or suppliers named in company filings, each placed in a country, with the share of revenue where the filing states it. side is customers (the default) or suppliers; columns from symbol, name, country, pct, fy, form and filed.

=SU.SUPPLY("CRUS","customers")

SU.INSIDERS(symbol, [columns], [limit])

Insider trades in one company filed over the last 90 days in the US and Sweden, newest first. Columns from traded, filed, name, role, group, kind (buy, sell, grant, exercise, tax, other), shares, price, currency, value, valueUsd, holdings and plan (TRUE for a trade under a prearranged plan). Defaults to traded, name, role, kind, shares, price and value; up to 400 rows, 20 by default.

=SU.INSIDERS("AAPL","traded,name,kind,shares,price",10)

SU.INSIDERBUYS([min], [days], [country], [columns], [limit])

The latest open-market insider buys across every company Suros reads in the US and Sweden, newest filing first. min is the smallest buy in US dollars (a buy with no dollar value is left out once it is set), days the look back by filing date, 1 to 90 and 30 by default, and country is US or SE. Columns from filed, traded, symbol, company, country, sector, display (the insider's name), pkey (the insider key SU.INSIDER takes), role, group, shares, price, currency, value, valueUsd, holdings, plan, cluster (TRUE when several insiders bought the same company within a short window) and id. Defaults to filed, traded, symbol, company, display, role and valueUsd; up to 400 rows, 20 by default. A filing arrives days after the trade.

=SU.INSIDERBUYS(100000,7,"US")

SU.INSIDER(insider, [columns], [limit])

Every trade one insider filed over the last 90 days, across companies, newest first. The key is the pkey column of SU.INSIDERBUYS: US: and the filer number for a US insider, or the country, ~ and the filed name for a Swedish one, where the name is all a filing carries. Columns from traded, filed, symbol, company, country, role, group, kind, open, shares, price, currency, value, valueUsd, holdings and plan. Defaults to traded, symbol, role, kind, shares, price and value; up to 500 rows, 20 by default.

=SU.INSIDER(B2,"traded,symbol,kind,shares,price")

SU.HOLDERS(symbol, [columns], [limit])

The largest institutional holders of a US-listed security in the newest quarterly holdings reports, largest first. Columns from name, cik (the manager's filer number, which SU.MANAGER takes), shares, value, pct (the share of the company's shares outstanding), weight (the share of the manager's reported value), change (new, added, reduced, unchanged, soldout), shareChange and prevShares. Defaults to name, shares, value, pct and change; up to 30 rows, 20 by default. Reports are due 45 days after the quarter ends and list long US-listed positions only.

=SU.HOLDERS("AAPL","name,shares,pct,change",10)

SU.MANAGER(manager, [columns], [limit])

One manager's positions in its newest quarterly holdings report, largest first, each marked against the quarter before. The manager is its filer number. Columns from symbol, name, cusip, class, putCall, shares, value, weight, change, shareChange, prevShares and sector. Defaults to symbol, name, shares, value, weight and change; up to 500 rows, 20 by default. A position whose code does not match a ticker has an empty symbol and keeps its cusip.

=SU.MANAGER("1067983","symbol,shares,value,weight,change",25)

Presets

A preset is a named field list you use instead of remembering one. They are the field lists the terminal's own views use, so a preset in Excel returns what the same panel returns in the terminal. Each is named in the formula's own argument help, listed in the Suros pane with an Insert button, and on the ribbon's Presets menu.

A FUND or EST preset spills a two column block, the field name and its value, under a field / value header. A SCREEN, SEARCH or PEERS preset sets the columns, and for SCREEN the filters and the sort as well.

SU.FUND

PresetBlockReturns
incomeFiled statementRevenue, cost of revenue, gross profit, R&D, SG&A, operating income, EBITDA, interest expense, pre-tax income, tax provision, net income, diluted EPS, diluted shares.
balanceFiled statementCash, current assets, total assets, current liabilities, total debt, minority interest, total equity.
cashFiled statementOperating cash flow, capex, depreciation and amortisation, free cash flow, stock-based compensation, dividends paid, buybacks.
valuationCurrent keyMarket cap, enterprise value, P/E, forward P/E, PEG, EPS, P/B, P/S, EV/revenue, EV/EBITDA, beta (measured, see above), dividend yield, 52-week high and low.
returnsCurrent keyRevenue, revenue growth, earnings growth, gross profit, EBITDA, net income, gross margin, operating margin, profit margin, EBITDA margin, return on equity, return on assets.
healthCurrent keyOperating cash flow, free cash flow, total cash, total debt, total assets, book value per share, current ratio, quick ratio, debt to equity, payout ratio.
profileCurrent keySector, industry, country, exchange, employees, shares outstanding, float, shares short, short ratio, short percent of float.

The three statement presets take a period: =SU.FUND("AAPL","income","0") is the newest reported year, "q0" the newest quarter, "ttm" the trailing twelve months. The four current presets have no periods, so leave the argument out.

=SU.FUND("AAPL","income","0")
=SU.FUND("AAPL","valuation")

SU.EST

PresetPeriod it readsReturns
consensus0q, +1q, 0y, +1yEPS mean, low, high and analyst count; revenue mean, low, high and analyst count; the year-ago figures; the period end date.
revisions0q, +1q, 0y, +1yThe EPS estimate now and as it stood 7, 30, 60 and 90 days ago, and how many analysts raised or cut in the last 7 and 30 days.
surpriseh0 to h3One reported quarter: its label, its date, the estimate, the actual, and the surprise in percent.
ratingsr0 to r3One month of the recommendation split: strong buy, buy, hold, sell, strong sell.
=SU.EST("AAPL","+1y","consensus")
=SU.EST("AAPL","h0","surprise")

SU.SCREEN

The first five are the screener's own server presets and set their own sort, so leave the sort argument out with those. The other eight are the filter sets behind the screener's preset chips.

PresetReturns
gainersThe biggest risers in scope today, with change, volume and market cap.
losersThe biggest fallers in scope today, same columns.
activeThe most value traded today, with value traded, volume and market cap.
high52Names within 1% of their 52-week high, with that high and the one-year return.
low52Names within 1% of their 52-week low, same columns.
qualityReturn on equity over 15, return on invested capital over 10, net margin over 10. Sorted on return on capital.
cheapqualityP/E between 0 and 15, return on equity over 12, debt to equity under 1. Sorted on market cap.
growthRevenue growth over 20% with a gross margin over 40%. Sorted on revenue growth.
cashFree cash flow margin over 15% at a price to free cash flow between 0 and 20. Sorted on free cash flow.
incomeDividend yield over 3% with a payout ratio under 80%. Sorted on yield.
netcashNet debt below zero with a current ratio over 1.5. Sorted on market cap.
momentumUp over 10% in three months, up over the year, RSI between 50 and 75. Sorted on the three-month return.
oversoldRSI under 30 after a month down more than 10%. Sorted on RSI, weakest first.
=SU.SCREEN("sxxp","quality","",50)

SU.SEARCH and SU.PEERS

PresetReturns
refSearch: ticker, name, instrument type, exchange, currency.
idsSearch: ticker, name, ISIN, FIGI, LEI. Only rows from the Suros symbol master carry identifiers; a row that came from the upstream search reads #N/A in those columns.
compsPeers: ticker, name, sector, industry, market cap, currency.
sizingPeers: ticker, name, market cap and the size-match score.

The ribbon

The add-in installs its own top-level SUROS tab with five groups. Every insert button follows one rule: if the selected cell holds a ticker, the formula goes in the cell to its right and uses that ticker; otherwise it goes in the selected cell and uses AAPL.

GroupWhat it does
Data Writes one formula. Price and History are their own buttons. Company is a menu of Fundamentals, Estimates, Peers and Search. Screen writes a worked screen over the S&P 500. Presets is a menu with one entry per preset family: income statement, balance sheet, cash flow, valuation, consensus, comparables and the quality screen.
Valuation Adds a valuation model as a new sheet. Valuation template opens the template gallery in the Suros pane. Models is a menu of the twelve valuation and cross-check models, Analysis a menu of the six analysis sheets, all listed below.
Templates Adds a sheet. Watchlist is your tickers in column A with price columns beside them. One-pager is one company: price header, ten statement lines over four periods, ratios computed from those cells, consensus estimates, peers, and the valuation and consensus preset blocks out to the right, all driven by the symbol in B3. Screen sheet is a filter block that builds the filter JSON and feeds a screen below it. All three write formulas, never values.
Refresh Selection recalculates the selected range; Workbook recalculates everything. Excel custom functions are not volatile, so this is how an SU formula fetches again. Both re-run every other formula in scope as well, which on a large workbook takes a while.
Account Suros pane opens the task pane: the key, its status, the connection test, the valuation template gallery, the function reference and the preset list, each with an Insert button. Help opens this page.

Valuation templates

Each template builds a new sheet in which every computed cell is a formula and the market figures are SU calls, so the sheet stays connected and a figure that cannot be sourced reads #N/A with its reason. Select a cell holding a ticker first and the sheet is built for that company; otherwise it uses AAPL. The conventions are the terminal's own: net debt in the cost of capital and in the equity bridge, tax struck on unlevered operating profit, an exit multiple discounted the full horizon with no mid-year uplift, and interest accrued on the opening debt balance. Where a sheet builds a cost of equity by CAPM, it starts from Suros's measured beta against the listing's local index and the latest US 10-year Treasury yield. Every other assumption, from growth and margins to the tax rate and the equity risk premium, is left blank for you to type, and the cells that use a blank one read #N/A until you do.

TemplateMenuWhat the sheet does
Discounted cash flowModelsFree cash flow to the firm over ten years, fading to a terminal rate, with the WACC built from its parts, the full equity bridge and an exact WACC-by-growth sensitivity grid.
Stable DCFModelsOne normalised year capitalised for ever, for a business whose margin and growth have stopped moving.
Flow to equityModelsCash flow after interest and net borrowing, discounted at the cost of equity. Lands on equity value directly.
Adjusted present valueModelsThe unlevered business plus the interest tax shield, discounted at the rate the leverage policy implies, with APV, WACC and flow to equity reconciled against each other.
Dividend discountModelsOne or two stages on the dividend, with a check on whether the growth is funded by retained profit.
Residual incomeModelsBook value plus what is earned above the cost of equity, fading. For a leveraged balance sheet.
Economic profitModelsInvested capital plus the present value of the spread over the cost of capital.
AFFO capitalisationModelsFunds from operations less recurring capital spending, capitalised. For property.
Mid-cycle cash flowModelsRebuilt from a mid-cycle price, a volume and a cash cost, so the cycle is an input.
Sum of the partsModelsA segment table you fill in from the accounts, summed to enterprise value and taken across the same bridge.
Trading comparablesModelsPeers with current multiples, the median applied to the subject four ways.
Football fieldModelsEvery method as a range rather than a point, laid out ready to chart.
Cost of capitalAnalysisUnlevers the comparables on debt over value, relevers on debt over equity, and reads off the WACC and the unlevered rate an APV needs.
Capital budgetingAnalysisOne project on incremental cash flow: NPV, IRR, the profitability index and payback, with sunk cost excluded.
Merger and synergiesAnalysisThe premium against the synergies that would justify it, and separately whether earnings per share moves.
Leveraged buyoutAnalysisEntry, a cash sweep debt schedule, exit, and the return split into debt paydown, growth and multiple expansion.
Option pricingAnalysisBlack-Scholes, the Greeks, a replicating portfolio, put-call parity, and equity read as a call on the assets.
Real optionsAnalysisThe options to wait, to expand and to abandon, priced, so a project with a negative NPV is judged on what it is worth.

Outside Excel: the REST API, the MCP server and Python

Four ways into the same data: a REST API, an MCP server, a Python SDK and the Excel add-in this page describes. Each runs on the same data layer and the same account, and takes the same key, so a figure read in a spreadsheet is the figure the terminal shows. The SHA-256 of every download below is in SHA256SUMS.txt.

The REST API

The data behind the terminal over /api/v1, with a key of your own that begins ss_ and travels as a bearer token. Twenty endpoints: quote, history, fundamentals, estimates, screen, peers and search; aliases for the canonical form of a renamed ticker; earnings for the next report with its status, session and the last quarter, and earningscalendar for the calendar; yields for the Treasury curve, fedpath for the rate path and feargreed for Suros's own index; positioning in financial futures, shorts from fifteen national short registers, stakes for five percent holders, adviser for registered investment advisers, supplychain for customers and suppliers placed by country, insiderflow for insider trades filed in the US and Sweden, and holdings13f for institutional holdings from quarterly 13F reports. Keys come with a subscription: sixty requests a minute on the Equities analyst and Commodity trader plans and six hundred on Pro and the beta, or inside an organisation that is itself on Pro, with the limit, what is left of it and the reset stamped on every answer. The plan behind the key decides what it may read, as it does in the terminal.

curl -H "Authorization: Bearer $SUROS_API_KEY" \
  "https://surossystems.com/api/v1/quote?symbols=AAPL,EQNR.OL,VOLV-B.ST"
curl -H "Authorization: Bearer $SUROS_API_KEY" \
  "https://surossystems.com/api/v1/earnings?symbols=NVDA"

The whole contract is openapi.json.

The MCP server

A stdio MCP server that hands those same twenty endpoints to an AI assistant as tools, with one more, suros_coverage, that says how many listings and exchanges the data covers. You ask the assistant a question in your own words and it queries Suros directly, so the answer comes off the data rather than out of the model's memory.

Claude Desktop. Download suros.mcpb and double-click it, or install it from the Settings window in Claude Desktop. It asks for your API key, keeps it in the system keychain, and runs on Claude Desktop's own Node, so there is nothing else to install.

Other MCP clients. Download suros-mcp-server.zip and unzip it. The server is one file, server.mjs, on Node 18 or newer; it reads your key from SUROS_API_KEY, and the path to the file must be absolute.

Claude Code. One command adds it for every project on your machine:

claude mcp add suros --scope user -e SUROS_API_KEY=ss_... -- node /full/path/to/server.mjs

Codex. Add it to ~/.codex/config.toml:

[mcp_servers.suros]
command = "node"
args = ["/full/path/to/server.mjs"]
env = { SUROS_API_KEY = "ss_..." }

Cursor. Add it to ~/.cursor/mcp.json for every project, or to .cursor/mcp.json in one project:

{
  "mcpServers": {
    "suros": {
      "command": "node",
      "args": ["/full/path/to/server.mjs"],
      "env": { "SUROS_API_KEY": "ss_..." }
    }
  }
}

Restart the assistant or reload its tools, then ask it something only the data can answer, such as the latest insider buys in a company you follow. On Windows write the path with forward slashes. The REST API answers these assistants too, if you would rather let one call it over HTTP with the same key.

The Python SDK

One file on the standard library, no dependencies, one method per endpoint, on Python 3.9 or newer: su.history("NVDA", range="5y", interval="1wk") hands back the candles as raw JSON. An upstream that cannot be reached arrives as {"source": "unavailable"} rather than a number somebody invented, and to_frame turns any payload into a pandas frame where pandas is installed. Install it with pip:

pip install https://surossystems.com/clients/suros-1.3.0-py3-none-any.whl

or download suros-python-sdk.zip and put suros_client.py next to your script. Either way it is from suros_client import Suros.

from suros_client import Suros, to_frame
su = Suros()  # reads SUROS_API_KEY
weeks = su.history("NVDA", range="5y", interval="1wk")
df = to_frame(weeks)
curve = to_frame(su.yields())  # one column per tenor, by date

Example: polling the insider feed

A script that asks the insider feed for open-market buys every 15 minutes, keeps those of $250,000 or more, marks a buy that is part of a cluster of insiders buying the same company, and prints each filing once. Every trade row carries an id that belongs to one line of one filing and stays the same between calls, so a set of the ids already seen is all the deduplication it needs. The first pass prints the last three days; after that only new filings. Four calls an hour is far inside either rate limit. A filing arrives days after the trade and the feed sees it only once it is published, so this tells you what an insider did, not what they are doing. It prints and places no order; what it does with a filing is up to you.

import time
from suros_client import Suros, SurosError

su = Suros()  # reads SUROS_API_KEY
seen = set()
while True:
    try:
        got = su.insider_trades(kind="buy", days=3, min=250000, limit=500)
    except SurosError as e:
        got = {"why": str(e)}
    if "feed" not in got:
        print("feed not read:", got.get("why") or got.get("error"))
    for t in reversed(got.get("feed") or []):
        if t["id"] in seen or not t["open"]:
            continue
        seen.add(t["id"])
        mark = "cluster" if t.get("cluster") else ""
        print(t["filed"], t.get("symbol") or t.get("company"), t.get("display"), t.get("role"), t.get("valueUsd"), mark)
    time.sleep(15 * 60)

Limits, and what is missing

The namespace is SU, and every function lives under it. Excel binds a workbook's formulas to the namespace that was registered when they were typed, so a sheet built here keeps working as long as the add-in is loaded on the machine opening it. Open that file somewhere the add-in is not installed and the cells read #NAME? until it is: the formulas are still there, Excel just has nothing to resolve them against.

Consensus estimates are not ours. SU.EST reads a third-party consensus feed Suros does not license itself. When that feed does not answer for a symbol, the cell reads #N/A with that reason, and a consensus or revisions block reads #N/A all the way down. Treat a working SU.EST as a bonus, not as a guarantee, and do not build a model that quietly assumes it resolved.

An absent figure is absent. Nothing falls back to zero, to a blank that reads as zero, or to a stale number. Every #N/A carries a sentence saying which figure is missing and why. That holds inside a spilled range: one missing close in one candle is one #N/A cell, not a zero in a column of prices. A symbol your plan does not include reads #N/A saying so, and a screen or search that lost rows to the plan says how many in a closing row of #N/A, or in a single #N/A when it lost them all, rather than passing for a complete or an empty result.

The screener answers for the fields it has built. The nightly build populates about a hundred fields from company filings, public identifier registries and the price feed. A field outside that set is refused by the formula rather than spilling a column of blanks, because the endpoint drops an id it does not know without saying so. Money fields are in each listing's own currency and are not converted, so ranking two listings on a raw reported figure ranks the currencies as much as the companies.

Prices are delayed and are not licensed for redistribution. Fifteen minutes or more, depending on the exchange. Nothing here is a real-time quote and nothing here is suitable for trading on. Taking the data out of the workbook and republishing it is not permitted. The restriction is in the terms, and the sources whose licence asks for a credit are named, with that credit, on the data sources page.

Rate limits are per key, per minute. 60 on standard, 600 on pro and beta, and no key at all without a subscription. A limited call returns the reason in the cell rather than a stale value; wait a minute and recalculate.

The buttons have no icon art. Every ribbon control uses the Suros mark.

Help and support

Questions, bugs and feature requests go to hello@surossystems.com, security reports to security@surossystems.com. Whether the service is up right now is on the status page.