Videos of Jim Simons

Regarding the quants at Renaissance Technologies:

I can only look at them and realize that you have the gods of the business and then you have mere mortals like me, Wadhwani said, echoing the view of the entire industry. Excerpt from Mallaby, "More Money Than God," pp. 298, 2010.

March 2008, Jim Simons interviewed by Bill Zimmerman on mathematics.

December 2010 at MIT about his remarkable careers.

Credit to Infectious Greed for pointing me to the second video.

The Power of Tangential Learning

According to Wikipedia, > tangential learning is the process by which some portion of people > will self-educate if a topic is exposed to them in something that they > already enjoy. I was just organizing my bookshelf the other day and is surprised by how fast my collection of statistics books have grown. I studied statistics back in school as a stepping stone to learning stochastic process for wireless communication theories (e.g. CDMA). Detecting radio-frequency and resolving wireless signals to meaningful messages is fundamentally about assessing the state of random processes. I hated statistics back then because I didn't *get it* and did poorly in those courses. It is ironic that years later I would realize how much I have grown to rely and love the little *p*'s and *q*'s in my little hobby of quantitative trading. I still don't like statistics (or theoretical math), per se. I just love *applying* them in my trading and quant programs. The more that I learn about statistics, the more that I realize how powerful they can be and how ignorant I am. For example, in my clinical study days I used either t-test or ANOVA for everything under the sun. Now that I've come to understanding about inferential statistics, I am aware of the assumptions and pitfalls such as the assumption of t-tests of homogeneity of variance between the two samples tested. If this assumption is violated, then the unequal variance t-test should be used. Finer points like these are routinely ignored in practice because many clinical studies are inherently designed in the experiment to meet these criteria. However, that's not the case when I am making creative use of statistics in my trading. I don't have a clinical study committee watching over my back. If I make a false or weaker-than-expected claim and don't know better, then it is my bank account that will suffer the consequences. Learning statistics was initially due to this got-to-know-better necessity. However, the more that I learn about statistics, the more that I appreciate it. If used correctly, statistics can provide a new dimension to the scientific assessment of your trading performance and market data.

Dissecting a JForex strategy -- MA_Play.java

Having studied the anatomy of an empty JForex strategy (Part 1 and Part 2), it's time to dissect a working one. MA_Play is the strategy that is included with every JForex API download as a demonstration. You can find the complete source code of this strategy in /src/singlejartest/ in the JForex API zipped package. Recall that the first Interface method which runs at the start of the strategy is onStart. The onStart method of MA_Play is reproduced below.

public void onStart(IContext context) throws JFException { 
    engine = context.getEngine(); 
    indicators = context.getIndicators();
    this.console = context.getConsole();
    console.getOut().println("Started"); 
}

The variables engine, indicators, and console are fields of the MA_Play class. They are global variables within the class. What lines 42--44 do is to save the IEngine, IIndicators, and IConsole objects for later use.

The last line of onStart, line 45, is merely to print a message on your JForex program console to notify the user that the strategy has started.

Once onStart is finished processing, the server is likely to call onTick if a market tick arrives. If it's not during market hours, then there's no tick and some other event might happen instead of onTick. Think of the methods as events rather than a linear process. You program your JForex strategy according to what you want to do with each of the six IStrategy Interface event.

For this particular strategy, the programmer decides to implement their strategy at the tick level. As such, much of the trading algorithm resides in onTick for MA_Play. Note that this is a design choice, you can use onBar if you want your strategy to process at the bar level (or you can use both onTick and onBar).

Here's the source code for onTick in MA_Play.

public void onTick(Instrument instrument, ITick tick) throws JFException {
    if (ma1[instrument.ordinal()] == -1) {
        ma1[instrument.ordinal()] = indicators.ema(instrument, 
            Period.TEN_SECS, 
            OfferSide.BID, 
            IIndicators.AppliedPrice.MEDIAN_PRICE, 
            14, 1);
    }
    double ma0 = indicators.ema(instrument, Period.TEN_SECS, OfferSide.BID, IIndicators.AppliedPrice.MEDIAN_PRICE, 14, 0);
    if (ma0 == 0 || ma1[instrument.ordinal()] == 0) {
        ma1[instrument.ordinal()] = ma0;
        return;
    }

    double diff = (ma1[instrument.ordinal()] - ma0) / (instrument.getPipValue());

    if (positionsTotal(instrument) == 0) {
        if (diff > 1) {
            engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.SELL, 0.001, 0, 0, tick.getAsk()
                    + instrument.getPipValue() * 10, tick.getAsk() - instrument.getPipValue() * 15);
        }
        if (diff < -1) {
            engine.submitOrder(getLabel(instrument), instrument, IEngine.OrderCommand.BUY, 0.001, 0, 0, tick.getBid()
                    - instrument.getPipValue() * 10, tick.getBid() + instrument.getPipValue() * 15);
        }
    }
    ma1[instrument.ordinal()] = ma0;
}

