SuperTrend for NinjaTrader

Dr.M

New member
Platform
  1. NinjaTrader
Can anyone help to convert this into NinjaTrader? Thank you! @barbaros
Code:
# SuperTrend Yahoo Finance Replica - Modified from Modius SuperTrend
# Modified Modius ver. by RConner7
# Modified by Barbaros to replicate look from TradingView version
# Modified by Barbaros to add EMA cross for bubbles and alerts
# Modified by Barbaros to update bar color painting
# v3.3

input AtrMult = 1.00;
input nATR = 6;
input AvgType = AverageType.HULL;
input PaintBars = yes;
input ShowBubbles = yes;
input ShowLabels = yes;
input UseEmaCross = yes;
input EMA1 = 10;
input EMA2 = 20;

def ATR = ATR("length" = nATR, "average type" = AvgType);
def UP_Band_Basic = HL2 + (AtrMult * ATR);
def LW_Band_Basic = HL2 + (-AtrMult * ATR);
def UP_Band = if ((UP_Band_Basic < UP_Band[1]) or (close[1] > UP_Band[1])) then UP_Band_Basic else UP_Band[1];
def LW_Band = if ((LW_Band_Basic > LW_Band[1]) or (close[1] < LW_Band[1])) then LW_Band_Basic else LW_Band[1];

def ST = if ((ST[1] == UP_Band[1]) and (close < UP_Band)) then UP_Band
else if ((ST[1] == UP_Band[1]) and (close > Up_Band)) then LW_Band
else if ((ST[1] == LW_Band[1]) and (close > LW_Band)) then LW_Band
else if ((ST[1] == LW_Band) and (close < LW_Band)) then UP_Band
else LW_Band;

def EMA1Val = MovAvgExponential(close, EMA1);
def EMA2Val = MovAvgExponential(close, EMA2);
def EMADirection = if EMA1Val > EMA2Val then 1 else if EMA1Val < EMA2Val then -1 else 0;

plot Long = if close > ST then ST else Double.NaN;
Long.AssignValueColor(Color.GREEN);
Long.SetLineWeight(2);

plot Short = if close < ST then ST else Double.NaN;
Short.AssignValueColor(Color.RED);
Short.SetLineWeight(3);

def LongTrigger = isNaN(Long[1]) and !isNaN(Long);
def ShortTrigger = isNaN(Short[1]) and !isNaN(Short);

plot LongDot = if LongTrigger then ST else Double.NaN;
LongDot.SetPaintingStrategy(PaintingStrategy.POINTS);
LongDot.AssignValueColor(Color.GREEN);
LongDot.SetLineWeight(4);

plot ShortDot = if ShortTrigger then ST else Double.NaN;
ShortDot.SetPaintingStrategy(PaintingStrategy.POINTS);
ShortDot.AssignValueColor(Color.RED);
ShortDot.SetLineWeight(4);

def LongConfirm = (UseEmaCross and close > ST and EMADirection == 1) or (!UseEmaCross and LongTrigger);
def ShortConfirm = (UseEmaCross and close < ST and EMADirection == -1) or (!UseEmaCross and ShortTrigger);

def LongAlert = LongConfirm and LongConfirm[1] != LongConfirm;
def ShortAlert = ShortConfirm and ShortConfirm[1] != ShortConfirm;

AddLabel(ShowLabels, "ST: " + (if close > ST then "Bullish" else if close < ST then "Bearish" else "Neutral"),
                              if close > ST then Color.GREEN else if close < ST then Color.RED else Color.GRAY);
AddLabel(ShowLabels and UseEmaCross, "EMA: " + (if EMADirection == 1 then "Bullish" else if EMADirection == -1 then "Bearish" else "Neutral"),
                              if EMADirection == 1 then Color.GREEN else if EMADirection == -1 then Color.RED else Color.GRAY);

AddChartBubble(ShowBubbles and LongAlert, ST, "BUY", Color.GREEN, no);
AddChartBubble(ShowBubbles and ShortAlert, ST, "SELL", Color.RED, yes);

AssignPriceColor(if PaintBars and close < ST and (!UseEmaCross or EMADirection == -1) then Color.RED
                 else if PaintBars and close > ST and (!UseEmaCross or EMADirection == 1) then Color.GREEN
                 else if PaintBars then Color.GRAY
                 else Color.CURRENT);

Alert(LongAlert, "Long", Alert.BAR, Sound.Ding);
Alert(ShortAlert, "Short", Alert.BAR, Sound.Ding);

# End Code SuperTrend Yahoo Finance Replica
.
 

barbaros

Administrator
Staff member
Here is a Supertrend for NT8

