Sunday, June 14, 2009
Erlang at SpeakerConf: What is an Erlang process?
Thursday, June 4, 2009
Option Profit and Loss in Erlang
Options are a complex game. I was quite surprised at how many of the rules can be expressed in a dozen lines of code. This function calculates the PNL of an options position at the market price of the underlying.
pnl(Px, #position{long = Long, short = Short}) ->
Pnl = [ Px - U#underlying.px || U <- Long#side.underlyings ] ++
[-Px + U#underlying.px || U <- Short#side.underlyings ] ++
[-C#option.px || C <- Long#side.calls, Px =< C#option.strike ] ++
[ C#option.px || C <- Short#side.calls, Px =< C#option.strike ] ++
[-P#option.px || P <- Long#side.puts, Px >= P#option.strike ] ++
[ P#option.px || P <- Short#side.puts, Px >= P#option.strike ] ++
[ Px - C#option.strike - C#option.px || C <- Long#side.calls, Px > C#option.strike ] ++
[-Px + C#option.strike + C#option.px || C <- Short#side.calls, Px > C#option.strike ] ++
[ Px - P#option.strike + P#option.px || P <- Short#side.puts, Px < P#option.strike ] ++
[-Px + P#option.strike - P#option.px || P <- Long#side.puts, Px < P#option.strike ],
lists:sum(Pnl).
Before we dive into the nuts and bolts of this function let's first discuss list comprehensions and how they are written in Erlang. A list comprehension is a way of composing a list from another list. For example, the following line of code creates a list of four integers and doubles every element greater than two.
[ X * 2 || X <- [1,2,3,4], X > 2 ]
% yields [6,8]
This expression can be read as "Double every X taken from [1,2,3,4] where X is greater than 2". Everything to the left of "||" is known as the expression template while everything to the right is known as the generator. The pnl/0 function sums the concatenated results of ten list comprehensions. Each list comprehension is an expression of how the business works. Let's walk through these expressions, one by one. Keep symmetry in your mind along the way ...
Line 1: Long underlyings
[ Px - U#underlying.px || U <- Long#side.underlyings ]You gain(lose) the market price less the underlying price for every underlying instrument you buy.
Line 2: Short underlyings
[-Px + U#underlying.px || U <- Short#side.underlyings ]You gain(lose) the underlying price less the market price for every underlying instrument you sell.
Line 3: Out of the money long calls
[-C#option.px || C <- Long#side.calls, Px =< C#option.strike ]You lose the premium for every call you buy if it expires worthless.
Line 4: Out of the money short calls
[ C#option.px || C <- Short#side.calls, Px =< C#option.strike ]You keep the premium for every call you sell if it expires worthless.
Line 5: Out of the money long puts
[-P#option.px || P <- Long#side.puts, Px >= P#option.strike ]You lose the premium for every put you buy if it expires worthless.
Line 6: Out of the money short puts
[ P#option.px || P <- Short#side.puts, Px >= P#option.strike ]You keep the premium for every put you sell that expires worthless.
Line 7: In the money long calls
[ Px - C#option.strike - C#option.px || C <- Long#side.calls, Px > C#option.strike ]You keep the market price less the strike price and premium for every call you buy when the market price exceeds strike price. Bonus points to anyone who has noticed that by this point the function begins a second traversal of the options.
Line 8: In the money short calls
[-Px + C#option.strike + C#option.px || C <- Short#side.calls, Px > C#option.strike ]You lose the strike price and the premium less the market price for every call you sell when you are assigned.
Line 9: In the money short puts
[ Px - P#option.strike + P#option.px || P <- Short#side.puts, Px < P#option.strike ]You lose market price plus the premium less the strike price for every put you sell when you are assigned.
Line 10: In the money long calls
[-Px + P#option.strike - P#option.px || P <- Long#side.puts, Px < P#option.strike ]You keep the strike price less the market price and premium when strike price exceeds market price.
Now let's look at some trends.
Big Risks
pnl(Px, #position{long = Long, short = Short}) ->
Pnl = [ Px - U#underlying.px || U <- Long#side.underlyings ] ++
[-Px + U#underlying.px || U <- Short#side.underlyings ] ++
[-C#option.px || C <- Long#side.calls, Px =< C#option.strike ] ++
[ C#option.px || C <- Short#side.calls, Px =< C#option.strike ] ++
[-P#option.px || P <- Long#side.puts, Px >= P#option.strike ] ++
[ P#option.px || P <- Short#side.puts, Px >= P#option.strike ] ++
[ Px - C#option.strike - C#option.px || C <- Long#side.calls, Px > C#option.strike ] ++
[-Px + C#option.strike + C#option.px || C <- Short#side.calls, Px > C#option.strike ] ++
[ Px - P#option.strike + P#option.px || P <- Short#side.puts, Px < P#option.strike ] ++
[-Px + P#option.strike - P#option.px || P <- Long#side.puts, Px < P#option.strike ],
lists:sum(Pnl).
Big Rewards
pnl(Px, #position{long = Long, short = Short}) ->
Pnl = [ Px - U#underlying.px || U <- Long#side.underlyings ] ++
[-Px + U#underlying.px || U <- Short#side.underlyings ] ++
[-C#option.px || C <- Long#side.calls, Px =< C#option.strike ] ++
[ C#option.px || C <- Short#side.calls, Px =< C#option.strike ] ++
[-P#option.px || P <- Long#side.puts, Px >= P#option.strike ] ++
[ P#option.px || P <- Short#side.puts, Px >= P#option.strike ] ++
[ Px - C#option.strike - C#option.px || C <- Long#side.calls, Px > C#option.strike ] ++
[-Px + C#option.strike + C#option.px || C <- Short#side.calls, Px > C#option.strike ] ++
[ Px - P#option.strike + P#option.px || P <- Short#side.puts, Px < P#option.strike ] ++
[-Px + P#option.strike - P#option.px || P <- Long#side.puts, Px < P#option.strike ],
lists:sum(Pnl).
Out of or at the money
pnl(Px, #position{long = Long, short = Short}) ->
Pnl = [ Px - U#underlying.px || U <- Long#side.underlyings ] ++
[-Px + U#underlying.px || U <- Short#side.underlyings ] ++
[-C#option.px || C <- Long#side.calls, Px =< C#option.strike ] ++
[ C#option.px || C <- Short#side.calls, Px =< C#option.strike ] ++
[-P#option.px || P <- Long#side.puts, Px >= P#option.strike ] ++
[ P#option.px || P <- Short#side.puts, Px >= P#option.strike ] ++
[ Px - C#option.strike - C#option.px || C <- Long#side.calls, Px > C#option.strike ] ++
[-Px + C#option.strike + C#option.px || C <- Short#side.calls, Px > C#option.strike ] ++
[ Px - P#option.strike + P#option.px || P <- Short#side.puts, Px < P#option.strike ] ++
[-Px + P#option.strike - P#option.px || P <- Long#side.puts, Px < P#option.strike ],
lists:sum(Pnl).
In the money options
pnl(Px, #position{long = Long, short = Short}) ->
Pnl = [ Px - U#underlying.px || U <- Long#side.underlyings ] ++
[-Px + U#underlying.px || U <- Short#side.underlyings ] ++
[-C#option.px || C <- Long#side.calls, Px =< C#option.strike ] ++
[ C#option.px || C <- Short#side.calls, Px =< C#option.strike ] ++
[-P#option.px || P <- Long#side.puts, Px >= P#option.strike ] ++
[ P#option.px || P <- Short#side.puts, Px >= P#option.strike ] ++
[ Px - C#option.strike - C#option.px || C <- Long#side.calls, Px > C#option.strike ] ++
[-Px + C#option.strike + C#option.px || C <- Short#side.calls, Px > C#option.strike ] ++
[ Px - P#option.strike + P#option.px || P <- Short#side.puts, Px < P#option.strike ] ++
[-Px + P#option.strike - P#option.px || P <- Long#side.puts, Px < P#option.strike ],
lists:sum(Pnl).
Tuesday, March 10, 2009
Erlang at SpeakerConf
Aslak Hellesoy, Amanda Laucher, Dave Hoover, Dennis Byrne, Fred George, George Malamidis, Jay Fields, Josh Graham, Justin Gehtland, Michael Feathers, Mike Roberts, Obie Fernandez, Philippe Hanrigou, Stuart Halloway and Venkat Subramaniam.
Monday, February 9, 2009
Article published on JsUnit and JsMock
Hold on, wait a minute ... the test function has more than one assertion. Is this OK? There is a small group of people in the Agile community who think it's a sin to put more than one assertion per test. Test suites written for real applications making real money however are rarely written this way. Many of these people are astounded when they see how many assertions per test are found within the actual test suite for the JUnit framework itself.
You can read the rest of it here.
Sunday, February 1, 2009
I Join DRW Trading
The interview process at DRW is the toughest I've seen in my career. It's the only company that has ever put me through eight interviews (six technical). I love interviewing. One of my dream jobs is to be a professional interviewer. It's also why I like presenting. I love the last ten minutes of a presentation because I never know what someone is going to shoot at me.
When I interview I'm not just there to do my best at answering questions and asking questions. I also want to see if the interviewers are asking the right questions. If I get an offer after getting through the interviews without being quizzed on unit testing, iterative delivery or continuous integration ... I know I'm probably going to regret taking the offer.
Other bonus points for me were the catered breakfast and lunch, a lot of health benefits I'll never use, and an iPhone. I don't like working in structured environments with a lot of rules, so I was very relieved by the fact that there is no dress code at DRW. Still very impressed at the compensation package they put together for me right in the middle of a global recession. I'm also looking forward to working with fellow ThoughtQuitters Jay Fields, Mike Ward, Mike Retig, Bobby Norton, Peter Ryan, etc. I'm also excited to get more opportunity to work in a heavy math environment with tools like Retlang or Jetlang.
Anyways, tomorrow I start a new job and boy do I have a lot to learn about trading. I'll be investing a lot less in my technical knowledge portfolio and lot more in the domain, at least for the short term. Besides, software is about to enter a pretty boring period. Concurrency and mobile are obviously going to matter more, but I keep telling people "the next big thing in software is going to be a little thing in hardware". I've got my eye on gumstix and GPU development.
I am certainly missing San Francisco though. I spent a little more than a year at my last two clients out in the bay area and I sure will miss the weather. I'll also miss the travel opportunities I got with consulting. Living on the road always fit well with me. Relocating back to Chicago was pretty easy this time because everything I own fits into a single trunk and a single piece of luggage. Now that I will have a permanent address, or at least a permanent city, I have to go buy things like dishes and chairs.
Well, that's about it for me. If any of you are in Chicago and you want to meet up just to talk about technology or trading, shoot me an email.
Monday, January 12, 2009
Sunday, December 28, 2008
JavaScript Trie Implementation
The Test (and how to use it)
function testThoughtWorks() {
var trie = new byrne.TrieNode(/* root */);
trie.add('thought');
assertEquals(1, trie.getWordCount('thought'));
assertEquals(0, trie.getPrefixCount('thought'));
trie.add('thoughtworks');
assertEquals(1, trie.getWordCount('thought'));
assertEquals(1, trie.getPrefixCount('thought'));
assertEquals(1, trie.getWordCount('thoughtworks'));
assertEquals(0, trie.getPrefixCount('thoughtworks'));
assertEquals(0, trie.getWordCount('foo'));
assertEquals(0, trie.getPrefixCount('foo'));
}The Implementation
byrne = {}; // create the namespace
/**
* @see http://en.wikipedia.org/wiki/Trie
* @author Dennis Byrne
* @constructor
*/
byrne.TrieNode = function(){
this.wordCount = 0;
this.prefixCount = 0;
this.children = [];
};
byrne.TrieNode.prototype.add = function(word) {
if(word){
this.prefixCount++;
var k = word.charAt(0);
(this.children[k] || (this.children[k] = new byrne.TrieNode()))
.add(word.substring(1));
}else
this.wordCount++;
};
/**
* Retrieve the prefix count of the applied argument w/ recursion.
*/
byrne.TrieNode.prototype.getPrefixCount = function(word){
return word ?
this.getCount(word, arguments.callee) : this.prefixCount;
};
/**
* Retrieve the word count of the applied argument w/ recursion.
*/
byrne.TrieNode.prototype.getWordCount = function(word){
return word ?
this.getCount(word, arguments.callee) : this.wordCount;
};
/**
* @private
*/
byrne.TrieNode.prototype.getCount = function(word, method){
var k = word.charAt(0);
return this.children[k] ?
method.call(this.children[k], word.substring(1)) : 0;
};
