From 94fcc058ee462e18f495c358f81c28ee0c596962 Mon Sep 17 00:00:00 2001 From: moshferatu Date: Fri, 15 Nov 2024 06:07:34 -0800 Subject: [PATCH] Initial commit of Advance / Decline Ratio strategy --- .../AdvanceDeclineRatioBot.cs | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 strategies/advances-and-declines/AdvanceDeclineRatioBot.cs diff --git a/strategies/advances-and-declines/AdvanceDeclineRatioBot.cs b/strategies/advances-and-declines/AdvanceDeclineRatioBot.cs new file mode 100644 index 0000000..2408dfe --- /dev/null +++ b/strategies/advances-and-declines/AdvanceDeclineRatioBot.cs @@ -0,0 +1,91 @@ +#region Using declarations +using NinjaTrader.NinjaScript.Indicators; +using System.ComponentModel.DataAnnotations; +#endregion + +namespace NinjaTrader.NinjaScript.Strategies +{ + public class AdvanceDeclineRatioBot : Strategy + { + private const int PrimaryBars = 0; + private const int AdvanceBars = 1; + private const int DeclineBars = 2; + + private SMA LongTermTrend; + + protected override void OnStateChange() + { + if (State == State.SetDefaults) + { + Name = "Advance / Decline Bot"; + Description = @"Based on chatper 5 (Market Breadth) of How Markets Really Work (2012) by Larry Connors"; + Calculate = Calculate.OnBarClose; + EntriesPerDirection = 1; + + Advances = 1.0; + Declines = 2.0; + LongTermTrendPeriod = 200; + DaysToExit = 5; + } + else if (State == State.Configure) + { + AddDataSeries("^ADV"); + AddDataSeries("^DECL"); + } + else if (State == State.DataLoaded) + { + LongTermTrend = SMA(LongTermTrendPeriod); + } + } + + protected override void OnBarUpdate() + { + if (PrimaryBars != BarsInProgress) + return; + + if (CurrentBars[AdvanceBars] < 1 || CurrentBars[DeclineBars] < 1) + return; + + if (Close[0] < LongTermTrend[0]) + return; + + double advances = BarsArray[AdvanceBars].GetClose(BarsArray[AdvanceBars].GetBar(Time[0])); + double declines = BarsArray[DeclineBars].GetClose(BarsArray[DeclineBars].GetBar(Time[0])); + + if (Advances >= Declines) + { + if ((advances / declines) >= (Advances / Declines)) + EnterLong(); + } + else + { + if ((declines / advances) >= (Declines / Advances)) + EnterLong(); + } + + if (BarsSinceEntryExecution(PrimaryBars, "", 0) >= DaysToExit) + ExitLong(); + } + + public override string DisplayName + { + get { return Name; } + } + + [NinjaScriptProperty] + [Display(Name = "Advances", GroupName = "Advance / Decline Bot", Order = 1)] + public double Advances { get; set; } + + [NinjaScriptProperty] + [Display(Name = "Declines", GroupName = "Advance / Decline Bot", Order = 2)] + public double Declines { get; set; } + + [NinjaScriptProperty] + [Display(Name = "Long-Term Trend Period", GroupName = "Advance / Decline Bot", Order = 3)] + public int LongTermTrendPeriod { get; set; } + + [NinjaScriptProperty] + [Display(Name = "Days to Exit", GroupName = "Advance / Decline Bot", Order = 4)] + public int DaysToExit { get; set; } + } +}