CSA Trading Dashboard for ThinkorSwim

netarchitech

Well-known member
tdb.png


The updated code can be found in the next post:
https://usethinkscript.com/threads/csa-trading-dashboard-for-thinkorswim.1047/#post-9248
 
Last edited by a moderator:
I have COMPLETED this mega 5 study integration into a single study as requested.

Here is the final line up
# 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 global coloring scheme that reflects the following states
Positive and Up
Positive and Down
Negative and Down
Negative and Up
For new users - make sure you have AT LEAST 11 bars in your expansion area for the bubbles to display.

Only took me the better part of 3 hours. My brain is fried as we speak :D

The design of the CSA Trading Dashboard (VERSION 1.2) is such that a GLOBAL standardized coloring scheme is used where the plot colors are dynamically set depending on the state of each individual study. The advantage is that there is only one place in the code to make decisions on color choices. On the flip side the downsize is that users would be unable to change the colors directly in the user interface.

Edit: Note: In order to see the bubbles that tags each individual study, please make sure you set your chart expansion area to at least 11 bars

Have fun with this! - tomsk

Code:
# CSA Trading Dashboard
# tomsk
# 11.14.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

# 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 global coloring scheme 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

DefineGlobalColor("Positive and Up", Color.GREEN);
DefineGlobalColor("Positive and Down", Color.DARK_GREEN);
DefineGlobalColor("Negative and Down", Color.RED);
DefineGlobalColor("Negative and Up", Color.DARK_RED);

# 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.AssignValueColor(if MACD_State == PosUp then GlobalColor("Positive and Up")
                       else if MACD_State == PosDn then GlobalColor("Positive and Down")
                       else if MACD_State == NegDn then GlobalColor("Negative and Down")
                       else GlobalColor("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.AssignValueColor(if Stochastic_State == PosUp then GlobalColor("Positive and Up")
                       else if Stochastic_State == PosDn then GlobalColor("Positive and Down")
                       else if Stochastic_State == NegDn then GlobalColor("Negative and Down")
                       else GlobalColor("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.AssignValueColor(if FREMA_State == PosUp then GlobalColor("Positive and Up")
                       else if FREMA_State == PosDn then GlobalColor("Positive and Down")
                       else if FREMA_State == NegDn then GlobalColor("Negative and Down")
                       else GlobalColor("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.AssignValueColor(if PPO_State == PosUp then GlobalColor("Positive and Up")
                       else if PPO_State == PosDn then GlobalColor("Positive and Down")
                       else if PPO_State == NegDn then GlobalColor("Negative and Down")
                       else GlobalColor("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.AssignValueColor(if Universal_State == PosUp then GlobalColor("Positive and Up")
                       else if Universal_State == PosDn then GlobalColor("Positive and Down")
                       else if Universal_State == NegDn then GlobalColor("Negative and Down")
                       else GlobalColor("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
 
Last edited by a moderator:
@BenTen Up and running...Let me know if there is anything else I should do when you have a chance...

Thanks for your continued assistance and support :cool: Much appreciated!
 
Just landed to this surprise! Nice work and congratulations it does take hours and we all appreciate the efforts and your contributions.
 
Last edited by a moderator:
@tomsk I just plugged in the latest version (1.2) with the newly added ChartBubbles, but they don't show up? Am I missing something? Let me know when you have a chance...Thanks :)

Once again, great job and thanks for the rapid update :cool:
 
It appears that some of you appear to have a problem with the bubbles. All you need to do is to load the study and zoom in. It works both on daily as well as intraday on futures, equities, etc. Here is a snapshot image


If you'd like to change the color definitions, there is only one place in the code to change it:

DefineGlobalColor("Positive and Up", Color.GREEN);
DefineGlobalColor("Positive and Down", Color.DARK_GREEN);
DefineGlobalColor("Negative and Down", Color.RED);
DefineGlobalColor("Negative and Up", Color.DARK_RED);

Please note that by design of the study, the plot colors are dynamically set depending on the state of each individual study. That is the fundamental reason why you are unable to change the colors in the user interface. You are of course free to make whatever changes you deem necessary to suit your needs. My take is - keep things simple, the code is already complex as it stands

One final note - The PPO is identical to the MACD except the PPO measures percentage difference between two EMAs, while the MACD measures absolute (dollar) difference. Personally I would just drop one of them from consideration
 
This is truly amazing work! Honestly cant wait to get up in the morning and see what I can do with these indicators, I’ve always been big on using the MACD with my trading systems.
 

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
294 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