LBR Indicator Watchlist columns

MBF

MBF

Active member
2019 Donor
Hi everyone,
I have been working on this for a while. Ive managed to get the color columns but I can't figure out the crossings since I believe both the 3, 10 are the same. I think. Anyway this is as far as I got. I want the 3/10 crossing above the slow 16. HELP! Driving me bonkers.
Here is the script for the indicator: and below that is what Ive made so far. I dont know how to script but I managed a few things.

Code:
# TD Ameritrade IP Company, Inc. (c) 2011-2019

declare lower;

input price = close;
input calculationMode = {default Normal, Alternate};

plot FastLine;
switch (calculationMode) {
case Normal:
    FastLine = Average(price, 3) - Average(price, 10);
case Alternate:
    FastLine = Average(price - Average(price[3], 3), 2);
}
plot SlowLine = Average(FastLine, 16);
plot Hist = FastLine;
plot ZeroLine = 0;

FastLine.SetDefaultColor(GetColor(1));
SlowLine.SetDefaultColor(GetColor(8));
Hist.DefineColor("Positive", Color.UPTICK);
Hist.DefineColor("Negative", Color.DOWNTICK);
Hist.AssignValueColor(if Hist >= 0 then Hist.color("Positive") else Hist.color("Negative"));
Hist.SetPaintingStrategy(PaintingStrategy.HISTOGRAM);
Hist.HideTitle();
ZeroLine.SetDefaultColor(GetColor(7));
So far:

Code:
INPUT ma1 = 3;

INPUT ma2 = 16;

DEF ALERT =SimpleMovingAvg("length" = ma1)."SMA" crosses SimpleMovingAvg("length" = ma2)."SMA";
Alert(ALERT, "MA CROSSES MA2", Alert.BAR, Sound.Ring);
# WILL CHANGE THE COLOR OF THE TEXT INSIDE THE COLUMN BOX
AddLabel(yes, IF 
SimpleMovingAvg("length" = ma1)."SMA" >
SimpleMovingAvg("length" = ma2)."SMA" THEN
ma1 ELSE ma2 ,IF 
SimpleMovingAvg("length" = ma1)."SMA" <
SimpleMovingAvg("length" = ma2)."SMA" then
color.RED else color.GREEN);

#WILL CHANGE THE COLOR OF THE COLUMN BOX
AssignBackgroundColor (IF 
SimpleMovingAvg("length" = ma1)."SMA" <
SimpleMovingAvg("length" = ma2)."SMA" then
color.RED else color.Light_GREEN);


#ALERT.AssignValueColor(if CLOSE  > ma1 then Color.DARK_GREEN else Color.Orange);
 
Last edited by a moderator:
horserider

horserider

Well-known member
VIP
No idea what you are trying to do but...First define ma1 and ma2.
 
T

tomsk

Well-known member
VIP
@MBF As I read through your request it appears to me that you're looking to implement a moving average crossover on the watchlist
If that is the case, here is a real simple starter script. I've used the 50/200 moving average, so feel free to use the MA of your choice in the code
Not quite sure I see the association with the LBR study you referenced

Code:
input fastLength = 50;
input slowLength = 200;
input AvgType = AverageType.SIMPLE;
input price = close;

plot FastAvg = MovingAverage(AvgType, price, fastLength);
plot SlowAvg = MovingAverage(AvgType, price, slowLength);

AddLabel(FastAvg crosses SlowAvg, if FastAvg > SlowAvg then "CROSS ABOVE" else "CROSS BELOW", if FastAvg > SlowAvg then Color.GREEN else Color.RED);

AssignBackgroundColor(if FastAvg > SlowAvg then Color.GREEN else Color.RED);
 
markos

markos

Well-known member
VIP
Hi @MBF try this tutorial. This is a worthwhile code for you. Your code attempt needs Inputs or Def's first. Once that's put together, post it. Hopefully you'll get some help.
@tomsk is this what you were thinking of in regards to a tutorial? I don't remember where I got it.

Code:
% Above - Below 200 SMA  AddLabel() displays a STRING value. So, it will be sorted alphabetically. Plot displays a numeric value and will be sorted numerically.
#HINT: This is a custom watchlist column looking for xx% percent above or below moving average line. \n It provides a visual alert with the percent from MA line where you expect price to revert to the mean by reversing to return to the MA line.

## because this is a watchlist column there is no Edit box.  therefore def could have been used insted of input.  To change type of price and/or type of moving average, click on the word "Inspector" top right of this box and click on the word close or the word AverageType.SIMPLE and the Inspector will show you your other choices.
input price = close;
input length = 200;
input Average_Type = AverageType.SIMPLE;
input percent_from_MA = 0.2;