At a glance, you may notice that the variables ma0 and ma1 play a key role in determining the setup. Hint: To reverse engineer a strategy, it may be easier to work backward from when the order is placed, which is done by engine.submitOrder in this case.

ma0 and ma1 hold results from exponential moving averages (EMA). ma0 is the current value. ma1 is the previous bar's value. Lines 56--63 check using IF tests (lines 56 and 60) to see if either of the variables hold invalid data. If the data is invalid, the indicator is calculated and the rest of the onTick is skipped with the return statement on line 62.

Note: Indicator values can sometimes be invalid (zero, negative, or Double.NaN, depending on the particular indicator implementation) if there is insufficient data to calculate it or an error occurred, for examples.

The EMAs are fetched in lines 57 and 59 using the IIndicators object (which was initialized in onStart). The JForex Wiki provides an explanation of its use.

Notice that ma1 is an array, which was declared in line 38 with a size equivalent to the number of all available JForex instruments. In particular, it is used with a special index value as in ma1[instrument.ordinal()]. In other words, it is asking for the current instrument's slot in the ma1 array. The current instrument is the one that is passed into the method in line 55.

Moving down the code, another point of interest is line 65, showing the use of instrument.getPipValue(). Line 67 checks if the current total number of position is zero. If it is, meaning no opened position, then the strategy proceeds to check the entry signal to enter a trade (lines 68--76).

positionsTotal() is a custom method defined in lines 84--92. It uses a FOR loop to cycle through all the orders obtained from [engine.getOrders(instrument)][]

Once either of the long or short condition, lines 68 and 72, respectively, is met, the strategy submits an order in lines 69 for a short and line 73 for a long. The particulars of submitting market orders is described in the JForex Wiki.

When you stop this strategy, onStop (lines 48--53) is called. For this strategy, the programmer loops through all the orders again using engine.getOrders() and closes each of the position with an [order.close()][] command in line 50.

That is it for this trivial strategy. If there is one point that you should remember. Note my use of the many links to the JForex javadoc and JForex Wiki throughout this post. You are likely to find many of your answers from those two sources. If not, there's always the JForex Support Board. Now that you've had an idea of how MA_Play.java works, it's time to test it. In the next post in January, we will discuss the JForex Historical Tester and what to watch for when running a strategy live.

A failed experiment with spectral density estimation in R

Spectrum analysis (see wiki entry) is a technical process to visualize a time series data in the frequency domain to find hidden periodicities. As I continue my struggle in data mining with R, I thought I might try looking at a year's worth of USDJPY 1-min exchange rate data in the frequency domain. This is what I got.

Certainly not one of those nice looking graphs in a textbook. Notice that:

  1. there is no distinct frequencies
  2. bandwidth is ridiculously small

What this means is that the USDJPY data is practically white noise. And that there's much work for me ahead before I can produce something useful in R. The source code to produce the graph is printed below. The USDJPY data isn't published as it's not small and you can get it at various places for free on your own. Update: Failed is a harsh word. I should call this a trivial experiment.

 op \<- options(digits.secs=3) \# set option to show milliseconds
cat("loading CSV file to 'data'\\n") print( system.time( data \<-
read.csv( file="data/USDJPY\_20090630-13-27to20101130-22-19\_1Min.csv",
head=TRUE, sep=",") ) ) \# convert long timestamp to POSIX
rownames(data) \<- as.POSIXct(as.numeric(rownames(data))/1000,
origin="1970-01-01", tz="GMT") data \<- data.matrix(data) library(xts)
\# load xts library cat("converting to xts 'data.x'\\n")
print(system.time(data.x \<- as.xts(data))) rm(data) \# remove data
object cat("data.x object size: ") print(object.size(data.x), units =
"auto") cat("spectral analysis\\n") spectrum(data.x\$close)

←   newer continue   →