Defining Intraday Setup Conditions
“Buy the opening-range breakout in a stock with high relative volume when the daily trend is up” is a sentence with three unspecified terms in it. Each one sounds like a definition. None of them is. Opening range over what window, measured from which bar, frozen when? Relative to what volume, over how many days, adjusted for the time of day or not? Daily trend as of when — yesterday’s close, or a daily bar that is still being built out of the minutes you are trading through?
Getting those three right is most of the work in this part. Getting them wrong produces a scanner that finds beautiful candidates in testing and finds nothing useful in a session, because at least one of the three was reading data that did not exist yet.
By the end of this lesson you should be able to write all three in AFL from past bars only, explain exactly which line in each one prevents a forward reference, and say why the intraday versions of these ideas are structurally more brittle than the daily versions you met earlier in the course.
The clock you are actually using
Section titled “The clock you are actually using”Every intraday condition begins with a time test, and there are three ways to get one wrong before you have written a single condition.
Bar timestamps are not trade times. A timestamp identifies a whole bar. AmiBroker’s
documented default is to stamp a bar with the start of its interval, so a five-minute
bar stamped 10:35 covers 10:35:00 to 10:39:59. The setting lives in
Tools → Preferences → Intraday and can be changed. If your bars carry the end time
instead, every comparison below is one bar out, silently, in the direction that flatters
you.
TimeNum() is not a number you can do arithmetic on. It packs the clock into decimal
digits: 10000 * hour + 100 * minute + second, so 12:37:15 becomes 123715. Comparisons
against it are safe — TimeNum() >= 93000 means what you think — but subtraction is not.
TimeNum() - 100 is “one minute earlier” only when the minute field happens to be
non-zero. Hour() and Minute() return ordinary numbers, so the safe habit is to build a
minutes-since-midnight array once and work in that:
Fragment — not a complete formula
BarMin = 60 * Hour() + Minute(); // minutes since midnight, safe for arithmeticThe clock in your database may not be the exchange’s clock. The intraday settings
include a time shift, and Status("timeshift") reports it in seconds. Your formula cannot
tell whether the session start you typed is exchange time or shifted time; it just
compares numbers. Part 20 is the place that argument belongs, and it is a prerequisite for
this one.
With minutes-since-midnight in hand, the session and its landmarks fall out cleanly:
Fragment — not a complete formula
InSession = BarMin >= SessionStartMin AND BarMin < SessionEndMin;PrevInSess = Nz( Ref( InSession, -1 ) ); // Nz, so bar 0 does not compare with NullSessionOpen = InSession AND NOT PrevInSess; // the first bar of each sessionThe Nz() matters more than it looks. On the very first bar of the array Ref(InSession, -1) is Null, and negating a Null is not a question with a good answer. Handling
missing data explicitly rather than letting Null propagate is a course rule; this is one
of the places it earns its keep.
Opening range, defined
Section titled “Opening range, defined”An opening range is the high and low of the first N minutes of a session, fixed once those minutes are over. Two things must be true of any correct implementation: it must reset at each session boundary, and it must stop changing at the end of the window without ever referring to a bar after the current one.
The reset is SessionOpen. The running extremes are HighestSince and LowestSince,
which return the highest and lowest value of an array since a condition was last true. The
freeze is ValueWhen.
Fragment — not a complete formula
ORHighRunning = HighestSince( SessionOpen, High );ORLowRunning = LowestSince( SessionOpen, Low );
InOR = InSession AND BarMin < SessionStartMin + ORMinutes;ORHigh = ValueWhen( InOR, ORHighRunning );ORLow = ValueWhen( InOR, ORLowRunning );ValueWhen( InOR, x ) returns x as it stood on the most recent bar where InOR was
true. During the opening range that is the current bar, so the value tracks. Once the range
window closes, the most recent such bar is permanently the last bar of the range — so the
level freezes, using only bars in the past.
Freezing a 15-minute opening range on 5-minute bars
| Bar | 9:30 | 9:35 | 9:40 | 9:45 | 9:50 | 9:55 |
|---|---|---|---|---|---|---|
High | 101.0 | 101.8 | 101.4 | 102.6 | 102.2 | 103.1 |
InOR | 1 | 1 | 1 | 0 | 0 | 0 |
HighestSince(SessionOpen, High) | 101.0 | 101.8 | 101.8 | 102.6 | 102.6 | 103.1 |
ValueWhen(InOR, running high) | 101.0 | 101.8 | 101.8 | 101.8 | 101.8 | 101.8 |
Compare that with the tempting alternative: find the last bar of the range window by
testing whether the next bar is outside it. That requires Ref( InOR, 1 ), a positive
shift, which reads a future bar. On a chart used only for drawing it would be harmless. In
a rule it is a look-ahead defect, and it is the single most common way this particular
condition is written wrongly.
One further guard is needed. Before today’s range has closed, ValueWhen is still holding
yesterday’s level, because that was genuinely the most recent bar where InOR was
true. A scanner that reads ORHigh at 09:35 gets a real number that describes a different
day. So nothing may consult the level unless the range has actually completed:
Fragment — not a complete formula
AfterOR = InSession AND BarMin >= SessionStartMin + ORMinutes;ORHighPlot = IIf( AfterOR, ORHigh, Null ); // do not draw, or test, a level that does not exist yetThere is also an arithmetic requirement that has nothing to do with AFL: the scan
interval must divide the opening-range length. A thirty-minute range on seven-minute bars
has no bar boundary to end on, so BarMin >= SessionStartMin + 30 first becomes true part
way through a bar that is partly inside the range. You will get a level. It will not be the
level you defined.
Relative volume, defined
Section titled “Relative volume, defined”“Relative volume” is used to mean at least three different things, and the differences are not cosmetic. The version that is useful intraday is a pace: how much has traded so far today, compared with how much would have traded by this point on an ordinary day.
The numerator is easy, and SumSince does it in one call — it accumulates an array since a
condition was last true, which is exactly a session-cumulative volume:
Fragment — not a complete formula
SessionVolume = SumSince( SessionOpen, Volume, True ); // True: include the opening barThe denominator is where the judgement lives. The baseline must come from completed days, or it contains today. Compute it in the daily timeframe, shift it back one daily bar, and bring it down:
Fragment — not a complete formula
TimeFrameSet( inDaily ); BaselineVolume = Ref( MA( Volume, VolDays ), -1 ); // completed daily bars onlyTimeFrameRestore();BaselineVolume = TimeFrameExpand( BaselineVolume, inDaily, expandFirst );Then the expectation, and the ratio:
Fragment — not a complete formula
BarLengthMin = Interval() / 60; // Interval() returns secondsElapsedMin = BarMin - SessionStartMin + BarLengthMin;ExpectedVolume = BaselineVolume * ElapsedMin / SessionMinutes;VolumePace = IIf( ExpectedVolume > 0, SessionVolume / ExpectedVolume, Null );The assumption you have just made
Section titled “The assumption you have just made”ExpectedVolume assumes volume arrives at a constant rate through the session. It does
not. Trading is concentrated near the open and near the close in most equity markets, so a
flat-rate expectation is too low in the morning and too high in the middle of the day. A
pace of 1.4 at 09:45 and a pace of 1.4 at 13:30 are not the same observation, and a
threshold of “pace above 1.2” applied all day is really a threshold that is easy to clear
in the first half hour and hard to clear at lunchtime.
That is a defect in the measure, and it has two honest responses.
The cheap one is to be explicit about it: use the pace as a ranking device within a single scan, where every symbol is being measured at the same moment and the distortion is common to all of them, rather than as an absolute gate that means the same thing at every hour.
The better one is to replace the flat rate with a baseline measured at the same time of day. Instead of comparing against a fraction of an average day, compare today’s cumulative volume at bar k of the session against the cumulative volume at bar k of previous sessions. That is a genuinely better measure, and it depends on every session having the same number of bars in the same order — which brings us to the reason the last section of this lesson exists.
The daily trend filter, applied intraday
Section titled “The daily trend filter, applied intraday”This is where multi-timeframe look-ahead usually enters an intraday scanner, and the mechanism is worth understanding precisely rather than avoiding by superstition.
TimeFrameExpand( array, interval, mode ) decides at which base-interval bar a
higher-timeframe value becomes visible. The documented meanings are exact:
expandLast writes the value starting from the last bar of the period,
expandFirst writes it starting from the first bar of the period, and
expandPoint writes it only at the period’s last bar and leaves the rest Null.
The documentation is explicit that expandFirst “used on price different than open may
look into the future” — the whole period’s aggregate is written onto the period’s first
bar, so on Monday you would be handed a value that is only knowable after Friday. Applied
to an intraday scanner reading daily bars, the same leak means the 09:30 bar is handed a
daily close that will not exist until the market shuts.
And yet the pattern below uses expandFirst, deliberately and safely:
Fragment — not a complete formula
TimeFrameSet( inDaily ); DailyTrendUp = Ref( Close > MA( Close, TrendLen ), -1 );TimeFrameRestore();DailyTrendUp = TimeFrameExpand( DailyTrendUp, inDaily, expandFirst );The Ref( ..., -1 ) is doing the work. Inside the daily frame it steps back one daily
bar, so the array holds yesterday’s value. Expanding that with expandFirst writes
yesterday’s completed result onto today’s first intraday bar — which is precisely what
you want, because it is known before the session opens and it stays constant all day.
Remove the Ref and the identical call becomes the leak.
The documented alternative says the same thing more briefly:
Fragment — not a complete formula
PrevDayClose = TimeFrameGetPrice( "C", inDaily, -1 ); // -1: previous COMPLETED daily barOne more caution belongs to this section. Compressing daily bars out of an intraday
database is one of the cases the QuickAFL documentation names by name: partial evaluation
“may not give identical results” for timeframe functions used with intervals much higher
than the base interval. The remedy is documented — SetBarsRequired( sbrAll, sbrAll ) at
the top of the formula, which turns QuickAFL off. Without it, the same scanner can produce
different daily-trend values for a narrow range than for all quotations, and you will
spend an evening looking for a bug in your logic.
Note also that the daily bars you get this way are the daily compression of your intraday database. They inherit its intraday settings — the session filtering, the daily-compression basis, the time shift. They are not guaranteed to equal an end-of-day vendor’s daily bars for the same symbol, and if you have both, comparing them is a worthwhile ten minutes.
Putting the three together
Section titled “Putting the three together”One intraday setup, assembled from causal parts
- Yesterday closedDaily trend and volume baseline become known and fixed
- Session opensSessionOpen resets the running extremes and the volume accumulator
- Opening range formsHighestSince / LowestSince track; nothing may be tested yet
- Range window closesValueWhen freezes the levels using past bars only
- Rest of sessionLevels fixed, pace updating, trend gate constant
Draw all three quantities on a chart, in the same formula and with the same definitions the scanner will use, so that they can be inspected before they are trusted.
Complete formula
Section titled “Complete formula”Complete runnable AFL
// opening-range-panel.afl// Part 24 - Defining Intraday Setup Conditions//// Draws, on an intraday chart, the three quantities the scanner in this part// depends on, so that you can look at them before you trust them://// 1. the session opening range, frozen at the moment the range window closes;// 2. the session volume pace ("relative volume"), measured against a baseline// built only from COMPLETED previous days;// 3. a daily trend gate, read from yesterday's completed daily bar.//// Nothing here is a trading rule. It is a set of definitions made visible.//// Assumptions declared up front:// - An intraday database, and a chart interval that divides the opening-range// length exactly. A 30-minute opening range on 7-minute bars has no bar// boundary to end on, and the level you get will not be the level you meant.// - Bars are stamped with the START time of the interval, which is AmiBroker's// documented default (Tools -> Preferences -> Intraday). If your bars carry// the END time instead, every time comparison below is one bar out.// - The session times below are entered in the SAME clock the database uses.// If a time shift is configured, these are shifted times, not exchange// times. This formula cannot detect that; Part 20 shows how to check it.// - The daily values come from daily compression OF THIS DATABASE, so they// inherit its Intraday Settings - session filtering and the daily-compression// basis in particular. They are not guaranteed to equal an end-of-day// vendor's daily bars for the same symbol.
_SECTION_BEGIN( "Opening range panel" );
StartHour = Param( "Session start - hour", 9, 0, 23, 1 );StartMinute = Param( "Session start - minute", 30, 0, 59, 1 );EndHour = Param( "Session end - hour", 16, 0, 23, 1 );EndMinute = Param( "Session end - minute", 0, 0, 59, 1 );ORMinutes = Param( "Opening range length (minutes)", 30, 5, 240, 5 );VolDays = Param( "Volume baseline (completed days)", 20, 5, 100, 1 );TrendLen = Param( "Daily trend average (days)", 50, 10, 200, 5 );
SetBarsRequired( sbrAll, sbrAll ); // daily compression from intraday bars is one // of the documented QuickAFL edge cases
// ---------------------------------------------------------------------------// Session geometry. Everything is expressed in minutes since midnight, because// TimeNum() is a decimal-packed number: 100000 minus 100 is not "one minute// before 10:00". Hour() and Minute() give values you can safely do arithmetic on.// ---------------------------------------------------------------------------BarLengthMin = Interval() / 60;SessionStartMin = 60 * StartHour + StartMinute;SessionEndMin = 60 * EndHour + EndMinute;SessionMinutes = SessionEndMin - SessionStartMin;
BarMin = 60 * Hour() + Minute();
InSession = BarMin >= SessionStartMin AND BarMin < SessionEndMin;PrevInSess = Nz( Ref( InSession, -1 ) ); // Nz, so the first bar of the array // does not compare against NullSessionOpen = InSession AND NOT PrevInSess;
InOR = InSession AND BarMin < SessionStartMin + ORMinutes;AfterOR = InSession AND BarMin >= SessionStartMin + ORMinutes;
// ---------------------------------------------------------------------------// The opening range. HighestSince/LowestSince give the running extremes of the// session so far; ValueWhen freezes them.//// ValueWhen( InOR, x ) returns x as it stood on the most recent bar where InOR// was true. Once the range window has closed, that bar is the LAST bar of the// range - so the level is frozen using past bars only, with no forward// reference anywhere in the expression.// ---------------------------------------------------------------------------ORHighRunning = HighestSince( SessionOpen, High );ORLowRunning = LowestSince( SessionOpen, Low );
ORHigh = ValueWhen( InOR, ORHighRunning );ORLow = ValueWhen( InOR, ORLowRunning );
// Before today's range has closed, ValueWhen is still holding YESTERDAY's// levels. Blank them rather than drawing a line that does not exist yet.ORHighPlot = IIf( AfterOR, ORHigh, Null );ORLowPlot = IIf( AfterOR, ORLow, Null );ORRange = ORHighPlot - ORLowPlot;
// ---------------------------------------------------------------------------// Volume pace and the daily trend gate, both built from completed daily bars.// ---------------------------------------------------------------------------SessionVolume = SumSince( SessionOpen, Volume, True ); // includes the open barElapsedMin = BarMin - SessionStartMin + BarLengthMin; // minutes of session done
TimeFrameSet( inDaily ); // Ref( ..., -1 ) steps back one DAILY bar, so today's still-forming daily // bar is excluded from both of these. BaselineVolume = Ref( MA( Volume, VolDays ), -1 ); DailyTrendUp = Ref( Close > MA( Close, TrendLen ), -1 );TimeFrameRestore();
// expandFirst is safe here, and it is safe only because of the Ref( ..., -1 )// above. What lands on today's first intraday bar is yesterday's completed// value. Without the shift, this same call would hand today's unfinished daily// bar to the first bar of the morning - the documented look-ahead leak.BaselineVolume = TimeFrameExpand( BaselineVolume, inDaily, expandFirst );DailyTrendUp = TimeFrameExpand( DailyTrendUp, inDaily, expandFirst );
// The flat-rate assumption: if today traded like an average recent day, and// volume arrived evenly through the session, this is what would have traded by// now. Volume does NOT arrive evenly - see the lesson - so a pace above 1.0// early in the session is normal rather than notable.ExpectedVolume = BaselineVolume * ElapsedMin / SessionMinutes;VolumePace = IIf( InSession AND ExpectedVolume > 0, SessionVolume / ExpectedVolume, Null );
// ---------------------------------------------------------------------------// Output.// ---------------------------------------------------------------------------Plot( Close, "Close", colorDefault, styleCandle );Plot( ORHighPlot, "OR high", colorGreen, styleStaircase | styleThick );Plot( ORLowPlot, "OR low", colorRed, styleStaircase | styleThick );
// Own scale: the pace ratio sits around 1 and would otherwise be an invisible// flat line at the bottom of a price axis.Plot( VolumePace, "Volume pace", colorBlue, styleLine | styleOwnScale );
PlotShapes( IIf( SessionOpen, shapeUpArrow, shapeNone ), colorLightGrey, 0, Low, -18 );
ReplayActive = GetPlaybackDateTime() > 0; // zero when Bar Replay is not running
Title = Name() + " " + Interval( 2 ) + " " + WriteIf( InSession, "in session", "outside session" ) + " " + WriteIf( AfterOR, "OR complete", WriteIf( InOR, "OR forming", "no opening range yet" ) ) + " " + "OR " + WriteVal( ORLowPlot, 1.2 ) + " - " + WriteVal( ORHighPlot, 1.2 ) + " (range " + WriteVal( ORRange, 1.2 ) + ") " + "pace " + WriteVal( VolumePace, 1.2 ) + "x " + WriteIf( DailyTrendUp, "daily trend up", "daily trend not up" ) + " " + WriteIf( ReplayActive, "[Bar Replay active]", "" );
// A modest, deliberately unambitious refresh. Part 23 covers what this costs and// why a shorter interval on a heavier formula is how people peg a CPU.RequestTimedRefresh( 5 );
_SECTION_END();How it works
Section titled “How it works”The formula converts the session parameters into minutes since midnight and derives
InSession, SessionOpen, InOR and AfterOR from the bar clock. It computes the
running session extremes, freezes them with ValueWhen, and blanks the frozen levels
outside the part of the session where they legitimately exist. It accumulates session
volume with SumSince, builds a completed-days baseline and a completed-days trend flag
inside a daily TimeFrameSet block, expands both down to the intraday bars, and forms the
pace ratio. Finally it plots the price, the two frozen levels and the pace on its own
scale, and writes a title that states the session state in words.
Key functions
Section titled “Key functions”HighestSince( EXPRESSION, ARRAY ) and LowestSince( EXPRESSION, ARRAY ) give running
extremes since a condition was last true. SumSince( condition, array, incFirst )
accumulates since a condition, and incFirst = True includes the bar on which it was true.
Interval( format = 0 ) returns the bar interval in seconds, which is how the formula
learns its own bar length instead of being told. GetPlaybackDateTime() returns the Bar
Replay position, or zero when replay is not active — the official example guards on
exactly that, and so does the title line here.
Expected result
Section titled “Expected result”Two horizontal step lines appear from the end of the opening-range window and hold their value for the rest of the session, restarting the next day. A grey up-arrow marks the first bar of each session. The pace line, on its own scale, tends to start high and settle — that visible shape is the U-shaped volume distribution discussed above, and seeing it is the point.
Test it
Section titled “Test it”Set the opening-range length to a multiple of your chart interval and count bars: the level must stop changing on the bar immediately after the last bar of the window. Then change the chart interval to something that does not divide the range length and watch the level move to a value you did not define. Finally, scroll back to a half day — an early-close session — and check what the levels and the pace do. That last check is the subject of the next section.
Common errors
Section titled “Common errors”Testing ORHigh before AfterOR is true, and getting yesterday’s level. Omitting the
Nz() around Ref( InSession, -1 ) and getting a Null in a Boolean chain. Dropping
SetBarsRequired and finding that the daily trend flag changes when you zoom. Setting the
session parameters in exchange time on a database that is time-shifted, which produces an
opening range starting at the wrong hour with no complaint from anything.
Extension
Section titled “Extension”Add a second pane that plots the pace against its own value at the same time of day on the previous session, rather than against a flat-rate expectation. If you build it, keep every reference negative — the point of the exercise is to construct the better measure without reintroducing a forward look.
Why intraday definitions are more fragile than daily ones
Section titled “Why intraday definitions are more fragile than daily ones”A daily bar is handed to you. A session is something you infer. That one sentence explains most of the difference, but it is worth breaking down, because each part fails independently.
Session boundaries are assumptions, not data. Nothing in an intraday bar says “this is the first bar of the regular session”. You assert it by comparing a clock. A daily bar, by contrast, arrives already labelled as a day.
The session length is not constant. Half days before holidays shorten it. Some markets
open late after an auction problem. If your SessionMinutes is a constant, every
percentage-of-session quantity — the pace above, most obviously — is wrong on those days,
and wrong in a direction that manufactures apparent activity.
Daylight saving moves everything by an hour, and not on the same date everywhere. A session filter hard-coded to 09:30 is correct until the exchange and your machine change clocks on different weekends, and then it is an hour out for a fortnight, twice a year. Part 20 covers the detection; the relevant point here is that the failure is silent and your opening range simply forms over the wrong sixty minutes.
Missing bars are normal. A thinly traded symbol produces no bar for an interval in
which it did not trade. Any construction that counts bars — “bar 6 of the session”, “the
same bar-of-session as yesterday” — is comparing different clock times on different days
the moment one bar is absent. Constructions that compare clock times survive this;
constructions that compare bar counts do not. That is the main argument for preferring
BarMin tests over Ref(x, -k) offsets in intraday code.
Extended-hours data changes the meaning of everything. Whether pre-market bars are in your database, and whether your intraday settings filter them out, changes the session open, the daily compression, the volume baseline and therefore the pace. Two people running the identical formula on identical raw data can get different answers purely from those settings.
The auctions are not ordinary bars. Opening and closing auctions print large volumes at single prices. Depending on your feed and your settings they may or may not be inside your first and last bars. A volume measure that includes the opening auction and a baseline that excludes it are not comparable.
And the sample is much smaller than it looks. Ten years of daily bars is about 2,500 observations of a daily setup. Ten years of intraday data contains far more bars but still only about 2,500 sessions, and an opening-range setup gets at most one observation per session per symbol. The bar count flatters you; the number of independent events does not change.
Doing this without a live feed
Section titled “Doing this without a live feed”Nothing in this lesson needs a streaming connection. Every definition here is computed from stored bars, so a historical intraday database is a complete substitute — and a better learning environment, because you can scroll back to the awkward days on purpose.
Load the panel formula on a historical intraday chart and step through: a normal session, a
half day, the session either side of a daylight-saving change, and a symbol that trades
thinly enough to have gaps in its bars. Each of those shows one of the fragilities above
directly, and takes about two minutes. Then open Tools → Bar Replay, set the step interval
to your database’s base interval, and play a session forward while watching the opening
range form and freeze. The title’s [Bar Replay active] marker tells you which mode you
are in, so a screenshot or a note taken during practice is never ambiguous later.
Readers on the Standard edition can do all of this, with one restriction worth stating: the Standard edition’s intraday support starts at the one-minute interval, so a database with a tick or sub-minute base interval is not available. Every definition in this lesson works unchanged on one-minute or five-minute bars.
What changed
Section titled “What changed”Three phrases have become three expressions, and each one has a specific line that keeps it
causal: ValueWhen(InOR, ...) freezes the opening range without a forward reference,
SumSince(SessionOpen, ...) resets the volume accumulator at the session boundary rather
than at midnight, and Ref( ..., -1 ) inside a daily TimeFrameSet block is what makes an
expandFirst expansion safe instead of a leak. The fragility is not a reason to avoid
intraday work; it is a reason to write the session assumptions down, test the awkward days
deliberately, and treat a formula that has only been run on well-behaved sessions as
untested.
Check your understanding
Sources for this lesson
13 verified · checked 2026-08-31
- 01AmiBroker AFL Function Reference — HighestSinceamibroker.com/guide/afl/highestsince.html2026-08-31
- 02AmiBroker AFL Function Reference — ValueWhenamibroker.com/guide/afl/valuewhen.html2026-08-31
- 03AmiBroker AFL Function Reference — SumSinceamibroker.com/guide/afl/sumsince.html2026-08-31
- 04AmiBroker AFL Function Reference — TimeNumamibroker.com/guide/afl/timenum.html2026-08-31
- 05AmiBroker AFL Function Reference — Intervalamibroker.com/guide/afl/interval.html2026-08-31
- 06AmiBroker AFL Function Reference — TimeFrameSetamibroker.com/guide/afl/timeframeset.html2026-08-31
- 07AmiBroker AFL Function Reference — TimeFrameExpandamibroker.com/guide/afl/timeframeexpand.html2026-08-31
- 08AmiBroker AFL Function Reference — TimeFrameGetPriceamibroker.com/guide/afl/timeframegetprice.html2026-08-31
- 09AmiBroker User's Guide — Multiple time frame supportamibroker.com/guide/h_timeframe.html2026-08-31
- 10AmiBroker User's Guide — Preferences, Intraday tabamibroker.com/guide/w_preferences.html2026-08-31
- 11AmiBroker User's Guide — Database settingsamibroker.com/guide/w_dbsettings.html2026-08-31
- 12AmiBroker Knowledge Base — QuickAFL factsamibroker.com/kb/2008/07/03/quickafl2026-08-31
- 13AmiBroker AFL Function Reference — GetPlaybackDateTimeamibroker.com/guide/afl/getplaybackdatetime.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.