Module D · Exploration & Scanning - Chapter 18

Exploration: the Analysis Window

Turn AFL into a spreadsheet over your whole watchlist with Filter and AddColumn.

Exploration
What you'll learn
  • ·The Analysis window
  • ·Filter = the row switch
  • ·AddColumn & AddTextColumn
  • ·Decimal formatting
  • ·Running over a watchlist
  • ·Range, date and N-bars settings

So far our formulas have spoken to one chart at a time. Now we open the door to AmiBroker's other half - the Analysis window - where the same AFL runs across your entire watchlist and hands you back a spreadsheet. Want a table of every stock in the NIFTY 50 with its close, RSI and 20-day EMA, sorted however you like? That is an Exploration, and it is one of the most useful things AFL can do.

Good to know

An Exploration is a backtest's twin: both run the same AFL across your whole watchlist. The Exploration just prints columns instead of simulating trades - and it can sweep thousands of symbols in seconds.

This chapter is the on-ramp. We will turn a formula into a table with just two ideas - a Filter that decides which rows appear, and AddColumn calls that decide which numbers show.

The Analysis window

Everything in this module happens in the Analysis window, not on a chart. Open a new Analysis (from AmiBroker's Analysis menu or toolbar) and you get a small control bar with a few choices and four buttons: Explore, Scan, Backtest and Optimize. We are interested in Explore.

Before you press it, you tell the window three things:

  • Apply to - which symbols to run over: the current symbol, all symbols, or a watchlist (a named group like "NIFTY 50" or "F&O stocks").
  • Range - which bars to use: the most recent n bars, a date range, or all data.
  • The formula - loaded from the Formula Editor via "Send to Analysis" or selected directly.

Press Explore and AmiBroker runs your formula once per symbol and fills a results grid with the rows and columns you asked for.

Filter: the row switch

In an exploration, one special variable decides whether a symbol's bar earns a row in the table: Filter. Think of it as a light switch per bar.

  • Filter = 1; - the switch is always on, so every bar of every symbol shows.
  • Filter = condition; - the switch is on only where your condition is true, so only matching bars show.
// Show a row for every symbol (no filtering yet)
Filter = 1;

That single line is the difference between a full dump and a screener. We will lean on it heavily, but for our first exploration we want to see everything, so we keep Filter = 1.

Key idea

Filter is the row switch of an exploration. Filter = 1 shows all rows; Filter = someCondition shows only the rows where that condition is true. Master this one line and you understand explorations.

AddColumn: choosing what to show

With rows decided, AddColumn decides the columns. Each call adds one column to the table:

AddColumn( array, "Heading", format );
  • array - the values to show, one per row (the selected bar of each symbol).
  • "Heading" - the column title.
  • format - how to display the number. The common one is 1.2, meaning "show 2 decimal places". 1.0 means no decimals (good for volume), 1.3 means three.

Here is a complete first exploration - close, RSI, volume and a 20-EMA for every symbol:

_SECTION_BEGIN( "First Exploration" );

Filter = 1;  // no conditions yet - show all symbols

AddColumn( Close,           "LTP",    1.2 );
AddColumn( RSI( 14 ),       "RSI",    1.2 );
AddColumn( Volume,          "Volume", 1.0 );
AddColumn( EMA( Close, 20 ), "EMA20", 1.2 );

_SECTION_END();

Apply this to a watchlist, press Explore, and you get a clean grid: one row per stock, four columns of numbers. Already this is a usable screener you can sort by clicking any heading.

Decimal formatting in practice

The format number reads as "digits before . digits after", but in practice only the part after the dot matters for everyday use - it sets the decimals. A few rules of thumb:

  • Prices and indicators: 1.2 (two decimals).
  • Whole-number counts like volume: 1.0.
  • Ratios and fine values: 1.3 or more.

Getting decimals right is not fussiness - a column of volumes with two trailing zeros is harder to scan than a clean integer column.

Tip

Keep your columns to what you will actually read. A table with six well-chosen columns is more useful than one with twenty. You can always add more later; start lean.

AddTextColumn: words instead of numbers

Not every column is a number. When you want to show text - a status label like "Bullish" or "Oversold" - use AddTextColumn with a string array, usually built from WriteIf:

trendUp   = Close > EMA( Close, 50 );
trendText = WriteIf( trendUp, "Bullish", "Bearish" );

Filter = 1;
AddColumn( Close, "Close", 1.2 );
AddTextColumn( trendText, "Trend" );   // a words column

AddTextColumn is how status dashboards-in-a-table are built: a column of "Bullish / Bearish", "Overbought / Oversold", "Above / Below VWAP" tells a richer story than a raw number. We will colour these cells in a later chapter.

Note

AddColumn expects a number array; AddTextColumn expects a text array. Pair them with their natural partners: IIf (numbers) feeds AddColumn, and WriteIf (text) feeds AddTextColumn.

Running over a watchlist, and choosing the range

Two settings turn a one-symbol formula into a market-wide screen:

  • Apply to a watchlist. Build a watchlist once (right-click symbols, add to a list), then point the "Apply to" box at it. The same formula now runs over every member.
  • Set the range. For a "right now" screen, choose the last 1 bar (or a recent n bars) so the table shows the latest reading. For a study across time, pick a date range and every matching bar in that window becomes a row.

The Range setting is easy to overlook and is the usual reason a beginner sees "too many" or "too few" rows. If your table has one row per symbol, you are on the last bar; if it has hundreds, you are scanning a date range.

Heads up

Range "1 recent bar" gives you a snapshot - one row per symbol, today's values. A wide date range with Filter = 1 can produce thousands of rows (every bar of every symbol). Pick the range that matches your question before pressing Explore.

Try it yourself

  • Run the four-column exploration on a watchlist of 10-20 stocks with the range set to "1 recent bar".
  • Add an AddTextColumn that prints "Above 200 EMA" or "Below 200 EMA".
  • Change the range to a 30-day window and watch the row count multiply - one row per matching bar.
  • Click a column heading to sort, and find the highest-RSI name in your list.

Recap

  • The Analysis window runs one formula across a watchlist; press Explore to build a table.
  • Filter is the row switch: Filter = 1 shows all, Filter = condition shows only matches.
  • AddColumn( array, "name", 1.2 ) adds a numeric column; the format sets the decimals.
  • AddTextColumn adds a words column, usually fed by WriteIf.
  • Apply to chooses the watchlist and Range chooses the bars - set both before exploring.

Next we sharpen the Filter from "show everything" to "show only the setups I care about" and build real signal scanners.