Skip to content
Level 5 · Real-Time AmiBroker UserLessonPart 26 · page 1 of 328 min
28Minutes
7AFL functions
7Sources
StandardRequires
AFL functions taught here7

Bar Replay: Mechanics and Honest Limits

Bar Replay hides the right-hand side of your chart and lets you walk forward through history one bar at a time. That is the whole idea, and it is enough to reproduce the one condition that no static chart can ever reproduce: not knowing what happens next.

By the end of this lesson you will be able to open the tool and drive it deliberately rather than by poking at buttons, explain what each control does to the data every other part of AmiBroker can see, write a formula that knows whether it is being replayed, and give a specific list of the things a replayed session leaves out. That last item is the one that decides whether replay makes you better or merely more confident.

Where it lives, and what switching it on actually does

Section titled “Where it lives, and what switching it on actually does”

The tool is on the Tools menu, as Bar Replay. It opens a small dialog with a navigation bar, a slider, two date fields and a handful of options.

Opening the dialog does nothing at all. You enter playback mode by pressing Play or Pause, and from that moment your data are truncated at the playback position. You leave playback mode by pressing Stop, or by closing the dialog, and the full data set comes back.

Two properties of this matter more than any button.

It is global. The User’s Guide is unambiguous: Bar Replay plays back data for all symbols at once, so every symbol’s data ends at the playback position, and this affects all formulas whether they are used in charts or in Analysis. It is not a chart-window feature that leaves the rest of the program alone. Every pane, every sheet, every scan, exploration and backtest you launch while replay is active sees the truncated database. The documented exception is the Quote Editor, which always shows every bar.

Nothing is written to disk. The guide states that the simulation is done internally and the database is kept untouched — which is why all the data are still visible in the Quote Editor. Replay cannot corrupt, delete or alter your quotes. Whatever else you worry about in this part, do not worry about that.

What each button does to your data

  1. Tools, Bar ReplayThe dialog opens. Nothing has changed yet; every bar is still visible everywhere
  2. Press Play or PausePlayback mode begins. Data past the playback position become invisible to charts and to Analysis
  3. Step, play, or drag the sliderThe playback position moves. Every formula in the program re-evaluates against the shorter history
  4. Press Stop, or close the dialogPlayback mode ends and the full data set is restored
Pause is not a neutral state: it truncates the data exactly as Play does, and it is the mode you use to move the slider by hand.
Control What it does
Rewind to the beginning Returns the playback position to the Start date
Step Back Moves back one step interval
Stop Turns replay off; charts are no longer affected
Pause Pauses playback, or enters pause mode so you can drag the slider by hand
Play Plays the history forward at the chosen speed
Step Forward Moves forward one step interval
Forward to end Jumps to the end of the selected range
Slider bar Shows progress, and can be dragged to move the position manually
Start and End The simulation’s first and last dates. The small ^ button beside each field sets it to the date currently selected on the chart
Step interval The size of one step
Speed Steps per second. Default 1, maximum 5, minimum 0.1
Skip after-hours Skips hours outside the regular session as defined in File, Database Settings, Intraday Settings
Skip weekends Skips Saturdays and Sundays

The ^ buttons are worth more than their size suggests. Select a bar on the chart, press ^ beside Start, select a later bar, press ^ beside End, and the exercise range is set exactly, without typing a date and without arithmetic.

Step interval and viewing interval are two different things

Section titled “Step interval and viewing interval are two different things”

The guide recommends setting Step interval to the base interval of your database: a one-minute database steps in one-minute increments, an end-of-day database steps daily. Higher step intervals are allowed.

The chart’s viewing interval is independent of that, and this is the most useful single fact in the chapter. You can play a one-minute database back in one-minute steps while watching a fifteen-minute chart, and the last fifteen-minute bar builds up as the minutes arrive — the guide describes it as a realistic “ghost” bar.

This matters because of a limitation nobody mentions. If your step interval equals your viewing interval, each bar appears whole, in one jump, fully formed. Live, a bar does not behave like that: it opens, extends, retraces, and only settles at the close. Stepping a five-minute chart in five-minute steps rehearses none of that. Stepping a one-minute database while watching five-minute bars does, and it is the only way replay can rehearse the experience of a bar changing its mind while you are looking at it.

