Forum Discussion

jsflint's avatar
jsflint
Frequent Visitor
5 years ago
Solved

Exponential Moving Average in Power Query M ?

Hello! How can an exponential moving average be created in Power Query M?  I already know how to do this in Excel, and DAX can be a pain in the tail.  Here's a table of example data.  Thank you!   ...
  • Fowmy's avatar
    5 years ago

    jsflint 

    Can you share the expected value based on the sample data that you have given?

    You can save the  Excel file with the results in One Drive or Google Drive and share the link 


  • jsflint's avatar
    jsflint
    5 years ago

    Ema 

    Here it is

  • Fowmy's avatar
    Fowmy
    5 years ago

    jsflint 

    Please find attached the PBIX file below my signature with the desired results. Basically, the solution involves a recursive operation to calculate the EMA ( Exponential Moving Average in Power Query ).

    There are two columns, Average and EMA.

    Complete M Code:

    let
      Source = Table.FromRows(
        Json.Document(
          Binary.Decompress(
            Binary.FromText(
              "VZLbbQRBCARz2e+TD5p3LNbln4Y5adnB3yVmmqJ/fy9+8xsEvl4X/Qghwwp2fV5fhIPY3BERuJEchFRIROmN9CAXB2Ua38gOSmEmS5Ib+UGVIdIobxQHGbsEdFLkIqlM7E/2Wu+hxDV5AjIdFmUIE58YvHQwJZX1d8OWD3PWkqL5jpeQTsim5jVsGSEEzEzGCC8lkZbO5bMdLydiZar8+OfYc17gHhy2tDi+xjrMsOVF4CQVz3WwvGSHJCedOfA+Qh8uO+qw5YWCoBJDdk24L+TBswGWFe3FJeMxhl2UXlz6eHMhbCtpndGmKFhSssvaZdYnypJC3YYyz4fVv4aBvOt8fT5/",
              BinaryEncoding.Base64
            ),
            Compression.Deflate
          )
        ),
        let
          _t = ((type nullable text) meta [Serialized.Text = true])
        in
          type table [Date = _t, Value = _t]
      ),
      #"Changed Type" = Table.TransformColumnTypes(
        Source,
        {{"Date", type date}, {"Value", type number}}
      ),
      Step1 = Table.AddIndexColumn(#"Changed Type", "Index", 0, 1, Int64.Type),
      Step2 = Table.AddColumn(
        Step1,
        "Average",
        each if [Index] > 6 then List.Average(List.Range(Step1[Value], _[Index] - 7, 7)) else null
      , type number),
      Step3 = Table.AddColumn(
        Step2,
        "EMA",
        each
          if [Index] > 6 then
            let
              start = List.First(List.RemoveNulls(Step2[Average])),
              vlist = List.Range(Step2[Value], 8, _[Index] - 7),
              acc = List.Accumulate(
                vlist,
                start,
                (state, current) => (current - state) * (2 / (1 + 7)) + state
              )
            in
              if [Index] = 7 then start else acc
          else
            null,
      type number )
    in
        Step3