Noticed few things in your code:
- Unassigned Boolean condition.
//Filter
W52wkHigh AND UnwrappedSMA AND UpTrend;
- Reassignment to
0
just after setting it.
Stage2UpTrend = W52wkHigh AND UnwrappedSMA AND UpTrend;
Stage2UpTrend = 0;
Stage2UpTrend = W52wkHigh AND UnwrappedSMA AND UpTrend
becomes meaningless the moment you set it to 0
in next line.
- Calling the array in a loop instead of looking into its elements bar-by-bar.
if( _Buy[ i ] AND !LongFlag AND Stage2UpTrend) {
- Incorrect use of an Array like a flag variable.
if( _Buy[ i ] AND !LongFlag AND Stage2UpTrend) {
Stage2UpTrend = 1;
Stage2UpTrend
is a bar-by-bar array of Bools i.e. 0
when False
(condition(s) not met) or 1
when True
(condition(s) met), you previously set it to W52wkHigh AND UnwrappedSMA AND UpTrend
. Now that since you set it to 1
from inside the if
check, once again the essence of Stage2UpTrend
is lost and trade occurs whenever just the Cross( H, Ref( HigherHighs, -1 ) )
condition is met. Logically redundant!
So after removing the unnecessary stuffs, this is how it looks:
// 52 week high/low check, within 25%
W52wkHigh = C > 0.75 * HHV( H, 52 * 5 ) AND C > LLV( L, 52 * 5 ) * 1.30;
// Check trend using SMAs
SMA050 = MA( C, 50 );
SMA150 = MA( C, 150 );
SMA200 = MA( C, 200 );
UnwrappedSMA = C > SMA050 AND SMA050 > SMA150 AND SMA150 > SMA200;
UpTrend = SMA200 > Ref( SMA200, -22 );
_SECTION_BEGIN( "Controlled TSL" );
Per = Param( "Swing Period", 15, 3, 144, 1 );
LevelInitTSL = Param( "Initial Stop-Loss Level (x%)", 5, 1, 10, 1 ) / 100;
LevelAtrTslSwitch = Param( "Level (x%) from Entry for TSL switch", 10, 1, 20, 1 ) / 100;
MultATR = Param( "ATR Multiplier", 3.5, 1, 4, 0.5 );
PerATR = Param( "ATR Period", 14, 3, 89, 1 );
_ATR = ATR( PerATR );
// A Simple Demo strategy
HigherHighs = HHV( H, Per );
LowerLows = LLV( L, Per );
_Buy = Cross( H, Ref( HigherHighs, -1 ) );
_Sell = Cross( Ref( LowerLows, -1 ), L );
// Array Initialization
Buy = Sell = InitTSL = TSL = Null;
LongFlag = ShortFlag = 0; // Simple flag vars
Stage2UpTrend = W52wkHigh AND UnwrappedSMA AND UpTrend;
arr = C; // Array whose value is used as reference to trigger the TSL switch
// Using Loop to generate signals
for( i = 0; i < BarCount; i++ ) {
// Long Positions
if( _Buy[ i ] AND Stage2UpTrend[ i ] AND !LongFlag ) {
Buy[ i ] = 1;
LongFlag = 1; // To record that we are in Long position
LongEntryPrice = HigherHighs[ i ];
}
if( LongFlag ) {
if( arr[ i ] < LongEntryPrice * ( 1 + LevelAtrTslSwitch ) ) { // Setting-up initial stop-loss
InitTSL[ i ] = LongEntryPrice * ( 1 - LevelInitTSL );
TSL[ i ] = InitTSL[ i ];
if( TSL[ i - 1 ] > InitTSL[ i ] ) TSL[ i ] = TSL[ i - 1 ];
else TSL[ i ] = InitTSL[ i ];
}
else { // Switching to ATR based TSL
if( TSL[ i - 1 ] > H[ i ] - _ATR[ i ] * MultATR ) TSL[ i ] = TSL[ i - 1 ];
else TSL[ i ] = H[ i ] - _ATR[ i ] * MultATR;
}
}
if( ( _Sell[ i ] OR L[ i ] < TSL[ i - 1 ] ) AND LongFlag ) {
Sell[ i ] = 1; // Selling-off the Long position
LongFlag = 0; // Reseting LongFlag back to False, to denote that we are no longer in "Long" position
}
}
// Plotting
Plot( C, "Price", colorDefault, styleBar | styleThick );
Plot( HigherHighs, "Highs", colorDarkGreen, styleDashed | styleNoRescale );
Plot( LowerLows, "Lows", colorBrown, styleDashed | styleNoRescale );
PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorBrightGreen, 0, L, -30 ); // Long Entry
PlotShapes( IIf( Sell, shapeSmallDownTriangle, shapeNone ), colorBrown, 0, H, -15 ); // Long Exit
Plot( TSL, "TSL", colorLightBlue, styleLine | styleNoRescale | styleNoLabel ); // Trailing Stop-Loss
_SECTION_END();
Otherwise as pointed out by @Metamega you can also write as below but need to take care of other unnecessary logic:
// 52 week high/low check, within 25%
W52wkHigh = C > 0.75 * HHV( H, 52 * 5 ) AND C > LLV( L, 52 * 5 ) * 1.30;
// Check trend using SMAs
SMA050 = MA( C, 50 );
SMA150 = MA( C, 150 );
SMA200 = MA( C, 200 );
UnwrappedSMA = C > SMA050 AND SMA050 > SMA150 AND SMA150 > SMA200;
UpTrend = SMA200 > Ref( SMA200, -22 );
_SECTION_BEGIN( "Controlled TSL" );
Per = Param( "Swing Period", 15, 3, 144, 1 );
LevelInitTSL = Param( "Initial Stop-Loss Level (x%)", 5, 1, 10, 1 ) / 100;
LevelAtrTslSwitch = Param( "Level (x%) from Entry for TSL switch", 10, 1, 20, 1 ) / 100;
MultATR = Param( "ATR Multiplier", 3.5, 1, 4, 0.5 );
PerATR = Param( "ATR Period", 14, 3, 89, 1 );
_ATR = ATR( PerATR );
// Array Initialization
Buy = Sell = InitTSL = TSL = Null;
LongFlag = ShortFlag = 0; // Simple flag vars
Stage2UpTrend = W52wkHigh AND UnwrappedSMA AND UpTrend;
arr = C; // Array whose value is used as reference to trigger the TSL switch
// A Simple Demo strategy
HigherHighs = HHV( H, Per );
LowerLows = LLV( L, Per );
_Buy = Cross( H, Ref( HigherHighs, -1 ) ) AND Stage2UpTrend;
_Sell = Cross( Ref( LowerLows, -1 ), L );
// Using Loop to generate signals
for( i = 0; i < BarCount; i++ ) {
// Long Positions
if( _Buy[ i ] AND !LongFlag ) {
Buy[ i ] = 1;
LongFlag = 1; // To record that we are in Long position
LongEntryPrice = HigherHighs[ i ];
}
if( LongFlag ) {
if( arr[ i ] < LongEntryPrice * ( 1 + LevelAtrTslSwitch ) ) { // Setting-up initial stop-loss
InitTSL[ i ] = LongEntryPrice * ( 1 - LevelInitTSL );
TSL[ i ] = InitTSL[ i ];
if( TSL[ i - 1 ] > InitTSL[ i ] ) TSL[ i ] = TSL[ i - 1 ];
else TSL[ i ] = InitTSL[ i ];
}
else { // Switching to ATR based TSL
if( TSL[ i - 1 ] > H[ i ] - _ATR[ i ] * MultATR ) TSL[ i ] = TSL[ i - 1 ];
else TSL[ i ] = H[ i ] - _ATR[ i ] * MultATR;
}
}
if( ( _Sell[ i ] OR L[ i ] < TSL[ i - 1 ] ) AND LongFlag ) {
Sell[ i ] = 1; // Selling-off the Long position
LongFlag = 0; // Reseting LongFlag back to False, to denote that we are no longer in "Long" position
}
}
// Plotting
Plot( C, "Price", colorDefault, styleBar | styleThick );
Plot( HigherHighs, "Highs", colorDarkGreen, styleDashed | styleNoRescale );
Plot( LowerLows, "Lows", colorBrown, styleDashed | styleNoRescale );
PlotShapes( IIf( Buy, shapeUpArrow, shapeNone ), colorBrightGreen, 0, L, -30 ); // Long Entry
PlotShapes( IIf( Sell, shapeSmallDownTriangle, shapeNone ), colorBrown, 0, H, -15 ); // Long Exit
Plot( TSL, "TSL", colorLightBlue, styleLine | styleNoRescale | styleNoLabel ); // Trailing Stop-Loss
_SECTION_END();
Few suggestions:
- Whenever in trouble use
DebugView
and/orExploration
for debugging your code. It will easily enable you to visualize the problem and hence solve it. - Please thoroughly read Understanding how AFL works.
- Also read Type coercion in AFL.