Instructions/probuilder · probacktest · proorder · proscreener

ArraySort

ArraySort orders the elements of a ProBuilder array in ascending or descending order, useful for ranking stored values inside indicators and strategies.

Syntax

probuilder
ArraySort($MyArray, ascend)
ArraySort($MyArray, descend)

Parameters

NameTypeDefaultDescription
$MyArrayarrayrequiredThe array variable whose elements are reordered.
modekeywordrequiredSorting direction, either ascend (smallest first) or descend (largest first).

How it works

ArraySort sorts the array in place: after the call, the same array variable holds the same values in the requested order. Nothing is returned and the original ordering is lost, so a copy must be made first when the insertion order still matters.

Sorting turns positional access into rank access. After an ascending sort, index 1 holds the minimum, the middle index holds the median, and LastSet($array) points to the maximum. This makes ArraySort the standard building block for medians, percentiles, and top-N selections that the built-in series functions do not cover.

The number of populated elements is best obtained with LastSet, which returns the highest assigned index. Iterating up to a hard-coded bound larger than the populated range risks touching unassigned elements.

Sorting has a real computational cost. Scripts that sort a large array on every bar of a long history can become slow. When the sorted result is only needed for display or a final reading, wrap the work in an IsLastBarUpdate block so it runs only on the most recent bar.

Examples

Example 1, Sort and plot random values (Indicator)

probuilder
DEFPARAM DrawOnLastBarOnly = true

IF IsLastBarUpdate THEN
  // Fill an array with 100 random values
  FOR i = 1 TO 100 DO
    $a[i] = Random(0, 1000)
  NEXT

  // Order the values from largest to smallest
  ArraySort($a, descend)

  // Print each sorted value on the chart
  FOR i = 1 TO LastSet($a) DO
    DRAWTEXT($a[i], barindex, i, sansserif, standard, 14)
  NEXT
ENDIF

RETURN 0

The array is populated with random numbers, sorted in descending order, and each value is drawn on the chart. Restricting the work to the last bar keeps the indicator responsive.

Example 2, Median close as a trade filter (ProOrder)

probuilder
DEFPARAM CumulateOrders = false

// Copy the last 21 closes into an array
FOR i = 0 TO 20 DO
  $window[i + 1] = close[i]
NEXT

// Sort ascending, then read the middle element as the median
ArraySort($window, ascend)
medianClose = $window[11]

// Only take long entries while price holds above its median
IF close > medianClose AND Average[10](close) CROSSES OVER Average[40](close) THEN
  BUY 1 CONTRACT AT MARKET
ENDIF

SET STOP %LOSS 2

The strategy sorts a 21-bar window of closes and reads element 11, the median, as a regime filter that is less sensitive to outliers than a moving average.

Example 3, Percentile rank of current range (ProScreener)

probuilder
// Store the bar ranges of the previous 50 bars
FOR i = 1 TO 50 DO
  $ranges[i] = high[i] - low[i]
NEXT

// Sort ascending so high indices hold the widest ranges
ArraySort($ranges, ascend)

// Keep instruments whose current range beats the 90th percentile
threshold = $ranges[45]
SCREENER[(high - low) > threshold] ((high - low) AS "Bar range")

The screener ranks the previous 50 bar ranges and flags instruments whose current range exceeds the 45th of 50 sorted values, roughly the 90th percentile.

Common errors and gotchas

  • Sorting is destructive. ArraySort reorders the array itself. When the original insertion order is still needed, copy the elements into a second array before sorting.
  • ascend and descend are keywords. They are written bare, not as quoted strings. ArraySort($a, "descend") does not compile.
  • Unassigned elements. Populate the array contiguously and use LastSet to find its true size. Looping past the populated range reads unassigned values and can cause runtime errors.
  • Cost on every bar. Sorting a large array on each bar of a long history slows execution noticeably. Guard display-only sorts with IsLastBarUpdate so they run once on the live bar.
  • ArrayMax, largest value of an array without sorting.
  • ArrayMin, smallest value of an array without sorting.
  • IsSet, tests whether an array element has been assigned.
  • LastSet, highest assigned index, in effect the array size.
  • Unset, clears an array or a single element.
  • Random, generates pseudo-random values, useful for testing array code.
  • IsLastBarUpdate, true only during the final bar update, used to limit heavy work.
  • DrawOnLastBarOnly, restricts drawing output to the most recent bar.