Erlang development on Windows

I do all my development on Windows. A fair amount of it is done in perl, hence I use Notepad++ a lot. The latter has syntax highlighting for a lot of languages, but not for erlang. A quick Google search yielded this. It has all the steps required to get Notepad++ to highlight your erlang code in a pretty complete fashion. It seems like code folding isn’t working properly, I will post something if I fix it later.

While it’s fine for writing code, it’s still pretty cumbersome to open an erlang console, and compile and run code in the console, jump back to the editor to make changes, go back, repeat as necessary. I ran into a similar situation during the course of perl development, and it turns out there is a plugin that allows you to execute programs in a shell, called NppExec. It can easily be found through the plugin manager of Notepad++. With that in place, you press F6, and a window pops up. Enter the following in the window:

cd $(CURRENT_DIRECTORY)
set ERLDIR = c:\Program Files (x86)\erl5.8.5\bin
"$(ERLDIR)\erlc.exe" $(FILE_NAME)
"$(ERLDIR)\erl.exe" -noshell -s $(NAME_PART) test -s init stop

And you should get:

NppExecDialog

I then saved that as “erlang run”. Now, you can make your changes, hit Ctrl-F6, and NppExec will compile and run your erlang code for you. The only assumption this makes is that the erlang file you are running has an exported function called test that takes no arguments. If you have multiple monitors you can un-dock the console in order not to impinge on your code real estate. The result is the following:

NppExecDialog

The NppExec shell give you quite a bit of flexibility. Obviously you will need to adjust $(ERLDIR) if yours is different from mine. The above will compile the file in the current directory. If you want to keep your .erl and .BEAM files in separate directories, adjust your NppExec script accordingly.

Posted in erlang, programming, Windows

Dipping our toes in erlang with bond math

They say you should write about what you know. I figured I would code something I know, in this case, fixed income analytics.
Below is a dead simple bond yield to price and price to yield calculator written in erlang. Roughly half the code is test.
I am planning on using this as a staring point to flesh out a more functional (hehe :-)) library. Next few posts will be about the dev setup I have, a testing framework and about date math.  The file repository can be found at https://github.com/manwithahammer/finlang.
I would love to hear from more season erlang programmers about how to make this code more erlang-idiomatic.

-module(fs_bond).

-export([bond_price/3, bond_yield/3, test/0]).

-define(tolerance, 0.000000001).

value_cashflow(CashFlow, Today, Yield) ->
	{Amount, Time} = CashFlow,
	Amount / (1.0 + Yield * (Time - Today)).

bond_price(CashFlows, Yield, Today) ->
	lists:foldl(fun(CashFlow, Sum) -> Sum + value_cashflow(CashFlow, Today, Yield) end, 0.0, CashFlows).

bond_price_bisection(CashFlows, Price, Time, Yleft, Yright, Iteration) when Iteration 
	Ymid = 0.5 * (Yleft + Yright),
	Pmid = bond_price(CashFlows, Ymid, Time),
	% io:format("Left = ~p, Right = ~p, Pmid = ~p, Diff = ~p~n", [Yleft, Yright, Pmid, abs(Pmid - Price)]),
	if
		abs(Pmid - Price) 
			Ymid;
		Pmid 
			bond_price_bisection(CashFlows, Price, Time, Yleft, Ymid, Iteration + 1);
		true ->
			bond_price_bisection(CashFlows, Price, Time, Ymid, Yright, Iteration + 1)
	end;
bond_price_bisection(CashFlows, Price, Time, _Yleft, _Yright, _Iteration) ->
	{bond_price_bisection_iterations_exceeded, {cashflows, CashFlows}, {price, Price}, {time, Time}}.

bond_yield(CashFlows, Price, Time) ->
	{Yleft, Yright} = bond_bracket_price(CashFlows, Price, Time, 0.01, 0.02, 0),
	bond_price_bisection(CashFlows, Price, Time, Yleft, Yright, 0).

bond_bracket_price(CashFlows, Price, Time, Yleft, Yright, Iteration) when Iteration 
	Pleft = bond_price(CashFlows, Yleft, Time),
	if
		Pleft 
			% io:format("[Left/~p/~p]~n", [Yleft, Pleft]),
			bond_bracket_price(CashFlows, Price, Time, Yleft - 0.001, Yright, Iteration + 1);
		true ->
			Pright = bond_price(CashFlows, Yright, Time),
			if
				Pright > Price ->
					% io:format("[Right/~p/~p]~n", [Yright, Pright]),
					bond_bracket_price(CashFlows, Price, Time, Yleft, Yright + 0.001, Iteration + 1);
				true ->
					% io:format("Price, Left = ~p, Right = ~p~n", [Pleft, Pright]),
					{Yleft, Yright}
			end
	end;
bond_bracket_price(CashFlows, Price, Time, _Yleft, _Yright, _Iteration) ->
	{bond_bracket_price_iterations_exceeded, {cashflows, CashFlows}, {price, Price}, {time, Time}}.

test() ->
	test_price(),
	test_yield(),
	test_consistency().

test_price() ->
	CashFlows = [{2.5, 0.5}, {2.5, 1.0}, {100.0, 1.0}],
	Yield = 0.02,
	Time = 0.0,
	Price = bond_price(CashFlows, Yield, Time),
	io:format("~n==========================~n", []),
	io:format("= test_price~n", []),
	io:format("==========================~n", []),
	io:format("CashFlows: ~p~n", [CashFlows]),
	io:format("Yield: ~p~n", [Yield]),
	io:format("Price: ~p~n", [Price]).

test_yield() ->
	CashFlows = [{1.5, 0.5}, {1.5, 1.0}, {100.0, 1.0}],
	Price = 102.0,
	Time = 0.0,
	Yield = bond_yield(CashFlows, Price, Time),
	io:format("~n==========================~n", []),
	io:format("= test_yield~n", []),
	io:format("==========================~n", []),
	io:format("CashFlows: ~p~n", [CashFlows]),
	io:format("Price: ~p~n", [Price]),
	io:format("Yield: ~p~n", [Yield]).

test_consistency() ->
	CashFlows = [{1.5, 0.5}, {1.5, 1.0}, {100.0, 1.0}],
	Price = 102.0,
	Time = 0.0,
	Yield = bond_yield(CashFlows, Price, Time),
	Reprice = bond_price(CashFlows, Yield, Time),
	io:format("~n==========================~n", []),
	io:format("= test_consistency~n", []),
	io:format("==========================~n", []),
	io:format("CashFlows: ~p~n", [CashFlows]),
	io:format("Price: ~p~n", [Price]),
	io:format("Yield: ~p~n", [Yield]),
	io:format("Reprice: ~p~n", [Reprice]),
	io:format("Result: ~p\n", [case abs(Price - Reprice)  "Success"; false -> "Error" end]).
Tagged with:
Posted in erlang, finance, programming
Follow

Get every new post delivered to your Inbox.