VolumeFlow/DirectionFE Signal indicator for the price window

Pelonsax

Pelonsax

Active member
VIP
Hi guys. For my first contribution, I want to share this arrow study that I wrote based on VFI (which I recoded in order to add a signal line). I started using OBVModified and I liked it but I like VFI better for spike dampening, so I switched. The next component takes the direction of the instrument into account using 13EMA. Then I added a Fractal Energy confirmation signal. The basic red an green arrows are when VFI(1, 10) is over the signal line and the direction is above or below the 13EMA. The FE portion is what I consider to be a confirmation that looks at whether FE(14) is above or below a threshold of 50. I have been playing around with adding an ADX filter for chop but it loses some of the good signals. Like everything else, this is not meant to be used as a primary trigger to enter or exit, but it can provide a valuable layer of situational awareness. It gets very good signals on the 1 minute chart when there is a clear trend forming or present, particularly the FE confirmation signals.

Basic signals are green up arrow on the bottom and red down arrow on top. FE confirmation signals are meant to appear as a large cyan down wedge on the bottom (so that it enhances the look of the up arrow) and a large magenta up wedge on top.

I have also added a candle color component which can toggle between green, red and yellow (for signals that are in disagreement) or simply green and red. If you already have a candle color study you like, you can just hashtag that part out. Here is a Picture of the simple indicator.

To my knowledge, every indicator repaints to a certain degree in live action. However, I have not seen this indicator repaint beyond the one candle that it is on, maaaaybe the following candle. I believe because of the nature of the indicator that it could produce a decent strategy study, but I have not recoded it for that which I believe would be necessary. This is still in early stages, therefore. Here is the link to the indicator:

https://tos.mx/CxBS7OF
Here is the full code:

Code:
###CUSTOMIZABLE VFI DIRECTION with FE###

###Ramon Del Villar AKA Pelonsax on useThinkScript###

declare upper;

###Fractal Energy Portion###
###The lower the number, the more linear the price movement, the higher the number, the more non-linear (CHOP).###
###Value of 100 shows all; Value of 0 shows none###

input FEPeriod = 14;
input FEThreshold = 50;

def sumTR = Sum (TrueRange(high, close, low), FEPeriod);
def HMax =  Highest (high, FEPeriod);
def LMax =  Lowest (low, FEPeriod);

def FE = 100 * Log (sumTR / (HMax - LMax)) / Log(FEPeriod);

def FEyes = if FE <= FEThreshold then 1 else 0;


###VFI Portion beings###

input VFIlength = 20;
###Number of bars used to calculate VFI###

input maxVolumeCutOff = 2.5;
###Coefficient used in calculation of “Cut Off” value. Lower values mean stronger damping of volume spikes###

Assert(maxVolumeCutOff > 0, "'max volume cut off' must be positive: " + maxVolumeCutOff);

def cutOff = 0.2 * StDev(Log(hlc3) - Log(hlc3[1]), 30) * close;
def hlcChange = hlc3 - hlc3[1];
def avgVolume = Average(volume, 30)[1];
def minVolume = Min(volume, avgVolume * maxVolumeCutOff);
def dirVolume = if hlcChange > cutOff
    then minVolume
    else if hlcChange < -cutOff
        then -minVolume
        else 0;

def VFI = ExpAverage(Sum(dirVolume, VFIlength) / avgVolume, 3);
def ZeroLine = 0;

input VFIMlength = 1;
input VFIMsignal = 10;
input VFIaverageType = AverageType.SIMPLE;

def VFIM = MovingAverage(VFIaverageType, VFI, VFIMlength);
def Signal = MovingAverage(VFIaverageType, VFIM, VFIMsignal);


###Price Window portion begins###
input EMA = 13;
def EMA13 = ExpAverage(close, EMA);

#1 - crosses above EMA13, 2 - above EMA13, 3 - crossing below EMA13, 4 - below EMA13

