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.
One window, four verbs
Section titled “One window, four verbs”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
- Apply toBuilds the list of symbols: all, current, or those matching the Filter Settings
- For each symbolLoads its bars and runs the whole formula once, on its own thread
- RangeDecides which of those bars count as "in range" for reporting
- ModeScan reads Buy/Sell/Short/Cover; Explore reads Filter and the AddColumn calls
- Result listRows stream in while the run is still going, and can be sorted and exported
Scan, defined
Section titled “Scan, defined”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:
- A Scan is driven by
Buy,Sell,ShortandCover. 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. - 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.
Exploration, defined
Section titled “Exploration, defined”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:
Filterdecides which rows appear. WhereFilteris 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.
Backtest and Optimization, previewed
Section titled “Backtest and Optimization, previewed”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.
Making one formula behave in two modes
Section titled “Making one formula behave in two modes”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.
Apply to: choosing the universe
Section titled “Apply to: choosing the universe”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.
Range: choosing the bars
Section titled “Range: choosing the bars”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.
How the results are produced
Section titled “How the results are produced”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.
What changed in your understanding
Section titled “What changed in your understanding”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
Sources for this lesson
5 verified · checked 2026-08-31
- 01AmiBroker User's Guide — Using New Analysis windowamibroker.com/guide/h_newanalysis.html2026-08-31
- 02AmiBroker User's Guide — How to create your own explorationamibroker.com/guide/h_exploration.html2026-08-31
- 03AFL Function Reference — Status§ "action" and the action constantsamibroker.com/guide/afl/status.html2026-08-31
- 04AFL Function Reference — GetOptionamibroker.com/guide/afl/getoption.html2026-08-31
- 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.