Traders' Tip text
Programming "complex" divergences in Wealth-Lab 6 is not complex and can be accomplished in different ways (for example, see February Traders' Tip "Trading Divergences"). Here we present an alternative approach that identifies a divergence between price and the "Leader of the MACD" when it fails to confirm a highest high, in its turn, creating a lower peak. (To save space, the rules are for short trades but reversing them is pretty easy.)
Figure 1. Illustrating on a short trade in Sugar futures, the "Leader of the MACD" helps spot a complex bearish divergence.
Strategy Code
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;
namespace WealthLab.Strategies
{
public class LeaderOfMACD : DataSeries
{
public LeaderOfMACD ( Bars bars ) : base(bars,"Leader of the MACD")
{
EMACalculation cm = EMACalculation.Modern;
EMA ema12 = EMA.Series( bars.Close, 12, cm );
EMA ema26 = EMA.Series( bars.Close, 26, cm );
DataSeries Indicator1 = ema12 + EMA.Series( bars.Close - ema12, 12, cm );
DataSeries Indicator2 = ema26 + EMA.Series( bars.Close - ema26, 26, cm );
for (int bar = FirstValidValue; bar < bars.Count; bar++)
this[bar] = Indicator1[bar] - Indicator2[bar];
}
public static LeaderOfMACD Series( Bars bars )
{
LeaderOfMACD _LeaderOfMACD = new LeaderOfMACD( bars );
return _LeaderOfMACD;
}
}
/*
Leader of the MACD divergence:
Price sets a highest high but the indicator fails to confirm the new high and turns down
*/
public class Leader_Divergence : WealthScript
{
private StrategyParameter paramHighest;
public Leader_Divergence()
{
paramHighest = CreateParameter("Highest high of", 20, 5, 50, 1);
}
protected override void Execute()
{
bool peak = false; int peakBar = -1;
int high = paramHighest.ValueInt;
LeaderOfMACD leader = LeaderOfMACD.Series( Bars );
Highest indicatorHighest = Highest.Series( leader, high );
Highest hHigh = Highest.Series( High, high );
MACD macd = new MACD( Close, "MACD" ); macd.Description = "MACD";
EMA signal = EMA.Series( macd, 9, EMACalculation.Modern ); signal.Description = "Signal Line of MACD";
HideVolume(); LineStyle solid = LineStyle.Solid;
ChartPane leaderPane = CreatePane( 50, false, true );
PlotSeries( leaderPane, leader, Color.Red, solid, 2 );
PlotSeries( leaderPane, macd, Color.Black, solid, 1 );
PlotSeries( leaderPane, signal, Color.Blue, solid, 1 );
for(int bar = 80; bar < Bars.Count; bar++)
{
if (!IsLastPositionActive)
{
/* 1st peak: both price and indicator */
if( peak == false )
{
if( ( High[bar-1] == Highest.Series( High, high )[bar-1] )
& ( leader[bar-1] == Highest.Series( leader, high )[bar-1] )
& TurnDown( bar, High ) & TurnDown( bar, leader ) )
{
peak = true; peakBar = bar-1;
}
}
if( peak == true )
{
if( ( High[bar] != Highest.Series( High, high )[bar] )
& ( leader[bar] == Highest.Series( leader, high )[bar] ) )
peak = false;
}
/* 2nd peak: price high not confirmed by the indicator */
if( peak == true )
{
if( ( High[bar-1] == Highest.Series( High, high )[bar-1] )
& ( High[bar-1] >= High[peakBar] )
& ( leader[bar-1] != Highest.Series( leader, high )[bar-1] )
& ( leader[bar-1] < leader[peakBar] ) &
TurnDown( bar, High ) & TurnDown( bar, leader ) )
{
peak = false;
ShortAtClose( bar );
/* Highlight divergence */
for (int b = peakBar; b <= bar; b++)
SetPaneBackgroundColor( leaderPane, b, Color.FromArgb( 30, Color.LightCoral ) );
DrawLine( PricePane, peakBar, High[peakBar], bar-1, High[bar-1], Color.Red, solid, 2 );
DrawLine( leaderPane, peakBar, leader[peakBar], bar-1, leader[bar-1], Color.Blue, solid, 2 );
}
}
} else
{
/* Exit after 5 days */
Position p = LastPosition;
if ( bar+1 - p.EntryBar >= 5 )
CoverAtMarket( bar+1, p, "Timed" );
}
}
}
}
}