Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Join us at FabCon Atlanta from March 16 - 20, 2026, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM. Register now.

Reply
avachris
Frequent Visitor

Recursive Function Forecasting

Hi there - 

 

I have a list of portfolios that I'd like to forecast through time. 

 

I also have a seperate table which outlines the quarter over quarter growth rate.

 

I think the right solution here is a recursive function. 

 

Here are the tables below

 

Input - Portfolio Table initial values to apply forecast

PortfolioStarting Value
Portfolio A100
Portfolio B150

 

Input - Forecast table - contains the forecast assumptions

ScenarioModeled Quarterly Growth Rate (%)Additional Growth ($)Quarter Index
Good1001
Good10502
Bad101
Bad202

 

 

Output- The function being:

Forecasted Value = Prior Value x Quarter over Quarter Growth + Additional Growth

PortfolioScenarioModeled Quarterly Growth Rate (%)Additional Growth ($)Quarter IndexForecasted Value
Portfolio AGood1001110
Portfolio AGood10502171
Portfolio ABad101101
Portfolio ABad202103.02

 

I was playing with a recursive function in M going something like this: 

 

(totalLoops as number, loop as number, Value as number, ForecastTable as table ) =>
let
CurrentValue = Value * ForecastTable{3}QoQ +ForecastTable{4}AdditionalGrowth , \\ applies the growth rate and additional growth
CurrentLoop = loop +1, \\ loop counter
ForecastTable =

\\ I am having trouble with this part
if ForecastTable is null then Table.FromRecords({[Scenario = "a", QoQ = 0, Quarter = 0,ForecastValue = Value]}) else 
Table.Combine({ForecastTable,Table.FromRecords({[Scenario = "b", QoQ = 0, Quarter = 0]})}),
Output =
if CurrentLoop >= totalLoops
then ForecastTable
else @fxForecast (totalLoops,CurrentLoop,CurrentValue,ForecastTable)
in
Output
1 ACCEPTED SOLUTION
wdx223_Daniel
Super User
Super User

10 REPLIES 10
wdx223_Daniel
Super User
Super User

assume the maturity date is in the 3rd column of portfolio table, then try update your code as below.

let
    PT = Table.ToRows(Portfolio),
    FT = Table.ToRows(Forecast)

in #table ({"Porfolio","Maturity Date"}&Table.ColumnNames(Forecast)&{"Forecast Value"},

List.TransformMany(PT, each FT, 


(x,y)=> {x{0},x{2}}&y& // starts building the table with the first column of portfolio and column from forecast

{List.Accumulate // start the accumulate loop

(List.Select(FT,each _{3}<=y{3} and _{0}=y{0} // filters a table for where the scenario names match and where the forecast rows are lessthan or equal to current forecast period


),x{1}, // seeds the value with the jump off of the portfolio


(x,y) => x*(1+y{1}/100)+y{2})})) // applies the assumptions from the forecast table

hi there - I want to be able to leverage the portfolio date within the list.accumulate loop. Something like if the maturity date is less than the forecasted date then the forecasted value is 0.  This is a much more simple example than what I am really trying to do.  Definitely seeing that the Dax solution appears to be way more flexible. 

then change this part of the code:            List.Select(FT,each _{3}<=y{3} and _{0}=y{0} and x{index of date column}<=y{index of date column}

then change this part of the code:            List.Select(FT,each _{3}<=y{3} and _{0}=y{0} and x{index of date column}<=y{index of date column}

avachris
Frequent Visitor

Hi there - For folks looking at this, here is the commented code as far as I can figure it out.

 

let
    PT = Table.ToRows(Portfolio),
    FT = Table.ToRows(Forecast)

in #table ({"Porfolio"}&Table.ColumnNames(Forecast)&{"Forecast Value"},

List.TransformMany(PT, each FT, 


(x,y)=> {x{0}}&y& // starts building the table with the first column of portfolio and column from forecast

{List.Accumulate // start the accumulate loop

(List.Select(FT,each _{3}<=y{3} and _{0}=y{0} // filters a table for where the scenario names match and where the forecast rows are lessthan or equal to current forecast period


),x{1}, // seeds the value with the jump off of the portfolio


(x,y) => x*(1+y{1}/100)+y{2})})) // applies the assumptions from the forecast table

 

 @wdx223_Daniel a couple of questions for you: 

 

In the following step is there a way to access the original Portfolio table to get additional columns, for example it would be helpful to grab the portfolio maturity date for the portfolio table. If not, was thinking I could use your method to create a permutation of the forecast table and portfolio table (essentially making the Y table bigger with all relevant columns) 

(x,y) => x*(1+y{1}/100)+y{2})})) // applies the assumptions from the forecast table

 

Also is the list accumulate limited to only 1 value, what if I wanted to track two values through time so that I could then compare those two values in a future period? 

wdx223_Daniel
Super User
Super User

or use dax formula like this

wdx223_Daniel_1-1631263892535.png

 

wdx223_Daniel
Super User
Super User

wdx223_Daniel_0-1631261722411.png

 

Wow that's really incredible - I enjoy and appreciate the DAX solution as well. 

 

Which in your opinion performs better? This is a simple example of a calculation that I'll have to run and then load to an OLAP cube via excel add in. Was thinking Power Query as it "generates" the data set, vs DAX where its being calculated.

 

Wow that's really incredible - I enjoy and appreciate the DAX solution as well. 

 

Which in your opinion performs better? This is a simple example of a calculation that I'll have to run and then load to an OLAP cube via excel add in. Was thinking Power Query as it "generates" the data set, vs DAX where its being calculated.

 

Anonymous
Not applicable

You don't state what trouble you are having, but you might want to change it from

 

if ForecastTable is null

 

to

 

if Table.IsEmpty(ForecastTable) then...

 

--Nate

Helpful resources

Announcements
FabCon Global Hackathon Carousel

FabCon Global Hackathon

Join the Fabric FabCon Global Hackathon—running virtually through Nov 3. Open to all skill levels. $10,000 in prizes!

October Power BI Update Carousel

Power BI Monthly Update - October 2025

Check out the October 2025 Power BI update to learn about new features.

FabCon Atlanta 2026 carousel

FabCon Atlanta 2026

Join us at FabCon Atlanta, March 16-20, for the ultimate Fabric, Power BI, AI and SQL community-led event. Save $200 with code FABCOMM.

Top Kudoed Authors