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")) *...
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);
 

Join useThinkScript to post your question to a community of 21,000+ developers and traders.

@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
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));
 
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
 
@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;
 
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?
 

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
375 Online
Create Post

Similar threads

Similar threads

The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
  • Exclusive indicators
  • Proven strategies & setups
  • Private Discord community
  • ‘Buy The Dip’ signal alerts
  • Exclusive members-only content
  • Add-ons and resources
  • 1 full year of unlimited support

Frequently Asked Questions

What is useThinkScript?

useThinkScript is the #1 community of stock market investors using indicators and other tools to power their trading strategies. Traders of all skill levels use our forums to learn about scripting and indicators, help each other, and discover new ways to gain an edge in the markets.

How do I get started?

We get it. Our forum can be intimidating, if not overwhelming. With thousands of topics, tens of thousands of posts, our community has created an incredibly deep knowledge base for stock traders. No one can ever exhaust every resource provided on our site.

If you are new, or just looking for guidance, here are some helpful links to get you started.

What are the benefits of VIP Membership?
VIP members get exclusive access to these proven and tested premium indicators: Buy the Dip, Advanced Market Moves 2.0, Take Profit, and Volatility Trading Range. In addition, VIP members get access to over 50 VIP-only custom indicators, add-ons, and strategies, private VIP-only forums, private Discord channel to discuss trades and strategies in real-time, customer support, trade alerts, and much more. Learn all about VIP membership here.
How can I access the premium indicators?
To access the premium indicators, which are plug and play ready, sign up for VIP membership here.
Back
Top