This strategy was featured in the January 2010 issue of
Active Trader magazine.
System Concept:
Instead of simply fading a breakout move, the following shorter term system waits for a strong confirmation of a reversal - i.e., a downside breakdown after an upside breakout or vice versa.
Strategy rules:
- Buy the next bar at the open if the closing price is above the 40-period highest closing price no more than eight bars after a signal in the opposite direction (a close below the 30-period lowest close), and the 30-period ADX is 25 or lower.
- Short the next bar at the open if the closing price is below the 40-period lowest closing price no more than eight bars after a signal in the opposite direction (a close above the 30-period highest close), and the 30-period ADX is 25 or lower.
- Exit the position at the market after 30 bars.
Strategy code:
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
using Community.Indicators;
namespace WealthLab.Strategies
{
public class FalseBreakouts30min : WealthScript
{
private StrategyParameter paramBrk1;
private StrategyParameter paramBrk2;
private StrategyParameter paramWindow;
private StrategyParameter paramExit;
public FalseBreakouts30min()
{
paramBrk1 = CreateParameter("1st breakout", 30, 6, 30, 2);
paramBrk2 = CreateParameter("2nd breakout", 40, 10, 100, 2);
paramWindow = CreateParameter("Window", 8, 2, 30, 2);
paramExit = CreateParameter("Exit after", 30, 5, 50, 5);
}
protected override void Execute()
{
int waitBars = paramWindow.ValueInt;
int exitBars = paramExit.ValueInt;
int BreakoutPeriod = paramBrk1.ValueInt;
int BreakoutPeriod2 = paramBrk2.ValueInt;
DataSeries l1 = Lowest.Series( Close, BreakoutPeriod ) >> 1;
DataSeries h2 = Highest.Series( Close, BreakoutPeriod2 ) >> 1;
DataSeries l2 = Lowest.Series( Close, BreakoutPeriod2 ) >> 1;
DataSeries h1 = Highest.Series( Close, BreakoutPeriod ) >> 1;
ADX adx = ADX.Series( Bars,30);
l1.Description = String.Concat( "Lowest Close of ", BreakoutPeriod.ToString(), " bars" );
h2.Description = String.Concat( "Highest Close of ", BreakoutPeriod2.ToString(), " bars" );
l2.Description = String.Concat( "Lowest Close of ", BreakoutPeriod2.ToString(), " bars" );
h1.Description = String.Concat( "Highest Close of ", BreakoutPeriod.ToString(), " bars" );
PlotSeries( PricePane, l1, Color.Red, LineStyle.Dashed, 1 );
PlotSeries( PricePane, h2, Color.Blue, LineStyle.Solid, 1 );
PlotSeries( PricePane, l2, Color.Red, LineStyle.Solid, 1 );
PlotSeries( PricePane, h1, Color.Blue, LineStyle.Dashed, 1 );
PlotStops();
SetBarColors( Color.Silver, Color.Silver);
for(int bar = Math.Max( BreakoutPeriod2, waitBars ); bar < Bars.Count; bar++)
{
if( bar == CrossUnderBar.Series( Close, l1 )[bar] )
SetBarColor( bar, Color.Red );
if( bar == CrossOverBar.Series( Close, h2 )[bar] )
SetBarColor( bar, Color.Blue );
if (IsLastPositionActive)
{
Position p = LastPosition;
if ( bar+1 - p.EntryBar >= exitBars )
ExitAtMarket( bar+1, p, "Timed" );
}
else
{
// Ensure we're not fading a strong trend
if( adx[bar] < 25 )
{
if( CrossOver( bar, Close, h2 ) &&
( CrossUnderBar.Series( Close, l1 )[bar] > (bar - waitBars) ) )
if( BuyAtMarket( bar + 1 ) != null )
LastPosition.Priority = -Close[bar];
if( CrossUnder( bar, Close, l2 ) &&
( CrossOverBar.Series( Close, h1 )[bar] > (bar - waitBars) ) )
if( ShortAtMarket( bar + 1 ) != null )
LastPosition.Priority = Close[bar];
}
}
}
}
}
}