📰 Latest: HaasOnline Academy Is Back — Structured Education for Smarter Trade Bots
Account
Using Data

Arrays

Arrays

Arrays (also called tables in Lua) are ordered collections of values. HaasScript arrays are 1-indexed, meaning the first element is at index 1, not 0. This is different from many programming languages where arrays are 0-indexed.

Creating Arrays

Use the NewArray() command or Lua table syntax:

-- Create empty array
local emptyArray = NewArray()

-- Create array with initial values
local numbers = NewArray(1, 2, 3, 4, 5)

-- Alternative Lua syntax
local prices = {100, 105, 110, 108, 112}

-- Array with mixed types
local mixed = {1, "two", 3.0, true}

Accessing Array Elements

Access elements using 1-based indexing:

local prices = {100, 105, 110, 108, 112}

local firstPrice = prices[1]    -- 100 (first element)
local secondPrice = prices[2]   -- 105 (second element)
local lastPrice = prices[5]     -- 112 (last element)

Critical: HaasScript does NOT support index 0. Using index 0 will throw an error:

-- WRONG: This will cause an error
local price = prices[0]

-- CORRECT: Use index 1 for the first element
local price = prices[1]

Use ArrayIndex() for dynamic access with negative indexing support:

local prices = {100, 105, 110, 108, 112}

local first = ArrayIndex(prices, 1)      -- 100
local last = ArrayIndex(prices, -1)     -- 112 (negative indexes from end)
local secondLast = ArrayIndex(prices, -2) -- 108

Getting Array Length

Use the Count() command or Lua's # operator:

local prices = {100, 105, 110, 108, 112}

local length1 = Count(prices)  -- 5
local length2 = #prices        -- 5

Adding Elements

Add elements to an array using ArrayAdd():

local prices = NewArray()
ArrayAdd(prices, 100)
ArrayAdd(prices, 105)
ArrayAdd(prices, 110)

-- prices now contains: {100, 105, 110}

Iterating Arrays

Use a standard for loop to iterate through array elements:

local prices = {100, 105, 110, 108, 112}

for i = 1, #prices do
    Log('Price at index ' .. i .. ': ' .. prices[i])
end

-- Output:
-- Price at index 1: 100
-- Price at index 2: 105
-- Price at index 3: 110
-- Price at index 4: 108
-- Price at index 5: 112

Array Operations

Finding Elements

Find all indices matching a value:

local prices = {100, 105, 100, 110, 100}

-- Find all occurrences of 100
local indices = ArrayFind(prices, 100)

-- indices contains: {1, 3, 5}

Filtering Arrays

Create a new array with matching elements:

local prices = {100, 105, 110, 108, 112}

-- Filter for prices above 105
local filtered = ArrayFilter(prices, 105, ArrayFilterGreaterThanType)

-- Note: Filter behavior depends on filterType parameter

Sorting Arrays

Sort arrays in ascending or descending order:

local prices = {112, 100, 108, 105, 110}

-- Sort ascending (default)
local sortedAsc = ArraySort(prices)
-- Result: {100, 105, 108, 110, 112}

-- Sort descending
local sortedDesc = ArraySort(prices, true)
-- Result: {112, 110, 108, 105, 100}

Summing Arrays

Calculate the sum of all array elements:

local prices = {100, 105, 110, 108, 112}

local total = ArraySum(prices)  -- 535

Removing Elements

Remove elements from an array:

local prices = {100, 105, 110, 108, 112}

-- Remove last element (returns removed element)
local lastPrice = ArrayPop(prices)
-- prices now: {100, 105, 110, 108}
-- lastPrice: 112

-- Remove first element (shifts remaining elements)
local firstPrice = ArrayShift(prices)
-- prices now: {105, 110, 108}
-- firstPrice: 100

-- Remove element at specific index
local removed = ArrayRemove(prices, 2)
-- prices now: {105, 108}
-- removed: 110

Multidimensional Arrays

Create arrays of arrays (matrices):

local matrix = {
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9}
}

-- Access elements
local value = matrix[2][3]  -- 6 (row 2, column 3)

-- Iterate through matrix
for i = 1, #matrix do
    for j = 1, #matrix[i] do
        Log('matrix[' .. i .. '][' .. j .. '] = ' .. matrix[i][j])
    end
