Arms Index (TRIN) Indicator for ThinkorSwim

TheGrimmReaper

New member
By making some simple mathematical adjustments to the original TRIN Indicator formula you can make a more intuitive and accurate indicator. Here’s what to do to create a Better TRIN Indicator:
  1. Take the Log of the NYSE TRIN value
  2. Invert this value so negative values are positive and vice versa
  3. Multiply the inverted Log value by 100, and
  4. Repeat for the NASDAQ TRIN data and average the two values
https://emini-watch.com/trading-indicators/trin-indicator/

COMMENT: I am new to ToS, so I have no idea how to code this seemingly simple indicator. I'm hoping that after looking at this link you might also find it of interest and code it into ThinkScript for others to utilize :)

Code:
# Eliades New TRIN (Peter Eliades)
# Nube
# cleaned up original mess 11-6-17
# changed to include both nyse and nasdaq 11-7-17
# added SP 500 11-9-17
#hint: Eliades New 10 TRIN for NYSE, S&P and NASDAQ composites
declare lower;

input Exchange = { NYSE, SP500, Default NASDAQ } ;#hint Exchange: select exchange
input LineNegative = 1.0;#hint LineNegative: input must be positive, script will invert it

assert(LineNegative > 0, "'LineNegative' must be positive - study will invert it. ");

def c  = close();
def na = Double.NaN;

def dvolc  = if     IsNaN(c) then na else
             if     !IsNaN(close("$DVOLC"))
              then  close("$DVOLC")
               else dvolc[1];
def uvolc  = if     IsNaN(c) then na else
             if     !IsNaN(close("$UVOLC"))
              then  close("$UVOLC")
               else uvolc[1];
def advnc   = if     IsNaN(c) then na else
              if     !IsNaN(close("$ADVNC"))
               then  close("$ADVNC")
                else advnc[1];
def decnc   = if     IsNaN(c) then na else
              if     !IsNaN(close("$DECNC"))
               then  close("$DECNC")
                else decnc[1];
def dvolcq  = if     IsNaN(c) then na else
              if     !IsNaN(close("$DVOLC/Q"))
               then  close("$DVOLC/Q")
                else dvolcq[1];
def uvolcq  = if     IsNaN(c) then na else
              if     !IsNaN(close("$UVOLC/Q"))
               then  close("$UVOLC/Q")
                else uvolcq[1];
def advncq  = if     IsNaN(c) then na else
              if     !IsNaN(close("$ADVNC/Q"))
               then  close("$ADVNC/Q")
                else advncq[1];
def decncq  = if     IsNaN(c) then na else
              if     !IsNaN(close("$DECNC/Q"))
               then  close("$DECNC/Q")
                else decncq[1];
def dvolspc = if     IsNaN(c) then na else
              if     !IsNaN(close("$DVOLSPC"))
               then  close("$DVOLSPC")
                else dvolspc[1];
def uvolspc = if     IsNaN(c) then na else
              if     !IsNaN(close("$UVOLSPC"))
               then  close("$UVOLSPC")
                else uvolspc[1];
def advspc  = if     IsNaN(c) then na else
              if     !IsNaN(close("$ADVSPC"))
               then  close("$ADVSPC")
                else advspc[1];
def declspc = if     IsNaN(c) then na else
              if     !IsNaN(close("$DECLSPC"))
               then  close("$DECLSPC")
                else declspc[1];
              
def dvol;
def uvol;
def advn;
def decn;
switch (Exchange) {
case NYSE:
    dvol = dvolc;
    uvol = uvolc;
    advn = advnc;
    decn = decnc;
case NASDAQ:
    dvol = dvolcq;
    uvol = uvolcq;
    advn = advncq;
    decn = decncq;
case SP500:
    dvol = dvolspc;
    uvol = uvolspc;
    advn = advspc;
    decn = declspc;
}


plot NegativeLine = -LineNegative;
     NegativeLine.SetDefaultColor(Color.Gray);
     NegativeLine.SetStyle(Curve.MEDIUM_DASH);
     NegativeLine.HideBubble();

    plot New10TRIN =-(sum(dvol,10)/sum(uvol,10)) / 
                     (sum((advn/decn)/(uvol/dvol),10)/10);
         New10TRIN.DefineColor("Up", Color.UpTick);
         New10TRIN.DefineColor("Down", Color.DownTick);
         New10TRIN.AssignValueColor(if     New10TRIN < NegativeLine
                                     then  New10TRIN.Color("Down")
                                      else New10TRIN.Color("Up"));

# f/
 