def direction = if close > EMA13 and close[1] <= EMA13 then 1 else if low > EMA13  then 2 else if close < EMA13 and close[1] >= EMA13 then 3 else 4;


###Variable Arrow Portion Begins###
###################################

def green = if VFIM > Signal and direction == 2 then 1 else 0;
def red = if VFIM < Signal and high < EMA13 then 1 else 0;
def yellow = if green == 0 and red == 0 then 1 else 0;

###Arrow ME DIRECTION###

plot Buy = if green > 0 and green[1] == 0 and high[1] > high[3] then 1 else 0;
Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
Buy.SetDefaultColor(color.GREEN);
Buy.SetLineWeight(1);

plot Sell = if red > 0 and red[1] == 0 and low[1] < low[3] then 1 else 0;
Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
Sell.SetDefaultColor(color. RED);
Sell.SetLineWeight(1);

###Arrow ME DIRECTION WITH FE###

input Buy_with_FE = yes;
plot FE_Buy = if FEyes > 0 and Buy > 0 then 1 else 0;
FE_Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_DOWN);
FE_Buy.SetDefaultColor(color.CYAN);
FE_Buy.SetLineWeight(5);
FE_Buy.SetHiding(!Buy_with_FE);

input Sell_with_FE = yes;
plot FE_Sell = if FEyes > 0 and Sell > 0 then 1 else 0;
FE_Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_UP);
FE_Sell.SetDefaultColor(color.MAGENTA);
FE_Sell.SetLineWeight(5);
FE_Sell.SetHiding(!Sell_with_FE);

###Candle Color###
input Candle_Chop_Yellow = yes;
AssignPriceColor(if VFIM > Signal and direction == 2 then Color.GREEN else if VFIM < Signal and direction == 4 then Color.RED else if Candle_Chop_Yellow then Color.YELLOW else color.CURRENT);

###End of Code###
 
K

kelbadawi

New member
Looks great will try it tomorrow thank you so much. What’s the best approach for a call option scenario wait for the close of the candle? How soon does the arrow pop? Or do u wait for the confirmation fe signal before entering? Do u recommend to sell wen the down trend arrow appear? @Pelonsax
 
R

raynzer

New member
VIP
Hi, everyone!

You are the experts, and I could really use your help with a custom watchlist column. @horserider @BenTen , I'm especially looking at you. :)

I've been trying to create a watchlist column for this indicator (code is below). I would like for the column to turn green when there's an "FE_Buy" signal; and red when there's an "FE_Sell" signal; orange when neutral.

I tried to use the same approach as @BenTen did on his MACD watchlist column signal, but wasn't able to get around the issue that "signal" is already defined earlier in the code. (I'm no coder...not even close, as much as I would like to be.)

Your help would be MUCH appreciated!


Code:
###CUSTOMIZABLE VFI DIRECTION with FE###

###Ramon Del Villar AKA Pelonsax on useThinkScript###

declare upper;

###Fractal Energy Portion###
###The lower the number, the more linear the price movement, the higher the number, the more non-linear (CHOP).###
###Value of 100 shows all; Value of 0 shows none###

input FEPeriod = 14;
input FEThreshold = 50;

def sumTR = Sum (TrueRange(high, close, low), FEPeriod);
def HMax =  Highest (high, FEPeriod);
def LMax =  Lowest (low, FEPeriod);

def FE = 100 * Log (sumTR / (HMax - LMax)) / Log(FEPeriod);

def FEyes = if FE <= FEThreshold then 1 else 0;


###VFI Portion beings###

input VFIlength = 20;
###Number of bars used to calculate VFI###

input maxVolumeCutOff = 2.5;
###Coefficient used in calculation of “Cut Off” value. Lower values mean stronger damping of volume spikes###

Assert(maxVolumeCutOff > 0, "'max volume cut off' must be positive: " + maxVolumeCutOff);