## these def or "define a new word to ThinkScript" did not have to be used, but it saved a lot of time and typing later in the code by providing ability to use the new "words" instead of typing the math formula multiple times in different lines later in the code

def Avg = MovingAverage(average_Type, price, length);
def MA_below_price = price > Avg;
def MA_above_price = price < Avg;
def percent_away = if MA_below_price or MA_above_price then (close / avg) - 1 else 0;

def oversold = percent_away * 100 <= percent_from_MA * (-1);
def overbought = percent_away * 100 >= (Percent_from_MA);

### AddLabel needs (1) condition to trigger it to be visible or the word yes if always visible, (2) text to appear in quotes + data to appear in the label, (3) color for the label which can be static color or can be dynamic using if __ then __ else ___

#AddLabel(yes, if oversold then " oversold " + AsPercent(percent_away) else if overbought then " overbought " + AsPercent(percent_away) else AsPercent(percent_away), color.BLACK);
#AssignBackgroundColor(if oversold then color.GREEN else if overbought then color.lIGHT_RED else color.LIGHT_GRAY);
AddLabel(yes, if oversold then " below " + AsPercent(percent_away) else if overbought then " above " + AsPercent(percent_away) else AsPercent(percent_away), color.BLACK);
AssignBackgroundColor(if oversold then color.DARK_ORANGE else if overbought then color.Green else color.LIGHT_GRAY);

# end code ------------------
 
T

tomsk

Well-known member
VIP
@markos Hey, very well done my friend (y) It has a bit more info like percent away but is a great starter script
 
MBF

MBF

Active member
2019 Donor
@horserider @tomsk @markos

Here is the crossovers, in the circles. The problem I have is the 3/10 is the difference btwn the two and plots as one MA. So I tried adding a third MA3 but then I got confused on how to write the rest. So at one point I had MA1=3, MA2=10, MA3=16. I am looking for the 3/10MA to cross above the slow 16MA.
Here is a photo.

 
markos

markos

Well-known member
VIP
@markos Hey, very well done my friend (y) It has a bit more info like percent away but is a great starter script
@tomsk For the above, @MBF would like this as MA1FastLine = Average(price, 3) - Average(price, 10);
Is this do-able for a WLC?
 
Last edited:
  • Wow
Reactions: MBF
T

tomsk

Well-known member
VIP
@markos Let's step back and look at the bigger picture.

FastLine measures the difference between 2 moving averages.
SlowLine is a moving average of the fast line, so it smoothens it out a bit,
Typically a moving average measures price, e.g. 16 SMA would measure the 16 period moving average based on price

My understanding is that the requester wants to compare that FastLine/SlowLine cross with SMA(16) which is based on price
The underlying parameters are different not quite sure if that comparison is really the intent.
 
J

Jimmy

New member
So what you want is the 3ma and the 10ma represented as one colored line... line to be one color(blue) if the 3ma is above the 10ma and another color if below (magenta).
Next you want a 16ma line. What conditions do you want to happen when ma1=3/10 crosses the ma2=16. An arrow or another color change?
 
markos

markos

Well-known member
VIP
Here it is! @MBF this is from the OneNote.
@tomsk are you able to cross check this script to find it's origin? JQ didn't have a citation in the ON.
Code:
# WLC for LBR_ThreeTenOscillator
#hint:<b>A WLC that shows the minutes-ago since the last turn of the moving average either up or down.</b>\nMay be use multiple times with each column set to a different aggregation. The exclusion of after-hours is recommended.

input price = close;#hint price: The price used to calculate the average. <b>(Default is CLOSE)</b>
input Length = 30;#hint Length: The number of bars used to calculate the moving average. <b>(Default is 30)</b>
input AvgType = {default Simple, Exponential, Weighted, Wilders, Hull};#hint AvgType: Type of the fast moving average to be used for calculation. <b>(Default is SIMPLE)</b>
input TurnType = {default ThreeBarTurn, FiveBarTurn};#hint TurnType:A <b>ThreeBarTurn</b> is one using a single before and after bar to define the turn.\n A <b>FiveBarTurn</b> is one using two bars before and two bars after to define a turn.

def AvgToUse;
switch (AvgType) {
case Simple:
AvgToUse = Average(price, Length);
case Exponential:
AvgToUse = ExpAverage(price, Length);
case Weighted:
AvgToUse = wma(price, Length);
case Wilders:
AvgToUse = WildersAverage(price, Length);
case Hull:
AvgToUse = HullMovingAvg(price, Length);
}

