Skip to content

Optimizations

Optimizations

During a backtest, the engine evaluates every minute in the historical period. While this is necessary for accuracy, it slows down the backtest speed. On this page, we will go over a few things that will help you improve the backtest speed.

Sections marked with SE (Script Editor, code-based), VE (Visual Editor, node-based), or CC (Custom Command) apply only to that script type.

Loops (SE)

Iterating over data takes time. In all cases try to avoid this as much as possible or keep the loop counts to the absolute minimum. With over 500 commands in HaasScript, there's almost always a command that can replace a loop.

OptimizedForInterval (SE)

In the script editor we can use OptimizedForInterval(). This command takes an interval and a callback. The command reduces the number of times the callback is executed. Execution of the callback is allowed when the candle on the specified interval closes. For example, if the script uses a MACD on a 1-hour interval, it will calculate the MACD once every 60 minutes instead of every tick. This reduces overall execution time and results in a faster backtest.

MA = OptimizedForInterval(CurrentInterval(), function() 
    return MA(ClosePrices(), 12, EmaType)
end)

You can also optimize full sections.

function dailyTA()
    local c = ClosePrices(1440)
    local sma = SMA(c, 200)
    local rsi = RSI(c, 14)
    local macd = MACD(c, 12, 26, 9)

    Plot(0, 'Daily SMA', sma, White)
    Plot(1, 'Daily RSI', rsi, SkyBlue)
    Plot(2, 'Daily MACD', macd.macd, SkyBlue)
    Plot(2, 'Daily MACD Signal', macd.signal, Red)

    return sma, rsi, macd
end

dailySMA, dailyRSI, dailyMACD = OptimizedForInterval(1440, dailyTA)

DefineIntervalOptimization (CC)

If a custom command works on interval-based data, like the MadHatter RSI, we can use DefineIntervalOptimization() in our command scripts. This command has the same effect as OptimizedForInterval() and increases backtest speed.

local interval = DefineParameter(NumberType, 'interval', 'The interval of the command', true, 1)
DefineIntervalOptimization(interval)

If the command takes a source as parameter we can get the interval with the CurrentInterval() command.

local source = DefineParameter(ListNumberType, 'source', 'Source data for the command', true, ClosePrices())
local interval = CurrentInterval(source)
DefineIntervalOptimization(interval)

Finalize

The Finalize() command works like the OptimizedForInterval(). It takes a callback but is only executed when we are doing the last step in a backtest or running the script in a live bot. This command should only be used with specific commands (e.g. CustomReport()) or under specific conditions (Log() with a cumulative value).