def cutOff = 0.2 * StDev(Log(hlc3) - Log(hlc3[1]), 30) * close;
def hlcChange = hlc3 - hlc3[1];
def avgVolume = Average(volume, 30)[1];
def minVolume = Min(volume, avgVolume * maxVolumeCutOff);
def dirVolume = if hlcChange > cutOff
    then minVolume
    else if hlcChange < -cutOff
        then -minVolume
        else 0;

def VFI = ExpAverage(Sum(dirVolume, VFIlength) / avgVolume, 3);
def ZeroLine = 0;

input VFIMlength = 1;
input VFIMsignal = 10;
input VFIaverageType = AverageType.SIMPLE;

def VFIM = MovingAverage(VFIaverageType, VFI, VFIMlength);
def Signal = MovingAverage(VFIaverageType, VFIM, VFIMsignal);


###Price Window portion begins###
input EMA = 13;
def EMA13 = ExpAverage(close, EMA);

#1 - crosses above EMA13, 2 - above EMA13, 3 - crossing below EMA13, 4 - below EMA13

def direction = if close > EMA13 and close[1] <= EMA13 then 1 else if low > EMA13  then 2 else if close < EMA13 and close[1] >= EMA13 then 3 else 4;


###Variable Arrow Portion Begins###
###################################

def green = if VFIM > Signal and direction == 2 then 1 else 0;
def red = if VFIM < Signal and high < EMA13 then 1 else 0;
def yellow = if green == 0 and red == 0 then 1 else 0;

###Arrow ME DIRECTION###

plot Buy = if green > 0 and green[1] == 0 and high[1] > high[3] then 1 else 0;
Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
Buy.SetDefaultColor(color.GREEN);
Buy.SetLineWeight(1);

plot Sell = if red > 0 and red[1] == 0 and low[1] < low[3] then 1 else 0;
Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
Sell.SetDefaultColor(color. RED);
Sell.SetLineWeight(1);

###Arrow ME DIRECTION WITH FE###

input Buy_with_FE = yes;
plot FE_Buy = if FEyes > 0 and Buy > 0 then 1 else 0;
FE_Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_DOWN);
FE_Buy.SetDefaultColor(color.CYAN);
FE_Buy.SetLineWeight(5);
FE_Buy.SetHiding(!Buy_with_FE);

input Sell_with_FE = yes;
plot FE_Sell = if FEyes > 0 and Sell > 0 then 1 else 0;
FE_Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_UP);
FE_Sell.SetDefaultColor(color.MAGENTA);
FE_Sell.SetLineWeight(5);
FE_Sell.SetHiding(!Sell_with_FE);

###Candle Color###
input Candle_Chop_Yellow = yes;
AssignPriceColor(if VFIM > Signal and direction == 2 then Color.GREEN else if VFIM < Signal and direction == 4 then Color.RED else if Candle_Chop_Yellow then Color.YELLOW else color.CURRENT);

Alert(FE_Buy,"", Alert.BAR, Sound.Chimes);
Alert(FE_Sell,"", Alert.BAR, Sound.Chimes);

###End of Code###
 
rad14733

rad14733

Well-known member
VIP
@raynzer For a watchlist you would use AssignBackgroundColor() with your criteria as the conditional trigger for color assignment... That would make the box the color of the signal, using an if . . then . . else clause...
 
R

raynzer

New member
VIP
@raynzer For a watchlist you would use AssignBackgroundColor() with your criteria as the conditional trigger for color assignment... That would make the box the color of the signal, using an if . . then . . else clause...

Thank you for taking the time to respond, @rad14733. I appreciate the suggestion. I tried to use the code below, but my "signal" is already assigned a value. I'm not sure how to get around this. (I tried to replace "signal" with "FE_Buy" and "FE_Sell" (seperately), but that didn't do the trick either.

