Milktrader

Iterating Until Convergence

Tuesday, January 24, 2012

batty natty

Rumors of a hedgefund blowing up and frantically selling out a long position. Mild winter weather across the country. Oversupply. Calls for prices to reach $1 and below. All the melodrama you could ask for is playing out in natural gas.

I glibly declared the sell-off ridiculous and went long the Feb contract of the NG future a few days back. No stops, because I was confident. When I woke in the morning I was awash in a 50+ tick profit and asked my 7-year old if I should take the $500 or not. He said 'take it Dad.' Of course I didn't. I judiciously placed a stop at break-even though. It took all of about an hour for my stop to get hit, and for 50+ ticks evaporate into a 1 tick profit.

I can say I felt annoyed. But also amused that something like this could happen so suddenly. I got back in long that same morning and after a meager 10 tick profit decided to place a stop at break even again. And again, it was hit in short order. I'm thinking, hmmm. This is curious indeed. One more trade for the morning. This time it goes against me right away for about 15 ticks. Wow, what a fine mess I've gotten into I think to myself. I take a breath and wait. It comes back to break even. It catapults to plus 16 ticks in what seems like seconds and I get out. Phew. It was fun. My 7-year old was unimpressed though that I blew a $500 profit. This is toy money (as in money for toys) we're talking about here!

Next day I'm at work and not trading. That's when the real rally happens of course, when I'm flat. Did I miss making over $4,000? No, not really. That's just not the way I see things. I get long that evening and repeat my previous mistakes. With my position positive 35+ ticks by morning, I set a stop at break-even. Where do you suppose it ends up going in the next couple hours? Yep, out for a 1-tick profit.

Mental note to myself. Take 30 ticks when you can. Next, I go long again about 20 ticks from where I was stopped out and push aside the feeble thoughts of ... 'if you didn't get stopped out, you'd be up 20 now ...'. Yeah sure. Whatever. I'm long now. It takes but a few minutes and I'm up 20 ticks again. Stop at 10 ticks. Up 30 ticks, stop at 20. And so on until I have a locked in profit of 40 ticks. It gets filled and I'm done for now.

When my 7-year-old comes home from school today, I'll have a better story to tell. I have no doubt he'll expect some free money for Hero Factory toys. I'll probably give it to him, along with his brother. You can never have too many legos in the house.

Wednesday, January 18, 2012

eurochatter

Things have been quite at the zoo recently so I've been assigned a project to capture chatter amongst the resident creatures. I'm taking a very learn-as-you-go approach to this challenge and so far have managed to create a working app that captures the twitter stream chattering about the eur/usd currency pair. You can see my progress at www.eurochatter.com but be fore-warned that it's a work in progress. Once you start seeing ads you'll know that I've solved most of the programming issues.

Here is a screenshot of what it looks like today:


Of course, this will not likely be its final styling format, but it's a start. The chart is generated by an open-source javascript library and has some cool features including the ability to get the values of various datapoints by mousing over the chart. Also, you can zoom in. Reloading the page brings it back to its original state.

The programming behind the app is a Ruby. It uses the Sinatra gem to serve the web page and it's currently being hosted at Heroku. I'm also using a Mongo database in the cloud, courtesy of MongoLab.

I still have a substantial hurdle to overcome in this app with regards to managing the database. I'm currently using a capped collection to store all tweets. I query the database as to its total and that's how the data is generated for the chart. But, as you can imagine, a capped collection reaches a limit at which point its total doesn't change. Only the contents does. I'm thinking that in the code block where I insert records into the database I can increment something there to avoid this limit problem, but I'm not sure.

Another problem will be that when I push changes up to the hosting company, the record of timestamped tweet totals will be erased. This is because the tweets.csv is being updated on Heroku servers. Meh, just another problem to solve. Kinda like a crossword.

I hope you enjoy the site. And remember to click on the ads after I get them up. I promise not to put up too many.

Monday, November 21, 2011

A Simple R Script for Traders

Now that we've got the Python implementation under out belts, let's do the same thing with R. We'll still be able to pass command-line arguments to get a quick look at what our stock of interest is doing during the day. And we start with the familiar incantation of enabling our script to run from command-line.

$ chmod +x yahoo.r

This is a further abuse of starting the story in the middle. So let's get to the beginning. Here is the R script that we'll be invoking from command-line.


