Your interactive trading laboratory!
 • 
17 users online

CNN Fear & Greed Index as an Extension
This is a Feature Request with 4 votes

Hi Glitch,

I love the CNN Fear & Greed Index and so far it works almost perfect for Index trading. What do you think about making an Extension out of it and making it available in Quantacula?

Here's the Tradingview Code I'm using:

//Safe Haven Demand:
safeHavenDemand1 = security ("SPX", "D", (close - close[20]) / close * 100)
safeHavenDemand2 = security ("ZB1!", "D", (close - close[20]) / close * 100)
safeHavenDemand = safeHavenDemand1 - safeHavenDemand2

//Stock Price Breadth:
stockPriceBreadth1 = security ("UVOL", "D", close)
stockPriceBreadth2 = security ("DVOL", "D", close)
stockPriceBreadth3 = stockPriceBreadth1 - stockPriceBreadth2
ema19 = ema(stockPriceBreadth3, 19)
ema39 = ema(stockPriceBreadth3, 39)
osci = ema19-ema39
stockPriceBreadth = cum(osci)

//Market Momentum:
marketMomentum1 = security ("SPX", "D", close)
marketMomentum2 = security ("SPX", "D", sma(close,125))
marketMomentum = (marketMomentum1 - marketMomentum2) / marketMomentum1 * 100

//Stock Price Strenth:
stockPriceStrenth1 = security ("MAHN", "D", ema(close, 5))
stockPriceStrenth2 = security ("MALN", "D", ema(close, 5))
stockPriceStrenth = ema((stockPriceStrenth1 - stockPriceStrenth2) / (stockPriceStrenth1 + stockPriceStrenth2) * 100, 10)

//Put and Call Options:
putCallOptions = security ("USI:PCC", "D", sma(close, 5))

//Junk Bond Demand
junkBondDemand1 = security ("Quandl:ML/USEY|0", "D", close)
junkBondDemand2 = security ("Quandl:ML/USTRI|0", "D", close)
junkBondDemand = junkBondDemand2 - junkBondDemand1

//Market Volatility:
marketVolatility = security ("VIX", "D", close)

//Rank Results
ind_safeHavenDemand = percentrank (safeHavenDemand, 252)
ind_stockPriceBreadth = percentrank (stockPriceBreadth, 252)
ind_marketMomentum = percentrank (marketMomentum, 252)
ind_stockPriceStrenth = percentrank (stockPriceStrenth, 252)
ind_putCallOptions = 100 - percentrank (putCallOptions, 252)
ind_junkBondDemand = 100 - percentrank (junkBondDemand, 252)
ind_marketVolatility = 100 - percentrank (marketVolatility, 252)

fg = (ind_safeHavenDemand + ind_stockPriceBreadth + ind_marketMomentum + ind_stockPriceStrenth + ind_putCallOptions + ind_junkBondDemand + ind_marketVolatility) / 7

plot (fg, linewidth=2, color=black, transp=0)
hline(20, color=black, linestyle=dotted,linewidth=1)
hline(70, color=black, linestyle=dotted,linewidth=1)  
Attachment

Cancel

Responses

USI:PCC would come from the CBOE extension. Would have to make sure we could get the Quandl symbols. Then, anyone using this indicator would need to have the Quandl and CBOE extensions installed as well. CBOE just broke their data format so we first need to repair the CBOE extension.

USI:PCC would come from the CBOE extension. Would have to make sure we could get the Quandl symbols. Then, anyone using this indicator would need to have the Quandl and CBOE extensions installed as well. CBOE just broke their data format so we first need to repair the CBOE extension.

I'm working on this now, but am wondering about:

cum(osci)

From my research, it seems this sums all values of the source data over the history? As such, it would make the indicator sensitive to the starting point of the data. I guess that's OK because plenty of other indicators like OBV do the same thing but just wanted to verify.

I'm working on this now, but am wondering about: [CODE] cum(osci) [/CODE] From my research, it seems this sums all values of the source data over the history? As such, it would make the indicator sensitive to the starting point of the data. I guess that's OK because plenty of other indicators like OBV do the same thing but just wanted to verify.

Here's the cum() help description.

Here's the cum() help description.

Thanks, we're just working on restoring the CBOE extension for the V3 migration, after that's done we should be in a good place to add this to the Community Indicators set :)

Thanks, we're just working on restoring the CBOE extension for the V3 migration, after that's done we should be in a good place to add this to the Community Indicators set :)

I was able to duplicate this TV author's attempt to reverse engineer the GFI but it isn't very close to the original. I'm going to spend a little time and see if I can figure out a closer approximation, they don't publish the precise calculations :) The good news is all of the data is available via QPremium symbols and the Quandl extension (for the junk bonds only).

I was able to duplicate this TV author's attempt to reverse engineer the GFI but it isn't very close to the original. I'm going to spend a little time and see if I can figure out a closer approximation, they don't publish the precise calculations :) The good news is all of the data is available via QPremium symbols and the Quandl extension (for the junk bonds only).

