(*Financial Modelling using Repeated Replace*)
Remove["Global`*"]
timestart=AbsoluteTime[];
periods=3;
n=periods;(*since this approach uses the zero index for initial conditions*)
eqns={
(*** Projection assumptions ***)
salesgrowthrate[t]==salesgrowthrate[t-1] ,
expensesgrowthrate[t]==expensesgrowthrate[t-1],
newloan[t]==newloan[t-1],
newcapital[t]==newcapital[t-1],
newassets[t]==depreciation[t-1],
depreciationrate[t]==depreciationrate[t-1],
loanintrate[t]==loanintrate[t-1],
netcashintrate[t]==netcashintrate[t-1],
taxrate[t]==taxrate[t-1],
daysdebtors[t]==daysdebtors[t-1],
daysstock[t]==daysstock[t-1],
dayscreditors[t]==dayscreditors[t-1],
divpayoutratio[t]==divpayoutratio[t-1],
interimdivpropn[t]==interimdivpropn[t-1],
interimprofitpropn[t]==interimprofitpropn[t-1],
interimnewcapitalpropn[t]==interimnewcapitalpropn[t-1],
interimnewloanpropn[t]==interimnewloanpropn[t-1],
interimnewassetspropn[t]==interimnewassetspropn[t-1],
(*** MAIN MODEL ***)
(** P&L **)
sales[t]==sales[t-1](1+salesgrowthrate[t]),
expenses[t]==expenses[t-1](1+expensesgrowthrate[t]),
(* start of interest calculation *)
(*first half*)
intloan1[t]==(loan[t-1]/2+newloan[t]interimnewloanpropn[t]/4)loanintrate[t],
intcf1[t]==(collections[t]-payments[t])interimprofitpropn[t]+newcapital[t]interimnewcapitalpropn[t]+newloan[t]interimnewloanpropn[t]- newassets[t]interimnewassetspropn[t],
(*earnings before interest on cash and after interest on loans*)
deprec1[t]==(netfixedassets[t-1]/2+newassets[t]interimnewassetspropn[t]/4)depreciationrate[t],
ebcit1[t]==(sales[t]-expenses[t])interimprofitpropn[t]-deprec1[t]-intloan1[t] ,
(* The follolowing equations resolve the circular loop:
cash1[t]==cash[t-1]+intcf1[t]+intcash1[t]-taxpmt1[t],
or, cash1[t]==cash[t-1]+intcf1[t]-intloan1[t]+intcash1[t]-(ebcit1[t]+intcash1[t])*taxrate[t]-provdiv[t-1] (1),
and intcash1[t]==(cash[t-1]+cash1[t])*cashintrate[t]/4 (2),
(1)in(2), intcash1[t]==(cash[t-1]+cash[t-1]+intcf1[t]-intloan1[t]+intcash1[t]-(ebcit1[t]+intcash1[t])*taxrate[t]-provdiv[t-1])*cashintrate[t]/4,
(4 intcash1[t])/cashintrate[t]==cash[t-1]+cash[t-1]+intcf1[t]-intloan1[t]+intcash1[t]-(ebcit1[t]+intcash1[t])*taxrate[t]-provdiv[t-1],
intcash1[t]((4/cashintrate[t])-1+taxrate[t])== 2 cash[t-1]+intcf1[t]-intloan1[t]-ebcit1[t]*taxrate[t]-provdiv[t-1],
intcash1[t]==(2 cash[t-1]+intcf1[t]-intloan1[t]-ebcit1[t]*taxrate[t]-provdiv[t-1])/((4/cashintrate[t])-1+taxrate[t]),*)
intcash1[t]==(2 netcash[t-1]+intcf1[t]-intloan1[t]-ebcit1[t]*taxrate[t]-provdiv[t-1])/((4/netcashintrate[t])-1+taxrate[t]),
taxpmt1[t]==(ebcit1[t]+intcash1[t])taxrate[t],
netcash1[t]==netcash[t-1]+intcf1[t]+intcash1[t]-taxpmt1[t],
(*second half*)
intloan2[t]==(loan[t-1]/2+newloan[t]interimnewloanpropn[t]/2+newloan[t](1-interimnewloanpropn[t])/4)loanintrate[t],
intcf2[t]==(collections[t]-payments[t])(1-interimprofitpropn[t])+newcapital[t](1-interimnewcapitalpropn[t])+newloan[t](1-interimnewloanpropn[t])-newassets[t](1-interimnewassetspropn[t]),
deprec2[t]==(netfixedassets[t-1]/2+newassets[t]interimnewassetspropn[t]/2+newassets[t](1-interimnewassetspropn[t])/4)depreciationrate[t],
ebcit2[t]==(sales[t]-expenses[t])(1-interimprofitpropn[t])-deprec2[t]-intloan2[t] ,
(* Solve: cash2[t]==cash1[t]+intcf2[t]-intloan2[t]+intcash2[t]-taxpmt2[t]-div2[t],
or,     cash2[t]==cash1[t]+intcf2[t]-intloan2[t]+intcash2[t]-(ebcit2[t]+intcash2[t])*taxrate[t]-(ebcit1[t]+intcash1[t]+ebcit2[t]+intcash2[t])*(1-taxrate[t])*divpayoutrate[t]*interimdivpropn[t] (1),
and    intcash2[t]==(cash1[t]+cash2[t])*cashintrate[t]/4 (2),
(1)in(2), intcash2[t]==(cash1[t]+cash1[t]+intcf2[t]-intloan2[t]+intcash2[t]-(ebcit2[t]+intcash2[t])*taxrate[t]-(ebcit1[t]+intcash1[t]+ebcit2[t]+intcash2[t])*(1-taxrate[t])*divpayoutratio[t]*interimdivpropn[t])*taxrate[t])*cashintrate[t]/4,
(4 intcash2[t])/cashintrate[t]==cash1[t]+cash1[t]+intcf2[t]-intloan2[t]+intcash2[t]-(ebcit2[t]+intcash2[t])*taxrate[t]-(ebcit1[t]+intcash1[t]+ebcit2[t]+intcash2[t])*(1-taxrate[t])*divpayoutratio[t]*interimdivpropn[t],
intcash2[t]((4/cashintrate[t])-1+taxrate[t]+(1-taxrate[t])*divpayoutratio[t]*interimdivpropn[t])== 2 cash1[t]+intcf2[t]-intloan2[t]-ebcit2[t]*taxrate[t]-(ebcit1[t]+intcash1[t]+ebcit2[t])*(1-taxrate[t])*divpayoutratio[t]*interimdivpropn[t],
intcash2[t]== (2 cash1[t]+intcf2[t]-intloan2[t]-ebcit2[t]*taxrate[t]-(ebcit1[t]+intcash1[t]+ebcit2[t])*(1-taxrate[t])*divpayoutratio[t]*interimdivpropn[t])/((4/cashintrate[t])-1+taxrate[t]+(1-taxrate[t])*divpayoutratio[t]*interimdivpropn[t])*)
divpropn2[t]==(1-taxrate[t])*divpayoutratio[t]*interimdivpropn[t],
intcash2[t]== (2 netcash1[t]+intcf2[t]-intloan2[t]-ebcit2[t]taxrate[t]-(ebcit1[t]+intcash1[t]+ebcit2[t])divpropn2[t])/((4/netcashintrate[t])-1+taxrate[t]+divpropn2[t]),
(*end of interest calculation *)
interest[t]==intloan1[t]+intloan2[t]-intcash1[t]-intcash2[t],
depreciation[t]==deprec1[t]+deprec2[t],
pbt[t]==sales[t]-expenses[t]-depreciation[t]-interest[t],
tax[t]==pbt[t]taxrate[t],
netprofit[t]==pbt[t]-tax[t],
dividend[t]==netprofit[t]*divpayoutratio[t],
(** Balance Sheet **)
netcash[t]==netcash[t-1]+cashflow[t],
cash[t]==netcash[t](1+Sign[netcash[t]])/2,
debtors[t]==sales[t]daysdebtors[t]/365,
stock[t]==sales[t]daysstock[t]/365,
fixedassets[t]==fixedassets[t-1]+newassets[t],
accumdepreciation[t]==accumdepreciation[t-1]+depreciation[t],
netfixedassets[t]==fixedassets[t]-accumdepreciation[t],
totalassets[t]==cash[t]+debtors[t]+stock[t]+netfixedassets[t],
overdraft[t]==-(netcash[t]-cash[t]),
creditors[t]==sales[t]dayscreditors[t]/365,
provdiv[t]==dividend[t](1-interimdivpropn[t]),
loan[t]==loan[t-1]+newloan[t],
totalliabilities[t]==overdraft[t]+creditors[t]+provdiv[t]+loan[t],
retainedprofit[t]==retainedprofit[t-1]+netprofit[t]-dividend[t],
capital[t]==capital[t-1]+newcapital[t],
equity[t]==capital[t]+retainedprofit[t],
balance[t]==totalassets[t]-totalliabilities[t]-equity[t],
(** Cash Flow **)
collections[t]==sales[t]-(debtors[t]-debtors[t-1]),
payments[t]==expenses[t]-(creditors[t]-creditors[t-1])+(stock[t]-stock[t-1]),
cashflow[t]==collections[t]-payments[t]+newloan[t]+newcapital[t]-newassets[t]-interest[t]-tax[t]-provdiv[t-1]-(dividend[t]-provdiv[t])
};
eqnsinitial={
(*** Year0 initial conditions ***)
sales[0]==150,
expenses[0]==50 ,
depreciation[0]==50,
interest[0]==30,
pbt[0]==sales[0]-expenses[0]-depreciation[0]-interest[0],
tax[0]==pbt[0]*taxrate[0],
taxrate[0]==0.3,
netprofit[0]==pbt[0]-tax[0],
dividend[0]==7,
cash[0]==100,
debtors[0]==30,
stock[0]==30, 
fixedassets[0]==500,
accumdepreciation[0]==100,
netfixedassets[0]==fixedassets[0]-accumdepreciation[0],
totalassets[0]==cash[0]+debtors[0]+stock[0]+netfixedassets[0],
overdraft[0]==0,
creditors[0]==20,
provdiv[0]==3.5,
loan[0]==236.5,
totalliabilities[0]==overdraft[0]+creditors[0]+provdiv[0]+loan[0],
capital[0]==200,
retainedprofit[0]==100,
equity[0]==capital[0]+retainedprofit[0],
balance[0]==totalassets[0]-totalliabilities[0]-equity[0],
collections[0]==sales[0]-(debtors[0](*-debtors[-1]*)),
payments[0]==expenses[0]-(creditors[0](*-creditors[1]*))+(stock[0](*-stock[-1]*)),
netfixedassets[0]==fixedassets[0]-accumdepreciation[0],
cashflow[0]==collections[0]-payments[0]-interest[0]+newcapital[0]+newloan[0]-newassets[0],
netcash[0]==cash[0]-overdraft[0],
newloan[0]==0,
newcapital[0]==0,
newassets[0]==depreciation[0],
salesgrowthrate[0]==0.1,
expensesgrowthrate[0]==0.1,
depreciationrate[0]==0.1,
loanintrate[0]==0.1,
netcashintrate[0]==loanintrate[0]/2,
daysdebtors[0]==debtors[0]/(sales[0]/365),
daysstock[0]==stock[0]/(sales[0]/365),
dayscreditors[0]==creditors[0]/(sales[0]/365),
divpayoutratio[0]==dividend[0]/netprofit[0],
interimdivpropn[0]==0.4,
interimprofitpropn[0]==0.6,
interimnewcapitalpropn[0]==0.5,
interimnewloanpropn[0]==0.5,
interimnewassetspropn[0]==0.5};
eqns2=Join[eqnsinitial,Flatten[Map[eqns/.{t->#}&,Range[n]]]];
{lhs,rhs}=Transpose[eqns2/.{Equal->List}];
resultsr=Thread[lhs->(rhs//.(eqns2/.{Equal->Rule}))];
Print["Time: ",(AbsoluteTime[]-timestart)/3600,"; Memory Mb: ",N[MaxMemoryUsed[]/10^6]];
Scan[(BlankLine[#]="")&,Range[0,n]]
Grid[Join[
{Table[If[i==-1,"Profit & Loss","Year"<>ToString[i]],{i,-1,n}]},
Map[Join[{If[ToString[#]=="BlankLine","",ToString[#]]},
Array[#,n+1,0]]&,{sales,expenses,depreciation,interest,pbt,tax,netprofit,dividend,BlankLine}]/.resultsr,
{Table[If[i==-1,"Balance Sheet","Year"<>ToString[i]],{i,-1,n}]},
Map[Join[{If[ToString[#]=="BlankLine","",ToString[#]]},
Array[#,n+1,0]]&,{cash,debtors,stock,fixedassets,accumdepreciation,netfixedassets,totalassets,BlankLine,
overdraft,creditors,provdiv,loan,totalliabilities,BlankLine,capital,retainedprofit,equity,BlankLine,balance,BlankLine}]/.resultsr,
{Table[If[i==-1,"CashFlow","Year"<>ToString[i]],{i,-1,n}]},
Map[Join[{If[ToString[#]=="BlankLine","",ToString[#]]},Array[#,n+1,0]]&,{collections,payments,interest,tax,dividend,newcapital,newloan,newassets,cashflow,cash
}]/.resultsr
], Alignment->{{Left}},Dividers->{{},Flatten[{False,True,Table[False,{9}],True,Table[False,{20}],True}]}]