FunctionDecisionTree
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © RicardoSantos

//@version=5

// @description Method to generate decision tree based on weights.
library(title='FunctionDecisionTree')

// @function Method to generate decision tree based on weights.
// @param weights float array, weights for decision consideration.
// @param depth int, depth of the tree.
// @returns int array
export decision_tree(float[] weights, int depth) => //{
    int _size_w = array.size(id=weights)
    //
    int[] _path = array.new_int(size=0, initial_value=0)
    int _sumweights = math.ceil(array.sum(id=weights))
    if _size_w > 0 and depth > 0 and _sumweights == 1
        for _d = 1 to depth by 1
            for _w = 0 to 999 by 1
                int _select_weight_index = int(math.random(max=_size_w))
                float _rng = math.random(max=1.0)
                float _weight = array.get(id=weights, index=_select_weight_index)
                if _weight >= _rng
                    array.push(id=_path, value=_select_weight_index)
                    break
    _path
//{ usage:
// Input Parameters:
int depth = input.int(defval=1, minval=1)
int paths = input.int(defval=2, minval=1)
int number_of_weights = input.int(defval=2, minval=1)
// Array to contain weights, sum of array values must be 1.
var float[] node_weights = array.new_float(size=number_of_weights, initial_value=0)
if barstate.isfirst
    float _weight = 1.0 / number_of_weights
    for _i=1 to number_of_weights
        array.set(node_weights, _i-1, _weight)
    string t = ''
    for _p = 1 to paths by 1
        _path = decision_tree(node_weights, depth)
        t := t + '\nPath ' + str.tostring(_p, '#') + ': ' + str.tostring(_path)
        t
    var label la = label.new(bar_index, 0.0, t)
//{ remarks:
//}}}