end

Practical Examples

Calculating Moving Average

local prices = {100, 105, 110, 108, 112, 115, 118, 114, 120, 122}
local period = 5

-- Calculate SMA for the last period
local sum = 0
local startIdx = period + 1

for i = startIdx, 1, -1 do
    sum = sum + prices[i]
end

local sma = sum / period
Log('SMA: ' .. sma)

Finding Extremes

local prices = {100, 105, 110, 108, 112, 115, 118, 114, 120, 122}

local minPrice = prices[#prices]
local maxPrice = prices[#prices]
local minIdx = 1
local maxIdx = 1

for i = #prices-1, 1, -1 do
    if prices[i] < minPrice then
        minPrice = prices[i]
        minIdx = i
    end
    if prices[i] > maxPrice then
        maxPrice = prices[i]
        maxIdx = i
    end
end

Log('Min price: ' .. minPrice .. ' at index ' .. minIdx)
Log('Max price: ' .. maxPrice .. ' at index ' .. maxIdx)

Tracking Trade History

-- Initialize or load trade history
local tradeHistory = Load('tradeHistory', NewArray())

-- Add new trade
ArrayAdd(tradeHistory, {
    time = Time(),
    type = 'long',
    entry = CurrentPrice(),
    rsi = RSI(ClosePrices(), 14)
})

-- Save updated history
Save('tradeHistory', tradeHistory)

-- Access recent trades
if #tradeHistory >= 5 then
    local last5Trades = {}
    for i = #tradeHistory - 4, #tradeHistory do
        table.insert(last5Trades, tradeHistory[i])
    end
    Log('Last 5 trades loaded')
end

Price Analysis

local closePrices = ClosePrices()
local lookback = 20

if #closePrices >= lookback then
    -- Get recent prices
    local recentPrices = NewArray()
    for i = #closePrices - lookback + 1, #closePrices do
        ArrayAdd(recentPrices, closePrices[i])
    end

    -- Calculate statistics
    local avgPrice = ArraySum(recentPrices) / #recentPrices
    local sortedPrices = ArraySort(recentPrices)
    local medianPrice = sortedPrices[math.floor(#sortedPrices / 2) + 1]

    Log('Average: ' .. avgPrice)
    Log('Median: ' .. medianPrice)
    Log('High: ' .. sortedPrices[#sortedPrices])
    Log('Low: ' .. sortedPrices[1])
end

Common Mistakes

Using 0-based indexing:

-- WRONG: Index 0 doesn't exist in HaasScript
local price = prices[0]

-- CORRECT: Use index 1 for first element
local price = prices[1]

Iterating with wrong bounds:

-- WRONG: Will miss the last element
for i = 0, #prices - 1 do  -- Index 0 causes error
    Log(prices[i])
end

-- CORRECT: Use 1 to length
for i = 1, #prices do
    Log(prices[i])
end

Modifying array during iteration:

-- RISKY: Adding/removing elements while iterating
local prices = {100, 105, 110}
for i = 1, #prices do
    if prices[i] == 105 then
        ArrayRemove(prices, i)  -- Can cause unexpected behavior
    end
end

-- BETTER: Collect indices to remove, then process
local toRemove = {}
for i = 1, #prices do
    if prices[i] == 105 then
        ArrayAdd(toRemove, i)
    end
end

-- Remove in reverse order to maintain indices
for i = #toRemove, 1, -1 do
    ArrayRemove(prices, toRemove[i])
end

Assuming array operations modify in place:

-- Note behavior: Some commands return new arrays
local prices = {112, 100, 108, 105, 110}
local sorted = ArraySort(prices)

-- original 'prices' may still be unsorted
-- 'sorted' contains the sorted version

Arrays vs Price Collections

HaasScript price data (ClosePrices(), HighPrices(), etc.) returns HaasNumberCollections, which behave like arrays but have special properties:

-- Price collections are 1-indexed
local closePrices = ClosePrices()
local currentClose = closePrices[1]  -- Latest close

-- They can be used in calculations directly
local change = closePrices[1] - closePrices[5] -- Returns an array of prices, where each cell is the result of c[x] - c[x+N]

-- Use Count() to get length
local count = Count(closePrices)