#!/usr/bin/Rscript
require(quantmod)
arg    <- commandArgs(trailingOnly = TRUE)
stock  <- getQuote(arg)
last   <- stock[2]
high   <- stock[6]
low    <- stock[7]
pctile <- (last-low)/(high-low)
bingo  <- round(pctile * 100)
b      <- as.integer(bingo)  
sprintf("%s is trading at the %ith percentile of its daily range", arg ,b)

We only need to call one package here, the inimitable quantmod. That's were we get access to the getQuote function. From there, it's basic boilerplate. I am by no means a professional programmer, so there are some issues with this script that I'm just living with for now including the fact that when this is invoked, R just doesn't shut up with it's messages. Let's run this on ^GSPC, which is the Yahoo symbol for S&P 500. You'll see what I mean.


$ ./yahoo.r ^GSPC
WARNING: ignoring environment value of R_HOME
Loading required package: quantmod
Loading required package: Defaults
Loading required package: xts
Loading required package: zoo
Loading required package: TTR
Loading required package: methods
[1] "GSPC is trading at the 3th percentile of its daily range"

First, you notice that the first line is what we typed in command-line. Starting at WARNING is where R starts to chatter. The last line is the one we expect to get returned. (Happened to catch the market at a low point). All of this Loading is necessary, but I'd like to silence it.

Our second issue is that '3th' isn't a word. It's supposed to be '3rd'. This can be programmatically corrected, but then the code starts getting dense. Better to live with it or find a better way to phrase the return phrase.

Also with quantmod, you can go to the races and calculate all manner of technical analysis data and have that output to terminal. Now I need to go figure out what's going on with the market...

EDITOR NOTE:

There is nothing going on in the market so I decided to start googling how get rid of Loading messages. Sure enough I found suppressPackageStartupMessages.Now I have to solve the WARNING message issue. That one I'm afraid is going to be a rat's nest.

Sunday, November 20, 2011

A Simple Python Script for Traders

My latest polyglot excursion has landed my in the world of snakes. I've started playing around with Python a few weeks ago and have to report that I'm very pleased with how well this programming language performs. I decided to take it out for a little run on Yahoo stock data and came up with a little script that returns the current state of your stock in relation to the current day's trading range.

To run this script from command line, you first need to give it execution permission. This is time to call the oft-run bash command:
 
 $ chmod +x yahoo.py

Of course I'm getting a little ahead of things. We haven't defined the yahoo.py program. It utilizes three modules: re (regex), sys (defining argv) and urllib (for opening an url). These modules provide the functions we need. Some more preliminaries. We start our program with the shebang line so the chmod invocation actually works. Next, I have used a main() function here when you really don't need it in its current implementation. The last two lines make reference to the main() function sentinel but it's virtually useless for our purposes. The reason to include it is if we decide to grow this program to do other stuff and import it into another script at some later time. Okay, here it is.

#!/usr/bin/python
import re
import urllib
import sys
site  = "http://finance.yahoo.com/d/quotes.csv?s="
sym   = sys.argv[1]
h     = urllib.urlopen(site + sym + "&f=shgl1")
j     = h.read()
h.close()
k     = re.findall('(\w+)",(\d+.\d\d),(\d+.\d\d),(\d+.\d\d)',j)
stock = k[0][0]
hi    = float(k[0][1])
lo    = float(k[0][2])
last  = float(k[0][3])
z     = (last-lo)/(hi-lo)
def main():
  if z >= 0.5:
    print "%s is trading in the top half of it's range" % stock
  else:
    print "%s is trading in the bottom half of it's range" % stock
if __name__ == '__main__':
  main()

There really isn't much to it, as you can plainly see. I've used the main() function to print two options based on the trading price of your stock. The way to input the stock you're interested in is to pass it as a command-line argument like this:

$ ./yahoo.py SPY


The sys.argv[1] is the first argument from command-line (that's not totally true, but this isn't a computer science course either) and that's all this little script can currently handle. The url address is a little cryptic, so I've chunked it out into three sections. First the http:// part, which is always the same. Then the stock you entered in command-line. And finally a bizarre looking string that has Yahoo values that you're interested in. In our case, we want the stock name, high, low and last price. This gets converted into a string that our regex engine begins to work on. It returns a list of tuples (or single tuple in our case), where we can subset the values we're interested in.


