ninja-patterns

Lightweight scaffold for NinjaTrader 8 NinjaScript/C# indicator development.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "ninja-patterns" with this command: npx skills add lgbarn/trading-indicator-plugins/lgbarn-trading-indicator-plugins-ninja-patterns

NinjaScript Patterns

Lightweight scaffold for NinjaTrader 8 NinjaScript/C# indicator development.

Before Generating Code

ALWAYS use doc-researcher agent or Ref MCP tools to verify:

  • NinjaTrader 8 API methods

  • Property attribute usage

  • Drawing object APIs

File Conventions

  • File naming: *LB.cs

  • Author: // Author: Luther Barnum

Namespace & Class

namespace NinjaTrader.NinjaScript.Indicators.LB { public class [Name]LB : Indicator { // Implementation } }

Lifecycle Methods

OnStateChange()

protected override void OnStateChange() { if (State == State.SetDefaults) { Description = "Indicator description"; Name = "IndicatorName"; // Set property defaults } else if (State == State.Configure) { AddPlot(Brushes.Blue, "PlotName"); } else if (State == State.DataLoaded) { // Initialize Series objects } }

OnBarUpdate()

protected override void OnBarUpdate() { if (CurrentBar < BarsRequiredToPlot) return; // Calculations }

Property Attributes

[NinjaScriptProperty] [Display(Name = "Period", Order = 1, GroupName = "Parameters")] [Range(1, int.MaxValue)] public int Period { get; set; }

Session Detection

if (Bars.IsFirstBarOfSession) { // Reset session values }

Series Objects

private Series<double> myValues;

// In State.DataLoaded: myValues = new Series<double>(this);

Drawing Objects

Draw.Rectangle(this, "tag", startBar, startPrice, endBar, endPrice, Brushes.Blue); Draw.Line(this, "tag", startBar, startPrice, endBar, endPrice, Brushes.Red); Draw.Text(this, "tag", "Label", 0, High[0] + TickSize, Brushes.White);

Complete Example

Reference: /Users/lgbarn/Personal/Indicators/Ninjatrader/PEMA.cs

#region Using declarations using System; using System.ComponentModel; using System.ComponentModel.DataAnnotations; using System.Windows.Media; using NinjaTrader.Gui.Chart; using NinjaTrader.NinjaScript.DrawingTools; #endregion

// Author: Luther Barnum

namespace NinjaTrader.NinjaScript.Indicators.LB { public class SimpleMALB : Indicator { private EMA fastEma; private SMA slowSma;

    protected override void OnStateChange()
    {
        if (State == State.SetDefaults)
        {
            Description = "Simple MA Crossover Indicator";
            Name = "SimpleMALB";
            Calculate = Calculate.OnBarClose;
            IsOverlay = true;

            // Default parameters
            FastPeriod = 9;
            SlowPeriod = 21;

            // Add plots
            AddPlot(Brushes.Cyan, "FastMA");
            AddPlot(Brushes.Orange, "SlowMA");

            Plots[0].Width = 2;
            Plots[1].Width = 2;
        }
        else if (State == State.DataLoaded)
        {
            fastEma = EMA(Close, FastPeriod);
            slowSma = SMA(Close, SlowPeriod);
        }
    }

    protected override void OnBarUpdate()
    {
        if (CurrentBar &#x3C; SlowPeriod)
            return;

        FastMA[0] = fastEma[0];
        SlowMA[0] = slowSma[0];
    }

    #region Properties
    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Fast Period", Order = 1, GroupName = "Parameters")]
    public int FastPeriod { get; set; }

    [NinjaScriptProperty]
    [Range(1, int.MaxValue)]
    [Display(Name = "Slow Period", Order = 2, GroupName = "Parameters")]
    public int SlowPeriod { get; set; }

    [Browsable(false)]
    [XmlIgnore]
    public Series&#x3C;double> FastMA { get { return Values[0]; } }

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

}

VWAP Calculation Pattern

private double cumVolume; private double cumVwap; private double cumVwap2;

protected override void OnBarUpdate() { if (Bars.IsFirstBarOfSession) { cumVolume = 0; cumVwap = 0; cumVwap2 = 0; }

double typicalPrice = (High[0] + Low[0] + Close[0]) / 3.0;
cumVolume += Volume[0];
cumVwap += Volume[0] * typicalPrice;
cumVwap2 += Volume[0] * typicalPrice * typicalPrice;

if (cumVolume > 0)
{
    double vwap = cumVwap / cumVolume;
    double variance = (cumVwap2 / cumVolume) - (vwap * vwap);
    double stdev = variance > 0 ? Math.Sqrt(variance) : 0;

    VWAP[0] = vwap;
    UpperBand[0] = vwap + stdev;
    LowerBand[0] = vwap - stdev;
}

}

Error Handling Patterns

Check bar history

protected override void OnBarUpdate() { // Ensure enough bars for calculation if (CurrentBar < BarsRequiredToPlot) return;

// Or use specific period
if (CurrentBar &#x3C; Period - 1)
    return;

}

Null/zero checks

// Safe division double divisor = High[0] - Low[0]; double result = divisor != 0 ? (Close[0] - Low[0]) / divisor : 0.5;

// Check indicator values if (myIndicator[0] != 0 && !double.IsNaN(myIndicator[0])) { // Safe to use }

Validate parameters

if (State == State.SetDefaults) { // Use [Range] attribute for validation } else if (State == State.Configure) { // Additional validation if (SlowPeriod <= FastPeriod) SlowPeriod = FastPeriod + 1; }

Historical data access

// Safe access to previous bars if (CurrentBar >= barsAgo) { double previousValue = Close[barsAgo]; }

Trading Context

  • Focus: /ES, /NQ futures

  • Timeframe: 5-minute

  • Key concepts: VWAP+bands, IB, Pivots

  • Location: /Users/lgbarn/Personal/Indicators/Ninjatrader/

Documentation Sources

Use Ref MCP to search:

  • NinjaTrader 8 Help Guide

  • NinjaScript Reference

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

pine-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
General

tradovate-patterns

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

test-driven-development

No summary provided by upstream source.

Repository SourceNeeds Review