millionchart
فارسی

Text and the log

An input read as text, with the text functions, and lines written to the script's log at three levels.

Text is a value like a number: it can be cut, trimmed, converted and built from parts. The log is where a script writes what it noticed, and where it stops on purpose when its inputs make no sense.

Logged crossings#

Lines written to the log at three levels, and a run stopped on purpose by log.abort when the inputs make no sense.

Cuprel
// Messages to the script's log. log.info fills {0} and {1} with the values after the text, log.warning and log.error write at their own level,
// and log.abort stops the run on purpose when an input makes no sense.
indicator "Logged crossings"
    edition = 1
    display = price

input fast_length: int = 8, name = "Fast length", min = 1
input slow_length: int = 21, name = "Slow length", min = 2
if fast_length >= slow_length
    log.abort("The fast length must be shorter than the slow length")
let fast = tech.ema(close, fast_length)
let slow = tech.ema(close, slow_length)
let up = tech.crosses_above(fast, slow)
let down = tech.crosses_below(fast, slow)
if up
    log.info("Up cross on bar {0}, close {1}", bar.index, close)
if down
    log.warning("Down cross on bar {0}", bar.index)
if close <= 0
    log.error("Bad price on bar {0}", bar.index)
plot(fast, name = "Fast", color = color.green)
plot(slow, name = "Slow", color = color.red)

Levels from text#

An input read as text: replace, split, trim and convert the parts, and build the labels with text.format.

Cuprel
// Text functions on an input. The input holds multipliers written as text. text.replace_all lets a semicolon stand for a comma, text.split cuts the text into parts,
// text.trim and text.to_number read each part, and text.format builds the label. A part that is not a number is skipped.
indicator "Levels from text"
    edition = 1
    display = price
    max_lines = 20
    max_labels = 20

input multipliers: text = "1; 1.5, 2.5", name = "Multipliers of the range"
let range = tech.atr(14)
if bar.is_last
    for part in text.split(text.replace_all(multipliers, ";", ","), ",")
        let k = text.to_number(text.trim(part))
        if not is_na(k)
            let price = close + k * range
            line.new(bar.index - 30, price, bar.index, price, style = dashed, color = color.gray)
            label.new(
                bar.index,
                price,
                text.format("{0} ranges", text.trim(part)),
                style = label_left,
            )
plot(close, name = "Close", color = color.blue)

Stopped on purpose#

The default inputs fail the check in the script, so log.abort ends the run with its message.

Cuprel · error E5637
// A mistake on purpose: the default fast length is longer than the slow one, so log.abort ends the run.
indicator "Logged crossings"
    edition = 1
    display = price

input fast_length: int = 30, name = "Fast length", min = 1
input slow_length: int = 21, name = "Slow length", min = 2
if fast_length >= slow_length
    log.abort("The fast length must be shorter than the slow length")
let fast = tech.ema(close, fast_length)
let slow = tech.ema(close, slow_length)
let up = tech.crosses_above(fast, slow)
let down = tech.crosses_below(fast, slow)
if up
    log.info("Up cross on bar {0}, close {1}", bar.index, close)
if down
    log.warning("Down cross on bar {0}", bar.index)
if close <= 0
    log.error("Bad price on bar {0}", bar.index)
plot(fast, name = "Fast", color = color.green)
plot(slow, name = "Slow", color = color.red)