Modifying Plot Values

MooreTechLLC

New member
I am trying to convert an indicator to TOS from MT4. The MT4 code is using a loop and repainting the plot values on each bar. I've included some pseudo code below to show what I'm trying to accomplish. How would I accomplish this TOS?

Code:
input Per=10;
for (x=0;x<Per;x++)
    plot myPlot[x] = Sum(close,x);
 
Solution
I believe you are misinterpreting the code I posted. It is not simply taking the sum of the prior 'x' bars. On the current bar, it is calculating the sum with a period of 1. Each bar it moves back, the period is increased by 1. So 9 bars ago would be using a period of 10. Does that make sense?

Example:
myPlot[0] = Sum(Close, 1);
myPlot[1] = Sum(Close, 2);
myPlot[2] = Sum(Close, 3);
....
myPlot[9] = Sum(Close, 10);
It's entirely possible that I misinterpret the code. I speak Thinkscript and python and sql and a few others but the nuances escape me often at first glance. Your explanation makes good sense and I can see your take on the code. Let me try again.

I've not tested this in a ToS editor... this is just a thought which...

mashume

Well-known member
VIP
Lifetime
Loops are done, in ToS, with the black-art magic of the FOLD() function.
https://tlc.thinkorswim.com/center/reference/thinkScript/Reserved-Words/fold
From the docs:
Code:
def <result> = fold <index> = <start> to <end> [ with <variable> [ = <init> ] ] [ while <condition> ] do <expression>;

so in your case, you'd have something like this:
Code:
input per = 10;
plot myPlot = (fold n = 0 to per with s do s + getValue(CLOSE, n, per));

but looking at your code, if each bar is simply the sum of the prior per bars, then this should do:
Code:
input per = 10;
plot myPlot = sum(CLOSE, per);

One of those should give you close to what you need. perhaps :)

Happy Trading,
mashume
 

MooreTechLLC

New member
I believe you are misinterpreting the code I posted. It is not simply taking the sum of the prior 'x' bars. On the current bar, it is calculating the sum with a period of 1. Each bar it moves back, the period is increased by 1. So 9 bars ago would be using a period of 10. Does that make sense?

Example:
myPlot[0] = Sum(Close, 1);
myPlot[1] = Sum(Close, 2);
myPlot[2] = Sum(Close, 3);
....
myPlot[9] = Sum(Close, 10);
 
Last edited:

mashume

Well-known member
VIP
Lifetime
I believe you are misinterpreting the code I posted. It is not simply taking the sum of the prior 'x' bars. On the current bar, it is calculating the sum with a period of 1. Each bar it moves back, the period is increased by 1. So 9 bars ago would be using a period of 10. Does that make sense?

Example:
myPlot[0] = Sum(Close, 1);
myPlot[1] = Sum(Close, 2);
myPlot[2] = Sum(Close, 3);
....
myPlot[9] = Sum(Close, 10);
It's entirely possible that I misinterpret the code. I speak Thinkscript and python and sql and a few others but the nuances escape me often at first glance. Your explanation makes good sense and I can see your take on the code. Let me try again.

I've not tested this in a ToS editor... this is just a thought which I'll test out and edit later in the day as I can...
Code:
input period = 10;
def barnum = BarNumber();

script MyFunc {
    input period = 1
    plot myFunc = (fold n = 0 to period with s do s + getValue(CLOSE, n, per));
}

def ThisBarInPeriod = highestall(barnum) - barnum;
def MyVar = if barnum > (highestall(barnum) - period)
    then
        MyFunc(period = ThisBarInPeriod)
    else
        double.nan;

plot MyPlot = MyVar;

By way of explanation
we define a script (sub script or function) which allows us to pass the length we need (period) for the specific candle to sum over.
we set the variable ThisBarInPeriod to tell us how many bars back from the highest bar we are, since ToS counts up with 0 on the left-most bar and the highestall(barnumber()) at the extreme right.
we define MyVar only when we're within the last period bars of the right side of the chart, since before that it seems it wouldn't have any meaning... I could be wrong here. Let me know.
we assign the value for MyVar by calling the MyFunc function with the number of bars back from the right side of the chart as the argument and plot the result.

Perhaps this runs the first time. Perhaps not. I've just constructed it here in browser. I'll test it later on.

I have the feeling there's a perfectly simple solution just waiting in plain sight somewhere around here. :)

-mashume
 
Solution

MooreTechLLC

New member
I had to modify your code slightly to get it to compile, but it is not plotting anything. The value says NA.

Code:
input Per = 14;

def barnum = BarNumber();

script MyFunc {
    input period = 1;
    plot myFunc = (fold n = 0 to period with s=0 do s + getValue(Close, n, 0));
}

def ThisBarInPeriod = highestall(barnum) - barnum;
def MyVar = if barnum > (highestall(barnum) - Per)
    then
        MyFunc(period = ThisBarInPeriod)
    else
        double.nan;

plot MyPlot = MyVar;

I'm not certain your example is going to do what I need, so I am going to try and further clarify. Assume the chart is loading the data, so our calculations will start on bar #1 (with a period of 3). When bar #1 closes:

Code:
plot myPlot = Sum(Close, 1);

When bar #2 closes, we need to set a value for the plot on bar #2 and also update the plot value on bar #1:

Code:
plot myPlot = Sum(Close, 1);
myPlot[1] = Sum(Close, 2);

