Skip to content
Level 2 · AmiBroker AnalystLessonPart 12 · page 1 of 928 min
28Minutes
5AFL functions
5Sources
StandardRequires
AFL functions taught here5

The Analysis Window and Its Four Modes

By the end of this lesson you will be able to look at any formula and say, before running it, which of AmiBroker’s four Analysis modes it is written for — and what will happen if you press the wrong button. That last point is not a curiosity. Pressing Scan on a formula written for Exploration is the most common cause of the complaint “my screen returns nothing”, and it produces no error message of any kind.

Open the Analysis window with File → New → New Analysis, or the Analysis → New Analysis menu, or the New Tab (+) button, or by pressing Send to Analysis in the Formula Editor. The window that appears has been AmiBroker’s analysis engine since version 5.50, when it replaced the older Automatic Analysis window.

Across the top sit the controls that decide what the run examines:

  • Formula — the AFL file that will be executed.
  • Apply to — which symbols. Three choices: All symbols, Current symbol, or Filter.
  • Filter — a button, next to the combo, that opens the Filter Settings window where the “Filter” option’s meaning is defined.
  • Range — which bars. All quotations, N recent bar(s), N recent day(s), or From-To dates.
  • Settings — the back-tester’s settings, plus a drop-down carrying Sync chart on select, Wait for backfill, Auto repeat Scan/Explore and Auto repeat interval.

And then the four action buttons that decide how it examines them: Scan, Explore, Backtest and Optimize. Below all of that is the result list, with tabs for the result list itself and for run information.

The critical thing to internalise is that the four buttons run the same formula file. They do not run different files, and AmiBroker does not check that the formula matches the button. Each mode simply honours a different part of your code and ignores the rest, silently.

What one Analysis run actually does

  1. Apply toBuilds the list of symbols: all, current, or those matching the Filter Settings
  2. For each symbolLoads its bars and runs the whole formula once, on its own thread
  3. RangeDecides which of those bars count as "in range" for reporting
  4. ModeScan reads Buy/Sell/Short/Cover; Explore reads Filter and the AddColumn calls
  5. Result listRows stream in while the run is still going, and can be sorted and exported
Apply to and Range are settings, not code. The same formula behaves completely differently when they change.

A Scan searches through the selected symbols and the selected range of quotations for the buy and sell signals defined by your trading rules. When one of those conditions is satisfied, AmiBroker writes a line saying when it happened and on which symbol. It then carries on to the end of the range, so a single symbol can produce several lines.

Two consequences follow, and both surprise people:

  1. A Scan is driven by Buy, Sell, Short and Cover. These are predefined variables. If your formula never assigns any of them, a Scan has nothing to report and returns an empty list, no matter how elaborate the rest of the formula is.
  2. The columns are fixed. Ticker, date and time, the signal type, the price. You do not design them, and AddColumn() calls in the formula produce no output at all in Scan mode.

Repeated appearances of one symbol are by design. If you scan five years of daily data for a moving-average crossover, a symbol that crossed eleven times gives you eleven rows. That is the honest answer to the question “when did this happen?”. If you wanted “is it happening now?”, the answer is to narrow the Range, not to complain about the output.

An Exploration works, in AmiBroker’s own framing, in a similar way to a Scan — but instead of reporting only buy and sell signals it generates a customisable screening report that can carry far more information.

The mechanism is one predefined variable and one function family:

  • Filter decides which rows appear. Where Filter is true for a given symbol and bar, that bar becomes a row.
  • AddColumn() and its relatives decide what those rows contain.

That is the entire contract. Filter = Close > 50; accepts every symbol and every bar whose close exceeded fifty. Filter = 1; accepts everything. If Filter is never assigned, the exploration produces no rows — there is no implicit default.

The other two buttons are Parts 28 to 33’s subject, but they belong to the same window and they share the same Apply to and Range settings, so it is worth knowing what they are now.

A Backtest takes the same Buy/Sell/Short/Cover signals a Scan reports and simulates trading them: entering, exiting, sizing positions, tracking capital across a portfolio. Where a Scan says “a signal occurred here”, a backtest says “and here is what would have happened to an account that acted on every one of them, under these assumptions”. The gap between those two statements is where most of the second half of this course lives.

An Optimization runs the backtest repeatedly across a range of parameter values and reports the results of every combination. It is the easiest way in the entire program to produce an impressive number that means nothing, which is why Part 31 spends a whole part on doing it responsibly.

For now, one practical note: Status("action") returns actionBacktest for optimization runs as well as backtests, and the documentation warns that this same value is used in other contexts such as code check. If you ever need to distinguish precisely, the finer-grained Status("ActionEx") exists.

Because the button decides which half of your code is honoured, a formula can legitimately contain both halves and choose at run time:

Fragment — not a complete formula

if( Status( "action" ) == actionScan )
{
// Only reached when the Scan button was pressed.
Buy = Cross( Close, MA( Close, 50 ) );
Sell = Cross( MA( Close, 50 ), Close );
}
else
{
Filter = Status( "lastbarinrange" ) AND Close > MA( Close, 50 );
AddColumn( Close, "Close", 1.2 );
}

Status("action") returns a number, and AmiBroker defines named constants for the values: actionIndicator (1), actionCommentary (2), actionScan (3), actionExplore (4), actionBacktest (5) and actionPortfolio (6). Use the names; the numbers exist only for backward compatibility.

The Apply to combo has exactly three settings, and from AFL you can read which one is active with GetOption("ApplyTo"), which returns 0 for all symbols, 1 for the current symbol and 2 for filter.

