Search code examples
technical-indicatorthinkscript

Understanding & Converting ThinkScripts CompoundValue Function


I'm currently converting a ThinkScript indicator to C#, however, I've run into this CompoundValue function and I'm unsure how to covert it.

The documents reads :

Calculates a compound value according to following rule: if a bar number is greater than length then the visible data value is returned, otherwise the historical data value is returned. This function is used to initialize studies with recursion.

Example Use:

declare lower;
def x = CompoundValue(2, x[1] + x[2], 1);
plot FibonacciNumbers = x;

My interpretation:

Based on description and example. It appears we are passing a calculation in x[1] + x[2] and it performing this calculation on the current bar and the previous bar (based on first param of 2). I'm unsure what the parameter 1 is for.

My Question:

Please explain what this function is actually doing. If possible, please illustrate how this method works using pseudo-code.


Solution

  • Please let me provide two equivalent working versions of the code in thinkscript itself. We use this approach to prove equivalence by subtracting the equivalent outputs from each other - the result should be 0.

    # The original Fibonacci code with a parameter "length" added.
    # That parameter is the first parameter of the CompoundValue function.
    declare lower;
    def length = 2;
    def x = CompoundValue(length, x[1] + x[2], 1);
    # plot FibonacciNumbers = x;
    
    # Equivalent code using the `if` statement:
    def y;
    if(BarNumber() > length){
        # Visible data. This is within the guarded branch of the if statement.
        # Historical data y[1] (1 bar back) and y[2] (2 bars back) is available
        y = y[1] + y[2];
    }else{
        # Not enough historical data so we use the special case satisfying the
        # original rule.
        y = 1;
    }
    plot FibonacciNumbersDiff = y - x;
    

    Thinkscript "recursion" is a somewhat inflated term. The function name CompoundValue is not very helpful so it may create confusion.

    The version using the if statement is more useful in general because when walking through the time series of bars, we often need a program structure with multiple nested if statements - this cannot be done with the CompoundValue function. Please see my other articles which make use of this in the context of scanning.

    In Java, using the same structure, it looks like this:

    int size = 100;
    int length = 2;
    int[] values = new int[size];
    for(int index = 1; index < size; index++){
        if(index > length){
            values[index] = values[index - 1] + values[index - 2];
        }else{
            values[index] = 1;
        }
    }
    

    The fundamental difference is the for loop which is not present in the thinkscript code. thinkscript provides the loop in a kind of inversion of control where it executes user code multiple times, once for each bar.