# Williams’ VIX Fix Indicator for ThinkorSwim

@diazlaz Thanks for posting the code!

I'm wondering if someone knows how to scan for when the vixfix turns grey from yellow? that seems to do well at finding the bottom and the beginning of the next uptrend. Would appreciate it then we could go ahead and backtest. I've only been able to figure out how to scan for when it turns Yellow but that just signifies the beginning of the down trend, rather, I'm looking for the beginning of the next bull run. Would be great, thanks again.

@diazlaz Thanks for posting the code!

I'm wondering if someone knows how to scan for when the vixfix turns grey from yellow? that seems to do well at finding the bottom and the beginning of the next uptrend. Would appreciate it then we could go ahead and backtest. I've only been able to figure out how to scan for when it turns Yellow but that just signifies the beginning of the down trend, rather, I'm looking for the beginning of the next bull run. Would be great, thanks again.
It would seem that the scan is the same for both tops and bottoms.
But when scanning for bottoms, make sure to set :
input plotBottoms = yes; #hint Plot Bottoms if yes or Plots Tops if no.
def wvf = if plotBottoms then ((Highest(close, pd) - low) / (Highest(close, pd))) * 100 else
((Lowest(close, pd) - high) / (Lowest(close, pd))) * 100;

if set to no, it flips the logic and highlights potential tops.

# VIX_FIX v3 Major Update
# Based on Larry Williams' Vix Fix
# Assembled by BenTen at useThinkScript.com

input pd = 22;
input bbl = 20;
input mult = 2.0;
input lb = 50;
input ph = 0.85;
input pl = 1.01;

# Downtrend Criterias
input ltLB = 40;
input mtLB = 14;
input str = 3;

# Williams Vix Fix Formula
def wvf = ((highest(close, pd) - low) / (highest(close, pd))) * 100;
def sDev = mult * stdev(wvf, bbl);
def midLine = SimpleMovingAvg(wvf, bbl);
def lowerBand = midLine - sDev;
def upperBand = midLine + sDev;
def rangeHigh = (highest(wvf, lb)) * ph;

# Filtered Bar Criteria
def upRange = low > low[1] and close > high[1];
def upRange_Aggr = close > close[1] and close > open[1];
# Filtered Criteria
def filtered = ((wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and(wvf<upperBand and wvf<rangeHigh));
def filtered_Aggr = (wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]);

def alert1 = wvf >= upperBand or wvf >= rangeHigh;
def alert2 = (wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh);
def alert3 = upRange and close > close[str] and (close < close[ltLB] or close < close[mtLB]) and filtered;
def alert4 = upRange_Aggr and close > close[str] and (close < close[ltLB] or close < close[mtLB]) and filtered_Aggr;

signal1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
signal1.SetDefaultColor(Color.magenta);

signal2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
signal2.SetDefaultColor(Color.blue);

plot signal3 = ((wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh));
signal3.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
signal3.SetDefaultColor(Color.cyan);

plot signal4 = (wvf >= upperBand or wvf >= rangeHigh);
signal4.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
signal4.SetDefaultColor(Color.lime);
The blue Arrow Signal #2 doesn't appear for any stocks or futures is there an error with this code? Can someone clarify?

# VIX_FIX v3 Major Update
# Based on Larry Williams' Vix Fix
# Assembled by BenTen at useThinkScript.com

input pd = 22;
input bbl = 20;
input mult = 2.0;
input lb = 50;
input ph = 0.85;
input pl = 1.01;

# Downtrend Criterias
input ltLB = 40;
input mtLB = 14;
input str = 3;

# Williams Vix Fix Formula
def wvf = ((highest(close, pd) - low) / (highest(close, pd))) * 100;
def sDev = mult * stdev(wvf, bbl);
def midLine = SimpleMovingAvg(wvf, bbl);
def lowerBand = midLine - sDev;
def upperBand = midLine + sDev;
def rangeHigh = (highest(wvf, lb)) * ph;

# Filtered Bar Criteria
def upRange = low > low[1] and close > high[1];
def upRange_Aggr = close > close[1] and close > open[1];
# Filtered Criteria
def filtered = ((wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and(wvf<upperBand and wvf<rangeHigh));
def filtered_Aggr = (wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]);

def alert1 = wvf >= upperBand or wvf >= rangeHigh;
def alert2 = (wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh);
def alert3 = upRange and close > close[str] and (close < close[ltLB] or close < close[mtLB]) and filtered;
def alert4 = upRange_Aggr and close > close[str] and (close < close[ltLB] or close < close[mtLB]) and filtered_Aggr;

