Skip to content

Instantly share code, notes, and snippets.

@ferd
Created December 15, 2015 14:18
Show Gist options
  • Save ferd/ab5fed3b8ffe4b226755 to your computer and use it in GitHub Desktop.
Save ferd/ab5fed3b8ffe4b226755 to your computer and use it in GitHub Desktop.
-module(pension2).
-export([totalBalance/1]).
%% memoization uses a process dictionary. While hackish and not portable
%% through processes, a PD of this kind has the advantage of being
%% garbage collected and being returned in a stack trace. There is also no
%% copying (see: comments over the macros) or locking needed.
-define(memoize(E), lazy_memoize(fun()-> E end)).
lazy_memoize(F) when is_function(F) ->
case erlang:get(F) of
undefined ->
erlang:put(F,F()),
erlang:get(F);
X -> X
end.
%% total of what you own:
totalBalance(T) -> caBalance(T) + saBalance(T).
%% balance of cash account - is constant since all money not spend is invested:
caBalance(0) -> caBalanceStart();
caBalance(T) ->
?memoize(caBalance(T-1)) +
?memoize(salary(T-1)) -
?memoize(expenses(T-1)) -
?memoize(tradingFees(T-1)).
%% balance of security account - rises while working - can rise while not working if yield > expenses
saBalance(0) -> saBalanceStart();
saBalance(T) -> ?memoize(saBalance(T-1)) * yieldRate() + ?memoize(investments(T-1)).
%% everything spend on securities - in case of not working fees and taxes are directly offset by sells
tradingFees(T) ->
case working(T) of
true -> investments(T) + transactionFee();
false -> investments(T) + tax(expenses(T),T) + transactionFee()
end.
%% what is actually spend on stocks:
investments(T) ->
case working(T) of
true-> salary(T) - expenses(T) - transactionFee();
false-> -expenses(T) - tax(expenses(T),T) - transactionFee()
end.
%% salary:
salary(0) -> netIncome();
salary(T) ->
case working(T) of
true -> salary(T-1)*inflationRate();
false -> 0
end.
%% expenses
expenses(0) -> expensesStart();
expenses(T) -> ?memoize(expenses(T-1))*inflationRate().
%% still working?
working(T) -> T<workingTimeUnits().
%% lots of constants - in respect to months
transactionFee() -> 10.
workingTimeUnits() -> 60. %%months
caBalanceStart() -> 10000.
saBalanceStart() -> 10000.
netIncome() -> 3000.
expensesStart() -> 2000.
inflationRate() -> 1.0017.
yieldRate() -> 1.004.
taxRate() -> 0.2638.
%% ------------HERE STARTS THE HEAVY LIFTING-----------------
%% used to calc taxes payed on profits
tax(X,T) -> ?memoize(profit(X,T,?memoize(portfolio(T))))*taxRate().
%% what is in the security account at time T:
portfolio(T) ->
case working(T) of
true -> [{?memoize(investments(X)),X} || X <- lists:seq(0,T)];
false -> remove(?memoize(investments(T-1)),T,?memoize(portfolio(T-1)))
end.
%% a helper method for removing positions from the portfolio
remove(X,T,[{Amount,Time}|Tail]) ->
case currentValue(Amount,T-Time) > X of
true -> [{Amount-?memoize(originalValue(X,T-Time)),T}|Tail];
false -> remove(X-currentValue(Amount,T-Time),T,Tail)
end.
%% tells you what is the actual profit for an amount/revenue generated by selling at a time T
profit(X,T,[{Amount,Time}|Tail]) ->
case currentValue(Amount,T-Time) > X of
true -> X - ?memoize(originalValue(X,T-Time));
false -> X - (Amount + ?memoize(profit((X - ?memoize(currentValue(Amount,T-Time))),T,Tail)))
end.
%% helper functions for calculation the current and original value of a position
currentValue(X,TD) -> X * math:pow(yieldRate(),TD).
originalValue(X,TD) -> X / math:pow(yieldRate(),TD)
@tuafeeqahmed
Copy link

Can you write "money denomination" code in erlang Language ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment