Fear and Greed Index Candlesticks
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © barnabygraham

// 1 to 7 are the original variables which this indicator is based upon. I've added others to add range, diversification and to improve the greed signals so that they (are more likely to) occur before downward moves. 

//@version=5
indicator("Fear and Greed Index Candlesticks", overlay=false, timeframe="D", timeframe_gaps=true)
length=input(1, "Length (Smoothing)")
LengthSMA=input(125,"Length of SMAs")
GreedCeiling = input(100,"Greed Ceiling")
GreedFloor = input(0,"Greed Floor")
FearCeiling = input(0,"Fear Ceiling")
FearFloor = input(-100,"Fear Floor")

// 1. Advancers minus decliners - the original index uses NYSE 52 week high/lows. That's now variable #14.
ADD = request.security('ADD', "D", close)
ADD2 = ADD/30
ADDma= ta.ema(ADD2,5)
ADDavg=((ADD2*2)+ADDma)/3
ADD3 = ADDavg > 100 ? 100 : ADDavg < -100 ? -100 : ADDavg
//plot(ADD3)

// 2. Volume Breadth - VOLD
VOLD = request.security('VOLD', 'D', hlc3)
VOLD2 = VOLD/20000000
VOLDma= ta.ema(VOLD2,5)
VOLDavg=((VOLD2*2)+VOLDma)/3
VOLD3 = VOLDavg > 100 ? 100 : VOLDavg < -100 ? -100 : VOLDavg
//plot(VOLD3)

// 3. Market momentum - SPY vs simple moving average
SPY = request.security('SPY', 'D', close)
Spy125sma = ta.sma(SPY,LengthSMA)
momentum = ((SPY/Spy125sma)-0.95)*400
momo = momentum > 100 ? 100 : momentum < -100 ? -100 : momentum
//plot(momo)

// 4. Put to Call ratio - Ticker 'PC' occasionally doesn't work - (this may be the cause if the script breaks) if so, and you want results now, you can replace PC with PCSP or any other PUT:CALL ratio symbol of your choice. 
PC = request.security('PC', 'D', close)
PC2 = ((PC*100)-100)*-1.5
PC3 = PC2 > 100 ? 100 : PC2 < -100 ? 100 : PC2
PC4 = na(PC3) ? 0 : PC3
//plot(PC4)

// 5. Safe haven demand; stocks vs bonds
TLT = request.security('TLT','D',close)
TLTma = ((-TLT/ta.sma(-TLT,LengthSMA))*-800)+800
TLT2 = na(TLTma) ? 0 : TLTma
SvB = (TLT2 + momentum)/2
//plot(SvB)

// 6. HYG vs TLT, high yeild vs low yeild
HYG2 = request.security('HYG','D',close)
HYG = na(HYG2) ? 0 : HYG2
HYGma = ((HYG/ta.sma(HYG,LengthSMA))*800)-800
HTG2 = na(HYGma) ? 0 : HYGma
HvL = HTG2+TLT2 > 100 ? 100 : HTG2+TLT2 < -100 ? -100 : HTG2+TLT2
//(HvL)

// 7. VIX - Volatility
VIX = request.security('VIX', 'D', close)
VIX2=(((VIX-10)*5)-100)*-1
VIX3 = VIX2 > 100 ? 100 : VIX2 < -100 ? -100 : VIX2
//plot(VIX3)

// 8. Risk Sentiment - XBI vs XLP; Biotech vs staples
XBI = request.security('XBI','D',close)
XLP = request.security('XLP','D',close)
xlp50sma = ta.sma(XLP,LengthSMA)
xlpmomentum = ((XLP/xlp50sma)-0.95)*400
xlpmomo2 = xlpmomentum > 100 ? 100 : xlpmomentum < -100 ? -100 : xlpmomentum
XBI50sma = ta.sma(XBI,LengthSMA)
XBImomentum = ((XBI/XBI50sma)-0.95)*400
XBImomo = XBImomentum > 100 ? 100 : XBImomentum < -100 ? -100 : XBImomentum
XVIvsXLP = XBImomo-xlpmomo2
//plot(XVIvsXLP)

// 9.  VUG vs VTV; growth vs value
VUG = request.security('VUG','D',close)
VTV = request.security('VTV','D',close)
GvV = (ta.roc(VTV,30)+ta.roc(VUG,30))*5
GvVz= GvV > 100 ? 100 : GvV < -100 ? -100 : GvV
GvVzFin=na(GvVz) ? 0 : GvVz
//plot(GvVzFin)