signal1.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
signal1.SetDefaultColor(Color.magenta);

signal2.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
signal2.SetDefaultColor(Color.blue);

plot signal3 = ((wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh));
signal3.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
signal3.SetDefaultColor(Color.cyan);

plot signal4 = (wvf >= upperBand or wvf >= rangeHigh);
signal4.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
signal4.SetDefaultColor(Color.lime);

Post #4 has this code for grabbing the tops could someone confirm that this is accurate I had to add a (1) to def wvf1 could you please verify?

This doesn't work
input plotBottoms = no; #hint Plot Bottoms if yes or Plots Tops if no.
def wvf = if plotBottoms then ((Highest(close, pd) - low) / (Highest(close, pd))) * 100 else
((Lowest(close, pd) - high) / (Lowest(close, pd))) * 100;

This works ??
input plotBottoms = no; #hint Plot Bottoms if yes or Plots Tops if no.
def wvf1 = if plotBottoms then ((Highest(close, pd) - low) / (Highest(close, pd))) * 100 else
((Lowest(close, pd) - high) / (Lowest(close, pd))) * 100;

The Williams’ VIX Fix indicator helps to measure volatility for individual stocks, similar to how the VIX does for the S&P 500 Index. Williams Vix Fix also includes a 20 Bollinger Bands indicating extremes in the signal line.

Some traders believe the Vix Fix indicator can find market bottoms in all instruments.

### thinkScript Code

Rich (BB code):
``````#Dilbert_VixFix
# V1.0  - 052816 - Dilbert - 1st code cut
# VixFix is a pretty close approximation to the standard VIX or implied volatility.  It can be used on intraday chart aggregations, and on symbols that do not have options.  When VixFIX spikes high it provides some pretty good buy signals.
input OverSold = .1;  # .1 good for SPY 1 day 1 minute chart
input OverBought = .01;  # .01 good for SPY 1 day 1 minute chart
input LengthVF = 22;
input LengthMA = 20;
declare lower;
def C = close;
def L = low;
plot VixFix = (Highest (C, LengthVF) - L) / (Highest (C, LengthVF)) * 100;
#VixFix.AssignValueColor(Color.GREEN);
plot OS = OverSold;
OS.AssignValueColor(Color.CYAN);
plot OB = OverBought;
OB.AssignValueColor(Color.CYAN);

# BollingerBands code

input ShowBollingerBands = No;
input displace = 0;
input BBlength = 20;
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageType = AverageType.Simple;

def sDev = stdev(data = VixFix[-displace], length = BBlength);
def MidLine = MovingAverage(averageType, data = VixFix[-displace], length = BBlength);

def LowerBand = MidLine + num_Dev_Dn * sDev;
def UpperBand = MidLine + num_Dev_Up * sDev;
plot LB = if ShowBollingerBands then LowerBand else Double.NaN;
plot UB = if ShowBollingerBands then UpperBand else Double.NaN;
LB.SetDefaultColor(GetColor(0));
UB.SetDefaultColor(GetColor(5));

VixFix.AssignValueColor(if VixFix > UpperBand then Color.Green else Color.Red);

input corrLength = 20;
def correlationWith = ImpVolatility();

plot CorrelationIV = correlation(VixFix, correlationWith, corrLength);
CorrelationIV.SetDefaultColor(color.light_gray);
addlabel(yes, "Correlation w IV: "+ correlationIV,color.light_gray);``````

https://tos.mx/yAq7s5

### thinkScript Code (Mobius)

Rich (BB code):
``````# Williams_Vix_Fix
# Mobius
# V01.2016
declare lower;

input n = 22;
plot WVF = (Highest (Close, n) - Low) / (Highest(Close, n)) * 100;
WVF.SetDefaultColor(Color.Cyan);

plot mean = inertiaAll(WVF);
mean.SetDefaultColor(Color.Gray);

# End Code Williams Vix Fix``````

https://tos.mx/5HigXD
great indicator i just love it, thank you very much!! a quick question, in this script i think is missing the ORANGE candle, we have the cyan entry, the magenta entry, lime bottom, but we are missing the ORANGE candle entry. can someone check if is just me? thanks in advance

Last edited by a moderator:
great indicator i just love it, thank you very much!! a quick question, in this script i think is missing the ORANGE candle, we have the cyan entry, the magenta entry, lime bottom, but we are missing the ORANGE candle entry. can someone check if is just me? thanks in advance
@BenTen could you update us on this

