using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators; using TASCIndicators;namespace WealthLab.Strategies { /* SRSI divergence: Price sets a lowest low but the indicator fails to confirm the new low and turns up */ public class SRSI_Divergence : WealthScript { private StrategyParameter paramHighest; private StrategyParameter paramPeriod; private StrategyParameter paramPeriodWMA; private StrategyParameter paramThresholdForTrend; private StrategyParameter paramExitDays; public SRSI_Divergence() { paramPeriod = CreateParameter("SRSI period", 6, 1, 100, 1); paramPeriodWMA = CreateParameter("WilderMA period", 14, 1, 100, 1); paramThresholdForTrend = CreateParameter("ADX Threshold", 30, 10, 50, 10); paramHighest = CreateParameter("Highest high of", 20, 5, 50, 1); paramExitDays = CreateParameter("Exit after", 20, 1, 50, 1); } protected override void Execute() { bool peak = false; int peakBar = -1; int high = paramHighest.ValueInt; bool trough = false; int troughBar = -1; int low = paramHighest.ValueInt; int period = paramPeriod.ValueInt; int periodWMA = paramPeriodWMA.ValueInt; int days = paramExitDays.ValueInt; int thresholdForTrend = paramThresholdForTrend.ValueInt; ADX adx = ADX.Series(Bars,periodWMA); SRSI srsi = SRSI.Series( Close, period, periodWMA ); Lowest indicatorLowest = Lowest.Series( srsi, low ); Lowest hLow = Lowest.Series( Low, low ); HideVolume(); LineStyle solid = LineStyle.Solid; ChartPane srsiPane = CreatePane( 50, false, true ); PlotSeries( srsiPane, srsi, Color.Green, solid, 2 ); ChartPane adxPane = CreatePane( 25, true, true ); PlotSeries( adxPane, adx, Color.Red, solid, 2 ); DrawHorzLine(adxPane,thresholdForTrend,Color.Blue,LineStyle.Dashed,1); for(int bar = GetTradingLoopStartBar(period); bar < Bars.Count; bar++) { if (!IsLastPositionActive) { /* 1st peak: both price and indicator */ if( peak == false ) { if( ( Highbar-1 == Highest.Series( High, high )bar-1 ) & ( srsibar-1 == Highest.Series( srsi, high )bar-1 ) & TurnDown( bar, High ) & TurnDown( bar, srsi ) ) { peak = true; peakBar = bar-1; } } if( peak == true ) { if( ( Highbar != Highest.Series( High, high )bar ) & ( srsibar == Highest.Series( srsi, high )bar ) ) peak = false; } /* 2nd peak: price high not confirmed by the indicator */ if( peak == true ) { if( ( Highbar-1 == Highest.Series( High, high )bar-1 ) & ( Highbar-1 >= HighpeakBar ) & ( srsibar-1 != Highest.Series( srsi, high )bar-1 ) & ( srsibar-1 < srsipeakBar ) & TurnDown( bar, High ) & TurnDown( bar, srsi ) ) { peak = false; /* Don't fade a strong trend */ if( adxbar < thresholdForTrend ) ShortAtMarket( bar+1 ); /* Highlight divergence */ for (int b = peakBar; b <= bar; b++) SetPaneBackgroundColor( srsiPane, b, Color.FromArgb( 30, Color.LightCoral ) ); DrawLine( PricePane, peakBar, HighpeakBar, bar-1, Highbar-1, Color.Red, solid, 2 ); DrawLine( srsiPane, peakBar, srsipeakBar, bar-1, srsibar-1, Color.Blue, solid, 2 ); } } /* 1st trough: both price and indicator */ if( trough == false ) { if( ( Lowbar-1 == Lowest.Series( Low, low )bar-1 ) & ( srsibar-1 == Lowest.Series( srsi, low )bar-1 ) & TurnUp( bar, Low ) & TurnUp( bar, srsi ) ) { trough = true; troughBar = bar-1; } } if( trough == true ) { if( ( Lowbar != Lowest.Series( Low, low )bar ) & ( srsibar == Lowest.Series( srsi, low )bar ) ) trough = false; } /* 2nd trough: price low not confirmed by the indicator */ if( trough == true ) { if( ( Lowbar-1 == Lowest.Series( Low, low )bar-1 ) & ( Lowbar-1 <= LowtroughBar ) & ( srsibar-1 != Lowest.Series( srsi, low )bar-1 ) & ( srsibar-1 > srsitroughBar ) & TurnUp( bar, Low ) & TurnUp( bar, srsi ) ) { trough = false; /* Don't fade a strong trend */ if( adxbar < thresholdForTrend ) BuyAtMarket( bar+1 ); /* Highlight divergence */ for (int b = troughBar; b <= bar; b++) SetPaneBackgroundColor( srsiPane, b, Color.FromArgb( 30, Color.LightGreen ) ); DrawLine( PricePane, troughBar, LowtroughBar, bar-1, Lowbar-1, Color.Blue, solid, 2 ); DrawLine( srsiPane, troughBar, srsitroughBar, bar-1, srsibar-1, Color.Red, solid, 2 ); } } } else { /* Exit after N days */ Position p = LastPosition; if ( bar+1 - p.EntryBar >= days ) ExitAtMarket( bar+1, p, "Timed" ); } } } } }