// 10. DXY rate of change
DXY = request.security('DXY', 'D', close)
DXYROC=ta.roc(DXY,100)*-5
DXYz = DXYROC > 100 ? 100 : DXYROC < -100 ? -100 : DXYROC
//plot(DXYz)

// 11. Aussie Dollar rate of change
AUDUSD = request.security('AUDUSD','D',close)
AUDROC = ta.roc(AUDUSD,69)*5
AUDz = AUDROC > 100 ? 100 : AUDROC < -100 ? -100 : AUDROC
//plot(AUDz)


// 12. SPY / VIX 10-day correlation - Early greed signals - (I felt this indicator was lacking appropriate greed signals before adding these)
SPYVIXa=ta.correlation(SPY,VIX,10)
SPYVIX10=(((SPYVIXa)*69)+60)
SPYVIXa10=SPYVIX10 > 100 ? 100 : SPYVIX10 < -100 ? -100 : SPYVIX10
//plot(SPYVIXa10)


// 13. SPY / VIX 20-day correlation - Early greed signals - (I felt this indicator was lacking appropriate greed signals before adding these)
SPYVIXb=ta.correlation(SPY,VIX,20)
SPYVIX20=(((SPYVIXb)*69)+60)
SPYVIXb20=SPYVIX20 > 100 ? 100 : SPYVIX20 < -100 ? -100 : SPYVIX20
//plot(SPYVIXb20)


// 14. NYSE 52 week highs vs 52 week lows
HIGN = request.security('HIGN','D',close)
LOWN = request.security('LOWN','D',close)
HIGNSMA = ta.sma(HIGN,1000)
LOWNSMA = ta.sma(LOWN,1000)
HIGNr = (HIGN/HIGNSMA)*15
LOWNr = (LOWN/LOWNSMA)*-5
HighsAndLows=(HIGNr+LOWNr)
HisLows=HighsAndLows > 100 ? 100 : HighsAndLows < -100 ? -100 : HighsAndLows
// plot(HisLows)

// 15. SPY Short Volume
SSV = request.security('SPY_SHORT_VOLUME','D',close)
SSVsma=ta.sma(SSV,LengthSMA)
SSVf=(SSV/SSVsma)
SSVf2 = na(SSVf) ? 0 : ((SSVf*-30)+30)
SSVf3=SSVf2 > 1 ? SSVf2*5 : SSVf2 < -100 ? -100 : SSVf2
//plot(SSVf3)

// 16. % of stocks above/below moving averages
Per5MA  = request.security('MMFD','D',close)
Per20MA = request.security('MMTW','D',close)
Per50MA = request.security('MMFI','D',close)
Per100MA= request.security('MMOH','D',close)
Per150MA= request.security('MMOF','D',close)
Per200MA= request.security('MMTH','D',close)
PerAverage=(Per5MA+Per20MA+Per50MA+Per100MA+Per150MA+Per200MA)/6
PerFin=na(PerAverage) ? 0 : (PerAverage*2)-100
//plot(PerFin)

// 17. McClellan Oscillator
ai = request.security('ADVN','D',close)
di = request.security('DECN','D',close)
rana=1000 * (ai-di)/(ai+di)
e1=ta.ema(rana, 19)
e2=ta.ema(rana, 39)
mo=e1-e2
mcclellan = mo > 100 ? 100 : mo < -100 ? -100 : mo
//plot(mcclellan)

// // 18. this is just an idea for now and may be better to use GS or some other large investment bank.... let me know if you have any ideas about this
// IBKR = request.financial('NASDAQ:IBKR', 'TOTAL_LIABILITIES' ,'FQ', barmerge.gaps_on)
// IBKRSMA = (ta.ema(IBKR,2))
// IBKRfin = IBKR/IBKRSMA
// IBKRfin2=ta.highest((((IBKRfin)-1.01)*2000),10)
// plot(IBKRfin2)

subTotal = ((ADD3 + VOLD3 + momo + PC4 + SvB + HvL + VIX3 + XVIvsXLP + GvVzFin + DXYz + AUDz + SPYVIXa10 + SPYVIXb20 + HisLows + SSVf3 + PerFin + mcclellan) / 8)
Total = subTotal > 100 ? 100 : subTotal < -100 ? -100 : subTotal
Final = ta.ema(Total,length)


//coloring method below
FearGradient = color.from_gradient(Final, FearFloor, FearCeiling, #17CC00, color.new(#17CC00,100))
GreedGradient= color.from_gradient(Final, GreedFloor, GreedCeiling, color.new(#FF0000,100), #FF0000)

barcolor(Final > 0 ? GreedGradient : FearGradient)