great indicator i just love it, thank you very much!! a quick question, in this script i think is missing the ORANGE candle, we have the cyan entry, the magenta entry, lime bottom, but we are missing the ORANGE candle entry. can someone check if is just me? thanks in advance
@BenTen could you update us on this
There is no "orange candle" in the post @FOTM_8888 referenced.

Post #4 has this code for grabbing the tops could someone confirm that this is accurate I had to add a (1) to def wvf1 could you please verify?
You added the definition for wvf to a script that already had a definition of wvf. Which gave you an error.
Your workaround is valid. By adding wvf1, you avoided the duplicate statement error.
What you should have done:

Replace this:
Rich (BB code):
``````# Williams Vix Fix Formula
def wvf = ((highest(close, pd) - low) / (highest(close, pd))) * 100;``````

With this:
Rich (BB code):
``````# Williams Vix Fix Formula
input plotBottoms = no; #hint Plot Bottoms if yes or Plots Tops if no.
def wvf = if plotBottoms then ((Highest(close, pd) - low) / (Highest(close, pd))) * 100 else
((Lowest(close, pd) - high) / (Lowest(close, pd))) * 100;``````

Last edited:
You added the definition for wvf to a script that already had a definition of wvf. Which gave you an error.
Your workaround is valid. By adding wvf1, you avoided the duplicate statement error.
What you should have done:

Replace this:
Rich (BB code):
``````# Williams Vix Fix Formula
def wvf = ((highest(close, pd) - low) / (highest(close, pd))) * 100;``````

With this:
Rich (BB code):
``````# Williams Vix Fix Formula
input plotBottoms = no; #hint Plot Bottoms if yes or Plots Tops if no.
def wvf = if plotBottoms then ((Highest(close, pd) - low) / (Highest(close, pd))) * 100 else
((Lowest(close, pd) - high) / (Lowest(close, pd))) * 100;``````
Great Job.. a quick question.. it is possible create this indicator for a TOP? thanks in advance

Great Job.. a quick question.. it is possible create this indicator for a TOP? thanks in advance
I have played around with this to see if the Code has worked for tops as Post#4 @diazlaz suggested he says it does a great job please post the code ? that you have used the current condition added as you suggested has not resulted in the same setups as buying the dips.

Hi,

I am trying to make an upper chart label but it fails. What am I missing here? Thanks

Code:
``````# EMA
input fastLength = 9;
input slowLength = 21;
def fastEMAOne = ExpAverage(close, fastLength);
def slowEMAOne = ExpAverage(close, slowLength);

# VIX
input n = 22;
def WVF = (Highest (Close, n) - Low) / (Highest(Close, n)) * 100;
def mean = inertiaAll(WVF);

def vix_bull = WVF crosses below mean;
def vix_bear = WVF crosses above mean;

#####
AddLabel(yes, "Put", if  fastEMAOne < slowEMAOne and vix_bear then Color.RED else Color.GRAY);

AddLabel(yes, "Call", if fastEMAOne > slowEMAOne and vix_bull then Color.GREEN else Color.GRAY);``````

I am trying to make an upper chart label but it fails. What am I missing here? Thanks
The inertiaAll function is the problem.
When a length is not provided for this function the plot calculation assumes the length of the chart.
When you attempt to use the inertiaAll function in a label, a watchlist, or a scan there is no 'plot'. So there is no "length of the chart" to assume.

Providing a length for ToS 'full range' functions when they are used in a label, a watchlist, or a scan, 'usually' resolves the issue.
Reading through this thread, the mean length for the inertiaAll that members find favorable seems to be 50 for the daily chart.

input gotarrows = yes ; turn on / off to your preference
input meanlength = 50 ; set to the best length for the aggregation that you are using.

EMA VIX Label ver 2.0
FYI: inertiaAll has other problems that will lag with your results.

Ruby:
``````# EMA VIX Label ver 2.0

input gotarrows = yes ;  # turn on /off  to your preference
input fastLength = 9;
input slowLength = 21;
def fastEMAOne = ExpAverage(close, fastLength);
def slowEMAOne = ExpAverage(close, slowLength);

# VIX
input n = 20;
input meanlength = 50 ;  # set to the best length for the aggregation that you are using.  default of 50 works for daily

def WVF = (Highest (Close, n) - Low) / (Highest(Close, n)) * 100;
def mean = inertiaAll(WVF,meanlength);

