Nested Fold Function Debugging

StoneMan

Member
Plus
Hello all, got an interesting little project here with a pesky bug I just can't seem to squash. I was building out a new type of filter/moving average I came up with and got the bright idea to try and take the average of all averages between two levels to smooth the data even further. As you can't feed a script a non-constant variable, I mimicked Script F within my fold function to properly iterate between average levels. This is where I am running into problems with how the output is displaying on the chart. The values are far too small. The design intent is to have the length1 and length2 variables be inclusive for the averaging of the averages. Also included in the script is the output of Script F, and an example of the math I began with and automated via Script F. You can see Script F and the "simple math" are the same for their given length. So those parts if the code are good. It's just that giant function giving me grief.
Rich (BB code):
#Averaging Expiramental Averages With Nested Fold
#StoneMan(StoneF)
#6.3.2023
#Hunting down bug SuperAverage

Declare Upper;
Script F {
Input Length = 10;

def data = close;

def FilterData =
    fold a = 0
    to Length
    with K = 0
    do K + data[a]*(Length - a);

def FilterCount =
    fold i = 0
    to Length + 1
    with P = 0
    do P + i;

def FilterAverage = FilterData / FilterCount;

plot Filter = FilterAverage;
}


input SupAvgLength1 = 10;
input SupAvgLength2 = 5;

def data = close;

#Number to divide moving averages by
def LengthDiff = AbsValue(SupAvgLength1 - SupAvgLength2) + 1;

def SuperAverage =
    if(SupAvgLength1 == SupAvgLength2, F(SupAvgLength1),
            (Fold q = if(SupAvgLength1 < SupAvgLength2, SupAvgLength1, SupAvgLength2)
             to if(SupAvgLength1 > SupAvgLength2, SupAvgLength1, SupAvgLength2)
             with R = 0
             do R + (
                     #Implementing nested fold function because ThinkScript cannot do F(q) but we can recreate function F
                     (Fold u = 0
                     to q
                     with X = 0
                     do X + GetValue(data, u)*(q-u)) /
                     #Now divide this by the filter count function as we do in F
                     (Fold w = 0
                     to q + 1
                     with G = 0
                     do G + q)
                     )
             ) / LengthDiff
      )
;

plot test = superaverage;

input FunctionF = 10;
Plot ScriptF = F(FunctionF);


#Example showing the calculation process function F is automating. This is equivalent to length = 10
def Average10 =(
    (data*10) +
    (data[1]*9) +
    (data[2]*8) +
    (data[3]*7) +
    (data[4]*6) +
    (data[5]*5) +
    (data[6]*4) +
    (data[7]*3) +
    (data[8]*2) +
    (data[9])
    ) /55;

plot ManualCalcTest = Average10;
 
I should add the logic I am trying to accomplish:

The if statement that begins the function looks to see if the inputs are equal. As in that case there would be no moving averages between them to average. So it just runs one of the inputs through script F which is our expirimental average. If the inputs are different, our indexing variable, q, is set to whichever value is lower. q will fold to which ever input is higher. This done to make the program more robust and not rely on a specific input being higher than another. Our temporary variable is set to zero and adds the nested fold logic.

The nested fold uses the same logic structure as script F to calculate our expirimental average. In that first fold function we fold from our nested indexing variable, u, to our main indexing variable, q. This means that for every instance of q we fold from u to q in this function.

In terms of calculating our expirimental average this means that q is the new length input you see in script F. Our temporary variable X holds that value from the data using the GetValue function to work with the dynamic offset. Using q as our length input in this nested average is what allows us to calculate each moving average between the SupAvgLength1 and SupAvgLength2 bounds. When that length is calculated it is added to R.

At this point q increments by one and the process starts over until q has incremented between all values of SupAvgLength1 and SupAvgLength1. That value is then divided by the absolute value of the difference between SupAvgLength1 and SupAvgLength1 plus one. Plus one assumes the averages taken are inclusive and makes the divsor work for the average of the averages which I decided to name SuperAverage.

That's the logic of the function, which isn't quite working right as posted so I hope this plain language road map of what I am trying to have the function do will help anyone interested in giving this a look. I know this is complex so thank you in advance.
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
444 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top