Last edited by a moderator:
Solution
I threw this together. I don't know how to make actual candles (I don't think it's possible), so I made individual plots for the OHLC values. You can mess with the symbols these plot as to tweak to your liking. You can either use this as a lower study or simply drag/drop it onto the upper part of the studies section on your $TRIN chart, then go to settings for the chart and change the actual TRIN candles to all black so they disappear.

Code:
declare lower;
def lnh = Log(high("$TRIN")) * -1 * 100;
def lnl = Log(low("$TRIN")) * -1 * 100;
def lnc = Log(close("$TRIN")) * -1 * 100;
def lno = Log(open("$TRIN")) * -1 * 100;
def lnhn = Log(high("$TRIN/Q")) * -1 * 100;
def lnln = Log(low("$TRIN/Q")) * -1 * 100;
def lncn = Log(close("$TRIN/Q")) *...

dolomick

Member
So I wanted a lower TRIN indicator and found this on the oneDrive. But on March 16th, we spiked to around 15 on the TRIN (just input $TRIN into the ticker field on a chart to see). If I look at this indicator, it does not show that for the same date. Can someone help explain why that would be?

Code starts here....

Code:
#Here is TRIN as lower study. I have inverted it to make it easier to understand, so spike above 2 is overbought (plot will turn red) and spike below 0.5 is oversold #(plot will turn green). It will draw horizontal line at 2 in pink and at 0.5 in light green to indicate overbought and oversold levels. 

#In regular TRIN it is upside down, spike above 2 is oversold and spike below 0.5 is overbought. 

declare lower; 

def UVOL = close(“$UVOL”); 
def DVOL = close(“$DVOL”); 
def ADV = close(“$ADVN”); 
def DECL = close(“$DECN”); 

plot TRIN = (DECL/ADV)/(DVOL/UVOL); 
TRIN.SetStyle(Curve.FIRM); 
TRIN.AssignValueColor(if TRIN >= 2 then Color.RED else if TRIN <= 0.5 then Color.GREEN else Color.GRAY); 

plot ZeroLine = 1; 
        ZeroLine.AssignValueColor(Color.LIGHT_GRAY); 

plot UB = 2; 
        UB.AssignValueColor(Color.PINK); 

plot LB = 0.5; 
        LB.AssignValueColor(Color.LIGHT_GREEN);
 

AlexNYC

New member
@TheGrimmReaper I'd love to see this as well, if possible. I found this code which I believe is the result of someone on the NinjaTrader forum converting the code from TradeStation, in case this helps

Code:
#region Using declarations
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Xml.Serialization;
using NinjaTrader.Cbi;
using NinjaTrader.Data;
using NinjaTrader.Gui.Chart;
#endregion

// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
    /// <summary>
    /// Better TRIN
    /// </summary>
    [Description("Better TRIN")]
    public class BetterTRIN : Indicator
    {
        #region Variables
        // Wizard generated variables
        // User defined variables (add any user defined variables below)
        #endregion

        /// <summary>
        /// This method is used to configure the indicator and is called once before any bar data is loaded.
        /// </summary>
        protected override void Initialize()
        {
            Add(new Plot(Color.FromKnownColor(KnownColor.Orange), PlotStyle.Line, "MyTRIN"));
            CalculateOnBarClose    = true;
            Overlay                = false;
            PriceTypeSupported    = false;
        }

        /// <summary>
        /// Called on each bar update event (incoming tick)
        /// </summary>
        protected override void OnBarUpdate()
        {
            MyTRIN.Set(-100 * Math.Log10(Input[0]));
        }

        #region Properties
        [Browsable(false)]    // this line prevents the data series from being displayed in the indicator properties dialog, do not remove
        [XmlIgnore()]        // this line ensures that the indicator can be saved/recovered as part of a chart template, do not remove
        public DataSeries MyTRIN
        {
            get { return Values[0]; }
        }

        #endregion
    }
}

#region NinjaScript generated code. Neither change nor remove.
// This namespace holds all indicators and is required. Do not change it.
namespace NinjaTrader.Indicator
{
    public partial class Indicator : IndicatorBase
    {
        private BetterTRIN[] cacheBetterTRIN = null;

        private static BetterTRIN checkBetterTRIN = new BetterTRIN();

        /// <summary>
        /// Better TRIN
        /// </summary>
        /// <returns></returns>
        public BetterTRIN BetterTRIN()
        {
            return BetterTRIN(Input);
        }

