Volume Positive-Negative (VPN) indicator

gravityflyer

New member
Hi all,

Just wondering if anyone has converted Markos Katsanos' new VPN indicator into a ToS script? He just released the indicator in this month's issue of Stocks & Commodities and he has provided the open source script for Amibroker on his website:

Code:
    // VPN Indicator
    // Created by Markos Katsanos
    // Copyright 2021

    Period = Param(“VP Period”, 30, 5, 100, 10 );
    SMOOTH=Param( “SMOOTH”, 3, 1, 10, 1 );
    VPNCRIT=Param( “VPNCRIT”, 10, 0, 40, 5 );
    MAB=Param( “MA BARS”, 30, 10, 200, 10 );
    MAV=MA(V,PERIOD);MAV=IIF(MAV>0,MAV,1);
    MF = Avg – Ref( Avg, -1 );MC=.1*ATR(PERIOD);
    VMP = IIf( MF > MC, V, 0 ) ;
    VP = Sum( VMP , PERIOD);
    VMN = IIf( MF < -MC, V, 0 ) ;
    VN = Sum( VMN , PERIOD);
    VPN=(VP-VN)/MAV/PERIOD*100;
    VPN=EMA(VPN,SMOOTH);MAVPN=MA(VPN,MAB);
    dynamic_color = IIf( VPN >= VPNCRIT, colorGreen, colorRED ) ;
    Plot( VPN, “VPN(” + PERIOD + “)”, DYNAMIC_COLOR , STYLETHICK );
    Plot( MAVPN, “MA”,colorGREEN, styleDashed );
    Plot(VPNCRIT,”CRIT”,colorBLUE);

Any help for use in ToS would be greatly appreciated!
 
I am not good at this but I tried to do it. let me know what you think

Code:
input length = 50;

def O = open;
def c = close;
def v = volume;


def v_up = if close >= close[1] then Volume else 0;
def v_down = if close < close [1] then Volume else 0;

def volavg = average (volume, length);

def vp = sum(v_up, length);
def vn = sum(v_down, length);


plot VPN = (VP-VN)/volavg/length*100;

plot zeroline = 0;
 
I am not good at this but I tried to do it. let me know what you think

Code:
input length = 50;

def O = open;
def c = close;
def v = volume;


def v_up = if close >= close[1] then Volume else 0;
def v_down = if close < close [1] then Volume else 0;

def volavg = average (volume, length);

def vp = sum(v_up, length);
def vn = sum(v_down, length);


plot VPN = (VP-VN)/volavg/length*100;

plot zeroline = 0;
Going over it again, I saw that the definition of up and down days is flawed. It needs to be corrected to include the ATR and the use of average daily price. Ill try to figure out how to do that.
 
A version of the indicator is available here:
http://traders.com/Documentation/FEEDbk_docs/2021/04/TradersTips.html
No code on page, but a ToS link to it

-mashume

linked code is this:
I DID NOT WRITE THIS AND DO NOT CLAIM TO HAVE DONE SO.
Reproduced here with citation to the original source. Please do not pirate someone else's code.
Code:
declare lower;

input length = 30;
input emaLength = 3;
input averageLength = 30;
input factor = 0.1;
input criticalValue = 10;
input averageType = AverageType.EXPONENTIAL;

def atr = WildersAverage(TrueRange(high,  close,  low), length);
def diff = hlc3 - hlc3[1];
def vp = Sum(if diff > factor * atr then volume else 0, length);
def vn = Sum(if diff < -factor * atr then volume else 0, length);

plot VPN = ExpAverage(100 * (vp - vn) / Sum(volume, length), emaLength);
plot VPNAvg = MovingAverage(averageType, VPN, averageLength);
plot CriticalLevel = criticalValue;

VPN.DefineColor("Above", Color.UPTICK);
VPN.DefineColor("Below", Color.DOWNTICK);
VPN.AssignValueColor(if VPN > CriticalLevel then VPN.Color("Above") else VPN.Color("Below"));
VPNAvg.SetDefaultColor(GetColor(7));
CriticalLevel.SetDefaultColor(GetColor(1));


EDIT
I tried to implement the strategy from the easylanguage code on the page shown above. It plots sell signals, but I haven't seen a buy signal. Perhaps I got something wrong...
Code:
declare lower;