Speed is steps per second: the default of 1 gives one step each second, 3 gives a step every 0.333 seconds, the maximum is 5 and the minimum is 0.1. For the exercises in this part, low is better. Anything above 1 is a screensaver. A speed of 0.2 gives you five seconds per bar, which is roughly enough time to look, think and write a line in a log — and if it is not, that is itself a finding about your process, not a reason to speed up.

Most disciplined practice is done in Pause and Step Forward, not in Play at all. Play adds time pressure; stepping adds deliberation. Decide which one you are training before you press anything.

Knowing, from inside AFL, that you are being replayed

Section titled “Knowing, from inside AFL, that you are being replayed”

Every real-time formula you wrote in Parts 23 to 25 has a problem under replay: it does not know. Now() returns the system clock, which is today; the last bar in the array is some Tuesday in March. A formula that mixes the two produces nonsense, and worse, it produces plausible-looking nonsense.

AmiBroker supplies exactly one function for this.

GetPlaybackDateTime() returns the playback position as a DateTime number, or zero when Bar Replay is not active. That zero is the whole design: it is a single call that answers both “where are we” and “are we in a replay at all”. It is also a trap, because zero is a perfectly legal number to hand to a date formatter, and an unguarded DateTimeToStr( GetPlaybackDateTime() ) will print a date from the nineteenth century rather than an error. The official example guards it with a plain if, and so should you.

What replay does to the arrays your formula receives

Illustrative values, not real quotes. Replay does not blank the later bars, it removes them: BarCount is smaller, LastValue() returns the 09:45 bar, and every indicator recomputes against the shorter series exactly as it would have at 09:45.
Bar09:3009:3509:4009:4509:5009:55
DateTime()09:3009:3509:4009:4509:5009:55
Close, replay off41.2041.6541.4041.9042.3042.10
Close, playback at 09:45the array simply ends41.2041.6541.4041.90
HHV(High, 3), playback at 09:4541.7042.00
Illustrative values, not real quotes. Replay does not blank the later bars, it removes them: BarCount is smaller, LastValue() returns the 09:45 bar, and every indicator recomputes against the shorter series exactly as it would have at 09:45.

A small pane that says, in words, whether Bar Replay is driving this chart, where the playback position is, which bar AFL currently thinks is the last one, and what the system clock says. Every other formula in this part assumes you can answer those questions without guessing, and after five minutes of stepping through a session it is genuinely easy to forget which mode you are in.

Complete runnable AFL