All symbols does what it says: every symbol in the database, including any artificial composite tickers you have created and any index symbols you have imported. That is rarely what you want for a stock screen, and the composites are a real nuisance because their “prices” are index values that happily pass price and trend filters.

Current symbol examines only the symbol selected in the Symbol window. It is for debugging, not for screening — but it is also the setting most likely to be left over from yesterday’s debugging session, and it produces exactly one row where you expected two hundred.

Filter runs on the symbols matching the criteria in the Filter Settings window, opened with the Filter button. There you can restrict the run to a market, group, sector, industry or watch list, include only favourites or only indexes, and — importantly — set both an include and an exclude filter. Multiple categories combine with logical AND: selecting a market and a sector passes only the symbols that belong to both, which is a conjunction, not an alternative. That catches people out regularly.

There is also an AFL-side kill switch. Assigning a true value to the predefined variable Exclude removes the current symbol from the run entirely — useful for dropping composite tickers by name, and complementary to the UI filter rather than a replacement for it. Note the documented side-effect: excluded symbols are also left out of buy-and-hold reference calculations in a backtest.

The Range combo offers All quotations, N recent bar(s), N recent day(s) and From-To dates. To set N you pick, for instance, “1 recent day(s)”, then type the number and press ENTER — the label rewrites itself to “15 recent day(s)”. You type only the number.

Range is shared by all four modes: the exploration uses the same range and filter settings that the back-tester and the scanner use. This is convenient and it is also a trap, because a From-To range you set for a backtest three weeks ago is still there when you run today’s screen, and the screen will faithfully report on bars from three weeks ago without complaint.

Two things are worth knowing about narrow ranges. First, for pure AFL, AmiBroker works out by itself how much history each function needs and supplies it, plus at least thirty extra past bars; you do not have to widen the range manually just to warm up a moving average. Second, that automatic inference cannot be done for a formula that uses a script or an external DLL, which is what SetBarsRequired() exists for. Part 36 returns to this under the name QuickAFL.

The New Analysis window is multi-threaded: one operation on one symbol is one thread, so N symbols can occupy N threads. The Standard edition allows up to two threads per Analysis window and the Professional edition up to thirty-two, capped in both cases by the number of logical processors Windows reports. Nothing in this part behaves differently between the editions; only the wall-clock time does.

The window is also non-blocking. Results appear in the list while the run is still going, and you can scroll and sort them meanwhile.

One further consequence of threading matters later in this part: because symbols are processed in parallel and in no guaranteed order, any code that must run exactly once per run needs a defined place to live. AmiBroker provides one. The statement if( Status("stocknum") == 0 ) is recognised specially: AmiBroker detects it, runs the very first symbol single-threaded, waits for it to finish, and only then launches the remaining threads. Status("stocknum") is zero-based, so symbol zero is the first one. The documentation is explicit that this statement must not be placed inside an #include file, or the detection does not happen.

Before this lesson, “running a formula across the market” was one idea. It is actually four operations that share a window, a formula file and two settings, and that honour completely different parts of your code. The formula you write is only half of what determines the output; Apply to and Range are the other half, they are not stored in the formula, and they are where a surprising proportion of screening failures actually live.

Check your understanding

Question 1. A formula assigns Filter and calls AddColumn() four times. It defines no Buy or Sell. What does pressing the Scan button produce?
Show the answer and why

Answer: An empty result list and no error

Scan honours Buy/Sell/Short/Cover and ignores Filter and AddColumn. With no signal variables assigned there is nothing to report, and nothing is wrong, so no error appears. This silence is the point: the mode mismatch is invisible.

Question 2. In the Filter Settings window you tick a market AND a sector. Which symbols enter the run?
Show the answer and why

Answer: Only symbols in both that market and that sector

Multiple categories combine with logical AND — a conjunction, not an alternative. Selecting several categories therefore narrows the universe much faster than people expect, and is a routine cause of a run examining far fewer symbols than intended.

Question 3. Which of these are decided by the Analysis window settings rather than by the formula? Select all that apply.
Show the answer and why

Answer: Which symbols the formula runs on, Which bars count as being in range, Whether Buy/Sell or Filter/AddColumn is honoured

Apply to sets the universe, Range sets the bars, and the button pressed sets the mode. Only the columns come from the formula. This is why a formula alone is not a reproducible piece of research: the settings must be recorded too, which is what an .APX analysis project file stores.

Question 4. A scan over ten years of daily data reports the symbol AAA on seven different dates. What does that tell you?
Show the answer and why

Answer: The rules produced a signal on seven bars in the range, which is how Scan works

A Scan proceeds to the end of the range and reports every signal it finds, so multiple lines per symbol are documented behaviour. Whether seven signals is too many is a question about your rules — Part 9 covers ExRem() and signal cleaning — but it is not evidence of a fault in the scan.

Sources for this lesson

5 verified · checked 2026-08-31

  1. 01AmiBroker User's Guide — Using New Analysis windowamibroker.com/guide/h_newanalysis.html2026-08-31
  2. 02AmiBroker User's Guide — How to create your own explorationamibroker.com/guide/h_exploration.html2026-08-31
  3. 03AFL Function Reference — Status§ "action" and the action constantsamibroker.com/guide/afl/status.html2026-08-31
  4. 04AFL Function Reference — GetOptionamibroker.com/guide/afl/getoption.html2026-08-31
  5. 05AmiBroker User's Guide — Multi-threading in AmiBrokeramibroker.com/guide/h_multithreading.html2026-08-31

Every technical claim on this page was checked against the official AmiBroker documentation on the date shown. Where the course disagrees with folklore, the source is how you can tell which one to trust.