Never Going Back Again
// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © allanster

//@version=5
indicator('Never Going Back Again', 'NGBA', overlay = true, max_lines_count = 500)

// Draws lines for each of up to 500 prices that have never been revisited at the present moment in time, as time progresses these levels may or may not hodl.
// Adaptation of "Never Look Back Price" originally described by Timothy Peterson in his research paper entitled "Why Bitcoin's Price Is Never Looking Back".
// For more information see: https://static1.squarespace.com/static/5d580747908cdc0001e6792d/t/5e93243abadd4454b360bf18/1586701372057/research+note+4.12.pdf

inSource  = input       (defval = low,                     title = 'Never Going Back Again Source')
inStyles  = input.string(defval = 'Solid',                 title = 'Lines Show As',                 options = ['Dashed', 'Dotted', 'Solid'], inline = '1')
inColors  = input.color (defval = color.new(#8000ff, 0), title = ' ',                                                                      inline = '1')

f_lineNew(_y) =>                                                    // create function to create new lines when called
    line.new(time, _y, time + 60 * 60 * 24, _y, xloc.bar_time, extend.right, inColors,
     inStyles == 'Dashed' ? line.style_dashed : inStyles == 'Dotted' ? line.style_dotted : line.style_solid)

var float[] prValues = array.new_float(0)                           // create float array of price values
var line[]  prLevels = array.new_line(0)                            // create  line array of price levels

if ta.rising(inSource, 1)                                           // if inSource rising
    array.push(prValues, inSource)                                  // populate price values array with higher inSource valu element
    array.push(prLevels, f_lineNew(inSource))                       // populate price levels array with higher inSource line element
if ta.falling(inSource, 1)                                          // if inSource falling
    for i = (array.size(prValues) == 0 ?
     na : array.size(prValues) - 1) to 0 by 1                       // loop backwards through array of price values
        if inSource < array.get(prValues, i)                        // check if inSource breaks below each of the stored price values
            deValu = array.pop(prValues)                            // depopulate any broken price valu element(s) and return valu
            deLine = array.pop(prLevels)                            // depopulate any broken price line element(s) and return line
            line.delete(deLine)                                     // delete any broken price line element(s) that were drawn
    array.push(prValues, inSource)                                  // populate price values array with lower inSource valu element
    array.push(prLevels, f_lineNew(inSource))                       // populate price levels array with lower inSource line element


// === Flex Crude Approximation Of Tolkien Runic Language ===
reVeiled = input       (group = ' ', inline = '2', title = 'One stRing To Rule Them All',    defval = true)
isSpoken = input.string(group = ' ', inline = '2', title = '',                               defval = 'ᚱᛁᛋK ᚩᚠ ᚱᚢᚾᛖ', options = ['ᚱᛁᛋK ᚩᚠ ᚱᚢᚾᛖ', 'Risk Of Rune'])
pureFlex = input       (group = ' ',               title = 'Lord Of The stRings Rune Color', defval = color.new(#ffd700, 0))

dCode(_text) =>  // input Tolkienish output English
    runic = '|ᚫ|ᛒ|ᚳ|ᛞ|ᛖ|ᚠ|ᚷ|ᚻ|ᛁ|ᛁ|K|ᛚ|ᛗ|ᚾ|ᚩ|ᛈ|Kᚹ|ᚱ|ᛋ|t|ᚢ|ᚢ|ᚹ|ᛉ|ᚣ|ᛦ'    + '|0|1|2|3|4|5|6|7|8|9| |᛫|᛬|\'|[|]|\n|'   //runic characters
    nglsh = '|A|B|C|D|E|F|G|H|I|J|K|L|M|N|O|P|Q|R|S|T|U|V|W|X|Y|Z' + '|0|1|2|3|4|5|6|7|8|9| |.|:|\'|[|]|\n|'  //nglih characters
    arrEN = str.split(nglsh, '|')                                   // split each nglsh character into an array of indexed alphn characters
    arrRN = str.split(runic, '|')                                   // split each runic character into an array of indexed runic characters
    arrIn = str.split(_text, '')                                    // split each input character into an array of indexed input characters
    lenIn = str.length(_text)                                       // count input characters in _text
    arrdC = array.new_string(lenIn, '•')                            // create string array of size lenIn and populate with character
    if barstate.islast
        for idxInChar = 0 to lenIn - 1 by 1                         // loop through array of character elements
            getInChar = array.get(arrIn, idxInChar)                 // get each input character from input string array
            idxRNChar = array.indexof(arrRN, getInChar)             // get index number of runic array character that matches input array character
            idxRNChek = idxRNChar == -1 ? 43 : idxRNChar            // if unsupported runic character substitute empty character
            getENChar = array.get(arrEN, idxRNChek)                 // get nglsh character of corresponding runic index number from runic array
            array.set(arrdC, idxInChar, getENChar)                  // overwrite populated character in dCoded array with nglsh characters
    dCoded = array.join(arrdC, '')                                  // create dCoded string array and return value of joined string element
    dCoded

runicInp = 
 '[ᚢᛖᚱᛋᛖ 1]\nᛋᚻᛖ ᛒᚱᚩKᛖ ᛞᚩᚹᚾ ᚫᚾᛞ ᛚᛖt ᛗᛖ ᛁᚾ\nᛗᚫᛞᛖ ᛗᛖ ᛋᛖᛖ ᚹᚻᛖᚱᛖ ᛁ\'ᛞ ᛒᛖᛖᚾ\n\n[ᚳᚻᚩᚱᚢᛋ]\nᛒᛖᛖᚾ ᛞᚩᚹᚾ ᚩᚾᛖ tᛁᛗᛖ\nᛒᛖᛖᚾ ᛞᚩᚹᚾ tᚹᚩ tᛁᛗᛖᛋ\nᛁ\'ᛗ ᚾᛖᚢᛖᚱ ᚷᚩᛁᚾᚷ ᛒᚫᚳK ' +
 'ᚫᚷᚫᛁᚾ\n\n[ᚢᛖᚱᛋᛖ 2]\nᚣᚩᚢ ᛞᚩᚾ\'t Kᚾᚩᚹ ᚹᚻᚫt ᛁt ᛗᛖᚫᚾᛋ tᚩ ᚹᛁᚾ\nᚳᚩᛗᛖ \'ᚱᚩᚢᚾᛞ ᚫᚾᛞ ᛋᛖᛖ ᛗᛖ ᚫᚷᚫᛁᚾ\n\n[ᚳᚻᚩᚱᚢᛋ]\nᛒᛖᛖᚾ ᛞᚩᚹᚾ ᚩᚾᛖ tᛁᛗᛖ\nᛒᛖᛖᚾ ᛞᚩᚹᚾ tᚹᚩ tᛁᛗᛖᛋ\nᛁ\'ᛗ ' + 
 'ᚾᛖᚢᛖᚱ ᚷᚩᛁᚾᚷ ᛒᚫᚳK ᚫᚷᚫᛁᚾ\n\nᚫᚱtᛁᛋt᛬ ᚠᛚᛖᛖtᚹᚩᚩᛞ ᛗᚫᚳ\nᚫᛚᛒᚢᛗ᛬ ᚱᚢᛗᚩᚢᚱᛋ\nᚱᛖᛚᛖᚫᛋᛖᛞ᛬ 1977\nᚷᛖᚾᚱᛖ᛬ ᚱᚩᚳK\nKᛖᚣ᛬ ᚷ ᛗᚫᛁᚩᚱ'

f_print(_text, _color) =>                                           // create function to print table _text when called
    var table _t = table.new(position.top_right, 1, 1)
    if barstate.islast
        table.cell(_t, 0, 0, _text, text_color = _color, text_halign = text.align_left, text_size = size.auto)
f_print(reVeiled ? isSpoken == 'ᚱᛁᛋK ᚩᚠ ᚱᚢᚾᛖ' ? runicInp : dCode(runicInp) : string(na), pureFlex)