+1 888 340 6572 GET STARTED

Oddballvar 1.2

Article/Author: Origin: http://www.oddballsystems.com/. Coded by: Charles Johnson

Download: oddballvar.ela

File Includes:
Strategy - Oddballvar 1.2
Signal - Oddballvar 1.2
Function - TimesToMinute

Category: Strategy > Oddballvar 1.2

Description:

See Mark Brown's article "Trading the momentum of market breadth" in Active Trader Magazine, Dec 2000:
www.activetradermag.com or www.oddballsystems.com

Mark Brown's concept is to trade S&P futures or SPY stock off the hourly rate of change in market breadth from the same time one day ago.

Current version is: 1.2

Revision history:
1.0, 10/13/01, initial release
1.1, 10/27/01, efficiency and documentation improvements; no functional changes.
1.2, 10/29/01, fixed "if osc < buyzone then sell;", cleaned up parens in osc, minor doc clarifications.

The basic program from Mark Brown, consolidated from his article and subsequent postings, is:

...
{RL = 8 for S&P futures, 7 for SPY}
Inputs: RL(8), BZ(3), SZ(1);

{Eastern time; you may have to adjust for your time zone.}
{last bar traded is 1600 for futures, 1500 for SPY}
if time > 930 and time <= 1600 then begin
value1 = ((close of data2 / close[RL] of data2) -1) * 100;
If value1 > BZ then buy;
If value1 < SZ then sell;
...

Data1 is the tradeable, data2 is the advancing issues of the NYSE (in Tradestation, $ADV; in quote.com QC:ADVN.NY).

Natural hour hourly bars are used. 7 hourly bars are generated, plus an extra one at 4:15 for futures. The last bar traded for futures is the 4 pm bar; there are 15 minutes to place an order. The SPY market closes at 4, so for SPY the 3 pm bar is the last bar traded.

The number of bars Mark's version will reference is equal to RL.

To force bars to form on hour boundaries, "natural hour bars" can be set if the data is in the 2000i global server database. For 3rd party data (in back testing), this setting doesn't work and 60 minute bars will form on half-hour boundaries; 30 minute bars and an interval of 60 can be used to allow polling on the hour. However, I am informed that 60 minute bars can be made to form on hour boundaries for third-party data if the symbol's session time is changed to start on an even hour, e.g., 10 am.

This variation gives the same results as Mark's program when settings are similar, but allows more flexibility, allowing experimentation with different bar lengths, intervals, start and end times. It can serve as a base for tinkering and expansion.

Usage:

On the first day the program sees, values are stored in an array for comparison. Actual trading starts on the second day. Maximum bars the stategy will reference may be set to zero.

Bar length can be any value equal to or less than the interval. A bar length should be chosen that will have data on every bar for the time period traded, as Tradestation will skip missing data1 and the program will skip missing data2, impairing the trading logic. The program is not adversely affected by spotty data outside of the times traded, e.g. night session data.

The start parameter must be on a boundary of the bar length. For example, starting at 10:32 with 5 minute bars will generate no trades, as there are no bars with times of 10:32, 10:37, etc.

Additional risk control may be desirable.

I suggest that anyone interested in trading this or any strategy conduct rigorous backtesting and pay careful attention to risks such as drawdowns and underwater/flat periods, and properly account for commissions and slippage in testing.

Inputs:

buyzone - buy when osc crosses over
sellzone - sell when osc crosses under
first - time of first polling; default 10 am Eastern
last - time of last polling; default 4 pm Eastern
interval - minutes between pollings

EasyLanguage Code:
INPUTS:	BUYZONE(3), 

SELLZONE(1),
FIRST(1000),
LAST(1600),
INTERVAL(60);

VAR: OSC(0), FIRSTTIME(0), INITIALIZED(FALSE), IDX(0);

{ARRAY SIZE MUST BE >= NUMBER OF POLLING TIMES PER DAY.
60*6.75=405 WILL HOLD 1 MINUTE POLLINGS FOR COMPLETE S&P DAY SESSION}
ARRAY: OBVALUE[500](0);

IF INITIALIZED = FALSE THEN BEGIN
FIRSTTIME = TIMETOMINUTES(FIRST);
INITIALIZED = TRUE;
END;

IF TIME >= FIRST AND TIME <= LAST THEN BEGIN

IDX = (TIMETOMINUTES(TIME) - FIRSTTIME)/INTERVAL;
IF FRACPORTION(IDX) = 0 AND IDX >= 0 THEN BEGIN
IF OBVALUE[IDX] > 0 AND CLOSE OF DATA2 > 0 THEN
OSC = ((CLOSE OF DATA2 / OBVALUE[IDX]) - 1) * 100;
IF CLOSE OF DATA2 > 0 THEN OBVALUE[IDX] = CLOSE OF DATA2;
END;

{THE CODE (NOT THE INITIAL HEADING) IN ONE AND ONLY ONE OF THE
FOLLOWING THREE SECTIONS SHOULD HAVE THE BRACES REMOVED TO CHANGE
IT FROM A COMMENT TO ACTIVE CODE.}

{FOR TRADESTATION 2000I:}
IF OSC > BUYZONE THEN BUY;
IF OSC < SELLZONE THEN SELL;

{FOR TRADESTATION 6:}
{IF OSC > BUYZONE THEN BUY THIS BAR;
IF OSC < SELLZONE THEN SELL SHORT THIS BAR;}

{FOR A TRADESTATION INDICATOR:}
{
PLOT1(OSC,"ROC");
PLOT2(BUYZONE,"BZ");
PLOT3(SELLZONE,"SZ");
}

END;