How To Create A Custom Watchlist Column -A Tutorial For ThinkOrSwim

M_Morisette

New member
LABEL ADDED AS A WATCHLIST COLUMN FOR EASY PICKINS
I'm a fan of this indicator:
https://usethinkscript.com/threads/...or-with-buy-sell-signals-for-thinkorswim.226/

so I added it as a column in my watchlist.



1. Click Gear -> Click Customize...
f0kOy3v.png




2. Search 'custom' and click the script icon for one of the options. I used 'Custom 4'
tfg9A8z.png




3. Delete the default study/condition.
9Xb4jWL.png




4. Click 'thinkScript Editor' tab
iQwFK4k.png




5. Add a name and remember it to add it later -> paste in the script -> click 'Apply' and 'OK'
Code:
input ThermoLookBackBars = 50;
input PlotType = {default AdaptiveMovingAverages, Standard};

def HighLowScore = 1000 * ((high - high[1]) / (high[1]) +
(low - low[1]) / low[1]);

#######ATR TrailingStop Code
input trailType = {default modified, unmodified};
input ATRPeriod = 5;
input ATRFactor = 3.5;
input firstTrade = {default long, short};

def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef = if low <= high[1]
    then high - close[1]
    else (high - close[1]) - 0.5 * (low - high[1]);
def LRef = if high >= low[1]
    then close[1] - low
    else (close[1] - low) - 0.5 * (low[1] - high);
def ATRMod = ExpAverage(Max(HiLo, Max(HRef, LRef)), 2 * ATRPeriod - 1);

def loss;
switch (trailType) {
case modified:
    loss = ATRFactor * ATRMod;
case unmodified:
    loss = ATRFactor * Average(TrueRange(high,  close,  low),  ATRPeriod);
}

rec state = {default init, long, short};
rec trail;
switch (state[1]) {
case init:
    if (!IsNaN(loss)) {
        switch (firstTrade) {
        case long:
            state = state.long;
            trail =  close - loss;
        case short:
            state = state.short;
            trail = close + loss;
    }
    } else {
        state = state.init;
        trail = Double.NaN;
    }
case long:
    if (close > trail[1]) {
        state = state.long;
        trail = Max(trail[1], close - loss);
    }
    else {
        state = state.short;
        trail = close + loss;
    }
case short:
    if (close < trail[1]) {
        state = state.short;
        trail = Min(trail[1], close + loss);
    }
    else {
        state = state.long;
        trail =  close - loss;
    }
}

def BuySignal = Crosses(state == state.long, 0, CrossingDirection.ABOVE);
def SellSignal = Crosses(state == state.short, 0, CrossingDirection.ABOVE);

plot TrailingStop = trail;
TrailingStop.Hide();
####End ATR Trailing Stop Code

def A = Highest(high[1], ThermoLookBackBars);
def B = Lowest(low[1], ThermoLookBackBars);

def FiftyTwoWeekHigh = A;

def FiftyTwoWeekLow = B;

def FiftyTwoWeekScore = 10 * (((high
- FiftyTwoWeekHigh) / FiftyTwoWeekHigh) +
((low - FiftyTwoWeekLow) / FiftyTwoWeekLow));

def ThermoScore = ExpAverage(HighLowScore + FiftyTwoWeekScore, ThermoLookBackBars);

input FastLengthShort = 5;
input SlowLengthShort = 15;
input EffRatioShort = 10;
input FastLengthLong = 10;
input SlowLengthLong = 25;
input EffRatioLong = 5;

def AMA = MovAvgAdaptive(ThermoScore, FastLengthShort, SlowLengthShort, EffRatioShort);
def AMA2 = MovAvgAdaptive(ThermoScore, FastLengthLong, SlowLengthLong, EffRatioLong);

plot Line1;
Line1.Hide();
plot Line2;
Line2.Hide();

switch (PlotType) {
case AdaptiveMovingAverages:
    Line1 = AMA;
    Line2 = AMA2;
case Standard:
    Line1 = ThermoScore;
    Line2 = ThermoScore;
}

def InvisibleLine = close * 0;
plot Line3 = InvisibleLine;
Line3.Hide();

