Reusable AFL Programming
By the end of Part 10 you could build a chart tool that does something worth keeping. This part is about the difference between a formula you wrote once and code you can still trust six months and forty formulas later.
That difference is smaller than it sounds and it costs less than you expect. Four ideas carry almost all of it: put a calculation in a function instead of copying it, know which variables that function can see, keep the functions in a file that every formula includes rather than in each formula separately, and write code that refuses to answer when it cannot answer honestly.
The problem this part solves
Section titled “The problem this part solves”Open the formulas you have written so far and count how many of them contain a
line that divides by something that could be zero, or a moving average whose
first thirty bars are Null, or a liquidity test with a threshold typed
directly into the expression. Now imagine changing that liquidity threshold
everywhere, correctly, without missing one.
This is not a hypothetical inconvenience. It is the mechanism by which research quietly stops being reproducible. Two formulas that were supposed to use the same definition of “liquid enough to trade” drift apart, a screen and a backtest disagree, and the disagreement is invisible because both files look right in isolation.
A shared library fixes that by making the definition exist in exactly one place. Everything else in this part exists to make a shared library safe to build.
What you will be able to do
Section titled “What you will be able to do”- Write a user-defined function or procedure, decide which of the two you
actually want, and know why AFL’s
returnstatement can only appear at the very end. - Predict, from reading a formula, whether a given variable inside a function is local to it or is the global of the same name - and say what will happen to the caller’s data either way.
- Split a formula across files with
#includeand#include_once, know where AmiBroker looks for the file, and read the error message when it does not find it. - Write code that validates its own inputs, guards its own division, states its own warm-up, and leaves a visible gap rather than a plausible number when the data cannot support an answer.
- Install and use a documented, tested utility library of your own.
The library
Section titled “The library”The project at the end of this part produces a real include file. It is deliberately small - ten functions covering safe division, warm-up, liquidity, normalised volatility, a z-score, a three-state trend regime and two display formatters - and it ships with a self-test formula that exercises every one of them and reports pass or fail.
Later parts of the course use it. When Part 12 builds a screener it will reach for the same liquidity function you wrote here; when Part 13 ranks symbols it will reach for the same z-score. That is the point: the library is not an exercise, it is infrastructure.
It is also the first piece of code in this course that you are expected to keep changing. Everything in it carries a version number and a changelog for exactly that reason.
What this part is not
Section titled “What this part is not”It is not a software-engineering course. AFL is a small language with an unusual execution model, and several habits that are good practice elsewhere - early returns, recursion, deep call chains - are either unsupported or a bad fit here. Where the official documentation is silent about something people commonly assume works, this part says so plainly rather than teaching a guess. Default argument values for user-defined functions are the clearest example, and the first lesson deals with them directly.
Nor is it about performance. Part 36 covers QuickAFL, multi-threading and what loops actually cost. Here the goal is code you can read, test and correct.
What you need first
Section titled “What you need first”Part 8 and Part 9, because everything below assumes you think in arrays and know
what Null does to a comparison. Part 10 helps, because the examples plot their
results, but the ideas do not depend on it.
You will also need somewhere to put files. Any folder you control will do, as
long as it is not the Formulas folder that ships with AmiBroker - the official
documentation is explicit that formulas supplied with the program are
overwritten by the next upgrade.
How to read it
Section titled “How to read it”The four lessons build on each other and the project assembles them, so read in order. Type the examples rather than pasting them; the scope lesson in particular is one where an error you cause deliberately teaches more than a paragraph you agree with.
0 / 5 lessons in this part completed
Progress tracking needs browser storage, which is unavailable here. The course works exactly the same without it.
- LessonUser-Defined Functions and Procedures30 min
- LessonVariable Scope: local, global and the Traps26 min
- LessonInclude Files and Building a Library28 min
- LessonDefensive AFL: Guarding Against Bad Input and Bad Data28 min
- ProjectProject: Your Personal AFL Utility Library60 min