Confusion about cycles

ldlework

New member
I am trying to learn Thinkscript and I've come across something I haven't been able to solve.

Imagine you're looking at a 10 minute chart. We could draw a line of the high of the 1 hour candle if we wanted. Each 1 hour candle high would be numbered, 1, 2, 3, 4, etc. For each 10 minute bar inside a 1 hour candle, we'd number them 1, 2, 3, 4, 5, 6, 1, 2, 3 ,4 ,5 ,6, 1, 2, etc

I have gotten really close:

nQVY6dv.png


As you can see, the hourly highs are drawn, and numbered. However, I cannot figure out how to properly count the 10 minute bars properly. Here is the relevant snippet from the code:

Code:
def lower_period_bar_index =
    if higher_period_bar_changed
    then 0 # reset to 0 after higher period bar change
    else lower_period_bar_index[1] + 1; # otherwise, count up

It seems like the "else" never gets utilized. But if I inverse the condition and put the increment in the "then", it doesn't work either. Can someone help me get this working, or understand why it can't?

Here is the entire code:


Code:
DECLARE UPPER;

#------------------------------------
# INPUTS
#------------------------------------
input higher_period = AggregationPeriod.HOUR;

#------------------------------------
# TIMEFRAMES
#------------------------------------
def lower_period = GetAggregationPeriod();
def lower_period_bar_count = higher_period / lower_period;

def H = high(period = higher_period);
def L = low(period = higher_period);
def O = open(period = higher_period);
def C = close(period = higher_period);
def NAN = double.Nan;

def higher_period_bar_changed =
    H != H[1] or
    O != O[1] or
    L != L[1] or
    C != C[1];

def higher_period_bar_index =
    if higher_period_bar_changed
    then higher_period_bar_index[1] + 1
    else higher_period_bar_index[1];

def lower_period_bar_index =
    if higher_period_bar_changed
    then 0 # reset to 0 after higher period bar change
    else lower_period_bar_index[1] + 1; # otherwise, count up

def even_higher_period_bar = higher_period_bar_index % 2 == 0;

#------------------------------------
# OPEN / CLOSE LINES
#------------------------------------

plot highline = H;
highline.AssignValueColor(if O < C then Color.Green else Color.Red);
highline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
highline.SetLineWeight(1);

#------------------------------------
# DISPLAY
#------------------------------------

# higher period bar index
AddChartBubble(H != H[1] or O != O[1] or L != L[1] or C != C[1], H, higher_period_bar_index, Color.GREEN);

# lower period bar index
AddChartBubble(yes, H + 1, lower_period_bar_index);

And here is a shared chart: http://tos.mx/JDZeL7J
 
@XeoNoX What about the code is off?

The script tracks the highs over a higher timestep. Say you're on 10 minute chart. You're tracking the 1 hour highs. That means there's 6 ten-minute bars in 1 one-hour bar.