def Buy = Line1 > 0 and Line2 < 0 and state == state.long;
def StrongBuy = Line1 > 0 and Line2 >= 0 and state == state.long;
def Sell = Line1 < 0 and Line2 > 0 and state == state.short;
def StrongSell = Line1 < 0 and Line2 <= 0 and state == state.short;


AddLabel(yes, Concat("", (

  if Buy then "Up"

  else if StrongBuy then "Strong Up"

  else if Sell then "Down"
 
  else if StrongSell then "Strong Down"
 
  else "Neutral"

)),
  Color.BLACK
);

AssignBackgroundColor(
  
    if Buy then Color.DARK_GREEN

    else if StrongBuy then Color.GREEN

    else if Sell then Color.DARK_RED
 
    else if StrongSell then Color.RED
 
    else Color.GRAY

  );
pjYujPT.png




6. Find what you just created and add it to the columns in 'Current Set'
APgeFvz.png




7. Valla
sj8mUYC.png
 
Last edited by a moderator:

atoli

New member
thanks for sharing. I'm not familiar with scripting. Can you shed some light what indicators you are using to create labels? What is the time frame these labels are working on? TIA
 

MerryDay

Administrative
Staff member
Staff
VIP
Lifetime
thanks for sharing. I'm not familiar with scripting. Can you shed some light what indicators you are using to create labels? What is the time frame these labels are working on? TIA
These are not "labels". This a watchlist column.
You choose any aggregation that you want. The example is set to Daily.
This is just an example. You can load any script that you want.

To see the indicator used in the example, go here:
https://usethinkscript.com/threads/...or-with-buy-sell-signals-for-thinkorswim.226/
 

Mattyb740

Member
LABEL ADDED AS A WATCHLIST COLUMN FOR EASY PICKINS
I'm a fan of this indicator:
https://usethinkscript.com/threads/...or-with-buy-sell-signals-for-thinkorswim.226/

so I added it as a column in my watchlist.



1. Click Gear -> Click Customize...
f0kOy3v.png




2. Search 'custom' and click the script icon for one of the options. I used 'Custom 4'
tfg9A8z.png




3. Delete the default study/condition.
9Xb4jWL.png




4. Click 'thinkScript Editor' tab
iQwFK4k.png




5. Add a name and remember it to add it later -> paste in the script -> click 'Apply' and 'OK'
Code:
input ThermoLookBackBars = 50;
input PlotType = {default AdaptiveMovingAverages, Standard};

def HighLowScore = 1000 * ((high - high[1]) / (high[1]) +
(low - low[1]) / low[1]);

#######ATR TrailingStop Code
input trailType = {default modified, unmodified};
input ATRPeriod = 5;
input ATRFactor = 3.5;
input firstTrade = {default long, short};

def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef = if low <= high[1]
    then high - close[1]
    else (high - close[1]) - 0.5 * (low - high[1]);
def LRef = if high >= low[1]
    then close[1] - low
    else (close[1] - low) - 0.5 * (low[1] - high);
def ATRMod = ExpAverage(Max(HiLo, Max(HRef, LRef)), 2 * ATRPeriod - 1);

def loss;
switch (trailType) {
case modified:
    loss = ATRFactor * ATRMod;
case unmodified:
    loss = ATRFactor * Average(TrueRange(high,  close,  low),  ATRPeriod);
}

rec state = {default init, long, short};
rec trail;
switch (state[1]) {
case init:
    if (!IsNaN(loss)) {
        switch (firstTrade) {
        case long:
            state = state.long;
            trail =  close - loss;
        case short:
            state = state.short;
            trail = close + loss;
    }
    } else {
        state = state.init;
        trail = Double.NaN;
    }
case long:
    if (close > trail[1]) {
        state = state.long;
        trail = Max(trail[1], close - loss);
    }
    else {
        state = state.short;
        trail = close + loss;
    }
case short:
    if (close < trail[1]) {
        state = state.short;
        trail = Min(trail[1], close + loss);
    }
    else {
        state = state.long;
        trail =  close - loss;
    }
}