This is my conversion of the TV code into Quantacula. Check it over when you get a chance. I don't think it lines up very closely with the historic FGI chart on the CNN web site so it will need some more investigation as to why.

using Quantacula.Backtest;
using Quantacula.Core;
using Quantacula.Indicators;
using Quantacula.Quandl;
using System.Drawing;

namespace Quantacula
{
    public class MyModel1 : UserModelBase
    {
        //create indicators and other objects here, this is executed prior to the main trading loop
        public override void Initialize(BarHistory bars)
        {
			//safe haven demand
			TimeSeries spx = SymbolData.Series(bars, "$SPX", PriceComponents.Close);
			TimeSeries safeHavenDemand1 = (spx - (spx >> 20)) / spx * 100.0;
			TimeSeries tlt = SymbolData.Series(bars, "TLT", PriceComponents.Close);
			TimeSeries safeHavenDemand2 = (tlt - (tlt >> 20)) / tlt * 100.0;
			TimeSeries safeHavenDemand = safeHavenDemand1 - safeHavenDemand2;

			//stock price breadth
			TimeSeries stockPriceBreadth1 = SymbolData.Series(bars, "$NYSE_ADVN", PriceComponents.Volume);
			TimeSeries stockPriceBreadth2 = SymbolData.Series(bars, "$NYSE_DECLN", PriceComponents.Volume);
			TimeSeries stockPriceBreadth3 = stockPriceBreadth1 - stockPriceBreadth2;
			TimeSeries ema19 = EMA.Series(stockPriceBreadth3, 19);
			TimeSeries ema39 = EMA.Series(stockPriceBreadth3, 39);
			TimeSeries osci = ema19 - ema39;
			TimeSeries stockPriceBreadth = new TimeSeries(bars.DateTimes);
			int idx = osci.FirstValidIndex;
			double cum = 0.0;
			for (int n = idx; n < bars.Count; n++)
			{
				cum += osci[n];
				stockPriceBreadth[n] = cum;
			}

			//market momentum
			TimeSeries marketMomentum1 = SymbolData.Series(bars, "$SPX", PriceComponents.Close);
			TimeSeries marketMomentum2 = SMA.Series(marketMomentum1, 125);
			TimeSeries marketMomentum = (marketMomentum1 - marketMomentum2) / marketMomentum1 * 100.0;

			//stock price strength
			TimeSeries stockPriceStrength1 = SymbolData.Series(bars, "$NYSE_NEWHI", PriceComponents.Close);
			TimeSeries stockPriceStrength2 = SymbolData.Series(bars, "$NYSE_NEWLO", PriceComponents.Close);
			TimeSeries stockPriceStrength = EMA.Series((stockPriceStrength1 - stockPriceStrength2) / (stockPriceStrength1 - stockPriceStrength2) * 100.0, 10);

			//put and call options
			TimeSeries putCallOption = SymbolData.Series(bars, "$TOTALPC", PriceComponents.Close);

			//junk bond demand
			TimeSeries junkBondDemand1 = new QuandlIndicator(bars, "ML", "USEY");
			TimeSeries junkBondDemand2 = new QuandlIndicator(bars, "ML", "USTRI");
			TimeSeries junkBondDemand = junkBondDemand1 - junkBondDemand2;

			//market volatility
			TimeSeries marketVolatility = SymbolData.Series(bars, "$VIX", PriceComponents.Close);

			//rank results
			TimeSeries ind_safeHavenDemand = PctRank.Series(safeHavenDemand, 252);
			TimeSeries ind_stockPriceBreadth = PctRank.Series(stockPriceBreadth, 252);
			TimeSeries ind_marketMomentum = PctRank.Series(marketMomentum, 252);
			TimeSeries ind_stockPriceStrenth = PctRank.Series(stockPriceStrength, 252);
			TimeSeries ind_putCallOptions = PctRank.Series(putCallOption, 252);
			TimeSeries ind_junkBondDemand = PctRank.Series(junkBondDemand, 252);
			TimeSeries ind_marketVolatility = PctRank.Series(marketVolatility, 252);

			TimeSeries fg = (ind_safeHavenDemand + ind_stockPriceBreadth + ind_marketMomentum + ind_stockPriceStrenth + ind_putCallOptions + ind_junkBondDemand + ind_marketVolatility) / 7.0;
			PlotTimeSeries(fg, "CNN Fear/Greed Index", "FG", Color.Red);
        }

        //execute the strategy rules here, this is executed once for each bar in the backtest history
        public override void Execute(BarHistory bars, int idx)
        {
            if (!HasOpenPosition(bars, PositionType.Long))
            {
                //code your buy conditions here
            }
            else
            {
                //code your sell conditions here
            }
        }

