TASC 2016-05 | Zero In On The MACD (Star)

Modified on 2016/03/30 14:50 by Eugene — Categorized as: TASC Traders Tips

Traders' Tip text

This month we illustrate the application of methods described in Barbara Star's article with two example strategies, long-only and short-only.

The first one enters long when price is above the 55-period EMA and when the price bars are blue, i.e. the crossover with MACD's zero line has taken place. Additionally, you can drag the slider in the lower-left corner to activate "warnings". To highlight this trade filter, the bars are painted orange when the EMA is above the 34-period WMA and the price closes above the WMA (see Figure 1).

Image

Figure 1: Riding the bullish trend in Gold in the winter of 2016.

The second method attempts to profit on divergence reversals. When price moves higher but the MACD does not reflect that move, creating a lower top, the strategy fades the move as illustrated on Figure 2 and exits after a specified number of bars.

Image

Figure 2: Shorting a price top not confirmed by a MACD bearish divergence in SCG (Scana Corp.) in February 2015.

Strategy 1:

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;

namespace WealthLab.Strategies { public class TASCMay2016_Crossovers : WealthScript { private StrategyParameter paramUseWarnings;

public TASCMay2016_Crossovers() { paramUseWarnings = CreateParameter("Filter Warnings",0,0,1,1); } protected override void Execute() { var wma = WMA.Series(Close,34); var ema = EMA.Series(Close,55,EMACalculation.Modern); var macd = MACD.Series(Close); bool avoidWarningBars = paramUseWarnings.ValueInt == 1 ? true : false; macd.Description = "MACD as Histogram"; ChartPane MACDPane = CreatePane(25, true, true); PlotSeries(MACDPane, macd, Color.Red, LineStyle.Histogram, 2); for (int bar = GetTradingLoopStartBar(55 * 3); bar < Bars.Count; bar++) { bool isBarBlue = false; bool isAboveMA = Close[bar] > ema[bar]; bool isWarning = (Close[bar] < wma[bar]) && (High[bar] > ema[bar]); if ( macd[bar] > 0 ) { SetSeriesBarColor( bar, macd, Color.Blue ); SetBarColor( bar, Color.Blue ); isBarBlue = true; if( isWarning ) SetBarColor( bar, Color.Orange ); } else if ( macd[bar] < 0 ) { SetSeriesBarColor( bar, macd, Color.Red ); SetBarColor( bar, Color.Red ); } if ( (CrossOver(bar, macd, 0) && !avoidWarningBars) || (CrossOver(bar, macd, 0) && avoidWarningBars && !isWarning) ) BuyAtMarket(bar + 1); if (CrossUnder(bar, macd, 0)) SellAtMarket(bar + 1, Position.AllPositions, "MACD"); } } } }

Strategy 2: (courtesy Robert Sucher)

using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using WealthLab;
using WealthLab.Indicators;

namespace WealthLab.Strategies { public class TASCMay2016_Divergences : WealthScript { private StrategyParameter peakPctPrice; private StrategyParameter peakPctIndicator; private StrategyParameter exitBars; public TASCMay2016_Divergences() { peakPctPrice = CreateParameter("Price Peak%", 4, 2, 10, 1); peakPctIndicator = CreateParameter("Indctr Peak%", 20, 5, 30, 1); exitBars = CreateParameter("Exit bars", 20, 1, 30, 1); } // Strategy logic protected override void Execute() { int pkPctPrice = peakPctPrice.ValueInt; int pkPctIndicator = peakPctIndicator.ValueInt; int barsToHold = exitBars.ValueInt; int lastDetectedBar = 0; _barLastChecked = 0; DataSeries rsi = MACD.Series(Close); ChartPane rsiPane = CreatePane(40, true, true); PlotSeries(rsiPane, rsi, Color.Brown, WealthLab.LineStyle.Solid, 2); for(int bar = 20; bar < Bars.Count; bar++) { if (IsLastPositionActive) { Position p = LastPosition; if (bar + 1 - p.EntryBar >= barsToHold) CoverAtMarket(bar + 1, p); } else if (PeakDivergence(bar, Close, pkPctPrice, rsi, pkPctIndicator, rsiPane)) if( ShortAtMarket( bar+1 ) != null ) LastPosition.Priority = Close[bar]; } }

// Returns true if divergence with indicator detected on the specified bar public bool PeakDivergence(int bar, DataSeries price, double pctRev1, DataSeries ind, double pctRev2, ChartPane indPane) { bool divergeDetected = false; PeakTroughMode mode = PeakTroughMode.Percent; int pb1 = (int)PeakBar.Value(bar, price, pctRev1, mode); if (pb1 > _barLastChecked) { _barLastChecked = pb1; int pb2 = (int)PeakBar.Value(pb1, price, pctRev1, mode); if (pb2 > -1) { int testBar = Math.Min(bar, pb1 + proxBars); int ibar1 = (int)PeakBar.Value( testBar, ind, pctRev2, mode); // test peak proximity if (Math.Abs(pb1 - ibar1) > proxBars) ibar1 = pb1; int span = Math.Min(pb1 - pb2 - 1, proxBars); testBar = Math.Min(ibar1 - 1, pb2 + span); int ibar2 = (int)PeakBar.Value( testBar, ind, pctRev2, mode); if (ibar2 < 0) ibar2 = 0; if (Math.Abs(pb2 - ibar2) > proxBars) ibar2 = pb2; divergeDetected = Math.Sign(price[pb1] - price[pb2]) != Math.Sign(ind[ibar1] - ind[ibar2]); if (divergeDetected) { // Highlight bar detected SetPaneBackgroundColor(PricePane, bar, Color.FromArgb(40, Color.Blue)); DrawLine(PricePane, pb1, price[pb1] * 1.01, pb2, price[pb2] * 1.01, Color.Blue, LineStyle.Solid, 2); DrawLine(indPane, ibar1, ind[ibar1] * 1.01, ibar2, ind[ibar2] * 1.01, Color.Red, LineStyle.Solid, 2); if (Math.Sign(price[pb1] - price[pb2]) == 1) for (int b = pb2; b <= pb1; b++) SetPaneBackgroundColor(indPane, b, Color.FromArgb(40, Color.Red)); } } } return divergeDetected; } private const int proxBars = 6; private int _barLastChecked = 0; } }

Eugene
Wealth-Lab team
www.wealth-lab.com