Code:
plot signal = if FE_Buy then 2 else if FE_Sell then 1 else 0;
signal.AssignValueColor(if signal == 2 then Color.Dark_Green else if signal == 1 then Color.Dark_Red else Color.Dark_Orange);
AssignBackgroundColor(if signal == 2 then Color.Dark_Green else if signal == 1 then Color.Dark_Red else Color.Dark_Orange);

Any thoughts?
 
rad14733

rad14733

Well-known member
VIP
@raynzer For future reference, having the entire script is always better than just a snippet because then we can make sure everything works rather than just taking a wild stab at things... It helps us and it helps get you a better answer quicker... I'd try editing the "=="'s to "="'s...
 
R

raynzer

New member
VIP
For future reference, having the entire script is always better than just a snippet because then we can make sure everything works rather than just taking a wild stab at things... It helps us and it helps get you a better answer quicker... I'd try editing the "=="'s to "="'s...

Thank you for the advice. Makes sense.


Code:
###CUSTOMIZABLE VFI DIRECTION with FE###

###Ramon Del Villar AKA Pelonsax on useThinkScript###

declare upper;

###Fractal Energy Portion###
###The lower the number, the more linear the price movement, the higher the number, the more non-linear (CHOP).###
###Value of 100 shows all; Value of 0 shows none###

input FEPeriod = 14;
input FEThreshold = 50;

def sumTR = Sum (TrueRange(high, close, low), FEPeriod);
def HMax =  Highest (high, FEPeriod);
def LMax =  Lowest (low, FEPeriod);

def FE = 100 * Log (sumTR / (HMax - LMax)) / Log(FEPeriod);

def FEyes = if FE <= FEThreshold then 1 else 0;


###VFI Portion beings###

input VFIlength = 20;
###Number of bars used to calculate VFI###

input maxVolumeCutOff = 2.5;
###Coefficient used in calculation of “Cut Off” value. Lower values mean stronger damping of volume spikes###

Assert(maxVolumeCutOff > 0, "'max volume cut off' must be positive: " + maxVolumeCutOff);

def cutOff = 0.2 * StDev(Log(hlc3) - Log(hlc3[1]), 30) * close;
def hlcChange = hlc3 - hlc3[1];
def avgVolume = Average(volume, 30)[1];
def minVolume = Min(volume, avgVolume * maxVolumeCutOff);
def dirVolume = if hlcChange > cutOff
    then minVolume
    else if hlcChange < -cutOff
        then -minVolume
        else 0;

def VFI = ExpAverage(Sum(dirVolume, VFIlength) / avgVolume, 3);
def ZeroLine = 0;

input VFIMlength = 1;
input VFIMsignal = 10;
input VFIaverageType = AverageType.SIMPLE;

def VFIM = MovingAverage(VFIaverageType, VFI, VFIMlength);
def Signal = MovingAverage(VFIaverageType, VFIM, VFIMsignal);


###Price Window portion begins###
input EMA = 13;
def EMA13 = ExpAverage(close, EMA);

#1 - crosses above EMA13, 2 - above EMA13, 3 - crossing below EMA13, 4 - below EMA13

def direction = if close > EMA13 and close[1] <= EMA13 then 1 else if low > EMA13  then 2 else if close < EMA13 and close[1] >= EMA13 then 3 else 4;


###Variable Arrow Portion Begins###
###################################

def green = if VFIM > Signal and direction == 2 then 1 else 0;
def red = if VFIM < Signal and high < EMA13 then 1 else 0;
def yellow = if green == 0 and red == 0 then 1 else 0;

###Arrow ME DIRECTION###

plot Buy = if green > 0 and green[1] == 0 and high[1] > high[3] then 1 else 0;
Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
Buy.SetDefaultColor(color.GREEN);
Buy.SetLineWeight(1);

plot Sell = if red > 0 and red[1] == 0 and low[1] < low[3] then 1 else 0;
Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
Sell.SetDefaultColor(color. RED);
Sell.SetLineWeight(1);