def BuySignal = Crosses(state == state.long, 0, CrossingDirection.ABOVE);
def SellSignal = Crosses(state == state.short, 0, CrossingDirection.ABOVE);

plot TrailingStop = trail;
TrailingStop.Hide();
####End ATR Trailing Stop Code

def A = Highest(high[1], ThermoLookBackBars);
def B = Lowest(low[1], ThermoLookBackBars);

def FiftyTwoWeekHigh = A;

def FiftyTwoWeekLow = B;

def FiftyTwoWeekScore = 10 * (((high
- FiftyTwoWeekHigh) / FiftyTwoWeekHigh) +
((low - FiftyTwoWeekLow) / FiftyTwoWeekLow));

def ThermoScore = ExpAverage(HighLowScore + FiftyTwoWeekScore, ThermoLookBackBars);

input FastLengthShort = 5;
input SlowLengthShort = 15;
input EffRatioShort = 10;
input FastLengthLong = 10;
input SlowLengthLong = 25;
input EffRatioLong = 5;

def AMA = MovAvgAdaptive(ThermoScore, FastLengthShort, SlowLengthShort, EffRatioShort);
def AMA2 = MovAvgAdaptive(ThermoScore, FastLengthLong, SlowLengthLong, EffRatioLong);

plot Line1;
Line1.Hide();
plot Line2;
Line2.Hide();

switch (PlotType) {
case AdaptiveMovingAverages:
    Line1 = AMA;
    Line2 = AMA2;
case Standard:
    Line1 = ThermoScore;
    Line2 = ThermoScore;
}

def InvisibleLine = close * 0;
plot Line3 = InvisibleLine;
Line3.Hide();

def Buy = Line1 > 0 and Line2 < 0 and state == state.long;
def StrongBuy = Line1 > 0 and Line2 >= 0 and state == state.long;
def Sell = Line1 < 0 and Line2 > 0 and state == state.short;
def StrongSell = Line1 < 0 and Line2 <= 0 and state == state.short;


AddLabel(yes, Concat("", (

  if Buy then "Up"

  else if StrongBuy then "Strong Up"

  else if Sell then "Down"
 
  else if StrongSell then "Strong Down"
 
  else "Neutral"

)),
  Color.BLACK
);

AssignBackgroundColor(
 
    if Buy then Color.DARK_GREEN

    else if StrongBuy then Color.GREEN

    else if Sell then Color.DARK_RED
 
    else if StrongSell then Color.RED
 
    else Color.GRAY

  );
pjYujPT.png




6. Find what you just created and add it to the columns in 'Current Set'
APgeFvz.png




7. Valla
sj8mUYC.png
i do not have any "custom" options that come up on my watchlist tab.
i click on gear-customize and ive searched for custom but there is none?
 

M_Morisette

New member
i do not have any "custom" options that come up on my watchlist tab.
i click on gear-customize and ive searched for custom but there is none?
Interesting.

Try looking for any "Available Items" that don't have locks on the scripts.

mBzl9bj.png


If you find one, click it and delete the default study in the Condition Wizard. For me, the default condition set is SimpleMovingAvg() and if you see that you can delete it. Now click on the thinkScriptEditor tab and if it is empty you can paste the code in there. Be sure to rename it up at the top before you save it so that you can find it easily.
 

Mattyb740

Member
Interesting.

Try looking for any "Available Items" that don't have locks on the scripts.

mBzl9bj.png


If you find one, click it and delete the default study in the Condition Wizard. For me, the default condition set is SimpleMovingAvg() and if you see that you can delete it. Now click on the thinkScriptEditor tab and if it is empty you can paste the code in there. Be sure to rename it up at the top before you save it so that you can find it easily.
That worked. Thank you.
You wouldn’t by chance have a similar step by step with a scan instead of a watchlist column?
 

M_Morisette

New member
1. You are going to want to add the original script that @BenTen created which I am pasting below this line. This is added as a study that you use in the charts, not as a watchlist column.
Rich (BB code):
input ThermoLookBackBars = 50;
input PlotType = {default AdaptiveMovingAverages, Standard};

def HighLowScore = 1000 * ((high - high[1]) / (high[1]) +
(low - low[1]) / low[1]);

