#region Using declarations using System; using NinjaTrader.Cbi; using NinjaTrader.Core.FloatingPoint; using NinjaTrader.NinjaScript.Indicators.TDU; using System.ComponentModel.DataAnnotations; using System.Windows.Controls; using NinjaTrader.Data; using NinjaTrader.NinjaScript.Indicators; #endregion namespace NinjaTrader.NinjaScript.Strategies { /// /// Sample automated strategy for the TDU PATS Indicator /// This strategy will trade a TRAP which occurs on the EMA /// https://tradedevils-indicators.com/products/tdu-price-action /// public class PATSTrapsStrategy : Strategy { private TDUPriceAction _patsIndicator; private EMA _ema; private int _lastOrderBar; protected override void OnStateChange() { if (State == State.SetDefaults) { Description = @"PATS Trap Strategy."; Name = "PATS Trap Strategy"; Calculate = Calculate.OnEachTick; EntriesPerDirection = 2; EntryHandling = EntryHandling.AllEntries; IsExitOnSessionCloseStrategy = false; ExitOnSessionCloseSeconds = 30; IsFillLimitOnTouch = false; MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix; OrderFillResolution = OrderFillResolution.Standard; Slippage = 0; StartBehavior = StartBehavior.WaitUntilFlat; TimeInForce = TimeInForce.Gtc; TraceOrders = true; RealtimeErrorHandling = RealtimeErrorHandling.IgnoreAllErrors; StopTargetHandling = StopTargetHandling.PerEntryExecution; BarsRequiredToTrade = 10; IsInstantiatedOnEachOptimizationIteration = true; StopLossTicks = 16; TargetTicks = 4; Contracts = 1; } else if (State == State.Configure) { // needed to get intrabar order fills AddDataSeries(Data.BarsPeriodType.Tick, 1); } else if (State == State.DataLoaded) { // add the PATS indicator _patsIndicator = TDUPriceAction(Close); _patsIndicator.LegCountMethod = TDUPatsRules.Mack; _patsIndicator.PositionType = TDUPATSPositionSizing.Contracts; _patsIndicator.FixedContracts = 1; _patsIndicator.CashValue = Account.Get(AccountItem.CashValue, Currency.UsDollar); _patsIndicator.ShowOrderPanel = false; AddChartIndicator(_patsIndicator); _ema = EMA(Close, 21); AddChartIndicator(_patsIndicator); } } protected override void OnBarUpdate() { if (CurrentBars[0] < 10) { return; } if (CurrentBars[0] == _lastOrderBar) return; if (Position.MarketPosition != MarketPosition.Flat) return; // Do we have a 2EL trap ? if (_patsIndicator.TrapLong[0].ApproxCompare(2) == 0) { // are we at the EMA ? if (AtEMA()) { // Then open short EnterShort(1, Contracts, "Sell"); SetProfitTarget(CalculationMode.Ticks, TargetTicks); SetStopLoss(CalculationMode.Ticks, StopLossTicks); ; _lastOrderBar = CurrentBars[0]; return; } } // // Do we have a 2ES trap ? if (_patsIndicator.TrapShort[0].ApproxCompare(-2) == 0) { // are we at the EMA ? if (AtEMA()) { // Then open long EnterLong(1, Contracts, "Buy"); SetProfitTarget(CalculationMode.Ticks, TargetTicks); SetStopLoss(CalculationMode.Ticks, StopLossTicks); ; _lastOrderBar = CurrentBars[0]; } } } private bool AtEMA() { return (Highs[0][0] > _ema[0] && Lows[0][0] < _ema[0]); } [Display(ResourceType = typeof(Custom.Resource), Name = "Contracts", GroupName = "01. Position Sizing", Order = 1)] public int Contracts { get; set; } [Display(ResourceType = typeof(Custom.Resource), Name = "Target (ticks)", GroupName = "01. Position Sizing", Order = 2)] public int TargetTicks { get; set; } [Display(ResourceType = typeof(Custom.Resource), Name = "Stoploss # ticks", GroupName = "01. Position Sizing", Order = 3)] public int StopLossTicks { get; set; } } }