input Period = 30;
input Smooth = 3;
input VPNCrit = 10;
input MAB = 30;
input MinC = 1;
input MinVol = 100000;
input MinVolAvgLen = 5;
input VolAvgLen = 50;
input MinVC = 0.5;
input VolDivisor = 100000;
input RSIMaxVal = 90;
input RSILen = 5;

def RSIVal = RSI( RSILen );

input length = 30;
input emaLength = 3;
input averageLength = 30;
input factor = 0.1;
input criticalValue = 10;
input averageType = AverageType.EXPONENTIAL;

def atr = WildersAverage(TrueRange(high,  close,  low), length);
def diff = hlc3 - hlc3[1];
def vp = Sum(if diff > factor * atr then volume else 0, length);
def vn = Sum(if diff < -factor * atr then volume else 0, length);

plot VPN = ExpAverage(100 * (vp - vn) / Sum(volume, length), emaLength);
plot VPNAvg = MovingAverage(averageType, VPN, averageLength);
plot CriticalLevel = criticalValue;

VPN.DefineColor("Above", Color.UPTICK);
VPN.DefineColor("Below", Color.DOWNTICK);
VPN.AssignValueColor(if VPN > CriticalLevel then VPN.Color("Above") else VPN.Color("Below"));
VPNAvg.SetDefaultColor(GetColor(7));
CriticalLevel.SetDefaultColor(GetColor(1));

def VPN_2 = MovAvgExponential(price = VPN, length = Smooth );
def MAVPN = SimpleMovingAvg( VPN_2, MAB );

def LQD = CLOSE > MinC
    and SimpleMovingAvg(VOLUME, MinVolAvgLen) > MinVol
    and SimpleMovingAvg(CLOSE * VOLUME, MinVolAvgLen) / VolDivisor > MinVC;

def BuyCond1 = LQD and
    SimpleMovingAvg(VOLUME, VolAvgLen) >
    SimpleMovingAvg(VOLUME, VolAvgLen)[50];

plot buy = if BuyCond1
    and VPN crosses above VPNCrit
    and RSIVal < RSIMaxVal
    and Close > SimpleMovingAvg( Close, Period ) then VPN else double.nan;

plot sell = if VPN crosses below MAVPN
    and Close < Highest( Close, 5 )
     - 3 * ATR( Period ) then VPN else double.nan;

Second Edit
Removing the BuyCond1 from the buy plot allowed the script to mark some entry points for me on the /es futures. But then again, I'm not worried about liquidity for that particular product.
 
Last edited:
@jckhoury / @mashume -- Awesome! I'm sure myself and other members of this community will really be eager to explore Katsanos' new indicator. I believe his other indicators have been use by many other traders in the past, and curious to see how this performs!
 
Below is the correct code from TASC. I added the Bollinger Bands.

You can get TOS codes each month using the following - just change the date each month. It is best to read and understand the indicator from the author before using. TASC is a great investment, been reading it for years.

http://traders.com/Documentation/FEEDbk_docs/2021/04/TradersTips.html#item3

Code:
declare lower;


input length = 30;
input emaLength = 3;
input averageLength = 30;
input factor = 0.1;
input criticalValue = 10;
input averageType = AverageType.EXPONENTIAL;


def atr = WildersAverage(TrueRange(high,  close,  low), length);
def diff = hlc3 - hlc3[1];
def vp = Sum(if diff > factor * atr then volume else 0, length);
def vn = Sum(if diff < -factor * atr then volume else 0, length);


plot VPN = ExpAverage(100 * (vp - vn) / Sum(volume, length), emaLength);
plot VPNAvg = MovingAverage(averageType, VPN, averageLength);
plot CriticalLevel = criticalValue;


VPN.DefineColor("Above", Color.UPTICK);
VPN.DefineColor("Below", Color.DOWNTICK);
VPN.AssignValueColor(if VPN > CriticalLevel then VPN.Color("Above") else VPN.Color("Below"));
VPNAvg.SetDefaultColor(GetColor(7));
CriticalLevel.SetDefaultColor(GetColor(1));


addCloud (VPN, CriticalLevel,color.DARK_GREEN, color.DARK_RED);


#Bollinger Bands added by mc01439 on 3.28.2021


input displace = 0;
input bblength = 120;#Hint #Use 4 to 4.5 times indicator lenght
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageTypebb = AverageType.Simple;


def sDev = stdev(data = VPN[-displace], length = bblength);


