using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators; using WealthLab.Rules;namespace WealthLab.Strategies { public class ShortTheInsiders : WealthScript { private StrategyParameter paramThreshold; private StrategyParameter paramExitAfter; public ShortTheInsiders() { paramThreshold = CreateParameter("Threshold $", 20000000, 1000000, 50000000, 1000000); paramExitAfter = CreateParameter("Exit after, days", 30, 5, 50, 5); } protected override void Execute() { /* Insider transactions series are not split-adjusted neither in WLP4 nor in WLP5. Therefore the need to create the adjusted series by multipling the insider trade volume by an adjustment factor. This adjustment factor is created using the 'split' item, so the insider trade volume would remain relative to the stock's split-adjusted volume. */ DataSeries reverseAdjustment; DataSeriesOp.SplitReverseFactor( this, "split", out reverseAdjustment); DataSeries dsAdjusted = Close * reverseAdjustment; ChartPane adjPane = PricePane; if( Close.Description.Contains("Volume") ) { dsAdjusted = Close / reverseAdjustment; adjPane = VolumePane; } // Now let's create the adjusted insider buying data series. IList<FundamentalItem> fListS = FundamentalDataItems("insider sell"); DataSeries InsiderSellingSeries = new DataSeries( Bars, "Insider Selling" ); InsiderSellingSeries.Description = "Insider Selling $"; for (int bar = 0; bar < Bars.Count; bar++) { double sumS = 0; foreach (FundamentalItem fi in fListS) { if( fi.Bar == bar ) { sumS += fi.Value; InsiderSellingSeries[bar] = sumS * dsAdjusted[bar]; } } } ChartPane iS = CreatePane( 20, true, true ); int high = 200; DataSeries isSumHighest = Highest.Series( InsiderSellingSeries, high ); isSumHighest.Description = high.ToString() + "-day Highest Aggregated Insider Selling ($)"; PlotSeries( iS, InsiderSellingSeries, Color.Red, LineStyle.Histogram, 2 ); PlotSeries( iS, isSumHighest, Color.Blue, LineStyle.Dashed, 2 ); // Split-adjusted price PlotSeries(adjPane, dsAdjusted, Color.FromArgb( 50, Color.Blue ), LineStyle.Solid, 1); // A dollar threshold for insider selling activity double threshold = paramThreshold.Value; // Time-based exit int daysToExit = paramExitAfter.ValueInt; for(int bar = high; bar < Bars.Count; bar++) { if (IsLastPositionActive) { Position p = LastPosition; if ( bar+1 - p.EntryBar >= daysToExit ) { CoverAtMarket( bar+1, p, "Timed" ); } else { if( !CoverAtStop( bar+1, p, p.EntryPrice + ATR.Series( Bars, 14 )[bar] * 3, "Loss 3*ATR" ) ) CoverAtLimit( bar+1, p, p.EntryPrice - ATR.Series( Bars, 14 )[bar] * 3, "Profit 3*ATR" ); } } else { if( InsiderSellingSeries[bar] > threshold ) if( InsiderSellingSeries[bar] >= isSumHighest[bar] ) ShortAtStop( bar+1, Low[bar] ); } } } } }
using System; using System.Collections.Generic; using System.Text; using System.Drawing; using WealthLab; using WealthLab.Indicators; using WealthLab.Rules;namespace WealthLab.Strategies { public class InsiderBuying : WealthScript { private StrategyParameter paramThreshold; private StrategyParameter paramExitAfter; public InsiderBuying() { paramThreshold = CreateParameter("Threshold $", 20000000, 1000000, 50000000, 1000000); paramExitAfter = CreateParameter("Exit after, days", 30, 5, 50, 5); } protected override void Execute() { /* Insider transactions series are not split-adjusted neither in WLP4 nor in WLP5. Therefore the need to create the adjusted series by multipling the insider trade volume by an adjustment factor. This adjustment factor is created using the 'split' item, so the insider trade volume would remain relative to the stock's split-adjusted volume. */ DataSeries reverseAdjustment; DataSeriesOp.SplitReverseFactor( this, "split", out reverseAdjustment); DataSeries dsAdjusted = Close * reverseAdjustment; ChartPane adjPane = PricePane; if( Close.Description.Contains("Volume") ) { dsAdjusted = Close / reverseAdjustment; adjPane = VolumePane; } // Now let's create the adjusted insider buying data series. IList<FundamentalItem> fListS = FundamentalDataItems("insider sell"); DataSeries InsiderSellingSeries = new DataSeries( Bars, "Insider Selling" ); InsiderSellingSeries.Description = "Insider Selling $"; for (int bar = 0; bar < Bars.Count; bar++) { double sumS = 0; foreach (FundamentalItem fi in fListS) { if( fi.Bar == bar ) { sumS += fi.Value; InsiderSellingSeries[bar] = sumS * dsAdjusted[bar]; } } } int high = 200; ChartPane iS = CreatePane( 20, true, true ); DataSeries isSum = InsiderSellingSeries; DataSeries isSumHighest = Highest.Series( isSum, high ); isSum.Description = "Insider Selling ($)"; isSumHighest.Description = high.ToString() + "-day Highest Aggregated Insider Selling ($)"; PlotSeries( iS, isSum, Color.Red, LineStyle.Histogram, 2 ); PlotSeries( iS, isSumHighest, Color.Blue, LineStyle.Dashed, 2 ); // Split-adjusted price PlotSeries(adjPane, dsAdjusted, Color.FromArgb( 50, Color.Blue ), LineStyle.Solid, 1); // Finally, some action! double threshold = paramThreshold.Value; int daysToExit = paramExitAfter.ValueInt; for(int bar = high; bar < Bars.Count; bar++) { if (IsLastPositionActive) { Position p = LastPosition; if ( bar+1 - p.EntryBar >= daysToExit ) SellAtMarket( bar+1, p, "Timed" ); } else { { if( isSum[bar] > threshold ) if( isSum[bar] >= isSumHighest[bar] ) if( BuyAtMarket( bar+1 ) != null ) LastPosition.Priority = Close[bar]; } } } } } }