From 12a3f61ea7f81ac333e846dbb2ae7306f8a31b43 Mon Sep 17 00:00:00 2001 From: moshferatu Date: Fri, 2 Aug 2024 13:26:39 -0700 Subject: [PATCH] Add long term trend filter and opening range bias to Sonic R Bot in addition to modifying stop logic --- strategies/SonicRBot.cs | 57 +++++++++++++++++++++++++++++++---------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/strategies/SonicRBot.cs b/strategies/SonicRBot.cs index baeabaa..635dbcf 100644 --- a/strategies/SonicRBot.cs +++ b/strategies/SonicRBot.cs @@ -1,5 +1,6 @@ #region Using declarations using NinjaTrader.Cbi; +using NinjaTrader.Data; using NinjaTrader.NinjaScript.Indicators; using System.ComponentModel.DataAnnotations; #endregion @@ -9,6 +10,8 @@ namespace NinjaTrader.NinjaScript.Strategies public class SonicRBot : Strategy { private ATR atr; + private SMA longTermTrend; + private OpeningRange openingRange; private SonicRDragon dragon; private bool lookingLong; @@ -28,7 +31,7 @@ namespace NinjaTrader.NinjaScript.Strategies Calculate = Calculate.OnBarClose; EntriesPerDirection = 1; EntryHandling = EntryHandling.AllEntries; - IsExitOnSessionCloseStrategy = true; + IsExitOnSessionCloseStrategy = false; ExitOnSessionCloseSeconds = 30; IsFillLimitOnTouch = false; MaximumBarsLookBack = MaximumBarsLookBack.TwoHundredFiftySix; @@ -45,26 +48,47 @@ namespace NinjaTrader.NinjaScript.Strategies DragonPeriod = 34; ATRPeriod = 14; ATRMultiplier = 2.0; + LongTermTrendPeriod = 20; + OpeningRangePeriod = 3; + LongOnly = true; + } + else if (State == State.Configure) + { + AddDataSeries(BarsPeriodType.Day, 1); + + // Data series required by the opening range indicator, must be loaded here. + AddDataSeries(BarsPeriodType.Minute, 1); + AddDataSeries(Instrument.FullName, BarsPeriod, "US Equities RTH"); } else if (State == State.DataLoaded) { atr = ATR(ATRPeriod); + longTermTrend = SMA(BarsArray[1], LongTermTrendPeriod); + openingRange = OpeningRange(OpeningRangePeriod, OpeningRangeBarType.Minutes); dragon = SonicRDragon(DragonPeriod); } } protected override void OnBarUpdate() { - if (BarsInProgress != 0) + if (BarsInProgress != 0 || CurrentBars[1] < 0) return; if (CurrentBar < BarsRequiredToTrade) return; if (Position.MarketPosition != MarketPosition.Flat) + { + if (Position.MarketPosition == MarketPosition.Long && Close[0] < dragon.LowEMA[0]) + ExitLong(); + else if (Position.MarketPosition == MarketPosition.Short && Close[0] > dragon.HighEMA[0]) + ExitShort(); + return; + } - if (Open[0] < dragon.HighEMA[0] && Close[0] > dragon.HighEMA[0]) + if (Open[0] < dragon.HighEMA[0] && Close[0] > dragon.HighEMA[0] && Close[0] > longTermTrend[0] && + openingRange.ORH[0] > 0.0 && Close[0] > openingRange.ORH[0]) { lookingLong = true; @@ -72,7 +96,8 @@ namespace NinjaTrader.NinjaScript.Strategies waitingForLongBreak = false; waitingForShortBreak = false; } - else if (Open[0] > dragon.LowEMA[0] && Close[0] < dragon.LowEMA[0]) + else if (Open[0] > dragon.LowEMA[0] && Close[0] < dragon.LowEMA[0] && Close[0] < longTermTrend[0] && + openingRange.ORL[0] > 0.0 && Close[0] < openingRange.ORL[0]) { lookingShort = true; @@ -94,21 +119,15 @@ namespace NinjaTrader.NinjaScript.Strategies lookingShort = false; } - double atrValue = atr[0]; - double stopLoss = ATRMultiplier * atrValue; - double profitTarget = ATRMultiplier * atrValue; - if (waitingForLongBreak && Close[0] > breakPrice) { - SetStopLoss(CalculationMode.Ticks, stopLoss / TickSize); - SetProfitTarget(CalculationMode.Ticks, profitTarget / TickSize); + SetTrailStop(CalculationMode.Ticks, (ATRMultiplier * atr[0]) / TickSize); EnterLong(); waitingForLongBreak = false; } - else if (waitingForShortBreak && Close[0] < breakPrice) + else if (!LongOnly && waitingForShortBreak && Close[0] < breakPrice) { - SetStopLoss(CalculationMode.Ticks, stopLoss / TickSize); - SetProfitTarget(CalculationMode.Ticks, profitTarget / TickSize); + SetTrailStop(CalculationMode.Ticks, (ATRMultiplier * atr[0]) / TickSize); EnterShort(); waitingForShortBreak = false; } @@ -132,6 +151,18 @@ namespace NinjaTrader.NinjaScript.Strategies [Range(0.1, double.MaxValue), NinjaScriptProperty] [Display(Name = "ATR Multiplier", GroupName = "Sonic R Bot", Order = 3)] public double ATRMultiplier { get; set; } + + [Range(1, int.MaxValue), NinjaScriptProperty] + [Display(Name = "Long Term Trend Period", GroupName = "Sonic R Bot", Order = 4)] + public int LongTermTrendPeriod { get; set; } + + [NinjaScriptProperty] + [Display(Name = "Opening Range Period", GroupName = "Sonic R Bot", Order = 5)] + public int OpeningRangePeriod { get; set; } + + [NinjaScriptProperty] + [Display(Name = "Long Only", GroupName = "Sonic R Bot", Order = 6)] + public bool LongOnly { get; set; } #endregion } }