using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators; using TASCIndicators;namespace WealthLab.Strategies { /* Divergence: price sets a lowest low but the indicator fails to confirm the new low and turns up */ public class WDMACD_Divergence : WealthScript { private StrategyParameter paramHighest; private StrategyParameter paramExitDays; private StrategyParameter paramDailyLength1; private StrategyParameter paramDailyLength2; private StrategyParameter paramWeeklyLength1; private StrategyParameter paramWeeklyLength2; public WDMACD_Divergence() { paramHighest = CreateParameter("Highest high of", 130, 60, 300, 10); paramExitDays = CreateParameter("Exit after", 20, 1, 50, 1); paramDailyLength1 = CreateParameter("Daily Length 1",12,2,300,20); paramDailyLength2 = CreateParameter("Daily Length 2",26,2,300,20); paramWeeklyLength1 = CreateParameter("Weekly Length 1",60,2,300,20); paramWeeklyLength2 = CreateParameter("Weekly Length 2",130,2,300,20); } protected override void Execute() { if( Bars.Scale != BarScale.Daily ) { DrawLabel(PricePane, "Switch to Daily scale"); Abort(); } bool peak = false; int peakBar = -1; int high = paramHighest.ValueInt; bool trough = false; int troughBar = -1; int low = paramHighest.ValueInt; int days = paramExitDays.ValueInt; var RDM = RelativeDailyMACD.Series(Close,paramDailyLength1.ValueInt,paramDailyLength2.ValueInt, paramWeeklyLength1.ValueInt,paramWeeklyLength2.ValueInt); var WM = WeeklyMACD.Series(Close,paramWeeklyLength1.ValueInt,paramWeeklyLength2.ValueInt); HideVolume(); LineStyle solid = LineStyle.Solid; ChartPane paneWDMACDPane1 = CreatePane(40,true,true); PlotSeries(paneWDMACDPane1,RDM,Color.FromArgb(255,0,100,0),LineStyle.Solid,2); PlotSeries(paneWDMACDPane1,WM,Color.FromArgb(255,0,0,0),LineStyle.Solid,2); DrawHorzLine(paneWDMACDPane1,0,Color.Blue,LineStyle.Solid,1); Lowest indicatorLowest = Lowest.Series( WM, low ); Lowest hLow = Lowest.Series( Low, low ); for(int bar = GetTradingLoopStartBar(130); 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] ) & ( WM[bar-1] == Highest.Series( WM, high )[bar-1] ) & TurnDown( bar, High ) & TurnDown( bar, WM ) ) { peak = true; peakBar = bar-1; } } if( peak == true ) { if( ( High[bar] != Highest.Series( High, high )[bar] ) & ( WM[bar] == Highest.Series( WM, 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] ) & ( WM[bar-1] != Highest.Series( WM, high )[bar-1] ) & ( WM[bar-1] < WM[peakBar] ) & TurnDown( bar, High ) & TurnDown( bar, WM ) ) { peak = false; ShortAtMarket( bar+1 ); /* Highlight divergence */ for (int b = peakBar; b <= bar; b++) SetPaneBackgroundColor( paneWDMACDPane1, b, Color.FromArgb( 30, Color.LightCoral ) ); DrawLine( PricePane, peakBar, High[peakBar], bar-1, High[bar-1], Color.Red, solid, 2 ); DrawLine( paneWDMACDPane1, peakBar, WM[peakBar], bar-1, WM[bar-1], Color.Blue, solid, 2 ); } } /* 1st trough: both price and indicator */ if( trough == false ) { if( ( Low[bar-1] == Lowest.Series( Low, low )[bar-1] ) & ( WM[bar-1] == Lowest.Series( WM, low )[bar-1] ) & TurnUp( bar, Low ) & TurnUp( bar, WM ) ) { trough = true; troughBar = bar-1; } } if( trough == true ) { if( ( Low[bar] != Lowest.Series( Low, low )[bar] ) & ( WM[bar] == Lowest.Series( WM, low )[bar] ) ) trough = false; } /* 2nd trough: price low not confirmed by the indicator */ if( trough == true ) { if( ( Low[bar-1] == Lowest.Series( Low, low )[bar-1] ) & ( Low[bar-1] <= Low[troughBar] ) & ( WM[bar-1] != Lowest.Series( WM, low )[bar-1] ) & ( WM[bar-1] > WM[troughBar] ) & TurnUp( bar, Low ) & TurnUp( bar, WM ) ) { trough = false; BuyAtMarket( bar+1 ); /* Highlight divergence */ for (int b = troughBar; b <= bar; b++) SetPaneBackgroundColor( paneWDMACDPane1, b, Color.FromArgb( 30, Color.LightGreen ) ); DrawLine( PricePane, troughBar, Low[troughBar], bar-1, Low[bar-1], Color.Blue, solid, 2 ); DrawLine( paneWDMACDPane1, troughBar, WM[troughBar], bar-1, WM[bar-1], Color.Red, solid, 2 ); } } } else { /* Exit after N days */ Position p = LastPosition; if ( bar+1 - p.EntryBar >= days ) ExitAtMarket( bar+1, p, "Timed" ); } } } } }