#######ATR TrailingStop Code
input trailType = {default modified, unmodified};
input ATRPeriod = 5;
input ATRFactor = 3.5;
input firstTrade = {default long, short};

def HiLo = Min(high - low, 1.5 * Average(high - low, ATRPeriod));
def HRef = if low <= high[1]
    then high - close[1]
    else (high - close[1]) - 0.5 * (low - high[1]);
def LRef = if high >= low[1]
    then close[1] - low
    else (close[1] - low) - 0.5 * (low[1] - high);
def ATRMod = ExpAverage(Max(HiLo, Max(HRef, LRef)), 2 * ATRPeriod - 1);

def loss;
switch (trailType) {
case modified:
    loss = ATRFactor * ATRMod;
case unmodified:
    loss = ATRFactor * Average(TrueRange(high,  close,  low),  ATRPeriod);
}

rec state = {default init, long, short};
rec trail;
switch (state[1]) {
case init:
    if (!IsNaN(loss)) {
        switch (firstTrade) {
        case long:
            state = state.long;
            trail =  close - loss;
        case short:
            state = state.short;
            trail = close + loss;
    }
    } else {
        state = state.init;
        trail = Double.NaN;
    }
case long:
    if (close > trail[1]) {
        state = state.long;
        trail = Max(trail[1], close - loss);
    }
    else {
        state = state.short;
        trail = close + loss;
    }
case short:
    if (close < trail[1]) {
        state = state.short;
        trail = Min(trail[1], close + loss);
    }
    else {
        state = state.long;
        trail =  close - loss;
    }
}

def BuySignal = Crosses(state == state.long, 0, CrossingDirection.ABOVE);
def SellSignal = Crosses(state == state.short, 0, CrossingDirection.ABOVE);

plot TrailingStop = trail;
TrailingStop.Hide();
####End ATR Trailing Stop Code

def A = Highest(high[1], ThermoLookBackBars);
def B = Lowest(low[1], ThermoLookBackBars);

def FiftyTwoWeekHigh = A;

def FiftyTwoWeekLow = B;

def FiftyTwoWeekScore = 10 * (((high
- FiftyTwoWeekHigh) / FiftyTwoWeekHigh) +
((low - FiftyTwoWeekLow) / FiftyTwoWeekLow));

def ThermoScore = ExpAverage(HighLowScore + FiftyTwoWeekScore, ThermoLookBackBars);

input FastLengthShort = 5;
input SlowLengthShort = 15;
input EffRatioShort = 10;
input FastLengthLong = 10;
input SlowLengthLong = 25;
input EffRatioLong = 5;

def AMA = MovAvgAdaptive(ThermoScore, FastLengthShort, SlowLengthShort, EffRatioShort);
def AMA2 = MovAvgAdaptive(ThermoScore, FastLengthLong, SlowLengthLong, EffRatioLong);

plot Line1;
Line1.Hide();
plot Line2;
Line2.Hide();

switch (PlotType) {
case AdaptiveMovingAverages:
    Line1 = AMA;
    Line2 = AMA2;
case Standard:
    Line1 = ThermoScore;
    Line2 = ThermoScore;
}

def InvisibleLine = close * 0;
plot Line3 = InvisibleLine;
Line3.Hide();

def Buy = Line1 > 0 and Line2 < 0 and state == state.long;
def StrongBuy = Line1 > 0 and Line2 >= 0 and state == state.long;
def Sell = Line1 < 0 and Line2 > 0 and state == state.short;
def StrongSell = Line1 < 0 and Line2 <= 0 and state == state.short;

plot GU = BuySignal;
GU.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_UP);
GU.SetDefaultColor(GetColor(8));
GU.SetLineWeight(2);

plot GX = SellSignal;
GX.SetPaintingStrategy(PaintingStrategy.BOOLEAN_ARROW_DOWN);
GX.SetDefaultColor(GetColor(8));
GX.SetLineWeight(2);


AssignPriceColor(if Buy then Color.DARK_GREEN else if StrongBuy then Color.GREEN else if Sell then Color.DARK_RED else if StrongSell then Color.RED else Color.BLUE);

