EquationDB

← Back to all articles

Why we built Apps and Dashboards

10 October 2026 · EquationDB team

A query answers one question, once. You write it, read the result and move on. A desk does not work that way. It asks the same question about whichever symbol is in front of it, wants six answers side by side, and wants them again tomorrow morning without retyping anything.

Before apps there were two ways to get that. You could keep a file of saved queries and edit the ticker by hand, which stops working after a handful of names. Or you could ask engineering for a screen, which turns every new question into a ticket. Apps and dashboards sit between the two. They are in the product under My › Apps and My › Dashboards, and the full reference is Apps & dashboards.

An app is a saved query with a slot in it

An app is any read-only EquationDB statement, in the market language or in SQL, with {symbol} where the symbol goes or {universe} where a list goes. It has a name, a category, a view (table, chart, pivot, or a card of labelled tiles) and a refresh setting: when opened, on a button, or every 1, 5 or 15 minutes. The simplest sample, Technical summary, has nothing else:

GET {symbol} SELECT close, rsi(14), sma(50), sma(200), adx(14), atr(14), rvol(20), dist_high(252)

Open it, type a ticker and you get one card: the last close, RSI, the 50 and 200-day averages, trend strength, ATR, relative volume and the distance from the 52-week high. Type another ticker and the same card fills again. Nobody edited a query.

Inputs: the parts of a question that change

The symbol is rarely the only thing that changes. One analyst wants a 21-day RSI, another wants two years of history, a third wants the screen for a different sector. So an app can declare inputs: named controls whose value goes into the query where you wrote {name}. There are twelve types: dropdown, multi-select, number, slider, toggle, text, date, date range, symbol, list, bar size and period.

RSI history has a slider and a period:

GET {symbol} SELECT rsi({length}) AS rsi LAST {period}

{length} is a slider from 2 to 50 that starts at 14. {period} is a dropdown from one month to five years that starts at six months. The AS rsi matters: it gives the column a fixed name, so the chart keeps its settings wherever the slider is.

Sector screen uses four inputs of four different types:

GET {universe} WHERE sector = {sector} SELECT symbol, name, close, ret, {metric} AS metric SORT metric {order} LIMIT {top}

{sector} is a dropdown filled from the database's own list of sectors. {metric} is a dropdown of expressions: one-month return, three-month return, RSI, distance from the 52-week high or relative volume. {order} is a toggle between highest first and lowest first, and {top} is the number of rows, from 5 to 100.

Rare events across a list turns the event index into a monitor:

EVENTS * IN {universe} LAST {window} WHERE rarity >= {rarity} SORT rarity DESC

{window} runs from one day to one month and {rarity} is a slider from 50 to 99, starting at 95. Rarity is the percentile of an event's size against the same stock's own past occurrences, so the slider means "how unusual, for that stock".

Beta vs a benchmark takes a second symbol:

ANALYZE beta {symbol} VS {benchmark}

{benchmark} is a symbol box that starts at SPY. The result is one row: beta, annualised alpha, R-squared, correlation, and up and down capture.

Every input can also be set from the link. #/apps/s.rsi?symbol=NVDA&length=21&period=1y opens the RSI app on those values, and the address changes as you move the controls, so a link you copy opens the view you were looking at.

A dashboard, and why its panels have colours

A dashboard is a grid of apps. Each one has a width, a height and, optionally, a link group: red, green, blue or amber, shown as a coloured edge on the panel. Apps in the same group show the same symbol.

The sample Oversold screen & chart is the shortest way to see why that matters. It has five apps, all in blue:

  1. Oversold screen, a table over the 500 largest US stocks: GET {universe} WHERE rsi(14) < {threshold} SELECT symbol, name, close, rsi(14), dist_low(252) SORT rsi(14) LIMIT {top}
  2. Price chart, daily candles with volume: GET {symbol} SELECT open, high, low, close, volume LAST {period}
  3. Technical summary, the card from above.
  4. RSI history, the slider app from above.
  5. Recent events, rarest first: EVENTS * IN {symbol} LAST {period} SORT rarity DESC

Click a row in the screen. Instead of opening the symbol page, the symbol goes to the blue group: the chart, the card, the RSI and the events all re-run for that stock. Work down the screen and you have reviewed twenty oversold names without typing one.

Now change Period on the chart. The RSI and the events change with it, because inputs with the same name and type in the same group stay in step. Only the apps that have that input re-run; the screen does not. Move the screen's RSI threshold and only the screen re-runs, because no other app has that input. You can take any input out of its group if one panel should keep its own value.

Two groups on one dashboard give you a comparison. Two-stock compare puts quote, moving averages, valuation and drawdowns in red on the left and the same four in blue on the right. In FX & crypto desk the currency table drives the green charts and the crypto table drives the amber ones, and each colour keeps its own Period. A dashboard remembers the last symbol and the last input values of each group, so it reopens where you left it.

Samples, and sharing with your firm

Apps and dashboards both ship with samples: more than forty apps in ten categories, from quotes and technicals to events, themes, currencies and risk, and six dashboards. Use this copies a sample into your own, where you can change the query, the inputs and the view.

An app or a dashboard is private until you share it with your firm. Shared means read-only for colleagues: they can change the symbol and the inputs for themselves, which is not saved, and they can duplicate it. If a shared dashboard contains an app that is still private to you, colleagues see that panel as unavailable, not its data.

Inputs cannot change what a query does

Putting user-supplied values into a query is how injection bugs happen, so this part was designed first.

  • An app only reads. A statement that creates or changes something is refused when you save the app.
  • {symbol} is replaced only by a ticker the database recognises, and {universe} only by a list name. Anything else is rejected before the query runs.
  • A value never reaches the query as the text that was typed. Numbers are read as plain decimals and written back as digits. Dates are read as dates. A dropdown, multi-select or toggle value must be exactly one of the choices the author declared. Text is limited to a safe character set and is always quoted.
  • A value outside its range, a missing value with no default, or a value for an input the app does not have is an error that names the input.
  • Every declared choice is checked when the app is saved, and the statement that actually runs is checked as read-only again on every run.

We tried the obvious attacks while writing this. A symbol with a second statement appended came back as "is not a symbol". A slider value that tried to close the bracket and continue the query came back as "is not a number". A length of 500 came back as "above the maximum 50". None of them reached the engine.

Every run is also an ordinary query on your account, so your plan's rate limit, row limit and time limit apply to apps as they do to anything else.

What this means for agents

For an agent, an app is a named tool with typed parameters. Handing an agent a query language means trusting it to write every statement correctly. Handing it an app means it picks a name and fills in values that have a type, a range and a list of allowed choices:

POST /v1/apps/s.rsi/run
{"symbol": "NVDA", "values": {"length": 21, "period": "1y"}}

The response is the result page plus two things worth having in a log: q, the exact statement that ran, and values, each input as the server understood it. The agent cannot leave read-only, cannot pass a value the author did not allow, and what it did can be replayed by a person in the query editor. The list of apps an account can see is GET /v1/apps, and the API section of the reference has the rest.

Where to start

Open Dashboards, press Use this on Single stock deep-dive and type a ticker you know well. Then open Apps, duplicate the sample closest to a question you ask every morning, and change the query until it is yours.