Screen Builder

Build your own screens from various data sources. Stocks can be selected and sorted using any combination of the supplied data fields, allowing many variations of existing screens, and well as testing completely new ideas.

Starting in
Holding Period: months

General instructions

Run the tester over the specified range of years. Available data runs from 2003 through 2022 for most screens. You may start at any month of the year, but other than January can only run through 2021/2022.

Stocks are picked from the screens every holding period (between 1 and 120 months) and held for that period.

You may give your backtest a name for convenience. If you use this backtest code in other testers, its name will be shown instead of a full description.

$ initial investment
Fixed allocation
Add $ every months
Rebalance: never always
every months
$ commission, % spread
Short-term tax: %
Long-term tax: %
Pay taxes every:
Trade day(s) after rankings

Trading simulation

Start with an initial investment. You may also add more money periodically. You can also subtract from the portfolio by adding a negative amount.

Instead of adding or subtracting a fixed amount, you can elect to keep the portfolio at a fixed allocation. This is useful for testing costs without considering the effects of compounded growth, to see what your money might do this year.

Normally, the stocks held in a screen are rebalanced on every trade. You can also specify to never rebalance, which may allow one stock to dominate a screen as it grows, or rebalance at a fixed interval (which must be a multiple of the holding period).

You can pay a fixed commission (which is applied to every buy and sell) as well as a percentage spread (half applied on buy, half on sell).

Capital-gains taxes can be applied, both short-term and long-term. Taxes may be taken out on every trade, quarterly, or annually.

Screen rankings come out on Friday, and backtests are typically done with the closing prices on the next Monday, one day after the rankings. This lag between ranking and trading can be varied from zero days (trade on Friday) and upward.


Screen Builder instructions

Stocks are selected from a specified database by applying a series of rules. Each rule is a filter that excludes stocks that don't pass - a stock must pass all rules to be selected.

Rules are generally entered as algebriac/programming expressions of data fields, functions, and numbers (and ocasionally quoted strings), with the comparison operators (= != > < >= <=), arithmetic operators (+ - * / **), and parentheses. The boolean operators "&" (AND) and "|" (OR) can be used to satisfy multiple conditions in a single expression. The field (column) names are represented by alphanumeric codes, as explained in this field guide.

Technical functions are independent of any database, and are based solely on stock data (price, etc.). Functions take one or more parameters, usually beginning with a lookback period expressed in days. Available functions are:
rs(days): traditional relative strength
ema(days): exponential moving average
rsi(days): relative strength index
Functions may also have an additional parameter that specifies a number of days to lag the technical measurement used.

Sort rules are entered using the keywords "top" (i.e. descending) and "bottom" (i.e. ascending), followed by a number. Tie-breakers can be included as a comma-separated list of expressions before the "top" or "bottom". You may select a percentage of the current stock list (rounding down), instead of a fixed number of stocks, by appending a "%" to the number.

Some screens are built with fields that don't exist during the entire backtest period. To extend the backtest further in these cases, you can assign replacement values to missing fields. Use the special form "(fld1 | fld2)" to use the field fld2 when fld1 is unavailable. Similarly, you can use a constant when a field is unavailable, e.g. "(fld1 | 0)". Many screens also use total-return fields not available from earlier VL data (such as tr4w - Total Return 4-Week), but this is handled automatically from the daily price data.

All this may sound pretty complicated. It is, but not unreasonably so. For example, here's the Small_Value screen. If you can make sense of that, you should be able to build your own screens as well.