def vix_bull =  WVF crosses below mean ;
def vix_bear = WVF crosses above mean;
#####
#Charting and Formatting
AddLabel(yes, "Put", if  fastEMAOne < slowEMAOne and vix_bear then Color.RED else Color.GRAY);
AddLabel(yes, "Call", if fastEMAOne > slowEMAOne and vix_bull then Color.GREEN else Color.GRAY);
#####
plot put_arrow = if  gotarrows and fastEMAOne < slowEMAOne and vix_bear then low else double.NaN ;
put_arrow.SetPaintingStrategy(PaintingStrategy.ARROW_up);
put_arrow.SetDefaultColor(color.blue) ;
put_arrow.SetLineWeight(1);

plot call_arrow = if gotarrows and fastEMAOne > slowEMAOne and vix_bull then high else double.NaN ;
call_arrow.SetPaintingStrategy(PaintingStrategy.ARROW_down);
call_arrow.SetDefaultColor(color.magenta) ;
call_arrow.SetLineWeight(1);

plot scan_bear = fastEMAOne < slowEMAOne and vix_bear  ;
plot scan_bull = fastEMAOne > slowEMAOne and vix_bull  ;
scan_bear.hide();
scan_bull.hide();``````

Call Scan: http://tos.mx/00gFlAl
Put Scan: http://tos.mx/QDe6WVs

providing a length for ToS 'full range' functions

Last edited:
The inertiaAll function is the problem.
When a length is not provided for this function the plot calculation assumes the length of the chart.
When you attempt to use the inertiaAll function in a label, a watchlist, or a scan there is no 'plot'. So there is no "length of the chart" to assume.

Providing a length for ToS 'full range' functions when they are used in a label, a watchlist, or a scan, 'usually' resolves the issue.
Reading through this thread, the mean length for the inertiaAll that members find favorable seems to be 50 for the daily chart.

input gotarrows = yes ; turn on / off to your preference
input meanlength = 50 ; set to the best length for the aggregation that you are using.

EMA VIX Label ver 2.0
FYI: inertiaAll has other problems that will lag with your results.

Ruby:
``````# EMA VIX Label ver 2.0

input gotarrows = yes ;  # turn on /off  to your preference
input fastLength = 9;
input slowLength = 21;
def fastEMAOne = ExpAverage(close, fastLength);
def slowEMAOne = ExpAverage(close, slowLength);

# VIX
input n = 20;
input meanlength = 50 ;  # set to the best length for the aggregation that you are using.  default of 50 works for daily

def WVF = (Highest (Close, n) - Low) / (Highest(Close, n)) * 100;
def mean = inertiaAll(WVF,meanlength);

def vix_bull =  WVF crosses below mean ;
def vix_bear = WVF crosses above mean;
#####
#Charting and Formatting
AddLabel(yes, "Put", if  fastEMAOne < slowEMAOne and vix_bear then Color.RED else Color.GRAY);
AddLabel(yes, "Call", if fastEMAOne > slowEMAOne and vix_bull then Color.GREEN else Color.GRAY);
#####
plot put_arrow = if  gotarrows and fastEMAOne < slowEMAOne and vix_bear then low else double.NaN ;
put_arrow.SetPaintingStrategy(PaintingStrategy.ARROW_up);
put_arrow.SetDefaultColor(color.blue) ;
put_arrow.SetLineWeight(1);

plot call_arrow = if gotarrows and fastEMAOne > slowEMAOne and vix_bull then high else double.NaN ;
call_arrow.SetPaintingStrategy(PaintingStrategy.ARROW_down);
call_arrow.SetDefaultColor(color.magenta) ;
call_arrow.SetLineWeight(1);

plot scan_bear = fastEMAOne < slowEMAOne and vix_bear  ;
plot scan_bull = fastEMAOne > slowEMAOne and vix_bull  ;
scan_bear.hide();
scan_bull.hide();``````

Call Scan: http://tos.mx/00gFlAl
Put Scan: http://tos.mx/QDe6WVs

providing a length for ToS 'full range' functions
Thanks for the details answer MD. I was interested to use it for intraday scalp strategy but for some reason it is not working on short time intervals like 3min or 5min. I really appreciate your help.

Thanks for the details answer MD. I was interested to use it for intraday scalp strategy but for some reason it is not working on short time intervals like 3min or 5min. I really appreciate your help.
input gotarrows = yes ; turn on / off to your preference
input meanlength= set to the best length for the aggregation that you are using.

