Project: Real-Time Breakout Alert
Everything in this part has been building towards one deliverable: an alert you would actually be willing to leave running. That means a formula whose behaviour you have counted, not estimated, and a testing procedure you can repeat on a Sunday afternoon with the markets shut and no subscription running.
The subject is a breakout — price exceeding the highest high of a recent window — because it is the rule most people write first and the rule that misbehaves most instructively. It breaks in every way this part has described: it is a state if you write it carelessly, it flickers inside a forming bar, it repeats all afternoon once the level is cleared, and it fires at 04:12 on a quote nobody would have traded.
The requirement, stated so it can fail
Section titled “The requirement, stated so it can fail”A specification you cannot fail is not a specification. Here is the one this formula is built to meet, written so that each clause is checkable:
- On a chosen symbol and interval, raise an alert on the first completed bar whose high exceeds the highest high of the previous N bars by at least a volatility-scaled margin.
- The current bar must never contribute to the level it is being measured against.
- Alert at most once per session, regardless of how many times the level is cleared, lost and cleared again.
- Do not alert outside a configurable session window.
- Produce no alert at all while the level cannot be computed — during the warm-up bars, or wherever data is missing.
- Label alerts raised during Bar Replay so a practice run cannot be mistaken for a real one.
- Place no orders, and provide no mechanism that could.
Clauses 1, 3 and 5 are where the previous two pages get paid for. Clause 6 exists because the first thing anyone does with a replay-driven alert is confuse it with a live one.
Design decisions, and why
Section titled “Design decisions, and why”The level uses High, not Close. A breakout is defined by price trading through a
level, and the high is the record of that. Using the close would change the rule into
“finished the bar above the level”, which is a different and slower rule. Both are defensible;
the point is to know which one you wrote.
The level is shifted back one bar. Ref( HHV( High, N ), -1 ) means the breakout bar’s
own high cannot raise the level it is trying to exceed. Without the shift, High > HHV(High, N) is almost never true, and beginners conclude their formula is broken when it is merely
self-referential.
The margin is volatility-scaled. A fixed buffer of two cents means one thing on a
four-dollar share and nothing at all on a four-hundred-dollar one. Using a fraction of
ATR() makes the same parameter mean roughly the same thing across instruments. It does not
make the rule better — it makes the parameter portable, which is a smaller and more honest
claim.
The session filter uses TimeNum(). This is the one clause that fails silently on
somebody else’s machine, because TimeNum() returns the start or the end time of the
interval depending on a Preferences setting. The formula documents that dependency in its
header rather than pretending it does not exist.
The reset is a change of calendar day. Of the three reset choices from the previous lesson, a session boundary is the one that matches clause 3 exactly.
From price to one alert
- Prior high, shifted back one barRef( HHV( High, N ), -1 ) — the current bar cannot raise its own level
- Plus a volatility bufferBufferAtr * ATR( AtrPeriod ), so the parameter means the same thing on any instrument
- Warm-up guardNOT IsNull( Level ) — no level, no signal, rather than a Null quietly poisoning the comparison
- Cross, not exceedCross( High, Level ) is one bar; High > Level is a whole afternoon
- Session gateTimeNum() between the configured start and end
- Once-per-session latchExRem( break, day change ) — the first one passes, the rest wait for tomorrow
- Completed bars onlyBarIndex() < LastValue( BarIndex() ) — the newest bar is still being written
- AlertIf, type 1Text carrying symbol, interval, bar stamp, high and level
The complete formula
Section titled “The complete formula”Complete runnable AFL
// realtime-breakout-alert.afl// Part 25 - Project: Real-Time Breakout Alert//// Watches one symbol on one chart pane and raises at most one alert per// session, on the first completed bar whose high exceeds the highest high of// the previous N bars plus a volatility buffer, inside a session window you// define.//// It raises an alert. It does not place an order, and nothing in this course// does. The chain ends at: alert -> you read it -> you decide.//// Assumptions declared up front:// - Any interval. On an intraday interval the session filter and the// once-per-session latch do real work; on daily bars they are harmless.// - Bar time-stamping: TimeNum() returns the START or the END time of the// interval depending on Tools -> Preferences -> Intraday. The session// window below is compared against whatever that setting produces, so// confirm which convention your database uses before trusting it.// - Alerts appear only if "custom indicators" is ticked under// Tools -> Preferences -> Alerts, "Enable alerts from".// - Neither a real-time feed nor the Professional edition is required to RUN// this. A live feed only changes how often the pane re-executes. Bar// Replay (Tools -> Bar Replay) drives it just as well, and that is the// tested, no-subscription path.
_SECTION_BEGIN( "Real-Time Breakout Alert" );
LookbackBars = Param( "Breakout lookback (bars)", 20, 2, 400, 1 );BufferAtr = Param( "Buffer (x ATR)", 0.10, 0, 2, 0.05 );AtrPeriod = Param( "ATR period", 14, 1, 100, 1 );SessionStart = Param( "Session start (HHMMSS)", 93000, 0, 235959, 100 );SessionEnd = Param( "Session end (HHMMSS)", 155900, 0, 235959, 100 );UseSession = ParamToggle( "Session filter", "Off|On", 1 );AlertsOn = ParamToggle( "Alerts", "Off|On", 1 );RefreshSecs = Param( "Self-refresh (seconds)", 5, 0, 300, 1 );AlertLookback = Param( "Alert lookback (bars)", 2, 1, 20, 1 );
// Ask this pane to re-execute on a timer. RequestTimedRefresh() works with or// without a data plugin, which is exactly what makes the formula testable with// no subscription. Set the parameter to 0 to switch the timer off.if( RefreshSecs > 0 ){ RequestTimedRefresh( RefreshSecs );}
// --- The level -----------------------------------------------------------// Ref( ..., -1 ) shifts the running high back one bar, so the current bar is// never part of the level it is being measured against. Without the shift the// high of the breakout bar raises the level it is trying to break.PriorHigh = Ref( HHV( High, LookbackBars ), -1 );Buffer = BufferAtr * ATR( AtrPeriod );Level = PriorHigh + Buffer;
// Warm-up: HHV and ATR are Null until they have enough bars, and a Null// quietly poisons every comparison it touches. Say so explicitly.HaveLevel = NOT IsNull( Level );
// --- The event -----------------------------------------------------------// Cross() is true on the one bar where High first exceeded the level. The// state "High > Level" stays true for as long as the market stays up there,// which is the difference between one alert and forty.RawBreak = HaveLevel AND Cross( High, Level );
// --- The session gate ----------------------------------------------------InSession = NOT UseSession OR ( TimeNum() >= SessionStart AND TimeNum() <= SessionEnd );
// --- Once per session ----------------------------------------------------// A change of calendar day resets the latch, so the first qualifying break of// each session passes and every later one is blocked until the next session.NewSession = Day() != Ref( Day(), -1 );FirstBreak = ExRem( RawBreak AND InSession, NewSession );
// --- Completed bars only -------------------------------------------------// The newest bar is still being built by the feed or by Bar Replay: its high// can still grow. Alerting on it is how one breakout becomes six alerts.BarComplete = BarIndex() < LastValue( BarIndex() );Trigger = FirstBreak AND BarComplete;
// --- The alert -----------------------------------------------------------// GetPlaybackDateTime() returns zero when Bar Replay is not running, so this// labels replayed alerts and keeps a practice run out of your real log.Playback = GetPlaybackDateTime();
if( Playback > 0 ){ ModeText = "[REPLAY] ";}else{ ModeText = "";}
AlertText = ModeText + "BREAKOUT " + Name() + " " + Interval( 2 ) + " bar " + DateTimeToStr( LastValue( DateTime() ) ) + " high " + NumToStr( LastValue( High ), 1.4 ) + " level " + NumToStr( LastValue( Level ), 1.4 );
// Type 1 (buy), default flags, and an explicit lookback of 2.//// The lookback is the argument people leave alone and should not. AlertIf reads// only the lookback most recent bars, and its default of 1 is exactly the bar// BarComplete excludes - so with the default nothing would ever fire. Two bars// puts the most recent completed bar inside the window.//// Bit 8 of the flags, "do not display repeated alerts having the same// date/time", is then what keeps that one completed-bar signal from being// re-reported on every timed refresh for the whole life of the next bar. The// AFL above decides WHICH bar may alert; bit 8 decides that it is said once.if( AlertsOn ){ AlertIf( Trigger, "", AlertText, 1, 1+2+4+8, AlertLookback );}
// --- Drawing --------------------------------------------------------------Plot( Close, "Close", colorDefault, styleCandle );Plot( Level, "Breakout level", colorOrange, styleLine | styleStaircase );
PlotShapes( Trigger * shapeUpArrow, colorGreen, 0, Low, -20 );
Title = Name() + " " + Interval( 2 ) + " " + ModeText + "\nLevel " + NumToStr( LastValue( Level ), 1.4 ) + " Last high " + NumToStr( LastValue( High ), 1.4 ) + "\nRaw breaks: " + NumToStr( LastValue( Cum( RawBreak ) ), 1.0 ) + " After latch: " + NumToStr( LastValue( Cum( FirstBreak ) ), 1.0 ) + " Alertable: " + NumToStr( LastValue( Cum( Trigger ) ), 1.0 );
_SECTION_END();How it works
Section titled “How it works”The level and the warm-up guard
Section titled “The level and the warm-up guard”HHV( High, LookbackBars ) gives the running highest high; Ref( ..., -1 ) shifts it back a
bar. ATR( AtrPeriod ) supplies the volatility scale, and BufferAtr is the fraction of it
you are demanding as clearance. The sum is Level.
HaveLevel = NOT IsNull( Level ) is not decoration. Both HHV() and ATR() return Null
until they have enough bars, and Null propagates through comparisons rather than raising an
error. Requiring HaveLevel explicitly means the warm-up produces no signal on purpose,
rather than producing no signal by luck.
The event and the session gate
Section titled “The event and the session gate”Cross( High, Level ) is true on the single bar where the high first exceeded the level. The
session gate is a plain range test on TimeNum(), which encodes the bar time as
10000 * hour + 100 * minute + second — so 09:30:00 is 93000. Note that this is a packed
decimal, not a count of seconds: comparisons like >= are safe, but arithmetic on it is not,
which is why the parameters are entered in the same packed form rather than being computed.
NOT UseSession OR ( ... ) lets the toggle switch the whole clause off for daily bars, where
every bar is the session.
The once-per-session latch
Section titled “The once-per-session latch”Fragment — not a complete formula
NewSession = Day() != Ref( Day(), -1 );FirstBreak = ExRem( RawBreak AND InSession, NewSession );Day() returns the day-of-month for each bar, so a change of value marks a new trading day.
ExRem() passes the first qualifying break and blocks the rest until NewSession is true
again. That is clause 3, in two lines, with no state to manage and nothing that behaves
differently in a Scan than on a chart.
The completed-bar guard and the alert
Section titled “The completed-bar guard and the alert”BarComplete = BarIndex() < LastValue( BarIndex() ) is true for every bar except the newest.
Trigger = FirstBreak AND BarComplete is what reaches AlertIf(). The consequence, which
you will verify below, is that the alert for a signal on bar T arrives one bar later — when
bar T can no longer change.
The alert is raised with type 1, the default flags, and an explicit lookback of 2. That
last argument is the one carried over from the previous lesson: AlertIf() examines only the
lookback most recent bars, its default is 1, and that one bar is precisely the one
BarComplete excludes. Two bars is the smallest window that contains a completed bar. It is
exposed as a Param() so you can set it back to 1 during testing and watch the alert go
silent, which is a faster way to believe it than reading about it.
Widening the window means the same signal stays eligible for the whole life of the next bar. Flag bit 8 — no repeated alerts with the same date/time — is what turns that back into one line. The AFL decides which bar may alert; bit 8 decides it is announced once.
Knowing whether you are replaying
Section titled “Knowing whether you are replaying”GetPlaybackDateTime() returns the Bar Replay position, or zero when replay is not
active. Zero is a perfectly legal-looking number, so the formula tests it before using it
rather than formatting it blindly. When replay is running, every alert line and the chart
title are prefixed [REPLAY].
RequestTimedRefresh( RefreshSecs ) asks the pane to re-execute on a timer. It works with or
without a data plugin, which is what lets the same formula be exercised offline. Refreshes
are aligned to the second boundary, and the manual is explicit that Windows timers are
accurate to roughly 55 milliseconds when the machine is idle — near enough for an alert, and
nowhere near a real-time scheduling promise.
Key functions
Section titled “Key functions”| Function | What it contributes here |
|---|---|
HHV( ARRAY, periods ) |
The running highest value over the lookback window |
Ref( ARRAY, period ) |
A negative period shifts back; -1 excludes the current bar from its own level |
ATR( period ) |
Volatility scale for the buffer. It has no documented default period, so it is always passed |
Cross( ARRAY1, ARRAY2 ) |
Converts “is above” into “just went above” |
TimeNum() |
The bar’s time as packed decimal HHMMSS, for the session gate |
Day() |
Day of month per bar; a change of value is a new session |
ExRem( ARRAY1, ARRAY2 ) |
The once-per-session latch |
BarIndex(), LastValue() |
Together, the completed-bar guard |
AlertIf( ..., flags, lookback ) |
The last two arguments: lookback of 2 so the guarded bar is inside the window, flags left at the default so bit 8 collapses re-reads |
RequestTimedRefresh( interval ) |
Re-executes this pane on a timer, plugin or no plugin |
GetPlaybackDateTime() |
Bar Replay position, or zero when replay is off |
Expected result
Section titled “Expected result”Apply the formula to a chart pane. You should see:
- An orange staircase line sitting above recent price — the breakout level. It steps up as
new highs are made and stays flat otherwise. If it hugs the price bars exactly, the
Ref()shift is missing. - A green up arrow beneath the low of each alertable bar. On an intraday chart with the session filter on, at most one arrow per day.
- A title reporting three counts: raw breaks, breaks after the latch, and alertable breaks. The first should be comfortably larger than the second. The second should exceed the third by at most one, and by exactly one when the final bar of the loaded range is itself a signal.
- Nothing at all during the first
LookbackBarsbars of history.
Testing it without a live feed
Section titled “Testing it without a live feed”This is the part of the project that matters, and it is deliberately the longest. Four stages, all on stored data.
Stage 1 — count the ground truth
Section titled “Stage 1 — count the ground truth”Before an alert can be verified, you need the number it is supposed to produce. The harness
is the identical rule with AlertIf() removed and every intermediate step exposed as a
column.
Complete runnable AFL
// breakout-alert-test-harness.afl// Part 25 - Project: Real-Time Breakout Alert (offline test harness)//// The same breakout rule as realtime-breakout-alert.afl, with AlertIf() taken// out and every intermediate step exposed as a column. Run it as an// Exploration over the history you are about to alert on.//// The "Latch count" on the final row is the number of alert lines the live// formula is permitted to write over that same range. Not approximately -// exactly. That is the whole point: the alert is checked against a number you// can count by hand, on data you already own, with no subscription and no// market open.//// Assumptions declared up front:// - The parameters here must match the chart pane exactly. One bar of// difference in the lookback changes the expected count.// - Analysis -> Range must match the span you intend to watch, because the// running counts start at the first bar of the range.// - "Alertable" excludes the final bar of the range for the same reason the// chart formula excludes it: on a live or replayed chart it is still// forming. Over pure history that costs you at most one signal, and the// lesson explains why paying it is the right trade.
_SECTION_BEGIN( "Breakout alert test harness" );
LookbackBars = Param( "Breakout lookback (bars)", 20, 2, 400, 1 );BufferAtr = Param( "Buffer (x ATR)", 0.10, 0, 2, 0.05 );AtrPeriod = Param( "ATR period", 14, 1, 100, 1 );SessionStart = Param( "Session start (HHMMSS)", 93000, 0, 235959, 100 );SessionEnd = Param( "Session end (HHMMSS)", 155900, 0, 235959, 100 );UseSession = ParamToggle( "Session filter", "Off|On", 1 );ShowAll = ParamToggle( "Rows", "Breaks only|Every bar", 0 );
PriorHigh = Ref( HHV( High, LookbackBars ), -1 );Buffer = BufferAtr * ATR( AtrPeriod );Level = PriorHigh + Buffer;HaveLevel = NOT IsNull( Level );
RawBreak = HaveLevel AND Cross( High, Level );InSession = NOT UseSession OR ( TimeNum() >= SessionStart AND TimeNum() <= SessionEnd );NewSession = Day() != Ref( Day(), -1 );FirstBreak = ExRem( RawBreak AND InSession, NewSession );
BarComplete = BarIndex() < LastValue( BarIndex() );Trigger = FirstBreak AND BarComplete;
Filter = ShowAll OR RawBreak;
AddColumn( High, "High", 1.4 );AddColumn( Level, "Level", 1.4 );AddColumn( TimeNum(), "Bar time", 1.0 );AddColumn( RawBreak, "Raw break", 1.0 );AddColumn( InSession, "In session", 1.0 );AddColumn( FirstBreak, "After latch", 1.0 );AddColumn( Trigger, "Alertable", 1.0 );AddColumn( Cum( RawBreak ), "Raw count", 1.0 );AddColumn( Cum( FirstBreak ), "Latch count", 1.0 );AddColumn( Cum( Trigger ), "Alert count", 1.0 );AddColumn( BarComplete, "Complete", 1.0 );
_SECTION_END();Run it as an Exploration, on one symbol, over a fixed range, with the parameters written down. Read the final row. The “Latch count” is the number of alert lines the chart formula is permitted to write over that range. Also copy out the timestamps of the qualifying bars — you are going to reconcile against them, not just against a total.
Set the row toggle to “Every bar” for a short range and read down the columns once. You should be able to see, for a single day, the level stepping up, one raw break, the “In session” flag excluding anything outside your window, and the latch turning the second and third breaks of that day into zeros. If you cannot see that in the table, the alert has nothing to be right about.
Stage 2 — prove the alert path is live
Section titled “Stage 2 — prove the alert path is live”An alert that produces nothing because a checkbox is clear looks exactly like an alert that produces nothing because it is correctly suppressing. Separate the two before going further.
- Open
Window -> Alert Outputand clear it. - Confirm the relevant boxes under
Tools -> Preferences -> Alertsare ticked — “custom indicators” for a chart pane, “Automatic Analysis” for a Scan. - Temporarily change the
AlertIf()call’s flags to1+2, and set the Analysis range so that the bar before the last one is a known signal bar. Run it twice. - Two identical lines is a pass: the plumbing works and suppression is off.
- Restore the default flags and run twice more. One line is a pass: suppression works.
- Set the “Alert lookback (bars)” parameter to 1 and run again. Nothing should appear, because the only bar examined is the one the completed-bar guard excludes. Set it back to 2 and confirm the line returns.
If step 4 produces nothing, stop. Nothing after this point can be interpreted until the alert path is known to be live. Step 6 is not a formality: it is the cheapest demonstration in this part of why an argument you never touched can silence an otherwise correct formula.
Stage 3 — walk the history under Bar Replay
Section titled “Stage 3 — walk the history under Bar Replay”Bar Replay truncates the database at a moving playback position and affects charts and the Analysis window alike, so advancing it one step is genuinely equivalent to one new bar arriving.
Tools -> Bar Replay. Set Start to a date before your first known signal and End after the last one. Set Step interval to the database’s base interval, which is the documented recommendation.- Press Pause to enter playback mode without running, then use the single-step-forward button.
- Watch the chart title.
[REPLAY]should appear as soon as playback is active. - Step forward through each known signal. The alert line for a signal on bar T must appear on the step onto T+1, carrying T’s timestamp.
- Step backwards over a signal bar and forwards again. No new line should appear.
- Press Stop when finished. The full data set is restored.
Stage 4 — the forming-bar test
Section titled “Stage 4 — the forming-bar test”The one behaviour left is intrabar flicker, and you can reproduce it without a feed. Bar Replay’s step interval is independent of the chart’s viewing interval, and the documentation states the last bar builds up realistically as data arrives.
Put the chart on five-minute bars, set the replay step interval to one minute, and step
manually. You will watch a five-minute bar assemble itself in five steps. Temporarily comment
out BarComplete from the Trigger line and step through a bar where the high pokes above
the level early and the bar closes back below. The alert fires on the forming bar, and the
finished data contains no signal at all. Restore the guard and repeat: no alert. That
contrast, seen once, is worth more than any amount of reading about it.
If you do have a live feed
Section titled “If you do have a live feed”Everything above still applies, and one thing is added: run the formula through a full session on a symbol you are not trading, and reconcile the Alert Output lines against the harness Exploration run over that same session afterwards. They should match exactly. If the live run produced more lines than the after-the-fact Exploration, you have found an intrabar defect that history cannot show you — which is the only thing a live feed genuinely buys you in testing.
Does it fire once? The checklist
Section titled “Does it fire once? The checklist”| Check | Pass criterion | What a failure means |
|---|---|---|
| Level excludes the current bar | Level line steps up only after a new high, never on the breakout bar itself | The Ref( ..., -1 ) shift is missing |
| Warm-up produces nothing | No arrows in the first LookbackBars bars |
The HaveLevel guard is missing or inverted |
| Event, not state | Raw break count is far below the number of bars above the level | Cross() was replaced by a comparison |
| Session gate | No alertable bar has a “Bar time” outside the window | Time-stamping convention differs from what the parameters assume |
| Once per session | Latch count equals the number of days with at least one qualifying break | The reset argument to ExRem() is wrong |
| Completed bars only | Alert appears on the step onto T+1, never onto T | Guard missing, or the comparison is the wrong way round |
| Lookback covers the guard | Setting the lookback parameter to 1 silences the alert; 2 restores it | If 1 also produces lines, the guard is not being applied at all |
| No re-fire on re-visit | Stepping back and forward adds no line | Suppression is being relied on where the latch should act |
| Counts reconcile | Alert Output line count equals the harness Latch count over the same range | Parameters or Analysis range differ between the two |
| Replay is labelled | Every replayed line begins [REPLAY] |
GetPlaybackDateTime() result used without the zero test |
| Replay stopped | Later scans return the full range | Bar Replay left in Pause |
Common errors
Section titled “Common errors”| Symptom | Cause |
|---|---|
| No alerts at all, no error | The context’s box is clear under Tools -> Preferences -> Alerts |
| No alerts, and the arrows are also missing | HaveLevel is false throughout: fewer loaded bars than LookbackBars |
| Arrows appear but no alert lines | AlertsOn toggle is off, or the lookback window excludes the guarded bar — the default of 1 does exactly that |
| An alert every few seconds | The completed-bar guard was removed, on a refreshing chart |
| One alert, then silence for days | Two alerts share type, so the state machine is suppressing the second |
| Alerts at implausible times | Session parameters written for start-of-bar stamping on an end-stamped database, or the reverse |
| Alert count exceeds the harness count | Different parameters, different range, or an intrabar fire |
| Scans suddenly return truncated results | Bar Replay is still in Pause |
A SOUND command does nothing |
Single backslashes in the path; AFL string literals need \\ |
Extensions
Section titled “Extensions”Across a watchlist. Move the same rule into an Analysis window as a Scan, apply it to a
watchlist, and enable “Auto repeat Scan/Explore” with an interval — a plain number means
minutes, and 5sec or 5s means seconds. The formula needs no change; the alert type stays
1, and because the state machine keys per symbol, each symbol carries its own memory. Note
what this costs: the Standard edition runs two threads per Analysis window against the
Professional edition’s thirty-two, so a large watchlist on a short repeat interval is a very
different proposition on the two editions.
A second alert type. Add a failure alert of type 5 that fires when price closes back
below the level within a few bars of the breakout. Two types now coexist, and the per-type
suppression keeps them independent — a good place to observe the state machine behaving
rather than reading about it.
An audit trail. Use StaticVarSetText() on each alert to record what was sent, and a
second small pane to display the last few entries. You then have something to reconcile
against the Alert Output window, and something that survives the window being cleared.
Routing. Once the alert is verified, EMAIL or an EXEC to a notification tool of your
choosing turns it into something that reaches you away from the machine. Verify the alert
first and route it second; a mis-firing alert that reaches your phone is worse than one that
does not.
You have a breakout alert whose behaviour is specified in seven clauses, each of which fails visibly if broken, and a two-formula workflow — the alerting chart pane and the auditing Exploration — where the second establishes the number the first is allowed to produce. You have walked it through history with Bar Replay and watched the one-bar offset that proves the completed-bar guard is real. You have reproduced intrabar flicker on stored data, seen what it does to an unguarded alert, and seen the guard remove it.
None of that required a subscription, and the parts of it that a live feed would have added are small and specific: genuinely live intrabar behaviour, and the reconciliation of a real session against its own history afterwards. Everything else was better done offline, because offline you can run the same twenty minutes as many times as you need.
The alert tells you something happened. What happens next is a decision you make, with the evidence in front of you. That boundary is where this course leaves it, deliberately.
Check your understanding
Sources for this lesson
9 verified · checked 2026-08-31
- 01AmiBroker User's Guide — Using formula-based alertsamibroker.com/guide/h_alerts.html2026-08-31
- 02AFL Function Reference — AlertIfamibroker.com/guide/afl/alertif.html2026-08-31
- 03AFL Function Reference — RequestTimedRefreshamibroker.com/guide/afl/requesttimedrefresh.html2026-08-31
- 04AFL Function Reference — GetPlaybackDateTimeamibroker.com/guide/afl/getplaybackdatetime.html2026-08-31
- 05AFL Function Reference — TimeNumamibroker.com/guide/afl/timenum.html2026-08-31
- 06AmiBroker User's Guide — Bar Replayamibroker.com/guide/w_barreplay.html2026-08-31
- 07AmiBroker User's Guide — Preferences§ Intraday and Alerts tabsamibroker.com/guide/w_preferences.html2026-08-31
- 08AmiBroker — Standard versus Professional edition comparisonamibroker.com/guide/versions.html2026-08-31
- 09AmiBroker User's Guide — Data sourcesamibroker.com/guide/h_quotes.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.