        //declare private variables below

    }
}
This is my conversion of the TV code into Quantacula. Check it over when you get a chance. I don't think it lines up very closely with the historic FGI chart on the CNN web site so it will need some more investigation as to why. [CODE] using Quantacula.Backtest; using Quantacula.Core; using Quantacula.Indicators; using Quantacula.Quandl; using System.Drawing; namespace Quantacula { public class MyModel1 : UserModelBase { //create indicators and other objects here, this is executed prior to the main trading loop public override void Initialize(BarHistory bars) { //safe haven demand TimeSeries spx = SymbolData.Series(bars, "$SPX", PriceComponents.Close); TimeSeries safeHavenDemand1 = (spx - (spx >> 20)) / spx * 100.0; TimeSeries tlt = SymbolData.Series(bars, "TLT", PriceComponents.Close); TimeSeries safeHavenDemand2 = (tlt - (tlt >> 20)) / tlt * 100.0; TimeSeries safeHavenDemand = safeHavenDemand1 - safeHavenDemand2; //stock price breadth TimeSeries stockPriceBreadth1 = SymbolData.Series(bars, "$NYSE_ADVN", PriceComponents.Volume); TimeSeries stockPriceBreadth2 = SymbolData.Series(bars, "$NYSE_DECLN", PriceComponents.Volume); TimeSeries stockPriceBreadth3 = stockPriceBreadth1 - stockPriceBreadth2; TimeSeries ema19 = EMA.Series(stockPriceBreadth3, 19); TimeSeries ema39 = EMA.Series(stockPriceBreadth3, 39); TimeSeries osci = ema19 - ema39; TimeSeries stockPriceBreadth = new TimeSeries(bars.DateTimes); int idx = osci.FirstValidIndex; double cum = 0.0; for (int n = idx; n < bars.Count; n++) { cum += osci[n]; stockPriceBreadth[n] = cum; } //market momentum TimeSeries marketMomentum1 = SymbolData.Series(bars, "$SPX", PriceComponents.Close); TimeSeries marketMomentum2 = SMA.Series(marketMomentum1, 125); TimeSeries marketMomentum = (marketMomentum1 - marketMomentum2) / marketMomentum1 * 100.0; //stock price strength TimeSeries stockPriceStrength1 = SymbolData.Series(bars, "$NYSE_NEWHI", PriceComponents.Close); TimeSeries stockPriceStrength2 = SymbolData.Series(bars, "$NYSE_NEWLO", PriceComponents.Close); TimeSeries stockPriceStrength = EMA.Series((stockPriceStrength1 - stockPriceStrength2) / (stockPriceStrength1 - stockPriceStrength2) * 100.0, 10); //put and call options TimeSeries putCallOption = SymbolData.Series(bars, "$TOTALPC", PriceComponents.Close); //junk bond demand TimeSeries junkBondDemand1 = new QuandlIndicator(bars, "ML", "USEY"); TimeSeries junkBondDemand2 = new QuandlIndicator(bars, "ML", "USTRI"); TimeSeries junkBondDemand = junkBondDemand1 - junkBondDemand2; //market volatility TimeSeries marketVolatility = SymbolData.Series(bars, "$VIX", PriceComponents.Close); //rank results TimeSeries ind_safeHavenDemand = PctRank.Series(safeHavenDemand, 252); TimeSeries ind_stockPriceBreadth = PctRank.Series(stockPriceBreadth, 252); TimeSeries ind_marketMomentum = PctRank.Series(marketMomentum, 252); TimeSeries ind_stockPriceStrenth = PctRank.Series(stockPriceStrength, 252); TimeSeries ind_putCallOptions = PctRank.Series(putCallOption, 252); TimeSeries ind_junkBondDemand = PctRank.Series(junkBondDemand, 252); TimeSeries ind_marketVolatility = PctRank.Series(marketVolatility, 252); TimeSeries fg = (ind_safeHavenDemand + ind_stockPriceBreadth + ind_marketMomentum + ind_stockPriceStrenth + ind_putCallOptions + ind_junkBondDemand + ind_marketVolatility) / 7.0; PlotTimeSeries(fg, "CNN Fear/Greed Index", "FG", Color.Red); } //execute the strategy rules here, this is executed once for each bar in the backtest history public override void Execute(BarHistory bars, int idx) { if (!HasOpenPosition(bars, PositionType.Long)) { //code your buy conditions here } else { //code your sell conditions here } } //declare private variables below } } [/CODE]

BTW I just sent the CTO of CNN a message on LinkedIn, let's see if we can get anywhere with getting the actual formula or historical data :)

BTW I just sent the CTO of CNN a message on LinkedIn, let's see if we can get anywhere with getting the actual formula or historical data :)

FWIW, this index is available from the Quandl extension.

FWIW, this index is available from the Quandl extension.

Yes, I did add the indicator to the Quandl extension package. I'll close this FR for now but we can address any lingering concerns and implement any new info that comes to light.

Yes, I did add the indicator to the Quandl extension package. I'll close this FR for now but we can address any lingering concerns and implement any new info that comes to light.
Forum Tips

Please sign in if you want to participate in our forum.

Our forum uses Markdown syntax to format posts.

To embed code snippets, enclose them in [CODE][/CODE] tags.