Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

Modifying the default Swing indicator

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Modifying the default Swing indicator

    I am attempting to modify the swing indicator as follows:
    1. Trading / watching price action on a volume chart
    2. Draw the swing highs / swing lows from a time based chart

    Example
    1. Open 5k volume chart on the ES
    2. Apply ModifiedSwing indicator
    3. Input series 5 minute ES chart
    4. Swing highs and lows from 5 minute time frame plotted on the 5k volume chart

    After multiple attempts, when the indicator plots, it only plots with the 5k data consumed for the swings.

    Is it possible to have a single chart consuming data from different time frames?

    #2
    As an update this is the code I am using ... it compiles, but doesn't do what I want specifically.

    region Using declarations
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Xml.Serialization;
    using NinjaTrader.Cbi;
    using NinjaTrader.Gui;
    using NinjaTrader.Gui.Chart;
    using NinjaTrader.Gui.SuperDom;
    using NinjaTrader.Gui.Tools;
    using NinjaTrader.Data;
    using NinjaTrader.NinjaScript;
    using NinjaTrader.Core.FloatingPoint;
    using NinjaTrader.NinjaScript.DrawingTools;
    #endregion

    //This namespace holds Indicators in this folder and is required. Do not change it.
    namespace NinjaTrader.NinjaScript.Indicators
    {

    public class SwingModified : Indicator
    {
    private int strength;
    private Series<double> swingHighs;
    private Series<double> swingLows;
    private Series<double> currentSwingHigh;
    private Series<double> currentSwingLow;
    private int lastSwingHighBar;
    private int lastSwingLowBar;
    private double lastSwingHighValue;
    private double lastSwingLowValue;
    private int saveCurrentBar;
    private int constant;
    private Bars fiveMinuteBars;




    protected override void OnStateChange()
    {
    if (State == State.SetDefaults)
    {
    Description = @"Swing indicator modified for 5-minute bars look back";
    Name = "SwingModified";
    Calculate = Calculate.OnBarClose;
    IsOverlay = true;
    DisplayInDataBox = true;
    DrawOnPricePanel = true;
    DrawHorizontalGridLines = true;
    DrawVerticalGridLines = true;
    PaintPriceMarkers = true;
    ScaleJustification = NinjaTrader.Gui.Chart.ScaleJustification.Right;
    IsSuspendedWhileInactive = true;
    Strength = 5;
    }
    else if (State == State.Configure)
    {
    // Add a 5-minute data series as primary data series
    AddDataSeries(BarsPeriodType.Minute, 5);

    // Initialize swing high and low variables
    swingHighs = new Series<double>(this);
    swingLows = new Series<double>(this);
    currentSwingHigh = new Series<double>(this);
    currentSwingLow = new Series<double>(this);
    lastSwingHighValue = 0;
    lastSwingLowValue = 0;
    saveCurrentBar = -1;
    constant = (2 * Strength) + 1;

    // Initialize currentSwingHigh and currentSwingLow to NaN
    for (int i = 0; i < BarsArray[0].Count; i++)
    {
    currentSwingHigh[i] = double.NaN;
    currentSwingLow[i] = double.NaN;
    }
    }
    else if (State == State.DataLoaded)
    {
    fiveMinuteBars = BarsArray[1];
    }
    }


    protected override void OnBarUpdate()
    {
    if (CurrentBars[0] < Strength || CurrentBars[1] < Strength)
    return;

    if (BarsInProgress == 1)
    {
    double high = MAX(High, Strength)[0];
    double low = MIN(Low, Strength)[0];

    if (fiveMinuteBars.IsFirstBarOfSession) // Check if it is the first bar
    {
    currentSwingHigh[0] = high; // Initialize currentSwingHigh here
    currentSwingLow[0] = low; // Initialize currentSwingLow here
    swingHighs[0] = high;
    swingLows[0] = low;
    }
    else
    {
    swingHighs[0] = swingHighs[1];
    swingLows[0] = swingLows[1];
    }

    if (High[0] >= high)
    currentSwingHigh[0] = high;
    if (Low[0] <= low)
    currentSwingLow[0] = low;
    }

    if (BarsInProgress == 0)
    {
    if (CurrentBar <= 1)
    return;

    // Plot Swing High
    if (swingHighs[0] > swingHighs[1] && swingHighs[0] > High[0])
    {
    SwingHigh[0] = swingHighs[0];

    }
    else
    SwingHigh[0] = double.NaN;

    // Plot Swing Low
    if (swingLows[0] < swingLows[1] && swingLows[0] < Low[0])
    {
    SwingLow[0] = swingLows[0];

    }
    else
    SwingLow[0] = double.NaN;

    // Initialize currentSwingHigh and currentSwingLow here
    currentSwingHigh[0] = double.NaN;
    currentSwingLow[0] = double.NaN;

    // Update last swing high and low values
    if (!double.IsNaN(currentSwingHigh[1]) && currentSwingHigh[1] != currentSwingHigh[0])
    {
    lastSwingHighValue = currentSwingHigh[1];
    saveCurrentBar = CurrentBar;
    }
    if (!double.IsNaN(currentSwingLow[1]) && currentSwingLow[1] != currentSwingLow[0])
    {
    lastSwingLowValue = currentSwingLow[1];
    saveCurrentBar = CurrentBar;
    }
    }
    }


    [Range(1, int.MaxValue), NinjaScriptProperty]
    public int Strength
    {
    get { return strength; }
    set { strength = Math.Max(1, value); }
    }

    region Properties
    [Browsable(false)]
    [XmlIgnore]
    public Series<double> SwingHigh
    {
    get { return Values[0]; }
    }

    [Browsable(false)]
    [XmlIgnore]
    public Series<double> SwingLow
    {
    get { return Values[1]; }
    }
    #endregion
    }
    }

    region NinjaScript generated code. Neither change nor remove.

    namespace NinjaTrader.NinjaScript.Indicators
    {
    public partial class Indicator : NinjaTrader.Gui.NinjaScript.IndicatorRenderBase
    {
    private SwingModified[] cacheSwingModified;
    public SwingModified SwingModified(int strength)
    {
    return SwingModified(Input, strength);
    }

    public SwingModified SwingModified(ISeries<double> input, int strength)
    {
    if (cacheSwingModified != null)
    for (int idx = 0; idx < cacheSwingModified.Length; idx++)
    if (cacheSwingModified[idx] != null && cacheSwingModified[idx].Strength == strength && cacheSwingModified[idx].EqualsInput(input))
    return cacheSwingModified[idx];
    return CacheIndicator<SwingModified>(new SwingModified(){ Strength = strength }, input, ref cacheSwingModified);
    }
    }
    }

    namespace NinjaTrader.NinjaScript.MarketAnalyzerColumns
    {
    public partial class MarketAnalyzerColumn : MarketAnalyzerColumnBase
    {
    public Indicators.SwingModified SwingModified(int strength)
    {
    return indicator.SwingModified(Input, strength);
    }

    public Indicators.SwingModified SwingModified(ISeries<double> input , int strength)
    {
    return indicator.SwingModified(input, strength);
    }
    }
    }

    namespace NinjaTrader.NinjaScript.Strategies
    {
    public partial class Strategy : NinjaTrader.Gui.NinjaScript.StrategyRenderBase
    {
    public Indicators.SwingModified SwingModified(int strength)
    {
    return indicator.SwingModified(Input, strength);
    }

    public Indicators.SwingModified SwingModified(ISeries<double> input , int strength)
    {
    return indicator.SwingModified(input, strength);
    }
    }
    }

    #endregion

    Comment


      #3
      Hello PaperStacks,

      Thank you for your post. Welcome to the NinjaTrader forum community!

      Yes, it would be possible to have your indicator receive data from multiple time frames and plot based on that data. That said, I do not see the use of AddPlot in your indicator, so there are no plots being added to visually render data on the chart. For more information regarding AddPlot(), please see the following page in the help guide:


      You may also review the system Swing indicator to see how the plots are added and updated.

      It may also be helpful to review the help guide page about multi-time frame & instrument scripts:


      Additionally, if you are unsure if the values are calculating as expected or if your conditions are being hit, you can add Print() statements to your script to better understand its behavior:


      You could likely achieve your desired result (without having to modify the Swing indicator) by simply plotting the swing indicator on a "hidden" 5-minute data series. For a video about plotting indicators on a hidden data series, please see the following link from our YouTube channel:


      Please let us know if we may be of further assistance.

      Comment

      Latest Posts

      Collapse

      Topics Statistics Last Post
      Started by Geovanny Suaza, 02-11-2026, 06:32 PM
      0 responses
      558 views
      0 likes
      Last Post Geovanny Suaza  
      Started by Geovanny Suaza, 02-11-2026, 05:51 PM
      0 responses
      324 views
      1 like
      Last Post Geovanny Suaza  
      Started by Mindset, 02-09-2026, 11:44 AM
      0 responses
      101 views
      0 likes
      Last Post Mindset
      by Mindset
       
      Started by Geovanny Suaza, 02-02-2026, 12:30 PM
      0 responses
      545 views
      1 like
      Last Post Geovanny Suaza  
      Started by RFrosty, 01-28-2026, 06:49 PM
      0 responses
      547 views
      1 like
      Last Post RFrosty
      by RFrosty
       
      Working...
      X