###Arrow ME DIRECTION WITH FE###

input Buy_with_FE = yes;
plot FE_Buy = if FEyes > 0 and Buy > 0 then 1 else 0;
FE_Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_DOWN);
FE_Buy.SetDefaultColor(color.CYAN);
FE_Buy.SetLineWeight(5);
FE_Buy.SetHiding(!Buy_with_FE);

input Sell_with_FE = yes;
plot FE_Sell = if FEyes > 0 and Sell > 0 then 1 else 0;
FE_Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_UP);
FE_Sell.SetDefaultColor(color.MAGENTA);
FE_Sell.SetLineWeight(5);
FE_Sell.SetHiding(!Sell_with_FE);

###Candle Color###
input Candle_Chop_Yellow = yes;
AssignPriceColor(if VFIM > Signal and direction == 2 then Color.GREEN else if VFIM < Signal and direction == 4 then Color.RED else if Candle_Chop_Yellow then Color.YELLOW else color.CURRENT);

Alert(FE_Buy,"", Alert.BAR, Sound.Chimes);
Alert(FE_Sell,"", Alert.BAR, Sound.Chimes);

###Watchlist Column###

plot signal = if FE_Buy then 2 else if FE_Sell then 1 else 0;
signal.AssignValueColor(if signal == 2 then Color.Dark_Green else if signal == 1 then Color.Dark_Red else Color.Dark_Orange);
AssignBackgroundColor(if signal == 2 then Color.Dark_Green else if signal == 1 then Color.Dark_Red else Color.Dark_Orange);
plot signal = if FE_Buy then 2 else if FE_Sell then 1 else 0;
signal.AssignValueColor(if signal == 2 then Color.Dark_Green else if signal == 1 then Color.Dark_Red else Color.Dark_Orange);
AssignBackgroundColor(if signal == 2 then Color.Dark_Green else if signal == 1 then Color.Dark_Red else Color.Dark_Orange);

###End of Code###
 
rad14733

rad14733

Well-known member
VIP
That was a perfect example of why posting the entire script helps... I was able to see the actual error and made the changes in seconds... Your plot name can never be the same as a previously defined variable... 💡

Edited to add: Still need to do more work... I only made sure there were no errors but you can only have one plot in a watchlist... Unfortunately, I won't be able to edit further until later this evening... :cautious:

Edited to add: Provided Watchlist code...

Code:
###CUSTOMIZABLE VFI DIRECTION with FE###

###Ramon Del Villar AKA Pelonsax on useThinkScript###

declare upper;

###Fractal Energy Portion###
###The lower the number, the more linear the price movement, the higher the number, the more non-linear (CHOP).###
###Value of 100 shows all; Value of 0 shows none###

input FEPeriod = 14;
input FEThreshold = 50;

def sumTR = Sum (TrueRange(high, close, low), FEPeriod);
def HMax =  Highest (high, FEPeriod);
def LMax =  Lowest (low, FEPeriod);

def FE = 100 * Log (sumTR / (HMax - LMax)) / Log(FEPeriod);

def FEyes = if FE <= FEThreshold then 1 else 0;


###VFI Portion beings###

input VFIlength = 20;
###Number of bars used to calculate VFI###

input maxVolumeCutOff = 2.5;
###Coefficient used in calculation of “Cut Off” value. Lower values mean stronger damping of volume spikes###

Assert(maxVolumeCutOff > 0, "'max volume cut off' must be positive: " + maxVolumeCutOff);

def cutOff = 0.2 * StDev(Log(hlc3) - Log(hlc3[1]), 30) * close;
def hlcChange = hlc3 - hlc3[1];
def avgVolume = Average(volume, 30)[1];
def minVolume = Min(volume, avgVolume * maxVolumeCutOff);
def dirVolume = if hlcChange > cutOff
    then minVolume
    else if hlcChange < -cutOff
        then -minVolume
        else 0;