Def TurnDown;
Switch(TurnType){
Case ThreeBarTurn:
   TurnDown = if AvgToUse[1] < AvgToUse && AvgToUse[-1] < AvgToUse then 1 else 0;
Case  FiveBarTurn:
TurnDown = if AvgToUse[2] < AvgToUse[1] && AvgToUse[1] < AvgToUse && AvgToUse[-1] < AvgToUse && AvgToUse[-2] < AvgToUse[-1] then 1 else 0;
}   

Def TurnUp;
Switch(TurnType){
Case ThreeBarTurn:
   TurnUp = if AvgToUse[1] > AvgToUse && AvgToUse[-1] > AvgToUse then 1 else 0;
Case  FiveBarTurn:
   TurnUp = if AvgToUse[2] > AvgToUse[1] && AvgToUse[1] > AvgToUse && AvgToUse[-1] > AvgToUse && AvgToUse[-2] > AvgToUse[-1]  then 1 else 0;
}   

Def IsUp = If TurnUp then 1 else 0;
Def IsDown = If TurnDown then 1 else 0;
Def NumbOfBars = If IsUp then sum(IsUp) else if IsDown then sum(IsDown) else double.nan;

#===== Define the bars-to-minutes factor ===========
Def Factor =  if getAggregationPeriod() == AggregationPeriod.MIN then 1 else if 
getAggregationPeriod() == AggregationPeriod.TWO_MIN then 2 else if
getAggregationPeriod() == AggregationPeriod.THREE_MIN then 3 else if 
getAggregationPeriod() == AggregationPeriod.FOUR_MIN then 4 else if
getAggregationPeriod() == AggregationPeriod.FIVE_MIN then 5 else if 
getAggregationPeriod() == AggregationPeriod.TEN_MIN then 10 else if
getAggregationPeriod() == AggregationPeriod.FIFTEEN_MIN then 15 else if 
getAggregationPeriod() == AggregationPeriod.TWENTY_MIN then 20 else if
getAggregationPeriod() == AggregationPeriod.THIRTY_MIN then 30 else if 
getAggregationPeriod() == AggregationPeriod.HOUR then 60 else if
getAggregationPeriod() == AggregationPeriod.TWO_HOURS then 120 else if 
getAggregationPeriod() == AggregationPeriod.FOUR_HOURS then 240 else if
getAggregationPeriod() == AggregationPeriod.DAY then 1440 else if 
getAggregationPeriod() == AggregationPeriod.TWO_DAYS then 2880 else if
getAggregationPeriod() == AggregationPeriod.THREE_DAYS then 4320 else if
getAggregationPeriod() == AggregationPeriod.FOUR_DAYS then 5750 else if
getAggregationPeriod() == AggregationPeriod.WEEK then 7200 else if
getAggregationPeriod() == AggregationPeriod.MONTH then 28800 
else double.nan;
#========

Def MinsSinceTurn = factor * NumbOfBars; #Minutes Since Polarity Change ms

Plot Data_MST = MinsSinceTurn;
Data_MST.setdefaultcolor(color.YELLOW);
AssignBackgroundColor(if IsUp  then color.dark_green
else if IsDown then
color.dark_RED 
else color.current);
#end
 
T

tomsk

Well-known member
VIP
Here it is! @MBF this is from the OneNote.
@tomsk are you able to cross check this script to find it's origin? JQ didn't have a citation in the ON.
Code:
# WLC for LBR_ThreeTenOscillator
#hint:<b>A WLC that shows the minutes-ago since the last turn of the moving average either up or down.</b>\nMay be use multiple times with each column set to a different aggregation. The exclusion of after-hours is recommended.

input price = close;#hint price: The price used to calculate the average. <b>(Default is CLOSE)</b>
input Length = 30;#hint Length: The number of bars used to calculate the moving average. <b>(Default is 30)</b>
input AvgType = {default Simple, Exponential, Weighted, Wilders, Hull};#hint AvgType: Type of the fast moving average to be used for calculation. <b>(Default is SIMPLE)</b>
input TurnType = {default ThreeBarTurn, FiveBarTurn};#hint TurnType:A <b>ThreeBarTurn</b> is one using a single before and after bar to define the turn.\n A <b>FiveBarTurn</b> is one using two bars before and two bars after to define a turn.

def AvgToUse;
switch (AvgType) {
case Simple:
AvgToUse = Average(price, Length);
case Exponential:
AvgToUse = ExpAverage(price, Length);
case Weighted:
AvgToUse = wma(price, Length);
case Wilders:
AvgToUse = WildersAverage(price, Length);
case Hull:
AvgToUse = HullMovingAvg(price, Length);
}

