How do I debug my formula?

Continuing the discussion from How do I learn AFL?:

Many new users with zero programming experience struggle when their formula works incorrectly. Here are few hints that everyone should use to make finding errors easier.

First of all: you have to get insight into what the formula is actually doing, not what you think it does.

Typically new user has no idea what is happening inside. Pretty often you make an assumption that things work one way but in fact they work differently. Do not assume things. Check the manual and if it is still unclear - try it. If you are want to use a new AFL function, use it alone in chart or exploration and experiment a bit to learn how it works. There are few tools that allow you to get that insight:

  1. use _TRACE()/_TRACEF() function a LOT!

    It is essential tool for every formula. It allows you to know the sequence of operations your formula is doing and the values of variables.

  2. use the Exploration as a debug tool to display your arrays

    Using _TRACE for arrays is tedious and you would get a lot clearer picture of what is happening in your arrays if you use exploration's AddColumn to display value of ANY variable

  3. visualise arrays via Plot() and PlotShapes()

    Plot is not only for charts. It can be used to visualise content of any array and and PlotShapes() is very useful in displaying content of arrays holding boolean conditions

  4. when backtesting, check the Detailed Log

    Inspecting the Detailed Log will tell you precisely what signals are generated each and every bar, what are position scores and when / why signals are ignored (due to constraints such as insufficient funds)

  5. use Edit->Prettify Selection in the AFL Editor

    This helps understanding code structure. As mentioned in this thread, sometimes incorrect indentation leads to misunderstandings. Using Prettify uncovers true structure of the code and helps finding problems with program flow.

  6. last but not least, use the Debugger

    The debugger allows you to single-step thru your formula, set breakpoints, watch the content of your variables and more

Keep in mind that debugging your own code is your task. If you want to use the formula for trading you absolutely must understand how it works. If you rely on somebody else to fix errors in your code you will not understand what is going on and you risk your money. So in your own best interest, spend time on debugging your code yourself.



For me, this is the single best piece of advice on how to use these trouble shooting tools, that I have learned. I am now able to see down into the roots of my systems. Where before I was only able to see the trunk and branches and only hope the roots were solid.

Please consider this a “standing thank you” for this and all of your thinking, building and implementation of AB.



The tips on how to debug AFL code is very helpful. Thanks.

Excellent advice @Tomasz.

The other item I would include would be use of the Detailed Log to identify what the backtester is doing internally on each bar. This can be invaluable when trying to figure out why an expected entry or exit isn’t occurring, or an unexpected one is.


The _Trace() function link is broken.

See also:

_TRACEF() : print formatted text to system debug viewer


You're too nice. I was going to introduce him to :slight_smile:

1 Like

To view debug messages generated _TRACE function we can use two programs:

  1. DebugView, from SysInternals. @Tomasz please note thet the link in the documentation has changed (Microsoft bought SysInternals some time ago). You can get it from Microsoft in the new link:
  2. DebugViewPlus. You can get it from:
    It's more powerful that the Microsoft one, and (if you are programmer) you can get it's code from GitHub:

Most of the comments here, so far, deal with tools, debugger, plots, etc. Instead, below, I present a more general approach to debugging, and design in general. (I know what I am talking about, >45 years as a successful electronic design engineer, hardware and software).

  1. "Divide and Conquer"! When you are having problems with your code, reduce it to the smallest snippet that still is problematic. In fact, even if you are not having problems (yet), you may start with small snippet and test, add, test, add, test,... until you are successful or you found that small addition that is problematic.

  2. Start with a "Written Plan" in your native language. This may be in the form of a specification, flow diagram, block diagram, hierarchy of user commands or routine calls, whatever you are most comfortable with and which you are most likely to refer to as you proceed. You are not limited to just one of the proceeding forms.

  3. BTW, 1. above is sometimes referred to as "Bottom Up", while 2. as "Top Down". Personally, I have done both, and still find both to be necessary and fun.

  4. If you have many years of experience, and are responsible for a 'product', you best start with 2. above. And might never do 1. yourself, but assign to others instead.

  5. If you are a true newbie, you best start with 1. above, but try to venture into as much of 2. as you can. At your level it is smart to start with the easiest stuff (builds familiarity, confidence, and good technique).

5 - more. Look over others' shoulders'. Learn from their successes and mistakes. Ask questions only after you have tried everything else first.

  1. "One learns little from one's own successes, but most from one's own mistakes". Mistakes should be like voting, "early and often".

I agree with the plot() function for debugging. Its the best tool to see how the arrays are behaving.

1 Like

...or misbehaving! :smiley:


Really, no one mention about using Interpretation Window for a quick checking? As easy as printf().

1 Like

Another solution, which in my opinion can be useful in some specific cases, is using Say() function. This time you don't use any visual output, but you simply hear what's going on and you are notified about some events right away even if you don't look at the screen or when for example AmiBroker is minimized.

Speak requests can be queued (spoken when previous requests are done) or next event can purge all previous speak requests. Of course such notifications can also be highly customized and provide detailed information.

1 Like