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
 

ldlework

New member
@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
 

XeoNoX

Well-known member
VIP
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.
 

ldlework

New member
@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
 

XeoNoX

Well-known member
VIP
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:

ldlework

New member
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.
 

XeoNoX

Well-known member
VIP
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 +"");
 
Thread starter Similar threads Forum Replies Date
Picard Planetary Cycles Indicator for ThinkorSwim Custom 15
J007RMC Linear Cycles Indicator for ThinkorSwim Indicators 8

Similar threads

Top