One can see how this program can easily be expanded to include much more information. You could also offer the option to pass flags to the script which tells it what path you want to take to get your desired result. I'm thinking it may be useful to pass a set of stocks to the script and have it tell what percent of the group is doing well or not that day. 


This program is obviously a toy program as written, but it's a good beginning for something a little more useful. I'm setting up camp in this snake pit to check it out. I'm not scared of snakes. At least not yet.



Wednesday, November 9, 2011

My Kids Are Correlated

I have three kids. Two boys and a girl. They are so different in so many ways that it's amazing they all come from the same genes. But sometimes, they're correlated. This week I told them that they are absolutely banned from any electronic devices after 8:00 pm on school nights. They all reacted the same way. Absolute incredulity. "How can this be?" they all three asked.

They all have different plans of defiance, but they will all fail. Because I'm one step ahead of them. They are all facing a unmovable force and they know it. They just want to make sure.

If I were to try to describe my kids, the last thing I would use is a mathematical concept that regresses them on a linear surface. Even though they appear to be behaving in unison, it's only because they all share a dominant force. And that would be their mother. In that way, I'm correlated to them.

The other night, just before the 8:00 pm pumpkin call, we all decided to dance to some tunes. It was a most interesting thing to observe how they were correlated to the notes and lyrics of the song. They knew the lyrics and sang them in unison. They were correlated.

In the right environment, everyone and everything is correlated. Once that environment erodes, there is the inevitable "quote" -- decoupling. Our song was over and they all went to their separate bedrooms. They decoupled from a momentary correlation. Or was it an opaque relationship? I'm still tapping my foot trying to get it.

Thursday, October 20, 2011

Algorithm Zoo

I suppose it was inevitable that once I started messing around with statistics and curve-fitting of data, I would find myself in a menagerie of equations and scripts. And so I'm moving into the Algorithm Zoo. It's my new home. It seems like a friendly place so far. The animals misbehave themselves as one would expect. And the weather is often nice.

I'll be honest though and admit that I think I've seen some unnatural things. It may have been my imagination, but sometimes at night I swear I see strange creatures roaming around outside of the exhibits.  I haven't gotten to visit some places yet, including a secret laboratory cordoned off in the back. I think I'll have access to it at some point. I'll report back here about anything I find that may be of interest.

I'm spending most of my time at the zoo messing around with data mining market behavior, and plotting out distributions. The work is not so easy I'm afraid. It turns out that this menial set of tasks I've been assigned is fraught with danger. Avoiding the perilous OBO error keeps me up at night. Data mining is very willing to accept your erroneous code so great care must be taken in the work. Already, I've had one exhibit taken down by management.

I'm restricted at the zoo as to how much color I can add, but I'll try to push the envelope when I can. Stop by and say "quote" -- hello. Great trading! I'll see you at the zoo!


Thursday, September 22, 2011

The Luckiest Man Next Week

My best birthday present ever was the birth of my daughter almost 12 years ago. Next week I get to celebrate the oddity again, of sharing my birthday with my child. Of course I'm not the only person on the planet whose birthday coincides with their child's, but I feel strangely privileged regardless. "You're birthday's coming up," I say. "Our birthday Dad." Dad smiles inside.

The chances of you sharing a birthday with your child are obviously 1 in 365. It's a longshot, but it happens. Odds mean nothing though. Who cares about them? You've got something special.

It was about two years ago that I had a parent/teacher conference with my daughter's substitute teacher. The regular one, as odds would have it, was having a baby. We started talking about babies and I mentioned, quite proudly, that I share the same birthday as my daughter. The substitute did the pencil-drop and incredulous stare that you get from someone who doesn't believe what you've just told them. "Yep," I said. I thought she would make some comment about "what's the odds of that happening" but instead she replied, "Wow, so do I."

I knew I wasn't the only one, but what are the chances you'd meet someone who shares your birthday secret at a parent/teacher conference? Chances are I would never have met this woman if the regular teacher hadn't gotten pregnant, and what's the chances of that?

"Our birthday is in September," I said.

"Really, so is ours. September 27 in fact," she replied.

This time, it was my turn to drop the jaw and stare with incredulity.

Next week on September 27, my daughter will turn 12. I am one of the luckiest men around.