Can anyone code John Ehler's FRAMA ?

Viewing 14 posts - 1 through 14 (of 14 total)
  • Author
    Posts
  • #17097 quote
    Bard
    Participant
    Master

    Hi

    I was looking into Ehlers Cycle theories and came across a Moving Averages Study that shows Ehler’s Fractal Adaptive Moving Average (FRAMA) is far superior to the EMA and SMA (although I don’t know how it would stand up to Kaufman’s Adaptive Moving Average) :

    http://etfhq.com/blog/2010/10/09/frama-is-it-effective/#Best

    Does anyone know how to code it from this Metatrader code? :

    https://www.mql5.com/en/code/72

    Cheers
    Brad

    #17102 quote
    Nicolas
    Keymaster
    Master

    Found this old code on a German forum for FRAMA moving average , modified some variables names for recent PRT version :

    // FRAMA
    
    p = 20
    
    pri=Customclose
    len=p
    
    
    N3=(Highest[len](High)-Lowest[len](Low))/len
    
    mH=High
    L=Low
    
    For count=0 To len/2-1
    If High[count] > mH Then
    mH=High[count]
    Endif
    
    If Low[count] < L Then
    L=Low[count]
    Endif
    Next
    
    N1=(mH-L)/(len/2)
    
    HH=High[len/2]
    LL=Low[len/2]
    
    For count=len/2 To len-1
    If High[count] > HH Then
    HH=High[count]
    Endif
    
    If Low[count] < LL Then
    LL=Low[count]
    Endif
    Next
    
    N2=(HH-LL)/(len/2)
    
    If N1 > 0 And N2 > 0 And N3 > 0 Then
    Dimen=(Log(N1+N2)-Log(N3))/Log(2)
    Endif
    
    alpha=Exp(-4.6*(Dimen-1))
    
    If alpha < 0.01 Then
    alpha=0.01
    Endif
    
    If alpha > 1 Then
    alpha=1
    Endif
    
    Filt=alpha*pri+(1-alpha)*Filt[1]
    
    If Barindex < len+1 Then
    Filt=pri
    Endif
    
    Return Filt as "FRAMA"

    I’ll post it too into the Library with credits for the author of course.

    Bard thanked this post
    #17108 quote
    Nicolas
    Keymaster
    Master

    Added to the Library for future reference: FRAMA indicator download

    #17116 quote
    Bard
    Participant
    Master

    Thanks Nicolas, much appreciated.

    Do you know if FRAMA is meant to have a fast (FC) and slow (SC) moving average setting like the Kaufman Adaptive Mov Ave?
    On the link above (efthq blog) is mentions in it’s conclusion:

    “The FRAMA is astoundingly effective as both a fast and a slow moving average and will outperform any SMA or EMA.  We selected a modified FRAMA with a “FC” of 4, a “SC” of 300 and a “FRAMA” period of 126 as being the most effective fast FRAMA although the settings for a standard FRAMA will also produce excellent results.  For a slower or longer term average the best results are likely to come from a “FC” of 40, a “SC” of 250 and a “FRAMA” period of 252.”

     

    Cheers

    Brad

    #17842 quote
    Bard
    Participant
    Master

    Hi Nicolas,

    The code above does appear to be come from a paper written by Ehler’s: http://www.mesasoftware.com/papers/FRAMA.pdf
    But I think there is a newer version. I found this code below for Ehler’s FRAMA which has the fast and slow moving averages setting.

    
    #'FRactal Adaptive Moving Average
    #'@param HLC an HLC price series
    #'@param n a lookback period
    #'@param FC a fast constant--aka lowest n for an EMA
    #'@param SC a slow constant--aka lowest n for an EMA
    #'@param triggerLag a number of days by which to lag the original computation
    #'@return an xts containing the FRAMA and the trigger
    #'@references 
    #'\cr\url{http://www.mesasoftware.com/Papers/FRAMA.pdf}
    #'\cr\url{http://etfhq.com/blog/2010/09/30/fractal-adaptive-moving-average-frama/}
    #'@export
    "FRAMA" <- function(HLC, n=20, FC=1, SC=200, triggerLag=1, ...) {
      price <- ehlersPriceMethod(HLC, ...)
      if (n%%2==1) n=n-1 #n must be even
      N3 <- (runMax(Hi(HLC), n)-runMin(Lo(HLC), n))/n
      N1 <- (runMax(Hi(HLC), n/2)-runMin(Lo(HLC), n/2))/(n/2)
      lagSeries <- lag(HLC, n/2)
      N2 <- (runMax(Hi(lagSeries), n/2)-runMin(Lo(lagSeries), n/2))/(n/2)
      dimen <- (log(N1+N2)-log(N3))/log(2)
      w <- log(2/(SC+1))
      oldAlpha <- exp(w*(dimen-1))
      oldN <- (2-oldAlpha)/oldAlpha
      newN <- ((SC-FC)*(oldN-1)/(SC-1))+FC
      alpha <- 2/(newN+1)
      alpha[which(alpha > 1)] <- 1
      alpha[which(alpha < w)] <- w
      alphaComplement <- 1-alpha
      initializationIndex <- index(alpha[is.na(alpha)])
      alpha[is.na(alpha)] <- 1; alphaComplement[is.na(alphaComplement)] <- 0
      FRAMA <- rep(0, length(price))
      FRAMA[1] <- price[1]
      FRAMA <- computeFRAMA(alpha, alphaComplement, FRAMA, price)
      FRAMA <- xts(FRAMA, order.by=index(price))
      FRAMA[initializationIndex] <- alpha[initializationIndex] <- NA
      trigger <- lag(FRAMA, triggerLag)
      out <- cbind(FRAMA=FRAMA, trigger=trigger)
      return(out)
    }
    

    There is also metatrader code using log values of the EMA: https://www.mql5.com/en/code/72

    FRAMA(i) = A(i) * Price(i) + (1 - A(i)) * FRAMA(i-1)
    where:
    
    FRAMA(i) - current value of FRAMA;
    Price(i) - current price;
    FRAMA(i-1) - previous value of FRAMA;
    A(i) - current factor of exponential smoothing.
    Exponential smoothing factor is calculated according to the below formula:
    
    A(i) = EXP(-4.6 * (D(i) - 1))
    where:
    
    D(i) - current fractal dimension;
    EXP() - mathematical function of exponent.
    Fractal dimension of a straight line is equal to one. It is seen from the formula that if D = 1, then A = EXP(-4.6 *(1-1)) = EXP(0) = 1. Thus if price changes in straight lines, exponential smoothing is not used, because in such a case the formula looks like this:
    
    FRAMA(i) = 1 * Price(i) + (1 - i) * FRAMA(i-1) = Price(i)
    I.e. the indicator exactly follows the price.
    
    The fractal dimension of a plane is equal to two. From the formula we get that if D = 2, then the smoothing factor A = EXP(-4.6*(2-1)) = EXP(-4.6) = 0.01. Such a small value of the exponential smoothing factor is obtained at moments when price makes a strong saw-toothed movement. Such a strong slow-down corresponds to approximately 200-period simple moving average.
    
    Formula of fractal dimension:
    
    D = (LOG(N1 + N2) - LOG(N3))/LOG(2)
    It is calculated based on the additional formula:
    
    N(Length,i) = (HighestPrice(i) - LowestPrice(i))/Length
    where:
    
    HighestPrice(i) - current maximal value for Length periods;
    LowestPrice(i) - current minimal value for Length periods;
    Values N1, N2 and N3 are respectively equal to:
    
    N1(i) = N(Length,i)
    N2(i) = N(Length,i + Length)
    N3(i) = N(2 * Length,i) 

    Is is possible to code these into PRT code (or incorporate this with your code) to compare the effectiveness of the FC and SC with the Log version?

    Thanks,

    Cheers
    Brad

    #17883 quote
    Nicolas
    Keymaster
    Master

    If you can find comprehensive formula from any other trading software (not from “R” like your first one), I could code the modified FRAMA for PRT of course.

    #17907 quote
    Bard
    Participant
    Master

    Not from “R”?

    #17922 quote
    Bard
    Participant
    Master

    Hi Nicholas,

    You mean Copyrighted “C”?

    This code has the fast and Slow Mov Averages and is logarithmic. Could you delete the other two codes above? Thanks (-:

    study("Fractal Adaptive Moving Average",shorttitle="FRAMA",overlay=true)
    
    price = close
    len = input(defval=252,minval=1)
    FC = input(defval=40,minval=1)
    SC = input(defval=252,minval=1)
    
    w = log(2/(SC+1))
    len1 = len/2
    H1 = highest(high,len1)
    L1 = lowest(low,len1)
    N1 = (H1 - L1)/len1
    
    H2 = for i = len1+1 to len
        high>high[i]?high:high[i]
        
    L2 = for i = len1+1 to len
        low>low[i]?low:low[i]
    
    N2 = (H2 - L2)/len1
    
    H3 = highest(high,len)
    L3 = lowest(low,len)
    N3 = (H1 - L1)/len
    
    dimen = (log(H1+H2) - log(H3))/log(2)
    oldalpha = exp(w*(dimen-1))
    oldN = (2-oldalpha)/oldalpha
    newN = ((SC-FC)*(oldN-1)/(SC-1))+FC
    alpha = 2/(newN+1)
    out = nz(out[1])*(1-alpha) + price*alpha
    
    plot(out,title="FRAMA")
    #17936 quote
    Nicolas
    Keymaster
    Master

    Nope I meant “R”, the statistical analysis software: https://www.r-project.org/

    This last new code is much more readable, I believe it can be converted to probuilder. Let me have a look.

    #17985 quote
    Nicolas
    Keymaster
    Master

    Your last code proposal have some variables that aren’t used in the final calculation of the FRAMA. This prorealtime code is the result of the conversion, it returns a curve, I let you verify its information on your charts 🙂

    price = close
    len = 126 //FRAMA period
    FC = 4 //fast constant--aka lowest n for an EMA
    SC = 300 //slow constant--aka lowest n for an EMA
    
    if barindex>len+fc+sc then
    w = log(2/(SC+1))
    len1 = len/2
    H1 = highest[len1](high)
    //L1 = lowest[len1](low)
    //N1 = (H1 - L1)/len1
    
    for i = len1+1 to len do
    if high>high[i] then
    H2 = high[i]
    endif
    next
    
    //for i = len1+1 to len do
    //if low>low[i] then
    //L2  = low[i]
    //endif
    //next
    
    //N2 = (H2 - L2)/len1
    
    H3 = highest[len](high)
    //L3 = lowest[len](low)
    //N3 = (H1 - L1)/len
    
    dimen = (log(H1+H2) - log(H3))/log(2)
    oldalpha = exp(w*(dimen-1))
    oldN = (2-oldalpha)/oldalpha
    newN = ((SC-FC)*(oldN-1)/(SC-1))+FC
    alpha = 2/(newN+1)
    out = (out[1])*(1-alpha) + price*alpha
    endif
    
    RETURN out as "modified FRAMA"
    #18057 quote
    supertiti
    Participant
    Master

    Avec FC = 40  SC = 250  LEN = 252  j’ai cela comme retour ?!  la moyenne est “flat”

    #35462 quote
    laurenzo
    Participant
    Average

    Dans le code on a du

    HH=High[len/2]
    LL=Low[len/2]
     
    For count=len/2 To len-1
    If High[count] > HH Then
    HH=High[count]
    Endif

    Tout va bien quand len est pair.

    Si len est impaire, ça va planter on va essayer d’accéder à Low[décimal].

    Du coup il faut faire un ROUND je suppose avant 🙂

    genre High[ROUND(count)]

    C’est pas super beau mais bon 🙂

    #35463 quote
    laurenzo
    Participant
    Average

    Voilà mon code avec les rounds et le FIX sur le LOG

     

    // FRAMA - Fractal Adaptive Moving Average by John Ehlers
    
    // --- parameters
    Series = CustomClose
    // Period = 20
    // ---
    
    Period = MAX(Period, 1)
    
    N3 = (highest[Period](High) - lowest[Period](Low)) / Period
    mH = High
    L = Low
    
    FOR count = 0 TO (Period / 2) - 1 DO
        count = ROUND(count)
        IF High[count] > mH THEN
            mH = High[count]
        ENDIF
        IF Low[count] < L THEN
            L = Low[count]
        ENDIF
    NEXT
    
    N1 = (mH - L) / (Period / 2)
    HH = High[ROUND(Period / 2)]
    LL = Low[ROUND(Period / 2)]
    
    FOR count = Period / 2 TO Period - 1 DO
        count = ROUND(count)
        IF High[count] > HH THEN
            HH = High[count]
        ENDIF
        IF Low[count] < LL THEN
            LL = Low[count]
        ENDIF
    NEXT
    
    N2 = (HH - LL) / (Period / 2)
    
    IF N1 > 0 AND N2 > 0 AND N3 > 0 THEN
        // FIX LOG
        Dimen = ((LOG(N1 + N2) / LOG(10)) - (LOG(N3) / LOG(10))) / (LOG(2) / LOG(10))
    ENDIF
    
    alpha = EXP(-4.6 * (Dimen - 1))
    IF alpha < 0.01 THEN
        alpha = 0.01
    ELSIF alpha > 1 THEN
        alpha = 1
    ENDIF
    
    IF BarIndex < Period THEN
        FRAMA = Series
    ELSE
        FRAMA = alpha * Series + (1 - alpha) * FRAMA[1]
    ENDIF
    
    RETURN FRAMA
    
    Nicolas thanked this post
    #35493 quote
    Bard
    Participant
    Master

    Appreciated, thanks @laurenzo.

Viewing 14 posts - 1 through 14 (of 14 total)
  • You must be logged in to reply to this topic.

Can anyone code John Ehler's FRAMA ?


ProBuilder: Indicators & Custom Tools

New Reply
Author
author-avatar
Bard @brad Participant
Summary

This topic contains 13 replies,
has 4 voices, and was last updated by Bard
8 years, 9 months ago.

Topic Details
Forum: ProBuilder: Indicators & Custom Tools
Language: English
Started: 11/24/2016
Status: Active
Attachments: 3 files
Logo Logo
Loading...