You will write 1,000 lines of AmiBroker AFL code and 999 of them will have bugs initially. Here is the professional debug workflow:
And here is where the abyss opens. You write a system. You backtest. The equity curve rises like a prayer. You add parameters—length of moving average, RSI threshold, stop-loss percentage. You optimize. The curve becomes vertical. You are a god.
But AFL, in its cruel honesty, offers a function called WalkForward() or prompts you to use out-of-sample testing. Most ignore it. They fall into the curvature of overfitting, worshipping the ghost of past volatility. The deep truth: AFL does not judge your logic. It merely executes it. You can code a system that wins 99% of the time in-sample and loses everything live. The language is innocent. The trader is the fool.
Let’s assemble a complete, tradeable strategy. This is a Volatility Breakout with RSI Filter.
Logic:
//========================================== // COMPLETE AMIBROKER AFL CODE - Breakout System // Author: Professional Trader //==========================================// --- Inputs --- DonchianPeriod = Param("Donchian Period", 20, 5, 50, 1); RSILen = Param("RSI Length", 14, 5, 30, 1); RSI_Threshold = Param("RSI Min", 50, 30, 70, 1); ExitMAPeriod = Param("Exit MA Period", 10, 5, 50, 1); amibroker afl code
// --- Indicators --- DonchianHigh = HHV(H, DonchianPeriod); DonchianLow = LLV(L, DonchianPeriod); RSIval = RSI(RSILen); ExitMA = MA(C, ExitMAPeriod);
// --- Entry Conditions --- BuyTrigger = Cross(C, DonchianHigh); TrendFilter = RSIval > RSI_Threshold; Buy = BuyTrigger AND TrendFilter;
// --- Short Conditions (Optional) --- ShortTrigger = Cross(DonchianLow, C); ShortFilter = RSIval < (100 - RSI_Threshold); Short = ShortTrigger AND ShortFilter;
// --- Exits --- Sell = Cross(ExitMA, C); // Price closes below MA Cover = Cross(C, ExitMA); // Price closes above MA for shorts
// --- Position Sizing (Risk 1% of equity) --- RiskPercent = 1; StopLossATR = 2; ATRval = ATR(14); PositionSize = -RiskPercent * (C / StopLossATR / ATRval); You will write 1,000 lines of AmiBroker AFL
// --- Plotting for Chart Analysis --- Plot(C, "Price", colorWhite, styleCandle); Plot(DonchianHigh, "Upper Band", colorBlue, styleLine); Plot(DonchianLow, "Lower Band", colorBlue, styleLine); Plot(ExitMA, "Exit MA", colorOrange, styleLine);
PlotShapes(Buy * shapeUpArrow, colorGreen, 0, L, -20); PlotShapes(Sell * shapeDownArrow, colorRed, 0, H, 20); PlotShapes(Short * shapeDownArrow, colorPink, 0, H, -20); PlotShapes(Cover * shapeUpArrow, colorLightGrey, 0, L, 20);
// --- Exploration for Scanning --- Filter = Buy OR Short; AddColumn(C, "Close", 1.2); AddColumn(RSIval, "RSI", 1.2); AddColumn(IIf(Buy, "BUY", IIf(Short, "SHORT", "")), "Signal", 1.0);
// --- Backtest Settings --- SetPositionSize(1, spsShares); // 1 share for testing SetOption("InitialEquity", 100000); SetOption("FuturesMode", False); SetOption("PriceBoundChecking", True);
Copy this code into AmiBroker (Analysis -> Formula Editor) and press Backtest. You will see a full equity curve, drawdown, and trade list.
// Section 1: Parameters (User adjustable) MAfastPeriod = Param("Fast MA Period", 10, 2, 50, 1); MAslowPeriod = Param("Slow MA Period", 30, 10, 200, 1);// Section 2: Calculate Indicators FastMA = MA(C, MAfastPeriod); SlowMA = MA(C, MAslowPeriod);
// Section 3: Define Signals Buy = Cross(FastMA, SlowMA); Sell = Cross(SlowMA, FastMA);
// Section 4: Visualization Plot(C, "Price", colorBlack, styleCandle); Plot(FastMA, "Fast MA", colorGreen, styleLine); Plot(SlowMA, "Slow MA", colorRed, styleLine); PlotShapes(Buy * shapeUpArrow, colorBrightGreen, 0, Low, -15); PlotShapes(Sell * shapeDownArrow, colorRed, 0, High, -15);
This is the "Hello World" of AmiBroker AFL code. It works, but it is not profitable. Let’s move to advanced logic.
for(i=20; i<BarCount; i++)
if(C[i] > C[i-1]) Buy[i] = 1;