AddLabel(yes, Concat("Current Reading is ", (if Buy then "Up Trend" else if StrongBuy then "Strong Up Trend" else if Sell then "Down Trend" else if StrongSell then "Strong Down Trend" else "Neutral")),  if Buy then Color.DARK_GREEN else if StrongBuy then Color.GREEN else if Sell then Color.DARK_RED else if StrongSell then Color.RED else Color.GRAY);

2. Click the 'Scan' tab at the top of TOS.

3. Delete/Remove all filters.

4. Add Filter->Study->Custom (The Scanner Custom Filter window should pop up)

5. Delete the default condition->Add Condition->Study->custom_trend_painter(or whatever you named it).

6. Find where it says 'Plot' it should be set by default to 'TrailingStop' change that to 'GU'->in the right column set it to 'is true' and then determine how many bars back you want it to look. For example, if you are using a 1 Day chart you may want to look back 3 bars/days. You also may want to set other filters to weed out penny stocks or large caps or you may simply want to just apply this to a certain watchlist that you already have created. Otherwise you are going to get an overwhelming number or stocks.

7. Save your scan query so that you can pull it up in the Watchlist widget. This will also be able to have the column labels we had setup before and you will be able to see if it's Neutral or Bullish without clicking into the stock.

If you need images let me know. I haven't used this yet, I may want to tweak the 'GU' to only be true when the trend is green and not just blue.
 

EvilSurgeon

Member
VIP
Hi all,

I am sure this must have been asked and answered, but I can not find with Google or by searching this site.

Can each watch list have different columns/custom columns?

Every watchlist I bring up has my same columns and if I try to edit one, it seems to apply to all watchlists, so the change (add or delete) is the same for all.

I'd like different columns depending on which watchlist I am looking at.

Thanks!
 

MerryDay

Administrative
Staff member
Staff
VIP
Lifetime
Hi all,

I am sure this must have been asked and answered, but I can not find with Google or by searching this site.

Can each watch list have different columns/custom columns?

Every watchlist I bring up has my same columns and if I try to edit one, it seems to apply to all watchlists, so the change (add or delete) is the same for all.

I'd like different columns depending on which watchlist I am looking at.

Thanks!
It is not clear what you are asking. No it is not possible for watchlist tables to interact with each other.
Read more here: https://usethinkscript.com/threads/...hlist-column-a-tutorial-for-thinkorswim.9709/

To choose what symbols to populate your watchlist column:
Choose from your personal lists or from hundreds of ToS built lists. If there is a purple symbol to the left of the name, the list populates dynamically from a scan. No purples, are static manual lists that you created.
7HdOTUW.png


To choose what columns to populate your watchlist with, click on the gear on the far-right side of your watchlist table
And then choose your columns.
4WtJTCP.png
 
Last edited:

EvilSurgeon

Member
VIP
Thanks again @MerryDay, I really appreciate the time and responsiveness. I'll see if I can explain one more time.

On the quotes tab under market watch, no matter what WL I select from upper right corner, they all show the same columns. Let's call them default,

*If I detach a WL, I can change the columns without affecting the default WL columns still on the quotes tab.

*If I save the workspace with both WLs open, then they will reopen as they were with the different columns in each.

#If I close the detached WL and try to go back to it under the quotes tab, it reverts to the default columns that always show under that tab.

#If I import someone else's WL, if I open it in the quotes tab or automatically with open shared item, they populate with my default columns and I don't know any other way to open them or how to get the columns as show in the shared WL (other than selecting those columns from the customize option).

# = the issues, unless * is just the way it has to be done, though I have closed WL windows by accident, then the non-default columns seem to be gone, at least if I try to re-open on the quotes tab (never tried a new detached window).

Either I am doing something wrong, don't understand what I am doing, or need to call customer support. I appreciate your quick answers and indulging me.

Best!
 

MerryDay

Administrative
Staff member
Staff
VIP
Lifetime
Detached Watchlists Tables exists as long as they are open on your screen.
Close the watchlist and then it is gone.

The 'default' under the Marketwatch tab is subject to change dependent on app updates.
 

Similar threads

Top