def VFI = ExpAverage(Sum(dirVolume, VFIlength) / avgVolume, 3);
def ZeroLine = 0;

input VFIMlength = 1;
input VFIMsignal = 10;
input VFIaverageType = AverageType.SIMPLE;

def VFIM = MovingAverage(VFIaverageType, VFI, VFIMlength);
def Signal = MovingAverage(VFIaverageType, VFIM, VFIMsignal);


###Price Window portion begins###
input EMA = 13;
def EMA13 = ExpAverage(close, EMA);

#1 - crosses above EMA13, 2 - above EMA13, 3 - crossing below EMA13, 4 - below EMA13

def direction = if close > EMA13 and close[1] <= EMA13 then 1 else if low > EMA13  then 2 else if close < EMA13 and close[1] >= EMA13 then 3 else 4;


###Variable Arrow Portion Begins###
###################################

def green = if VFIM > Signal and direction == 2 then 1 else 0;
def red = if VFIM < Signal and high < EMA13 then 1 else 0;
def yellow = if green == 0 and red == 0 then 1 else 0;

###Arrow ME DIRECTION###

def Buy = if green > 0 and green[1] == 0 and high[1] > high[3] then 1 else 0;
#Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
#Buy.SetDefaultColor(color.GREEN);
#Buy.SetLineWeight(1);

def Sell = if red > 0 and red[1] == 0 and low[1] < low[3] then 1 else 0;
#Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
#Sell.SetDefaultColor(color. RED);
#Sell.SetLineWeight(1);

###Arrow ME DIRECTION WITH FE###

input Buy_with_FE = yes;
def FE_Buy = if FEyes > 0 and Buy > 0 then 1 else 0;
#FE_Buy.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_DOWN);
#FE_Buy.SetDefaultColor(color.CYAN);
#FE_Buy.SetLineWeight(5);
#FE_Buy.SetHiding(!Buy_with_FE);

input Sell_with_FE = yes;
def FE_Sell = if FEyes > 0 and Sell > 0 then 1 else 0;
#FE_Sell.SetPaintingStrategy(PaintingStrategy.BOOLEAN_WEDGE_UP);
#FE_Sell.SetDefaultColor(color.MAGENTA);
#FE_Sell.SetLineWeight(5);
#FE_Sell.SetHiding(!Sell_with_FE);

###Candle Color###
input Candle_Chop_Yellow = yes;
#AssignPriceColor(if VFIM > Signal and direction == 2 then Color.GREEN else if VFIM < Signal and direction == 4 then Color.RED else if Candle_Chop_Yellow then Color.YELLOW else color.CURRENT);

#Alert(FE_Buy,"", Alert.BAR, Sound.Chimes);
#Alert(FE_Sell,"", Alert.BAR, Sound.Chimes);

###Watchlist Column###


plot tradeSignal = if FE_Buy then 2 else if FE_Sell then 1 else 0;
tradeSignal.AssignValueColor(if tradeSignal == 2 then Color.Dark_Green else if tradeSignal == 1 then Color.Dark_Red else Color.Dark_Orange);
AssignBackgroundColor(if tradeSignal == 2 then Color.Dark_Green else if tradeSignal == 1 then Color.Dark_Red else Color.Dark_Orange);


###End of Code###
 
Last edited:
rad14733

rad14733

Well-known member
VIP
@raynzer The code above provides you with a watchlist column... You may want to remove all of the commented out code for streamlining... I did not add credit for the watchlist coding... Column cells painted black have not returned a value so contain a Double.NaN...

 
Last edited:
R

raynzer

New member
VIP
@raynzer The code above provides you with a watchlist column... You may want to remove all of the commented out code for streamlining... I did not add credit for the watchlist coding... Column cells painted black have not returned a value so contain a Double.NaN...



Thank you so much! This is exactly what I was looking for! :)
 

Similar threads

Top