[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

More Robust OddBall



PureBytes Links

Trading Reference Links

Several people have had trouble getting consistent results with Mark 
Brown's OddBall system because of missing bars of data, issues with 
using natural bars, etc.

Earlier today I mentioned the need for making trading systems more 
robust to be able to handle such things.

So as an example, I made a more robust version of Oddball.

The features of this code are listed in the comments below. Try 
applying it to a chart with 5-minute bars for both $SPX (S&P cash 
index) or SP (S&P futures) as data1 and $ADV (NYSE advancing issues) 
as data2. With the default settings, it should give the same trades 
as the original code using 60 minute natural hour bars.

Then try varying the "Offset" input from -15 to +15 in steps of 5 to 
see the effects of offsetting the trades from the hour point in steps 
of 5 minutes. (On $SPX with Offset > 0 the last trade bar will be 
near the 1500 bar, not 1600, since using the 1600 bar would require 
data after 1600.)

Then try adding a little filtering by using values of "Periods" from 
1 to 4 in steps of 0.2. I found a little filtering improves profit 
and reduces drawdown. (The default value, Periods = 1.0, is the same 
as no filtering.)

The ELA is attached in the next message. It verifies in both TS4.0 and TS2000i so should 
work in TS 6 also.

Have fun.

Bob Fulks


{ *******************************************************************

   Signal      : bf.OddBall
   
   Last Edit   : 3/15/02

   Provided By : Bob Fulks

   Description : This is a more robust version of Mark Brown's 
      OddBall system. It is more tolerant of data errors and the 
      differences between how the various TradeStation versions 
      handle missing bars. With the default settings, it should give 
      the same trades as the original on "perfect" data of various 
      compressions. On data with missing bars, there will be small 
      differences.

      Features:

      > Works on any time compression that is a sub-multiple of 
        60 minutes such as 30, 20, 15, 10, 5, 3, 2, 1 minute bars. 
        It begins trading at the "TStart" bar and evaluates each 
        "Interval" bars thereafter. This eliminates problems using 
        "natural hour bars".

      > Counts the number of bars in a day and automatically compares 
        the bar of today with the corresponding bar yesterday. This 
        eliminates the error from using the incorrect look-back 
        interval.

      > Allows offsetting the evaluation bars by "Offset" minutes 
        (+ or -) from the specified bar. This allows trades to be 
        offset from the hour bar to "get away from the crowd".
  
      > Saves the value of data2 to be able to get a stable value 
        when data2 is missing bars as a missing 1615 bar when 
        trading futures.

      > Allows filtering the rate-of-change to help eliminate noise. 
        This causes lag but since the system compares the signal on 
        consecutive days and the lag is the same for both days, 
        the effects of lag should be minimal.


********************************************************************}

Input: BZ(3), SZ(1), Periods(1), TStart(1000), TLast(1600), Interval(60), Offset(0);

Vars: Init(FALSE), TFirst(AddTime(TStart, Offset)), TNext(TStart), 
      BCount(0), Count(0), DCount(0), ADV(Close of data2), ROC2(0), 
      ROCa(0), Num(0), TradeOK(FALSE);

if Date <> Date[1] then begin                {New day initialization}
   DCount = DCount + 1;                      {Count days for 2-day initialization}
   TNext = TFirst;                           {Reset TNext to first bar time}
   BCount = Count;                           {Save count of bars yesterday}
   Count = 1;                                {Initialize count of bars in day}
end else begin
   Count = Count + 1;                        {Count bars in the day}
end;

ADV = Close of data2;                        {Save ADV values to hold value on empty bars}

if Time >= TFirst then 
   ROC2 = (ADV / ADV[BCount] - 1) * 100;     {Calculate rate of change}

ROCa = T3Average(ROC2, Periods);             {Smooth ROC2 some}

Num = 250 / BigPointValue;                   {Trade 250 shares of SPX or 1 contract of SP}

TradeOK = DCount >= 2 and Time = TNext and Time <= TLast;

{---------------------System Code-----------------------}

if TradeOK then begin                        {Action on a trading bar}
   if ROCa > BZ then Buy  Num shares;
   if ROCa < BZ then Sell Num shares;
   TNext = AddTime(TNext, Interval);         {Find time of next trading bar}
   {Print(Date:7:0, Time:5:0, Count:3:0, BCount:3:0, ROC2:4:2, TNext:5:0);}
end;

{--------------------Indicator Code-----------------------}
{
if TradeOK then begin                        {Action on a trading bar}
   TNext = AddTime(TNext, Interval);         {Find time of next trading bar}
end;

begin
   Plot1(ROCa, "1");
   Plot2(ROC2, "2");
   if FALSE then Plot3(0, "3");
   Plot4(0, "4");
end;
}

{------------------------End Code--------------------------}