Array to SMA/EMA
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © antondmt

// @version=5
indicator("Array to SMA/EMA")
// SMA FUNCTION {
// Returns an array of SMA values from a given array
array_sma(input_array, int sma_length = 2) =>
    array_size = array.size(input_array)
    output_array = array.new_float(array_size, na)
    
    if(array_size >= sma_length and sma_length > 0) // Period length has to be same or shorter than array length and above 0 to calculate
        for index = 0 to array_size - 1
            sum = 0.0
            if index < sma_length - 1
                for i = 0 to index 
                    sum := sum + array.get(input_array, i)
            else 
                for i = index - sma_length + 1 to index
                    sum := sum + array.get(input_array, i)
            array.set(output_array, index, sum / sma_length)
    output_array
// }

// EMA FUNCTION {
// Returns an array of EMA values from a given array
array_ema(input_array, int ema_length = 2, bool sma_seed = true) => // SMA seed: True for first value being SMA. False for first value being used and unchanged
    array_size = array.size(input_array)
    output_array = array.new_float(array_size, na)

    if(array_size >= ema_length and ema_length > 0) // Avoids bugs where period length is longer than the array
        for index = 0 to array_size - 1
            alpha = 2 / (ema_length + 1)
            sum = 0.0
            if(index == 0)
                if(sma_seed)
                    array.set(output_array, index, array.get(input_array, index) / ema_length)
                else 
                    array.set(output_array, index, array.get(input_array, index))
            else 
                array.set(output_array, index, (alpha * array.get(input_array, index)) + (1 - alpha) * array.get(output_array, index - 1)) 
    output_array
// }

// TEST SPACE
test_array = array.new_float(0)
array.push(test_array, 1)
array.push(test_array, 2)
array.push(test_array, 3)
array.push(test_array, 4)
array.push(test_array, 5)

test_array := array_sma(test_array, 4)
// test_array := array_sma(test_array, 0)
// test_array := array_sma(test_array)
// test_array := array_ema(test_array, 3)
// test_array := array_ema(test_array, 3, false)

// PRINT SPACE {
lab = " | "
for i = 0 to array.size(test_array) - 1
    lab := lab + str.tostring(array.get(test_array, i)) + " | "
l = label.new(bar_index, close, lab)
label.delete(l[1])
// }