Averaging based on condition

Viewing 9 posts - 1 through 9 (of 9 total)
  • Author
    Posts
  • #198485 quote
    gfx
    Participant
    Average

    Hi all,

    I hope you are doing fine.  I am stuck with a single problem so I’d rather ask help than building another 1000 lines indicator 🙂

    The idea is to create a moving average of n candles  ( n is user defined) but only of up candles.

    I was thinking of a while loop with a counter, but I can’t even get a first function to work.

    I get infinite loop warning when running this …

    runback = 0
    
    WHILE i <= triggerBars
    
    IF Close[runback] > Open[runback] THEN
     i = i + 1
    ENDIF
    
     runback = runback + 1
    WEND

    Thks in advance for your hints.

    gfx

    #198486 quote
    PeterSt
    Participant
    Master

    What I did for you is testing with

    • More and less bars (possibility of reading beyond the first bar in the chart)
    • More than one instrument (Fx vs Index)
    • Setting up the loop completely different (so PRT could not pre-process it and have false alarms on e.g. i not increasing for a while)
    • Finding the threshold

    Regarding the latter, it is always around (triggerbars) 2300 – 2500 that it fails. Under 2300 thus works (for what I tested with).

    You could make a Technical Report (via the Help menu – check the checkbox to allow PRT to open and read the code – just this code but with triggerbars initiated at 3000 or so) and tell them that you found a bug.
    It could be better to find a workaround because the solution may stay out many months (if ever).

    gfx thanked this post
    #198488 quote
    gfx
    Participant
    Average

    Thks. I added

    defparam CALCULATEONLASTBARS = 20

    and indeed it works. Though…

    I tried this …

    defparam CALCULATEONLASTBARS = 5
    
    // Initialise Trend
    FOR x = 1 to 20 
    IF Close[x]> Open[x] THEN
    DRAWARROW(barindex, high)
    ENDIF
    NEXT
    
    return

    and see attached picture.

    First it only executes on 4 last bars … not 5.

    Wired enough… if condition is not exectued as expected

    #198490 quote
    gfx
    Participant
    Average

    this drives me nuts !!

    #198504 quote
    JS
    Participant
    Senior

    Hi @gfx,

    Try this…

    N = 5
    
    If Close > Open then
    xAverage = Average[N](Close)
    DrawArrow(BarIndex,High)
    EndIf
    
    Return xAverage as "xAverage"
    
    #198527 quote
    druby
    Participant
    New

    hi…

    From your original post, I think the reason you may be getting the infinite loop is this:

    To exit the loop ‘i’ has to equate up to ‘triggerBars’+1.

    Now let’s say halve the candles in your chart are bull candles, ‘i’ can only increment up to halve of what ever you set ‘triggerBars’ to, since it only increments on a bull candle via the if condition. Along with this may be some error checking of historical bars loaded and also it has to end the loop before moving on to next bar. Don’t really fully understand whats going on, but that’s my thinking

    If you replace ‘i’ with runback in the ‘while’ condition, ‘runback’ always ends up ‘1’ bigger at the end of each loop iteration. This then terminates the loop at the end of the iteration when ‘triggerBars’ value is hit.

    Any way, I was looking at huge problem and your ‘up candle moving average’ kind of brushed against a concept I come up with and was thinking of using to solve it.

    While testing the concept I knocked up this code, which I think does something very close to what you were trying to do.

    It identify up candle’s and uses them to display a SMA via a lookback value. Two things to note, your up candle may be different from my define, and the SMA doesn’t use the current candle, not tested.

    Hold on to nuts, get your head around this!

     

    defparam drawOnLastBarOnly = true  // comment out to see arrows over up candles
    
    once cnt = -1 // up candle  barindex count
    lookback = 10
    
    //---------------------- indentify up candles - see below
    
    candle = 0
    if open < close or (open[1] < close[1] and close[1] < close) then // define up candle
    candle = 1
    endif
    
    //---------------------- on up candles 
    
    if candle then  // if a up candle
    cnt=cnt+1    // increment the count on a new up candle
    upBarindex = cnt // store the count
    accClose = accClose + close // keep an accumulated total of the up candle close's for sma calculation
    drawArrowDown(barindex,high+10)
    else
    upBarindex = -1 // if not up candle fill value with -1 for an identifier
    endif
    
    //---------------------- indentify last closed up candle
    
    for i = 1 to barindex[1] // loop back to find previous upBarindex
    if upBarindex[i] > -1 then // stop on first non -1
    x= upBarindex[i]
    drawtext("previous #x#",0,0)anchor(middle)
    previous = i // previous lookback distance
    break // terminate loop when found
    endif
    next
    
    //---------------------- indentify lookback up candle 
    
    for i = 1 to barindex[1] // loop back to find lookback upBarindex
    if upBarindex[i] = upBarindex[previous]-(lookback) then // stop
    y = upBarindex[i]
    drawtext("lookback #y#",0,-20)anchor(middle)
    back = i // lookback distance
    break // terminate loop when found
    endif
    next
    
    //---------------------- calculate sma using accumulated total data
    
    upSMA = (accClose[previous] - accClose[back])/lookback
    
    //---------------------- compare sma
    
    sma= average[lookback](close)
     
    return UpSma as"upSma", sma as"sma"style(dottedline,1)
    gfx thanked this post
    #198532 quote
    PeterSt
    Participant
    Master

    This one works. 🙂

    DefParam CalculateOnLastBars = 10   // This is unimportant as long as it is there and "few" for speed. Minimum is 2.
    
    ExamineAmount = 100000
    TriggerBars = 6000   // The amount of up-bars we want to find.
    i = 0   // Number of UpBars we counted (keep i the same as in gfx' example).
    
    for LoopCounter = 1 to ExamineAmount
    
      if Close[LoopCounter] > Open[LoopCounter] then   // Change to < for the Down-bars.
        i = i + 1
        if i > TriggerBars then
          break   // So we exit here ot ar the end of the loop (ExamineAmount).
        endif
      endif
      
    next
    
    Return i

    2nd attachment shows the down-bars.
    Both are equal-ish, which I suppose it possible tonight. The chart comprises of 10K bars but it runs for a while so more bars populated.

    It will do the calculation at each new bar, so maybe it is not smart to let this run forever.

     

    First it only executes on 4 last bars … not 5.

    Yes, something seems wrong there because DrawOnLastBars can not be 1 (error message) and with 2 it draws 1.

    gfx thanked this post
    #198544 quote
    gfx
    Participant
    Average

    looks good 🙂

    #198549 quote
    gfx
    Participant
    Average

    I ended up with this approach…

     

    defparam CALCULATEONLASTBARS = 30
    i = 0
    IF Close[0]> Open[0] THEN
    FOR x = 0 to 20
    IF Close[x] > Open[x] and i < 3 Then
    ...
    i = i + 1
    ENDIF
    NEXT
    
Viewing 9 posts - 1 through 9 (of 9 total)
  • You must be logged in to reply to this topic.

Averaging based on condition


ProBuilder: Indicators & Custom Tools

New Reply
Author
author-avatar
gfx @gfx Participant
Summary

This topic contains 8 replies,
has 4 voices, and was last updated by gfx
3 years, 6 months ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 08/04/2022
Status: Active
Attachments: 5 files
Logo Logo
Loading...