        /// <summary>
        /// Better TRIN
        /// </summary>
        /// <returns></returns>
        public BetterTRIN BetterTRIN(Data.IDataSeries input)
        {

            if (cacheBetterTRIN != null)
                for (int idx = 0; idx < cacheBetterTRIN.Length; idx++)
                    if (cacheBetterTRIN[idx].EqualsInput(input))
                        return cacheBetterTRIN[idx];

            BetterTRIN indicator = new BetterTRIN();
            indicator.BarsRequired = BarsRequired;
            indicator.CalculateOnBarClose = CalculateOnBarClose;
            indicator.Input = input;
            indicator.SetUp();

            BetterTRIN[] tmp = new BetterTRIN[cacheBetterTRIN == null ? 1 : cacheBetterTRIN.Length + 1];
            if (cacheBetterTRIN != null)
                cacheBetterTRIN.CopyTo(tmp, 0);
            tmp[tmp.Length - 1] = indicator;
            cacheBetterTRIN = tmp;
            Indicators.Add(indicator);

            return indicator;
        }

    }
}

// This namespace holds all market analyzer column definitions and is required. Do not change it.
namespace NinjaTrader.MarketAnalyzer
{
    public partial class Column : ColumnBase
    {
        /// <summary>
        /// Better TRIN
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.BetterTRIN BetterTRIN()
        {
            return _indicator.BetterTRIN(Input);
        }

        /// <summary>
        /// Better TRIN
        /// </summary>
        /// <returns></returns>
        public Indicator.BetterTRIN BetterTRIN(Data.IDataSeries input)
        {
            return _indicator.BetterTRIN(input);
        }

    }
}

// This namespace holds all strategies and is required. Do not change it.
namespace NinjaTrader.Strategy
{
    public partial class Strategy : StrategyBase
    {
        /// <summary>
        /// Better TRIN
        /// </summary>
        /// <returns></returns>
        [Gui.Design.WizardCondition("Indicator")]
        public Indicator.BetterTRIN BetterTRIN()
        {
            return _indicator.BetterTRIN(Input);
        }

        /// <summary>
        /// Better TRIN
        /// </summary>
        /// <returns></returns>
        public Indicator.BetterTRIN BetterTRIN(Data.IDataSeries input)
        {
            if (InInitialize && input == null)
                throw new ArgumentException("You only can access an indicator with the default input/bar series from within the 'Initialize()' method");

            return _indicator.BetterTRIN(input);
        }

    }
}
#endregion
 
I threw this together. I don't know how to make actual candles (I don't think it's possible), so I made individual plots for the OHLC values. You can mess with the symbols these plot as to tweak to your liking. You can either use this as a lower study or simply drag/drop it onto the upper part of the studies section on your $TRIN chart, then go to settings for the chart and change the actual TRIN candles to all black so they disappear.

Code:
declare lower;
def lnh = Log(high("$TRIN")) * -1 * 100;
def lnl = Log(low("$TRIN")) * -1 * 100;
def lnc = Log(close("$TRIN")) * -1 * 100;
def lno = Log(open("$TRIN")) * -1 * 100;
def lnhn = Log(high("$TRIN/Q")) * -1 * 100;
def lnln = Log(low("$TRIN/Q")) * -1 * 100;
def lncn = Log(close("$TRIN/Q")) * -1 * 100;
def lnon = Log(open("$TRIN/Q")) * -1 * 100;

plot open = (lno + lnon) / 2;
plot low = (lnh + lnhn) / 2;
plot high = (lnl + lnln) / 2;
plot close = (lnc + lncn) / 2;

open.SetPaintingStrategy(paintingStrategy = PaintingStrategy.POINTS);
high.SetPaintingStrategy(paintingStrategy = PaintingStrategy.ARROW_UP);
low.SetPaintingStrategy(paintingStrategy = PaintingStrategy.ARROW_DOWN);
close.SetPaintingStrategy(paintingStrategy = PaintingStrategy.SQUARES);

open.assignvalueColor(if open > close then Color.RED else Color.GREEN);
high.assignvalueColor(if open > close then Color.RED else Color.GREEN);
low.assignvalueColor(if open > close then Color.RED else Color.GREEN);
close.assignvalueColor(if open > close then Color.RED else Color.GREEN);

Here's a version of it more like in the video with a single line connecting the closing values as a lower study.

Code:
declare lower;
def lnh = Log(high("$TRIN")) * -1 * 100;
def lnl = Log(low("$TRIN")) * -1 * 100;
def lnc = Log(close("$TRIN")) * -1 * 100;
def lno = Log(open("$TRIN")) * -1 * 100;
def lnhn = Log(high("$TRIN/Q")) * -1 * 100;
def lnln = Log(low("$TRIN/Q")) * -1 * 100;
def lncn = Log(close("$TRIN/Q")) * -1 * 100;
def lnon = Log(open("$TRIN/Q")) * -1 * 100;