def MidLine = MovingAverage(averageTypebb, data = VPN[-displace], length = bblength);
plot LowerBand = MidLine + num_Dev_Dn * sDev;
plot UpperBand = MidLine + num_Dev_Up * sDev;


LowerBand.SetDefaultColor(GetColor(4));
#MidLine.SetDefaultColor(GetColor(1));
UpperBand.SetDefaultColor(GetColor(4));
 
Below is the correct code from TASC. I added the Bollinger Bands.

You can get TOS codes each month using the following - just change the date each month. It is best to read and understand the indicator from the author before using. TASC is a great investment, been reading it for years.

http://traders.com/Documentation/FEEDbk_docs/2021/04/TradersTips.html#item3

Code:
declare lower;


input length = 30;
input emaLength = 3;
input averageLength = 30;
input factor = 0.1;
input criticalValue = 10;
input averageType = AverageType.EXPONENTIAL;


def atr = WildersAverage(TrueRange(high,  close,  low), length);
def diff = hlc3 - hlc3[1];
def vp = Sum(if diff > factor * atr then volume else 0, length);
def vn = Sum(if diff < -factor * atr then volume else 0, length);


plot VPN = ExpAverage(100 * (vp - vn) / Sum(volume, length), emaLength);
plot VPNAvg = MovingAverage(averageType, VPN, averageLength);
plot CriticalLevel = criticalValue;


VPN.DefineColor("Above", Color.UPTICK);
VPN.DefineColor("Below", Color.DOWNTICK);
VPN.AssignValueColor(if VPN > CriticalLevel then VPN.Color("Above") else VPN.Color("Below"));
VPNAvg.SetDefaultColor(GetColor(7));
CriticalLevel.SetDefaultColor(GetColor(1));


addCloud (VPN, CriticalLevel,color.DARK_GREEN, color.DARK_RED);


#Bollinger Bands added by mc01439 on 3.28.2021


input displace = 0;
input bblength = 120;#Hint #Use 4 to 4.5 times indicator lenght
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageTypebb = AverageType.Simple;


def sDev = stdev(data = VPN[-displace], length = bblength);


def MidLine = MovingAverage(averageTypebb, data = VPN[-displace], length = bblength);
plot LowerBand = MidLine + num_Dev_Dn * sDev;
plot UpperBand = MidLine + num_Dev_Up * sDev;


LowerBand.SetDefaultColor(GetColor(4));
#MidLine.SetDefaultColor(GetColor(1));
UpperBand.SetDefaultColor(GetColor(4));
Nice work ! How would you Mod the code so that it only turned green once both lines have past above to filter out false signals?
 
Below is the correct code from TASC. I added the Bollinger Bands.

You can get TOS codes each month using the following - just change the date each month. It is best to read and understand the indicator from the author before using. TASC is a great investment, been reading it for years.

http://traders.com/Documentation/FEEDbk_docs/2021/04/TradersTips.html#item3

Code:
declare lower;


input length = 30;
input emaLength = 3;
input averageLength = 30;
input factor = 0.1;
input criticalValue = 10;
input averageType = AverageType.EXPONENTIAL;


def atr = WildersAverage(TrueRange(high,  close,  low), length);
def diff = hlc3 - hlc3[1];
def vp = Sum(if diff > factor * atr then volume else 0, length);
def vn = Sum(if diff < -factor * atr then volume else 0, length);


plot VPN = ExpAverage(100 * (vp - vn) / Sum(volume, length), emaLength);
plot VPNAvg = MovingAverage(averageType, VPN, averageLength);
plot CriticalLevel = criticalValue;


VPN.DefineColor("Above", Color.UPTICK);
VPN.DefineColor("Below", Color.DOWNTICK);
VPN.AssignValueColor(if VPN > CriticalLevel then VPN.Color("Above") else VPN.Color("Below"));
VPNAvg.SetDefaultColor(GetColor(7));
CriticalLevel.SetDefaultColor(GetColor(1));


addCloud (VPN, CriticalLevel,color.DARK_GREEN, color.DARK_RED);


#Bollinger Bands added by mc01439 on 3.28.2021


input displace = 0;
input bblength = 120;#Hint #Use 4 to 4.5 times indicator lenght
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageTypebb = AverageType.Simple;


def sDev = stdev(data = VPN[-displace], length = bblength);


def MidLine = MovingAverage(averageTypebb, data = VPN[-displace], length = bblength);
plot LowerBand = MidLine + num_Dev_Dn * sDev;
plot UpperBand = MidLine + num_Dev_Up * sDev;