When bar #3 closes, we need to set a value for the plot on bar #3 and also update the plot values on bars #1 and #2:

Code:
plot myPlot = Sum(Close, 1);
myPlot[1] = Sum(Close, 2);
myPlot[2] = Sum(Close, 3);

Because we are using a period of 3, the value of myPlot on bar #1 will not be modified again after bar #3 closes.
 

mashume

Well-known member
VIP
Lifetime
Code:
declare lower;

input Per = 14;

def barnum = BarNumber();

script MyFunc {
    input num = 1;
    input period = 14;
    plot myFunc =
        if num <= period then
        fold n = 0 to num with s = 0 do s + (getValue(Close, n) - getValue(Close, n + 1 ))
    else
        fold a = 0 to period with q = 0 do q + (getValue(Close, a) - getValue(Close, a + 1))
    ;
}

def ThisBarInPeriod = highestall(barnum) - barnum;
def MyVar = MyFunc(num = ThisBarInPeriod, period = per);

plot MyPlot = MyVar;
plot zero = 0;

?
 

mashume

Well-known member
VIP
Lifetime
Code:
declare lower;

input Per = 14;

def barnum = BarNumber();

script MyFunc {
    input num = 1;
    input period = 14;
    plot myFunc =
        if num <= period then
        fold n = 0 to num with s = 0 do s + (getValue(Close, n) - getValue(Close, n + 1 ))
    else
        fold a = 0 to period with q = 0 do q + (getValue(Close, a) - getValue(Close, a + 1))
    ;
}

def ThisBarInPeriod = highestall(barnum) - barnum;
def MyVar = MyFunc(num = ThisBarInPeriod, period = per);

plot MyPlot = MyVar;
plot zero = 0;

?
Still not sure that's doing what you want it to.
 

mashume

Well-known member
VIP
Lifetime
Not quite. Is it not possible to modify a plot value a few bars after it is initially assigned a value?
No. Thinkscript is really a functional language, not procedural. That's why there are no loops per se and why variables are really immutable once set. Therein lies the need to make a call to a subscript to handle different inputs. (you can call the same function differently at each candle, but can't 'poke' values into past registers and can't change data once evaluated.

Now, all that said, ToS does rerun the script for each candle generated (for all candles on the chart each time), thus the never ending discussions about repainting.

we live with the limits because we like the other features.

-mashume
 

halcyonguy

Well-known member
VIP
Lifetime
I had to modify your code slightly to get it to compile, but it is not plotting anything. The value says NA.

Code:
input Per = 14;

def barnum = BarNumber();

script MyFunc {
    input period = 1;
    plot myFunc = (fold n = 0 to period with s=0 do s + getValue(Close, n, 0));
}

def ThisBarInPeriod = highestall(barnum) - barnum;
def MyVar = if barnum > (highestall(barnum) - Per)
    then
        MyFunc(period = ThisBarInPeriod)
    else
        double.nan;

plot MyPlot = MyVar;

I'm not certain your example is going to do what I need, so I am going to try and further clarify. Assume the chart is loading the data, so our calculations will start on bar #1 (with a period of 3). When bar #1 closes:

Code:
plot myPlot = Sum(Close, 1);

When bar #2 closes, we need to set a value for the plot on bar #2 and also update the plot value on bar #1:

Code:
plot myPlot = Sum(Close, 1);
myPlot[1] = Sum(Close, 2);

When bar #3 closes, we need to set a value for the plot on bar #3 and also update the plot values on bars #1 and #2:

Code:
plot myPlot = Sum(Close, 1);
myPlot[1] = Sum(Close, 2);
myPlot[2] = Sum(Close, 3);

Because we are using a period of 3, the value of myPlot on bar #1 will not be modified again after bar #3 closes.

maybe this is what you are looking for.

select a period , default is 10
when a barnumber is within the 'period' bars from the last bar then,
2 loops will sum up close prices
. on each of those bars,
. cls_cnt_past - sums the close prices from that bar to previous 'period' bars
. cls_cnt_future - sums the close prices from that bar to future 'period' bars

past data is shown in yellow bubbles, under the candles
future data is shown in green bubbles, above the candles

Ruby:
# sumprevx_close_00

def bn = barnumber();
def lastbarbn = HighestAll(If(IsNaN(close), 0, bn));
def lastbar = if (bn == lastbarbn) then 1 else 0;

#count bars to lastbar
input qty = 10;
def barz = lastbarbn - bn;

def cls_cnt_past;
def cls_cnt_future;
if barz <= qty then {

# sum past close's
  cls_cnt_past = fold i = 0 to barz+1
  with p
  do p + getvalue( close, i);

# sum future close's
cls_cnt_future = fold j = 0 to barz+1
  with q
  do q + getvalue( close, -j);

} else {
  cls_cnt_past = 0;
  cls_cnt_future = 0;
}

addchartbubble(1, low*0.994,
"sum of past close" + "\n" +
bn + " bar#\n" +
barz + " bn to last\n" +
close + " cls\n" +
cls_cnt_past + " sum"
, (if barz <= qty then color.yellow else color.gray), no);

addchartbubble(1, high*1.006,
"sum of future close" + "\n" +
bn + " bar#\n" +
barz + " bn to last\n" +
close + " cls\n" +
cls_cnt_future + " sum"
, (if barz <= qty then color.green else color.gray), yes);
#


TJX 1hr jan 21
GPeXpr7.jpg
 

Similar threads

Top