def open = (lno + lnon) / 2;
def low = (lnh + lnhn) / 2;
def high = (lnl + lnln) / 2;
plot close = (lnc + lncn) / 2;

#open.SetPaintingStrategy(paintingStrategy = PaintingStrategy.POINTS);
#high.SetPaintingStrategy(paintingStrategy = PaintingStrategy.ARROW_UP);
#low.SetPaintingStrategy(paintingStrategy = PaintingStrategy.ARROW_DOWN);
close.SetPaintingStrategy(paintingStrategy = PaintingStrategy.LINE);

#open.assignvalueColor(if open > close then Color.RED else Color.GREEN);
#high.assignvalueColor(if open > close then Color.RED else Color.GREEN);
#low.assignvalueColor(if open > close then Color.RED else Color.GREEN);
close.AssignValueColor(color = Color.CYAN);
 
Last edited:
Solution

BenTen

Administrative
Staff member
Staff
VIP
Code:
# Weighted Moving Average of $TRIN Index
# Assembled by BenTen at UseThinkScript.com

def price = close("$TRIN");
input length = 5;
input displace = 0;

plot AvgWtd = wma(price, length)[-displace];
AvgWtd.SetDefaultColor(GetColor(1));
 

Skyfly93

New member
VIP
Link 1
https://emini-watch.com/trading-indicators/trin-indicator/

Link 2
https://www.thinkscripter.com/community/index.php?resources/polarized-trin-oscillator.8/

The idea is to create an oscillator based on TRIN that can identify overbought/oversold and divergence. Could anyone help code this? Copy pasted some instructions from Link 1 below:

By making some simple mathematical adjustments to the original TRIN Indicator formula you can make a more intuitive and accurate indicator. Here’s what to do to create a Better TRIN Indicator:

  1. Take the Log of the NYSE TRIN value
  2. Invert this value so negative values are positive and vice versa
  3. Multiply the inverted Log value by 100, and
  4. Repeat for the NASDAQ TRIN data, and RUSSELL TRIN data and average the three values
The chart above shows what the adjusted or Better TRIN Indicator looks like. If you have successfully followed the steps above, the Better TRIN Indicator is easy to interpret at a glance and gives you a better idea of market trends when averaged:

  • Values range between -100 and +100, with 0 as the neutral point
  • Positive values indicate buying and a market in an upswing
  • Negative results indicate selling activity and downward moves in the market
  • Values are balanced, requiring the same amount of buying or selling for the indicator to be +100 or -100 and, therefore, averages are accurate

The TRINS are referenced in TOS as the following: $TRIN, $TRIN/Q, $TRINRL
 

ktp

New member
@Skyfly93 Something like this:
Code:
declare lower;
input aggr = AggregationPeriod.DAY;
input over_bought=75;
input over_sold=-75;
plot trin = (((-100*Log(close("$TRIN", period=aggr)))+(-100*Log(close("$TRIN/Q", period=aggr)))+(-100*Log(close("$TRINRL", period=aggr))))/3);
plot zero=0;
plot ob = over_bought;
plot os = over_sold;
 

ILIKESTOCKS

New member
So I wanted a lower TRIN indicator and found this on the oneDrive. But on March 16th, we spiked to around 15 on the TRIN (just input $TRIN into the ticker field on a chart to see). If I look at this indicator, it does not show that for the same date. Can someone help explain why that would be?

Code starts here....

Code:
#Here is TRIN as lower study. I have inverted it to make it easier to understand, so spike above 2 is overbought (plot will turn red) and spike below 0.5 is oversold #(plot will turn green). It will draw horizontal line at 2 in pink and at 0.5 in light green to indicate overbought and oversold levels.

#In regular TRIN it is upside down, spike above 2 is oversold and spike below 0.5 is overbought.

declare lower;

def UVOL = close(“$UVOL”);
def DVOL = close(“$DVOL”);
def ADV = close(“$ADVN”);
def DECL = close(“$DECN”);

plot TRIN = (DECL/ADV)/(DVOL/UVOL);
TRIN.SetStyle(Curve.FIRM);
TRIN.AssignValueColor(if TRIN >= 2 then Color.RED else if TRIN <= 0.5 then Color.GREEN else Color.GRAY);

plot ZeroLine = 1;
        ZeroLine.AssignValueColor(Color.LIGHT_GRAY);

plot UB = 2;
        UB.AssignValueColor(Color.PINK);

plot LB = 0.5;
        LB.AssignValueColor(Color.LIGHT_GREEN);
Can this shown as labels? or Bubbles on chart?
 

MerryDay

Administrative
Staff member
Staff
VIP

Similar threads

Top