Code:
#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

namespace NinjaTrader.NinjaScript.Indicators
{
    public class Supertrend : Indicator
    {
        private double                barHighValue, barLowValue, bottomValue, topValue;
        private Series<double>        atrSeries, bottomSeries, topSeries;

        protected override void OnStateChange()
        {
            if (State == State.SetDefaults)
            {
                Description        = @"Supertrend indicator as detailed in the July 2023 Technical Analysis Stocks and Commodities article Stay On Track With by Barbara Star, PhD.";
                Name            = "Supertrend";
                Calculate        = Calculate.OnBarClose;
                IsOverlay        = true;

                ATRMultiplier    = 3;
                ATRPeriod        = 10;

                AddPlot(Brushes.Firebrick, "Supertrend");
            }
            else if (State == State.DataLoaded)
            {
                topSeries        = new Series<double>(this, MaximumBarsLookBack.TwoHundredFiftySix);
                bottomSeries    = new Series<double>(this, MaximumBarsLookBack.TwoHundredFiftySix);
                atrSeries        = new Series<double>(this, MaximumBarsLookBack.TwoHundredFiftySix);

                if (!(Input is PriceSeries) && (!Bars.IsTickReplay || Calculate == Calculate.OnBarClose))
                    Log("Supertrend: Enable TickReplay with Calculate.OnPriceChange/.OnEachTick when using another indicator as the input series. (To collect the intra-bar high and low in historical)", LogLevel.Warning);
            }
        }

        protected override void OnBarUpdate()
        {
            if (IsFirstTickOfBar)
            {
                barHighValue    = double.MinValue;
                barLowValue        = double.MaxValue;
            }

            // calculate the bar high and low when another indicator is input series
            barHighValue    = (Input is PriceSeries) ? High[0] : Math.Max(barHighValue, Input[0]);
            barLowValue        = (Input is PriceSeries) ? Low[0] : Math.Min(barLowValue, Input[0]);
            
            // calculate the ATR, but allowing for another indicator as an input series
            if (CurrentBar == 0)
                atrSeries[0]        = barHighValue - barLowValue;
            else
            {
                double close1        = Input is PriceSeries ? Close[1] : Input[1];
                double trueRange    = Math.Max(Math.Abs(barLowValue - close1), Math.Max(barHighValue - barLowValue, Math.Abs(barHighValue - close1)));
                atrSeries[0]        = ((Math.Min(CurrentBar + 1, ATRPeriod) - 1 ) * atrSeries[1] + trueRange) / Math.Min(CurrentBar + 1, ATRPeriod);
            }

            //    dis:= a2 * ATR(a1);
            //    bTop:= MP() + dis;
            //    bBot:= MP() - dis;
            topValue        = ((barHighValue + barLowValue) / 2) + (ATRMultiplier * atrSeries[0]);
            bottomValue        = ((barHighValue + barLowValue) / 2) - (ATRMultiplier * atrSeries[0]);

            if (CurrentBar < 1)
                return;

            //    Top:= If((bTop < PREV) OR(Ref(C, -1)) > PREV, bTop, PREV);
            //    Bot:= If((bBot > PREV) OR(Ref(C, -1)) < PREV, bBot, PREV);
            topSeries[0]    = (topValue < Default[1] || Input[1] > Default[1]) ? topValue : Default[1];
            bottomSeries[0]    = (bottomValue > Default[1] || Input[1] < Default[1]) ? bottomValue : Default[1];

            //    If(PREV = Ref(top, -1), If(C <= Top, Top, Bot), If(PREV = Ref(bot, -1), If(C >= Bot, Bot, Top), top));
            Default[0]        = (Default[1] == topSeries[1]) ? ((Input[0] <= topSeries[0]) ? topSeries[0] : bottomSeries[0]) : ((Default[1] == bottomSeries[1]) ? ((Input[0] >= bottomSeries[0]) ? bottomSeries[0] : topSeries[0]) : topSeries[0]);
        }

        #region Properties
        //        a2:= Input(�Multiplier for ATR�, 1, 10, 3) ;
        [NinjaScriptProperty]
        [Range(1, 10)]
        [Display(Name="ATRMultiplier", Description="Multiplier of the ATR distance", Order=1, GroupName="Parameters")]
        public int ATRMultiplier
        { get; set; }

        //        a1:= Input(�Number of periods in ATR�, 2, 100, 7);
        [NinjaScriptProperty]
        [Range(2, 100)]
        [Display(Name="ATRPeriod", Description="Period supplied to ATR calculation", Order=2, GroupName="Parameters")]
        public int ATRPeriod
        { get; set; }

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

    }
}
 
Top