Def TurnDown;
Switch(TurnType){
Case ThreeBarTurn:
   TurnDown = if AvgToUse[1] < AvgToUse && AvgToUse[-1] < AvgToUse then 1 else 0;
Case  FiveBarTurn:
TurnDown = if AvgToUse[2] < AvgToUse[1] && AvgToUse[1] < AvgToUse && AvgToUse[-1] < AvgToUse && AvgToUse[-2] < AvgToUse[-1] then 1 else 0;
} 

Def TurnUp;
Switch(TurnType){
Case ThreeBarTurn:
   TurnUp = if AvgToUse[1] > AvgToUse && AvgToUse[-1] > AvgToUse then 1 else 0;
Case  FiveBarTurn:
   TurnUp = if AvgToUse[2] > AvgToUse[1] && AvgToUse[1] > AvgToUse && AvgToUse[-1] > AvgToUse && AvgToUse[-2] > AvgToUse[-1]  then 1 else 0;
} 

Def IsUp = If TurnUp then 1 else 0;
Def IsDown = If TurnDown then 1 else 0;
Def NumbOfBars = If IsUp then sum(IsUp) else if IsDown then sum(IsDown) else double.nan;

#===== Define the bars-to-minutes factor ===========
Def Factor =  if getAggregationPeriod() == AggregationPeriod.MIN then 1 else if
getAggregationPeriod() == AggregationPeriod.TWO_MIN then 2 else if
getAggregationPeriod() == AggregationPeriod.THREE_MIN then 3 else if
getAggregationPeriod() == AggregationPeriod.FOUR_MIN then 4 else if
getAggregationPeriod() == AggregationPeriod.FIVE_MIN then 5 else if
getAggregationPeriod() == AggregationPeriod.TEN_MIN then 10 else if
getAggregationPeriod() == AggregationPeriod.FIFTEEN_MIN then 15 else if
getAggregationPeriod() == AggregationPeriod.TWENTY_MIN then 20 else if
getAggregationPeriod() == AggregationPeriod.THIRTY_MIN then 30 else if
getAggregationPeriod() == AggregationPeriod.HOUR then 60 else if
getAggregationPeriod() == AggregationPeriod.TWO_HOURS then 120 else if
getAggregationPeriod() == AggregationPeriod.FOUR_HOURS then 240 else if
getAggregationPeriod() == AggregationPeriod.DAY then 1440 else if
getAggregationPeriod() == AggregationPeriod.TWO_DAYS then 2880 else if
getAggregationPeriod() == AggregationPeriod.THREE_DAYS then 4320 else if
getAggregationPeriod() == AggregationPeriod.FOUR_DAYS then 5750 else if
getAggregationPeriod() == AggregationPeriod.WEEK then 7200 else if
getAggregationPeriod() == AggregationPeriod.MONTH then 28800
else double.nan;
#========

Def MinsSinceTurn = factor * NumbOfBars; #Minutes Since Polarity Change ms

Plot Data_MST = MinsSinceTurn;
Data_MST.setdefaultcolor(color.YELLOW);
AssignBackgroundColor(if IsUp  then color.dark_green
else if IsDown then
color.dark_RED
else color.current);
#end

@markos JQ is pretty good at noting the source of studies he posts to the ON.
I know that in addition to him, there are other folks that have edit priviledges
Perhaps one of them posted that. BTW I don't recall seeing that study in TSL, but I have missed a few days
 
MBF

MBF

Active member
2019 Donor
@markos ! :love:😃
Thank you! Should have visited this morning! I didnt think it was possible. I am eager to try it out!
Thank you guys so much for trying to figure this indicator out. Rough one for me!
@tomsk @Jimmy @horserider
 
MBF

MBF

Active member
2019 Donor
It says NaN on all aggregations. Is this a template that I fill in?
 
markos

markos

Well-known member
VIP
It says NaN on all aggregations. Is this a template that I fill in?
It should work as advertised.
@tomsk or anyone else, could you take a look at this tonight to see what you can find out? I am on mobile today/tonight. Thanks.
@MBF Is it giving you a warning of any type? It may be "complicated" and thus take TOS a while to populate. Please let us know if it occurs when you scan the S&P 100. That smaller list might help. Please give the particulars.
 
T

tomsk