LowerBand.SetDefaultColor(GetColor(4));
#MidLine.SetDefaultColor(GetColor(1));
UpperBand.SetDefaultColor(GetColor(4));
I added Arrows
Code:
declare lower;

input length = 30;
input emaLength = 3;
input averageLength = 30;
input factor = 0.1;
input criticalValue = 10;
input averageType = AverageType.EXPONENTIAL;

def atr = WildersAverage(TrueRange(high,  close,  low), length);
def diff = hlc3 - hlc3[1];
def vp = Sum(if diff > factor * atr then volume else 0, length);
def vn = Sum(if diff < -factor * atr then volume else 0, length);

plot VPN = ExpAverage(100 * (vp - vn) / Sum(volume, length), emaLength);
plot VPNAvg = MovingAverage(averageType, VPN, averageLength);
plot CriticalLevel = criticalValue;

VPN.DefineColor("Above", Color.UPTICK);
VPN.DefineColor("Below", Color.DOWNTICK);
VPN.AssignValueColor(if VPN > CriticalLevel then VPN.Color("Above") else VPN.Color("Below"));
VPNAvg.SetDefaultColor(GetColor(7));
CriticalLevel.SetDefaultColor(GetColor(1));

addCloud (VPN, CriticalLevel,color.DARK_GREEN, color.DARK_RED);


#Bollinger Bands added by mc01439 on 3.28.2021


input displace = 0;
input bblength = 120;#Hint #Use 4 to 4.5 times indicator lenght
input Num_Dev_Dn = -2.0;
input Num_Dev_up = 2.0;
input averageTypebb = AverageType.Simple;


def sDev = stdev(data = VPN[-displace], length = bblength);


def MidLine = MovingAverage(averageTypebb, data = VPN[-displace], length = bblength);
plot LowerBand = MidLine + num_Dev_Dn * sDev;
plot UpperBand = MidLine + num_Dev_Up * sDev;


LowerBand.SetDefaultColor(GetColor(4));
#MidLine.SetDefaultColor(GetColor(1));
UpperBand.SetDefaultColor(GetColor(4));

#ARROWS
input arrows1 = No;
input arrows2 = No;
input arrows3 = No;
input DotSize = 3;
plot ArrowDown = if arrows1 and (VPN Crosses below VPNAvg) then VPNAvg else double.nan;
ArrowDown.setpaintingStrategy(paintingStrategy.Arrow_Down);
ArrowDown.setDefaultColor(color.Magenta);
ArrowDown.setLineWeight(dotsize-1);

plot ArrowUp = if arrows1 and (VPN crosses above VPNAvg ) then VPNAvg else double.nan;
ArrowUp.setpaintingStrategy(paintingStrategy.Arrow_Up);
ArrowUp.setDefaultColor(color.Cyan);
ArrowUp.setLineWeight(dotsize-1);

plot ArrowDownb=if arrows2 and (VPN Crosses below CriticalLevel) then CriticalLevel else double.nan;
ArrowDownb.setpaintingStrategy(paintingStrategy.Arrow_Down);
ArrowDownb.setDefaultColor(color.Magenta);
ArrowDownb.setLineWeight(dotsize+1);

plot ArrowUpb = if arrows2 and (VPN crosses above CriticalLevel) then CriticalLevel else double.nan;
ArrowUpb.setpaintingStrategy(paintingStrategy.Arrow_Up);
ArrowUpb.setDefaultColor(color.Cyan);
ArrowUpb.setLineWeight(dotsize+1);

plot ArrowDownc=if arrows3 and (VPN Crosses below UpperBand) then UpperBand else double.nan;
ArrowDownc.setpaintingStrategy(paintingStrategy.Arrow_Down);
ArrowDownc.setDefaultColor(color.Yellow);
ArrowDownc.setLineWeight(dotsize);

plot ArrowUpc = if arrows3 and (VPN crosses above LowerBand) then LowerBand else double.nan;
ArrowUpc.setpaintingStrategy(paintingStrategy.Arrow_Up);
ArrowUpc.setDefaultColor(color.Yellow);
ArrowUpc.setLineWeight(dotsize);
 
We can take any indicator that can be imagined, code it, redefine it, add features, signals, clouds, bubbles, change the colorization of lines, Color prices, add multi time frame capabilities, create systems and scans.

It just starts with an idea.
 

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

Similar threads

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
411 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