The script numbers each higher-timestep high, incrementing as it goes. (That's in the screenshot, the green pips tracking the 60 minute highs).

The script should also number each lower-timestep bar, incrementing as it goes. (In the screenshot, the red pips, tracking the 10 minute bars). The numbering should go from 1-6, 1-6, 1-6, etc.

Code:
(1)                          (2)

____________________________________________________________

|                            |                             |   <-- hourly highs

[  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ] [  ]    <-- 10 minute bars of the current chart

(1)  (2)  (3)  (4)  (5)  (6)  (1)  (2)  (3)  (4)  (5)  (6)

The hourly highs are correctly drawn, and counted. I cannot cyclically count the 10 minute bars that fall under each hourly bar.

Here is simplified code:


Code:
DECLARE UPPER;

#------------------------------------
# INPUTS
#------------------------------------
input higher_period = AggregationPeriod.HOUR;

#------------------------------------
# TIMEFRAMES
#------------------------------------
def lower_period = GetAggregationPeriod();
# how many lower-timeframe bars in 1 higher-timeframe bar
def lower_period_bar_count = higher_period / lower_period;

# higher timeframe high/open/close
def H = high(period = higher_period);
def O = open(period = higher_period);
def C = close(period = higher_period);
def NAN = double.Nan;

def higher_bar_changed = H != H[1];

def higher_period_bar_index =
    if higher_bar_changed
    then higher_period_bar_index[1] + 1
    else higher_period_bar_index[1];

def lower_period_bar_index =
    if higher_bar_changed
    then 1 # reset to 1 after higher period bar change
    else lower_period_bar_index[1] + 1; # otherwise, count up


#------------------------------------
# HIGH LINES
#------------------------------------

plot highline = H;
highline.AssignValueColor(if O < C then Color.Green else Color.Red);
highline.SetPaintingStrategy(PaintingStrategy.HORIZONTAL);
highline.SetLineWeight(1);

#------------------------------------
# DISPLAY BAR NUMBERS
#------------------------------------

# higher period bar index
AddChartBubble(H != H[1], H, higher_period_bar_index, Color.GREEN);
# extra question:
# why can't we use `higher_bar_changed` variable as the condition
# instead of typing H != H[1] explicitly?

# lower period bar index
AddChartBubble(yes, H + 1, lower_period_bar_index);

Chart with updated code: http://tos.mx/Ilz3CZz
 
i spent about an hour learning your thought processes in your code and one thing i can say is that it is amazing you had coded that without referencing gettime or seconds from time. if you dont mind i cant get it to count using seconds from time or gettime, the code will be longer of course.
 
@XeoNoX I of course would be interested in seeing a version this script that works. If you write it, thanks for doing that. It's part of a larger script I'm working on.

However, I think the primary thing is that I am quite baffled why the code does not work as expected. I think it has something to do with boolean streams.

I have concocted a minimal example that demonstrates the confusion.

Let's have Plot A plot higher-timeframe highs:

Code:
input higher_period = AggregationPeriod.HOUR;
plot A = high(period = higher_period);

Let's have Plot B plot when the higher-timeframe high changes:

Code:
plot B = A != A[1];


Plot B should waffle between 0 and 1 based on whether Plot A changed.

Let's add add a coloring effect to both plots as well:

Code:
A.AssignValueColor(if A != A[1] then Color.Cyan else Color.Gray);
B.AssignValueColor(if B then Color.Green else Color.Gray);

We should expect A to plot the hourly highs in grey, switching to cyan anytime the high changes.

We should expect B to plot 0 in gray while A stays constant, and 1 in green on bars where A changes.

But instead we get this:

GuXRFk2.png


Can you explain why A is correctly colored but B is incorrectly colored?

Can you explain why B does not correctly plot the bars where A changes?

Here is the complete code:

Code:
DECLARE UPPER;

input higher_period = AggregationPeriod.HOUR;

plot A = high(period = higher_period);
plot B = A != A[1];

A.AssignValueColor(if A != A[1] then Color.Cyan else Color.Gray);
B.AssignValueColor(if B then Color.Green else Color.Gray);

And shared chart: http://tos.mx/4KvXLX7
 
thats the problem, you are using higher_period = AggregationPeriod.HOUR;
you cant count anything lower than an hour as long as you continue to use that reference.
you need to start all new lines of codes for the 10 minute without referencing any higher aggregation period than 10 minutes.

one way you can do this is using secondsfromtime and manually do the hours, example:

if secondsfromtime is 0000-0100 or 0100-0200 or 0200-0300 or 0300-0400 or (keep counting this pattern till you hit the end of the day) then count else doublenan.

you can give it a shot, if not ill post it later today or tomorrow, ive been busy past few days.
if you want to save me sime time you can atleast do this pattern till the end of the day so i can just copy and paste:

0000-0100 or 0100-0200 or 0200-0300 or 0300-0400
 
Last edited:
Hey I actually discovered the same thing yesterday and figured out a work around to correctly resample the higher aggregation period. The issue is actually mentioned in the thinkscript documentation! Just had to read the whole thing :) Thanks for your help.
 
you can keep repeating this, final code will be slightly long code, there might be a shorter way, but this works.

Code:
declare upper;
def selected_time = if SecondsFromTime(0600) >= 0 and SecondsFromTime(659) <
0 then 1 else 0 ;
def var = selected_time and low;
def barUpCount = CompoundValue(1, if var then barUpCount[1] + 1 else 0, 0);
AddChartBubble(barUpCount, close, barUpCount +"");

def selected_time2 = if SecondsFromTime(0700) >= 0 and SecondsFromTime(759) <
0 then 1 else 0 ;
def var2 = selected_time2 and low;
def barUpCount2 = CompoundValue(1, if var2 then barUpCount2[1] + 1 else 0, 0);
AddChartBubble(barUpCount2, close, barUpCount2 +"");
 

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

Not the exact question you're looking for?

Start a new thread and receive assistance from our community.

87k+ Posts
415 Online
Create Post

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