replay-clock.afl
// replay-clock.afl
// Part 26 - Bar Replay: Mechanics and Honest Limits
//
// Answers one question at a glance: is Bar Replay driving this chart right
// now, and if so, where has it got to? Every other formula in this part
// depends on knowing that, because a chart under replay and a chart showing
// the whole database look identical until you check.
//
// How to run it:
// Formula Editor -> paste -> name it "Replay clock" -> Apply Indicator.
// Then open Tools -> Bar Replay, set Start and End, and press PAUSE.
// The panel should change the moment playback mode is entered.
//
// Assumptions declared up front:
// - This is a CHART formula. GetPlaybackDateTime() reports the position of a
// charting feature; there is nothing for it to report inside a backtest,
// and a backtest run while replay is active is silently truncated instead.
// - It works on any interval, any database, with or without a data feed.
// - It reads data and draws. It places no orders and contacts no broker.
_SECTION_BEGIN( "Replay clock" );
ShowCandles = ParamToggle( "Plot price in this pane", "No|Yes", 1 );
RefreshSeconds = Param( "Timed refresh (seconds, 0 = off)", 0, 0, 60, 1 );
// Bar Replay repaints the chart itself on every step, so a timed refresh is
// NOT needed to follow a replay. It is here only so that the same pane keeps a
// moving clock when it is watching a genuinely updating feed. Leave it at zero
// while you practise, and the pane costs nothing when nothing is happening.
if ( RefreshSeconds > 0 )
{
RequestTimedRefresh( RefreshSeconds );
}
// GetPlaybackDateTime() returns the playback position as a DateTime number, or
// ZERO when Bar Replay is not active. Zero is a legal-looking number, so it has
// to be tested before it is formatted - printing it unguarded produces a date
// in 1899 and a reader who trusts it.
PlaybackPos = GetPlaybackDateTime();
ReplayActive = PlaybackPos != 0;
// The last bar AFL can see. Under replay this is the playback position's bar;
// with replay off it is the last bar in the database.
LastBarTime = LastValue( DateTime() );
LastBarClose = LastValue( Close );
BarSeconds = Interval(); // bar size in seconds
BarSizeName = Interval( 2 ); // "Daily", "5-minute", and so on
if ( ReplayActive )
{
StateLine = "BAR REPLAY ACTIVE - playback position "
+ DateTimeToStr( PlaybackPos );
}
else
{
StateLine = "Bar Replay is OFF - this chart shows the whole database";
}
// A one-line comparison of the two clocks that matter. When they disagree by
// months, you are practising. When they agree, you are not.
Title = Name() + " " + BarSizeName + " bars (" + NumToStr( BarSeconds, 1.0 )
+ " s)\n"
+ StateLine + "\n"
+ "Last bar visible to AFL: " + DateTimeToStr( LastBarTime )
+ " close " + NumToStr( LastBarClose, 1.4 ) + "\n"
+ "System clock: " + Now( 0 );
if ( ShowCandles )
{
Plot( Close, "Close", colorDefault, styleCandle );
}
// A ribbon rather than a colour change alone: 1 while replay is driving the
// chart, 0 otherwise, with the value written in the pane's legend either way.
// GetPlaybackDateTime() returns a single number, so the flag has to be lifted
// to one value per bar before Plot() will take it.
ReplayRibbon = IIf( BarIndex() >= 0, ReplayActive, 0 );
Plot( ReplayRibbon, "Replay active (1) / off (0)", colorPaleBlue,
styleArea | styleOwnScale | styleNoLabel, 0, 4 );
_SECTION_END();

Download replay-clock.afl83 lines

There are four parts to it.

The state test is two lines: read GetPlaybackDateTime() once into a variable, then compare it with zero. Reading it once matters — it is the value the rest of the formula branches on, and calling it repeatedly invites the two calls to disagree.

The two clocks are the point of the panel. LastValue( DateTime() ) is the timestamp of the last bar the formula can see, which under replay is the playback position’s bar. Now( 0 ) is your computer’s clock. When those two are months apart you are practising; when they agree to the minute you are not, and the difference between those situations is the difference between a rehearsal and a decision that costs money.

The interval report uses Interval() for the bar size in seconds and Interval( 2 ) for its name. The guide warns explicitly against comparing that name as text, because a localised build of AmiBroker will translate it; the name is for humans, and any logic goes through the numeric form or the inDaily-style constants.

The ribbon exists so the state is legible without reading the title, and it is drawn as a value of 1 or 0 with the meaning written into the plot’s name, rather than as a colour you would have to remember. GetPlaybackDateTime() returns a single number, so the flag is lifted to one value per bar before Plot() will accept it.

The optional RequestTimedRefresh() is switched off by default and the comment says why: Bar Replay repaints the chart on every step by itself, so a timer adds cost and nothing else. It is in the file only so the same pane keeps a moving clock when it is pointed at a genuinely updating feed.

  • GetPlaybackDateTime() — the playback position as a DateTime, or zero when replay is off. No arguments. Introduced in AmiBroker 5.0.
  • DateTimeToStr( number, mode = 0 ) — formats a DateTime value. Mode 0 gives date and time, 1 date only, 2 time only, 3 and 4 the ISO forms. Mode 2 returns an empty string on a daily or longer chart, which is a reasonable way to be surprised.
  • Interval( format = 0 ) — bar size in seconds by default; Interval( 2 ) returns the interval’s name as text.
  • RequestTimedRefresh( interval, onlyvisible = True ) — asks AmiBroker to re-execute this pane every interval seconds. Left at zero here.