A VERY RUDIMENTARY review of online VIX scalping strategies suggest a meanlength = 10 ** might be a good place to start refining your length. You need to adjust the meanlength to each aggregation that you trade. The meanlength of 10 on the 5 minute seems to fire a little early and still needs adjusting. This is just an EXAMPLE to illustrate that your study does work on lower timeframes.

If you are able to optimize this to your strategy and you want to give back to the community; come back and report what lengths work best and how you are using it.

Ruby:
``````# EMA VIX Label ver 2.0

input gotarrows = yes ;  # turn on /off  to your preference
input fastLength = 9;
input slowLength = 21;
def fastEMAOne = ExpAverage(close, fastLength);
def slowEMAOne = ExpAverage(close, slowLength);

# VIX
input n = 20;
input meanlength = 10 ;  # set to the best length for the aggregation that you are using.  default of 50 works for daily

def WVF = (Highest (Close, n) - Low) / (Highest(Close, n)) * 100;
def mean = inertiaAll(WVF,meanlength);

def vix_bull =  WVF crosses below mean ;
def vix_bear = WVF crosses above mean;
#####
#Charting and Formatting
AddLabel(yes, "Put", if  fastEMAOne < slowEMAOne and vix_bear then Color.RED else Color.GRAY);
AddLabel(yes, "Call", if fastEMAOne > slowEMAOne and vix_bull then Color.GREEN else Color.GRAY);
#####
plot put_arrow = if  gotarrows and fastEMAOne < slowEMAOne and vix_bear then low else double.NaN ;
put_arrow.SetPaintingStrategy(PaintingStrategy.ARROW_up);
put_arrow.SetDefaultColor(color.blue) ;
put_arrow.SetLineWeight(1);

plot call_arrow = if gotarrows and fastEMAOne > slowEMAOne and vix_bull then high else double.NaN ;
call_arrow.SetPaintingStrategy(PaintingStrategy.ARROW_down);
call_arrow.SetDefaultColor(color.magenta) ;
call_arrow.SetLineWeight(1);

plot scan_bear = fastEMAOne < slowEMAOne and vix_bear  ;
plot scan_bull = fastEMAOne > slowEMAOne and vix_bull  ;
scan_bear.hide();
scan_bull.hide();``````

I plan on releasing this sometime next week, but @diazlaz was kind enough to port the first version to ThinkorSwim yesterday so I thought it would be fair to share this now, so there is no delay on the development of this indicator.

I recommend watching this video before using the indicator: http://vimeopro.com/user32804960/tradingview-indicators/video/115973132

### thinkScript Code

Code:
``````# VIX_FIX v3 Major Update
# Based on Larry Williams' Vix Fix
# Assembled by BenTen at useThinkScript.com

input pd = 22;
input bbl = 20;
input mult = 2.0;
input lb = 50;
input ph = 0.85;
input pl = 1.01;

# Downtrend Criterias
input ltLB = 40;
input mtLB = 14;
input str = 3;

# Williams Vix Fix Formula
def wvf = ((highest(close, pd) - low) / (highest(close, pd))) * 100;
def sDev = mult * stdev(wvf, bbl);
def midLine = SimpleMovingAvg(wvf, bbl);
def lowerBand = midLine - sDev;
def upperBand = midLine + sDev;
def rangeHigh = (highest(wvf, lb)) * ph;

#  Filtered Bar Criteria
def upRange = low > low[1] and close > high[1];
def upRange_Aggr = close > close[1] and close > open[1];
#  Filtered Criteria
def filtered = ((wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and(wvf<upperBand and wvf<rangeHigh));
def filtered_Aggr = (wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]);

def alert1 = wvf >= upperBand or wvf >= rangeHigh;
def alert2 = (wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh);
def alert3 = upRange and close > close[str] and (close < close[ltLB] or close < close[mtLB]) and filtered;
def alert4 = upRange_Aggr and close > close[str] and (close < close[ltLB] or close < close[mtLB]) and filtered_Aggr;

AssignPriceColor(if alert4 then color.magenta else if alert3 then color.orange else if ((wvf[1] >= upperBand[1] or wvf[1] >= rangeHigh[1]) and (wvf < upperBand and wvf < rangeHigh)) then color.cyan else if (wvf >= upperBand or wvf >= rangeHigh) then color.lime else color.white);``````
When was the last update? could you include date to the script?

87k+ Posts
393 Online

## The Market Trading Game Changer

Join 2,500+ subscribers inside the useThinkScript VIP Membership Club
• Exclusive indicators
• Proven strategies & setups
• Private Discord community
• Exclusive members-only content
• 1 full year of unlimited support

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?