1
//@version=4
study("Keep data across bars (var)", overlay=true)

// Variables
var bool canGoShort = true
var bool canGoLong = true
var int myTest = 5

// Functions
f_print(_txt) => t = time + (time - time[1]) * 3, var _lbl = label.new(t, high, _txt, xloc.bar_time, yloc.price, #00000000, label.style_none, color.gray, size.large), label.set_xy(_lbl, t, high + 3 * tr)

// MAIN
if canGoShort
    myTest := myTest + 1

if canGoLong
    myTest := myTest + 1

f_print("myTest=" + tostring(myTest))

I'm baffled by this simple script that doesn't seem to work as intended.

I initialize a var variable myTest with value 5.
Since canGoShort and canGoLong both are always true, I'd expect the value of myTest to be incremented by 1, twice on each bar:
Once in the if canGoShort, and once in the if canGoLong.
Say we have 5000 bars, then I'd expect it to finish at 5 + (5000 * 2) = 10005.

However, when running the script, myTest=7 is printed?

I'm getting the impression that the declaration var int myTest = 5 is executed on each bar.
It was my understanding that a variable defined with the keyword var keeps its value across all bars, but it doesn't appear to be that way.

The documentation clearly says that it should keep it's value:

What am I missing here?

Bjorn Mistiaen
  • 6,459
  • 3
  • 18
  • 42

1 Answers1

0

Calcs are happening as expected. What's wrong there is our f_print() function. Apologies for that. The version you picked up doesn't refresh the text. This code has a newer version of f_print() that does that.

Note that to inspect values bar by bar, as you would want here, our plotchar() trick is more useful, if you also have your Data Window open to inspect the value, as you can inspect each bar's value when you mouse bar to bar. See our answer here for our AHK macro that generates the statement from a variable name, if you have a Windows setup and are interested.

//@version=4
study("Keep data across bars (var)", overlay=true)

// Variables
var bool canGoShort = true
var bool canGoLong = true
var int myTest = 5

// Functions
f_print(_txt) => var _lbl = label.new(bar_index, highest(10)[1], _txt, xloc.bar_index, yloc.price, #00000000, label.style_none, color.gray, size.large, text.align_left), label.set_xy(_lbl, bar_index, highest(10)[1]), label.set_text(_lbl, _txt)
// MAIN
if canGoShort
    myTest := myTest + 1

if canGoLong
    myTest := myTest + 1

f_print("myTest=" + tostring(myTest, "0.0"))
plotchar(myTest, "myTest", "", location.top)

enter image description here Again, apologies for the trouble. We updated all the instances of f_print() in our FAQ. Note, btw, that we use that version mostly for debugging because it holds on one line. This is the AHK code we use to generate our f_print() with Ctrl+Shift+p for debugging:

^+P:: SendInput f_print(_txt) => var _lbl = label.new(bar_index, highest(10)[1], _txt, xloc.bar_index, yloc.price, {#}00000000, label.style_none, color.gray, size.large, text.align_left), label.set_xy(_lbl, bar_index, highest(10)[1]), label.set_text(_lbl, _txt)`nf_print(){Left}

In scripts that will be published, we use this version, which is more flexible and more efficient, but can't be compressed to one line because of the if statements:

// ————— Print a label at end of chart.
f_print(_txt, _y, _color, _offsetLabels) => 
    var label _lbl = na
    _t = int(time + (time - time[1]) * _offsetLabels)
    if barstate.islast
        if na(_lbl)
            // Only create label once.
            _lbl := label.new(_t, _y, _txt, xloc.bar_time, yloc.price, #00000000, label.style_none, color.gray, size.large)
            // Fudge return type of `if` block so compiler doesn't complain (thx midtownsk8rguy for the trick).
            int(na)
        else
            // Rather than delete and recreate the label on every realtime bar update, update the label's information; it's more efficient.
            label.set_xy(_lbl, _t, _y)
            label.set_text(_lbl, _txt)
            label.set_textcolor(_lbl, _color)
            int(na)
PineCoders-LucF
  • 8,288
  • 2
  • 12
  • 21