Apply the formula as an indicator. With Bar Replay closed, the title’s second line reads that replay is off, the last visible bar is the newest bar in your database, and the ribbon sits at zero.

Now open Tools, Bar Replay, set Start to a date a few months back, and press Pause. The chart should shorten immediately, the second line should change to name a playback position, and the ribbon should rise to one. Press Step Forward a few times: the playback position and the last visible bar both advance by one step, and they stay equal to each other. Press Stop: the full chart returns and the ribbon drops.

The test that would catch this being wrong is the one that separates the two clocks. Replay a date at least a month in the past and confirm that the “last bar” line and the “system clock” line disagree by about that much. A formula that reports today’s date as the last bar under replay is reading Now() where it should be reading DateTime(), and that is precisely the defect this panel exists to expose in your other formulas.

Then close the Bar Replay dialog without pressing Stop. The full data set should return and the ribbon should drop to zero, because closing the dialog also exits playback mode.

  • The title prints a date in 1899. GetPlaybackDateTime() returned zero and it was formatted without being tested. Guard it with if.
  • The pane never changes. The formula is applied to a chart in a sheet you are not looking at, or it was applied to the Analysis window rather than as an indicator. Bar Replay is a charting feature; apply the formula with Apply Indicator.
  • The ribbon is a flat line at zero even under replay. You opened the dialog but never pressed Play or Pause. Opening it changes nothing.
  • Everything works, but the chart shows fewer bars than the replay range. Check Skip after-hours and Skip weekends; both hide bars the range technically covers.

Add a countdown of how many steps remain to the End date, by comparing GetPlaybackDateTime() with a ParamDate() value you set to match the dialog’s End field. It is a small piece of arithmetic, and it turns the panel into something you can glance at during an exercise without switching windows.

This is the part of the lesson that decides whether the two exercises are worth doing.

The spread. Your chart shows trade prices. Replay shows them back to you. At no point does it show a bid, an ask, or the distance between them, so every entry you imagine happens at a price that nobody was actually offering. On a liquid large-cap over a multi-day hold, that is a rounding error. On a thin instrument, or on a scalp of a few ticks, it is the entire result.

The fill. A replayed decision is filled instantly, entirely, at the price you chose. Live, you join a queue. You may be filled partially, or after the price has moved, or not at all — and the trades you miss are disproportionately the ones you most wanted, because everyone else wanted them at the same moment. Replay cannot simulate queue position and does not try to.

Slippage and gaps. A stop is a request, not a level. If the next print is below your stop, you leave below your stop. Replay steps neatly from bar to bar and never gaps through anything you placed, because you did not place anything.

Intra-bar sequence. A completed bar records four prices and no order. If a five-minute bar has a high above your entry and a low below your stop, the bar cannot tell you which came first, and neither can replay. The finer your step interval relative to your viewing interval, the less of this ambiguity there is; it never reaches zero.

Operational reality. Feeds disconnect. Symbols halt. Platforms freeze at the worst moment. Part 21’s frozen-chart challenge exists because that happens. None of it happens in a replay.

The conditions you decide in. No money is at stake. Nobody is waiting for you. The session cannot run over into a meeting. You can pause, walk away, and come back with a clear head — an option that does not exist at 15:47 on a real Friday. Replay rehearses the reading; it cannot rehearse the pressure.

And you may already know the answer. This is the largest problem and the one most often waved away. If you replay a session you have seen before, or a symbol whose chart you have studied, or a date you can recognise from the shape of the market, then you are not making decisions under uncertainty — you are recalling an outcome and calling it a decision. Replaying the same session twice destroys it entirely. Choose sessions you have never looked at, on symbols you do not follow, and do not check the outcome before you start.

None of that makes replay useless. It makes it a rehearsal tool, and rehearsal is exactly what it is good at.

Replay is well suited to: classifying market structure without hindsight; watching an indicator update bar by bar so that its lag stops being an abstraction; discovering that your alert fires three times, or not at all; finding out that your session filter is an hour out; practising a checklist until running it takes ten seconds instead of two minutes; and building a tolerance for the specific discomfort of not knowing.

