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)