Well-known member
VIP
@markos Per your request, I looked into the problem that was reported. Loading it onto the watchlist, I see NaN across all timeframes in the watchlist, daily, and intraday. That tells me that there is no data, or the underlying data sequence is being calculated incorrectly. Hence no data is being presented in the watchlist.

Since you say you obtained this from JQ's ON, probably best to check if he knows where the code originated from, perhaps it might have been an interim or works in progress version. I just don't know

Please post the exact link to the ON where you found it this study, which in my assessment is fubar, so probably best not to use it. If you like, I'll ask a friend to check in with JQ and ask him for the attribution and other details. Personally I don't use JQ's ON as I find that there are some instances of code being posted without having undergone QA.

Hope that helps @markos
 
T

tomsk

Well-known member
VIP
@markos As a follow up to your previous note, I had a friend contact JQ. Apparantly this study was in StanL’s Treebase. In case you are unaware, StanL was a lounge librarian of sorts who passed on in 2014. The WLC was found in a directory titled SFL Coded Studies. There is no header or attribution detail in the treebase.

After looking through the contents, he found a previous version of the study dated Feb 2012. Here is the code... I tested it on my watchlist (daily), and it performs MUCH better - no more NaN gibberish. However reviewing the code, it has nothing to do with LBR Three Ten oscillator, so perhaps that was something that was works in progress and uncompleted. Best to ditch that previous study

Hope this helps

Code:
#hint:Here's updated code that facilitates monitoring where in the intraday's high-low range a stock currently is. This is used in as a watchlist-gadget column as well as in TOS' 'MarketWatch/Quotes' tab. A Hi is definable and above that value will be highlighted with a green background. Likewise for a Lo but with a red. A dark red or dark green means that the current price is below yesterday's close.

#Title = %HL, Revision 2/22/12
#Please post any problems or suggestions with this code for 'Stan L' on TOS' Thinkscript Lounge chatroom

input HiPct = 0.90;
input LoPct = 0.10;

def diffclose = close[1] - close;
def diffH = high - close;
def diffTotal = high - low;
def Range = 1 - (diffH / diffTotal);
#def down = close < close[1];
plot data = round(Range);
data. assignvaluecolor(if Range >= HiPct then color.black
else if Range < LoPct then color.black else color.yellow);

Assignbackgroundcolor (if Range >= HiPct and (close > close[1]) then color.green
else if Range >= HiPct and (close < close[1]) then color.dark_green
else if Range <= LoPct and (close > close[1]) then color.RED
else if Range <= LoPct and (close < close[1]) then color.Dark_RED
else color.black);
#------End of Code--------
 
Last edited:
markos

markos

Well-known member
VIP
@markos As a follow up to your previous note, I had a friend contact JQ. Apparantly this study was in StanL’s Treebase. In case you are unaware, StanL was a lounge librarian of sorts who passed on in 2014. The WLC was found in a directory titled SFL Coded Studies. There is no header or attribution detail in the treebase.

After looking through the contents, he found a previous version of the study dated Feb 2012. Here is the code... I tested it on my watchlist (daily), and it performs MUCH better - no more NaN gibberish.

Hope this helps

Code:
#hint:Here's updated code that facilitates monitoring where in the intraday's high-low range a stock currently is. This is used in as a watchlist-gadget column as well as in TOS' 'MarketWatch/Quotes' tab. A Hi is definable and above that value will be highlighted with a green background. Likewise for a Lo but with a red. A dark red or dark green means that the current price is below yesterday's close.

#Title = %HL, Revision 2/22/12
#Please post any problems or suggestions with this code for 'Stan L' on TOS' Thinkscript Lounge chatroom

input HiPct = 0.90;
input LoPct = 0.10;

def diffclose = close[1] - close;
def diffH = high - close;
def diffTotal = high - low;
def Range = 1 - (diffH / diffTotal);
#def down = close < close[1];
plot data = round(Range);
data. assignvaluecolor(if Range >= HiPct then color.black
else if Range < LoPct then color.black else color.yellow);

Assignbackgroundcolor (if Range >= HiPct and (close > close[1]) then color.green
else if Range >= HiPct and (close < close[1]) then color.dark_green
else if Range <= LoPct and (close > close[1]) then color.RED
else if Range <= LoPct and (close < close[1]) then color.Dark_RED
else color.black);
#------End of Code--------
Thanks @tomsk I can work with that and a few snippets to help her come up with the code. She's ( @MBF ) tuned into the LBR code, so I'll try this weekend. @Townsend added a new entry on scanning in Tutorials, so I asked him if he could add this to his tutorial. Thanks again!
 
  • Love
Reactions: MBF

Similar threads

Top