It is poorly suited to: estimating an edge; comparing two rule sets; setting a parameter; or persuading anyone, including yourself, that a strategy works. Those need many instruments, many years, explicit costs and a test you did not design after seeing the answer.

Bar Replay lives on the Tools menu, starts when you press Play or Pause, ends when you press Stop or close the dialog, and affects every symbol and every formula in AmiBroker while it is running — with the Quote Editor as the documented exception. It changes nothing on disk. Step interval and viewing interval are independent, and setting the step finer than the view is what makes a bar appear to form rather than appear whole.

Inside AFL, GetPlaybackDateTime() is the one function that tells a formula it is being replayed, returning the playback position or zero, and the zero must be tested before it is formatted. The replay clock formula turns that into a panel you can glance at, and the two exercises that follow both assume it is on your screen.

What replay leaves out is not a footnote: spread, fills, slippage, intra-bar sequence, outages, pressure, and your own memory of what happened next. Hold all of that in mind and replay is the best practice environment available without spending money. Forget it and replay is a machine for manufacturing unearned confidence.

Check your understanding

Question 1. You start a portfolio backtest and it reports results that stop in March, although you asked for ten years. Bar Replay was left in Pause an hour ago. What happened?
Show the answer and why

Answer: Bar Replay truncates data for the whole program, including Analysis, so the backtest ran on history up to the playback position

The guide states that Bar Replay plays back data for all symbols at once and that this affects all formulas, whether used in charts or in Analysis. Pause is not a neutral state — it truncates the data exactly as Play does. Pressing Stop restores the full data set.

Question 2. What does GetPlaybackDateTime() return when Bar Replay is not active?
Show the answer and why

Answer: Zero

It returns zero, which is why the official example tests the value with a plain if before formatting it. Zero is a valid number for a date formatter, so an unguarded DateTimeToStr() call prints a nineteenth-century date instead of failing visibly.

Question 3. You want a replayed five-minute chart to feel like a live one, with the last bar extending and retracing rather than appearing whole. What produces that?
Show the answer and why

Answer: Setting the step interval finer than the chart interval, for example replaying a one-minute database while watching five-minute bars

Step interval and viewing interval are independent. With a finer step, the bar you are watching builds up across several steps — the guide calls the result a realistic ghost bar. Speed only changes how fast whole steps arrive.

Question 4. Which of these can a replayed session legitimately establish? Select all that apply.
Show the answer and why

Answer: That your alert formula fires exactly once on a completed bar, That your session-time filter matches the exchange hours in your data, That you can classify structure without seeing the following bars

The first, second and fourth are properties of your formulas and of your own reading, and one session is enough to observe them. Expectancy is a statement about a distribution of outcomes over many trades, with costs — it needs the portfolio backtesting and out-of-sample work in Parts 28 to 33, not a rehearsal you selected and controlled.

Question 5. Why does replaying the same session a second time undermine the exercise?
Show the answer and why

Answer: You already know what happened next, so you are recalling an outcome rather than deciding under uncertainty

Replay changes nothing on disk and can be run as often as you like. The damage is to you, not to the data: the single condition replay exists to reproduce is not knowing what comes next, and your memory removes it. Use sessions and symbols you have never studied.

Sources for this lesson

7 verified · checked 2026-08-31

  1. 01AmiBroker User's Guide — Bar Replay windowamibroker.com/guide/w_barreplay.html2026-08-31
  2. 02AmiBroker AFL Function Reference — GetPlaybackDateTimeamibroker.com/guide/afl/getplaybackdatetime.html2026-08-31
  3. 03AmiBroker AFL Function Reference — DateTimeToStramibroker.com/guide/afl/datetimetostr.html2026-08-31
  4. 04AmiBroker AFL Function Reference — Intervalamibroker.com/guide/afl/interval.html2026-08-31
  5. 05AmiBroker AFL Function Reference — RequestTimedRefreshamibroker.com/guide/afl/requesttimedrefresh.html2026-08-31
  6. 06AmiBroker User's Guide — Database Settings§ Intraday Settingsamibroker.com/guide/w_dbsettings.html2026-08-31
  7. 07AmiBroker User's Guide — About AmiBroker Editionsamibroker.com/guide/versions.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.