# CSA Trading Dashboard
# tomsk
# 11.15.2019
# V1.0 - 11.14.2019 - tomsk - Initial release of CSA Trading Dashboard
# V1.1 - 11.14.2019 - tomsk - Added bubbles to identify study being displayed
# V1.2 - 11.14.2019 - tomsk - Synthesized similar internal variables and minor edits
# V2.0 - 11.15.2019 - tomsk - Revamped coloring scheme to enable UI color customization
# This is a lower study represented by 5 dotted lines. Each line represents
# the “price performance” of the following five indicators
#
# Line 1: MACD with a more Normal Distribution
# Line 2: Stochastic Full Diff
# Line 3: FREMA
# Line 4: PPO MMA
# Line 5: Universal Oscillator
#
# Please note that each study was normalized to a standard form and uses a
# standardized coloring scheme defined separatelky under each sub indiocator
# that reflects the following states
#
# Positive and Up
# Positive and Down
# Negative and Down
# Negative and Up
#
# MACD FREMA already includes Ehlers Forward/Reverse EMA as that indicator
# is already represented in Line3. Since all we want to represent is the
# histogram, removed the Multi Moving Average Component from the MACD FREMA.
# Hence we are really left with the MACD with a more Normal Distribution
# study. Therefore, replaced Line 1 with MACD with a more Normal Distribution
# which is the basis of MACD FREMA
# Global Defs
input DotSize = 3;
input n = 3;
def n1 = n + 1;
def PosUp = 1; # Positive and Up
def PosDn = 2; # Positive and Down
def NegDn = 3; # Negative and Down
def NegUp = 4; # Negative and Up
# MACD with a more Normal Distribution
# Mobius
# V01.09.2015
#
# Plots a Gaussian distribution. If Normal Distribution is met, then at
# minimum, 68.2% of the close values should be inside a One Standard Deviation
# Envelope and 95.4% of the close values should be inside a 2 Standard
# Deviation Envelope.
declare lower;
input MACDFastLength = 12;
input MACDSlowLength = 26;
input MACDLength = 9;
# Four Pole Filter
script g{
input length = 4;
input betaDev = 2;
input price = OHLC4;
def c;
def w;
def beta;
def alpha;
def G;
c = price;
w = (2 * Double.Pi / length);
beta = (1 - Cos(w)) / (Power(1.414, 2.0 / betaDev) - 1 );
alpha = (-beta + Sqrt(beta * beta + 2 * beta));
G = Power(alpha, 4) * c +
4 * (1 – alpha) * G[1] – 6 * Power( 1 - alpha, 2 ) * G[2] +
4 * Power( 1 - alpha, 3 ) * G[3] - Power( 1 - alpha, 4 ) * G[4];
plot Line = G;
}
# Modified MACD
def MACD_Value = g(length = MACDFastLength) - g(length = MACDSlowLength);
def MACD_Avg = g(price = MACD_Value, length = MACDLength);
def MACD_Diff = MACD_Value - MACD_Avg;
def MACD_State = if MACD_Diff >= 0
then if MACD_Diff > MACD_Diff[1]
then PosUp
else PosDn
else if MACD_Diff < MACD_Diff[1]
then NegDn
else NegUp;
plot MACD_Dot = if IsNaN(close) then Double.NaN else 1;
MACD_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
MACD_Dot.SetLineWeight(DotSize);
MACD_Dot.DefineColor("Positive and Up", Color.GREEN);
MACD_Dot.DefineColor("Positive and Down", Color.DARK_GREEN);
MACD_Dot.DefineColor("Negative and Down", Color.RED);
MACD_Dot.DefineColor("Negative and Up", Color.DARK_RED);
MACD_Dot.AssignValueColor(if MACD_State == PosUp then MACD_Dot.Color("Positive and Up")
else if MACD_State == PosDn then MACD_Dot.Color("Positive and Down")
else if MACD_State == NegDn then MACD_Dot.Color("Negative and Down")
else MACD_Dot.Color("Negative and Up"));
AddChartBubble(!IsNaN(close[n1]) and IsNaN(close[n]), 1, "MACD", Color.Yellow, yes);
# End Code Modified MACD - Gaussian
# Stochastic Full Diff
# Extracted from Standard TOS Release
input priceH = high;
input priceL = low;
input priceC = close;
input kPeriod = 10;
input kSlowingPeriod = 3;
input dPeriod = 10;
input STOAverageType = AverageType.SIMPLE;
def Stochastic_Diff = reference StochasticFull(0, 0, kPeriod, dPeriod, priceH, priceL, priceC, kSlowingPeriod, STOAverageType).FullK -
reference StochasticFull(0, 0, kPeriod, dPeriod, priceH, priceL, priceC, kSlowingPeriod, STOAverageType).FullD;
def Stochastic_State = if Stochastic_Diff >= 0
then if Stochastic_Diff > Stochastic_Diff[1]
then PosUp
else PosDn
else if Stochastic_Diff < Stochastic_Diff[1]
then NegDn
else NegUp;
plot Stochastic_Dot = if IsNaN(close) then Double.NaN else 2;
Stochastic_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
Stochastic_Dot.SetLineWeight(DotSize);
Stochastic_Dot.DefineColor("Positive and Up", Color.GREEN);
Stochastic_Dot.DefineColor("Positive and Down", Color.DARK_GREEN);
Stochastic_Dot.DefineColor("Negative and Down", Color.RED);
Stochastic_Dot.DefineColor("Negative and Up", Color.DARK_RED);
Stochastic_Dot.AssignValueColor(if Stochastic_State == PosUp then Stochastic_Dot.Color("Positive and Up")
else if Stochastic_State == PosDn then Stochastic_Dot.Color("Positive and Down")
else if Stochastic_State == NegDn then Stochastic_Dot.Color("Negative and Down")
else Stochastic_Dot.Color("Negative and Up"));
AddChartBubble(!IsNaN(close[n1]) and IsNaN(close[n]), 2, "Stoch", Color.Yellow, yes);
# End Code Modified Stochastic Full Diff
# Forward / Reverse EMA
# (c) 2017 John F. Ehlers
# Ported to TOS 07.16.2017
# Mobius
# Inputs:
input AA = .1;
# Vars:
def CC;
def RE1;
def RE2;
def RE3;
def RE4;
def RE5;
def RE6;
def RE7;
def RE8;
def EMA;
CC = if CC[1] == 0 then .9 else 1 – AA;
EMA = AA * Close + CC * EMA[1];
RE1 = CC * EMA + EMA[1];
RE2 = Power(CC, 2) * RE1 + RE1[1];
RE3 = Power(CC, 4) * RE2 + RE2[1];
RE4 = Power(CC, 8) * RE3 + RE3[1];
RE5 = Power(CC, 16) * RE4 + RE4[1];
RE6 = Power(CC, 32) * RE5 + RE5[1];
RE7 = Power(CC, 64) * RE6 + RE6[1];
RE8 = Power(CC, 128) * RE7 + RE7[1];
def FREMA_Diff = EMA – AA * RE8;
def FREMA_State = if FREMA_Diff >= 0
then if FREMA_Diff > FREMA_Diff[1]
then PosUp
else PosDn
else if FREMA_Diff < FREMA_Diff[1]
then NegDn
else NegUp;
plot FREMA_Dot = if IsNaN(close) then Double.NaN else 3;
FREMA_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
FREMA_Dot.SetLineWeight(DotSize);
FREMA_Dot.DefineColor("Positive and Up", Color.GREEN);
FREMA_Dot.DefineColor("Positive and Down", Color.DARK_GREEN);
FREMA_Dot.DefineColor("Negative and Down", Color.RED);
FREMA_Dot.DefineColor("Negative and Up", Color.DARK_RED);
FREMA_Dot.AssignValueColor(if FREMA_State == PosUp then FREMA_Dot.Color("Positive and Up")
else if FREMA_State == PosDn then FREMA_Dot.Color("Positive and Down")
else if FREMA_State == NegDn then FREMA_Dot.Color("Negative and Down")
else FREMA_Dot.Color("Negative and Up"));
AddChartBubble(!IsNaN(close[n1]) and IsNaN(close[n]), 3, "FREMA", Color.Yellow, yes);
# End Code Ehlers Forward / Reverse EMA
# PPO Multiple Moving Averages
# Based on earlier PPO FREMAS code from netarchitect
# Revamped by tomsk
# 11.13.2019
# V11.11.2019 - tomsk - revamped netarchitect's base PPO code
# V11.13.2019 - tomsk - enhanced code structure, collapsed computation into a single switch
input PPOFastLength = 12;
input PPOSlowLength = 26;
input PPOSignalPeriod = 9;
input price = close;
input PPOMovingAverageType = {"Simple MA", default "Exponential MA", "Wilders Smoothing", "Weighted MA",
"Hull MA", "Adaptive MA", "Triangular MA", "Variable MA", "Dema MA", "Tema MA", "EHMA", "THMA"};
def periodOK = PPOFastLength < PPOSlowLength;
AddLabel(!periodOK, "ERROR: PPOFastLength MUST be less than PPOSlowLength");
def fast;
def slow;
def _ppo;
def _signal;
switch (PPOMovingAverageType) {
case "Simple MA":
fast = Average(price, PPOFastLength);
slow = Average(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = Average(_ppo, PPOSignalPeriod);
case "Exponential MA":
fast = ExpAverage(price, PPOFastLength);
slow = ExpAverage(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = ExpAverage(_ppo, PPOSignalPeriod);
case "Wilders Smoothing":
fast = WildersAverage(price, PPOFastLength);
slow = WildersAverage(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = WildersAverage(_ppo, PPOSignalPeriod);
case "Weighted MA":
fast = wma(price, PPOFastLength);
slow = wma(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = wma(_ppo, PPOSignalPeriod);
case "Hull MA":
fast = HullMovingAvg(price, PPOFastLength);
slow = HullMovingAvg(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = HullMovingAvg(_ppo, PPOSignalPeriod);
case "Adaptive MA":
fast = MovAvgAdaptive(price, PPOFastLength);
slow = MovAvgAdaptive(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = MovAvgAdaptive(_ppo, PPOSignalPeriod);
case "Triangular MA":
fast = MovAvgTriangular(price, PPOFastLength);
slow = MovAvgTriangular(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = MovAvgTriangular(_ppo, PPOSignalPeriod);
case "Variable MA":
fast = variableMA(price, PPOFastLength);
slow = variableMA(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = variableMA(_ppo, PPOSignalPeriod);
case "Dema MA":
fast = DEMA(price, PPOFastLength);
slow = DEMA(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = DEMA(_ppo, PPOSignalPeriod);
case "Tema MA":
fast = TEMA(price, PPOFastLength);
slow = TEMA(price, PPOSlowLength);
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = TEMA(_ppo, PPOSignalPeriod);
case EHMA:
fast = ExpAverage(2 * ExpAverage(price, PPOFastLength / 2) -
ExpAverage(price, PPOFastLength), Round(Sqrt(PPOFastLength)));
slow = ExpAverage(2 * ExpAverage(price, PPOSlowLength / 2) -
ExpAverage(price, PPOSlowLength), Round(Sqrt(PPOSlowLength)));
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = ExpAverage(2 * ExpAverage(_ppo, PPOSignalPeriod / 2) -
ExpAverage(_ppo, PPOSignalPeriod), Round(Sqrt(PPOSignalPeriod)));
case THMA:
fast = WMA(WMA(price, (PPOFastLength / 2) / 3) * 3 - WMA(price, (PPOFastLength / 2) / 2) -
WMA(price, (PPOFastLength / 2)), (PPOFastLength / 2));
slow = WMA(WMA(price, (PPOSlowLength / 2) / 3) * 3 - WMA(price, (PPOSlowLength / 2) / 2) -
WMA(price, (PPOSlowLength / 2)), (PPOSlowLength / 2));
_ppo = if periodOK then ((fast - slow) / slow) * 100 else 0;
_signal = WMA(WMA(_ppo, (PPOSignalPeriod / 2) / 3) * 3 - WMA(_ppo, (PPOSignalPeriod / 2) / 2) -
WMA(_ppo, (PPOSignalPeriod / 2)), (PPOSignalPeriod / 2));
}
def Ppo = _ppo;
def PpoEma = _signal;
def PPO_Diff = 2 * (_ppo - _signal);
def PPO_State = if PPO_Diff >= 0
then if PPO_Diff > PPO_Diff[1]
then PosUp
else PosDn
else if PPO_Diff < PPO_Diff[1]
then NegDn
else NegUp;
plot PPO_Dot = if IsNaN(close) then Double.NaN else 4;
PPO_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
PPO_Dot.SetLineWeight(DotSize);
PPO_Dot.DefineColor("Positive and Up", Color.GREEN);
PPO_Dot.DefineColor("Positive and Down", Color.DARK_GREEN);
PPO_Dot.DefineColor("Negative and Down", Color.RED);
PPO_Dot.DefineColor("Negative and Up", Color.DARK_RED);
PPO_Dot.AssignValueColor(if PPO_State == PosUp then PPO_Dot.Color("Positive and Up")
else if PPO_State == PosDn then PPO_Dot.Color("Positive and Down")
else if PPO_State == NegDn then PPO_Dot.Color("Negative and Down")
else PPO_Dot.Color("Negative and Up"));
AddChartBubble(!IsNaN(close[n1]) and IsNaN(close[n]), 4, "PPO", Color.Yellow, yes);
# End Code PPO Multiple Moving Averages
# Ehlers Universal Oscillator
# LazyBear
# initial port by netarchitech
# 2019.11.05
# source: https://www.tradingview.com/script/ieFYbVdC-Ehlers-Universal-Oscillator-LazyBear/
input bandedge = 20;
input EUOLengthMA = 9;
def whitenoise = (close - close[2])/2;
def a1 = ExpAverage(-1.414 * 3.14159 / bandedge);
def b1 = 2.0 * a1 * cos(1.414 * 180 /bandedge);
def c2 = b1;
def c3 = -a1 * a1;
def c1 = 1 - c2 - c3;
def filt = c1 * (whitenoise + (whitenoise[1]))/2 + c2 * (filt[1]) + c3 * (filt[2]);
def filt1 = if totalsum(1) == 0 then 0
else if totalsum(1) == 2 then c2 * filt1[1]
else if totalsum(1) == 3 then c2 * filt1[1] + c3 * (filt1[2])
else filt;
def pk = if totalsum(1) == 2 then .0000001
else if absvalue(filt1) > pk[1] then absvalue(filt1)
else 0.991 * pk[1];
def denom = if pk == 0 then -1 else pk;
def euo = if denom == -1 then euo[1] else filt1/pk;
def euoMA = ExpAverage(euo, EUOLengthMA);
def Universal_Diff = euo;
def Universal_State = if Universal_Diff >= 0
then if Universal_Diff > Universal_Diff[1]
then PosUp
else PosDn
else if Universal_Diff < Universal_Diff[1]
then NegDn
else NegUp;
plot Universal_Dot = if IsNaN(close) then Double.NaN else 5;
Universal_Dot.SetPaintingStrategy(PaintingStrategy.POINTS);
Universal_Dot.SetLineWeight(DotSize);
Universal_Dot.DefineColor("Positive and Up", Color.GREEN);
Universal_Dot.DefineColor("Positive and Down", Color.DARK_GREEN);
Universal_Dot.DefineColor("Negative and Down", Color.RED);
Universal_Dot.DefineColor("Negative and Up", Color.DARK_RED);
Universal_Dot.AssignValueColor(if Universal_State == PosUp then Universal_Dot.Color("Positive and Up")
else if Universal_State == PosDn then Universal_Dot.Color("Positive and Down")
else if Universal_State == NegDn then Universal_Dot.Color("Negative and Down")
else Universal_Dot.Color("Negative and Up"));
AddChartBubble(!IsNaN(close[n1]) and IsNaN(close[n]), 5, "Univ Osc", Color.Yellow, yes);
# End Code Ehlers Universal Oscillator
# End CSA Trading Dashboard