//@version=6 indicator("Star Cycles", "Stars", overlay = true, max_boxes_count = 500, max_labels_count = 500) // ============================================================================= // Alleen de ster-cycli. Niets anders. // // DE REGEL, uit zijn eigen tmu-cycle-ladder.pine: // f_star(s) = (s==0 or s==3) ? 0 : 2 welk 2H-derde de ster is // isOpener40/13/44 = pos == 0 daaronder altijd het eerste derde // // Asia en NY PM hebben hun ster dus in het EERSTE 2H-derde van hun sessie, // Londen en NY AM in het DERDE. Daaronder is het telkens het eerste derde van // de ster erboven. Dat levert vier takken van vier niveaus: // // tak ster 2H 40m 13,3m 4,44m // Asia 18:00-20:00 18:00-18:40 18:00-18:13:20 18:00-18:04:27 // Londen 04:00-06:00 04:00-04:40 04:00-04:13:20 04:00-04:04:27 // NY AM 10:00-12:00 10:00-10:40 10:00-10:13:20 10:00-10:04:27 // NY PM 12:00-14:00 12:00-12:40 12:00-12:13:20 12:00-12:04:27 // // 16 ster-cycli per dag, maar op VIER momenten: binnen een tak beginnen alle // vier de niveaus op dezelfde seconde. Je ziet dus vier trechters, geen // zestien losse blokken. Daarom loopt de transparantie van buiten naar binnen // op -- het binnenste blok is het sterkst. // // VORM. Elk blok omsluit de kaarsen van zijn eigen venster: top = hoogste // high, bodem = laagste low, levend meegroeiend. Rechterrand wordt een bar // teruggetrimd zodat de volgende cyclus zijn eigen openingskaars houdt. // // RESOLUTIE. 13,3m is 800 seconden en 4,44m is 266,67 seconden. Geen van beide // past op een 1-minuut raster. Op een 1-minuut chart vallen de randen op hele // bars (13,3m wordt 14 bars, 4,44m wordt 5) -- dezelfde soort afronding als // een sessie op een uurchart. Exact wordt het pas op 10s/20s/40s bars. Die // twee niveaus zijn daarom gesloten boven 1 minuut. // // BUDGET. Niets wordt verwijderd, dus TradingView gooit de oudste weg bij 500. // 16 blokken per dag = ongeveer 31 dagen historie. // // Alle tijden New York, zomer/wintertijd automatisch. // ============================================================================= tz = "America/New_York" // ───────────────────────────── takken ───────────────────────────── gB = "Takken" bAS = input.bool(true, "Asia 18:00", inline = "b1", group = gB) bLO = input.bool(true, "Londen 04:00", inline = "b1", group = gB) bAM = input.bool(true, "NY AM 10:00", inline = "b2", group = gB) bPM = input.bool(true, "NY PM 12:00", inline = "b2", group = gB) // ───────────────────────────── niveaus ───────────────────────────── // Transparantie per niveau: buiten licht, binnen sterk. Zo lees je de trechter. gL = "Niveaus" on2H = input.bool(true, "2H", inline = "l1", group = gL) tr2H = input.int(92, "", minval = 0, maxval = 100, inline = "l1", group = gL) on40 = input.bool(true, "40m", inline = "l2", group = gL) tr40 = input.int(88, "", minval = 0, maxval = 100, inline = "l2", group = gL) on13 = input.bool(true, "13,3m", inline = "l3", group = gL) tr13 = input.int(82, "", minval = 0, maxval = 100, inline = "l3", group = gL, tooltip = "800 seconden. Past niet op een 1-minuut raster: de randen vallen op hele bars, dus het blok wordt 14 bars breed in plaats van 13,33. Exact op 10s/20s/40s. Boven 1 minuut wordt dit niveau niet getekend.") on44 = input.bool(true, "4,44m", inline = "l4", group = gL) tr44 = input.int(74, "", minval = 0, maxval = 100, inline = "l4", group = gL, tooltip = "266,67 seconden, dus niet eens een heel aantal seconden. Op 1 minuut wordt dit 5 bars. Boven 1 minuut niet getekend.") // ───────────────────────────── uiterlijk ───────────────────────────── gS = "Uiterlijk" starC = input.color(color.orange, "Ster-kleur", group = gS, tooltip = "Een kleur voor alle zestien. De vier niveaus verschillen alleen in transparantie, zodat het als een familie leest en niet als vier losse dingen.") bordOn = input.bool(true, "Rand", inline = "bd", group = gS) bordS = input.string("Dotted", "", options = ["Solid", "Dashed", "Dotted"], inline = "bd", group = gS) lblOn = input.bool(true, "Namen", group = gS) lblSzI = input.string("tiny", " └ grootte", options = ["tiny", "small", "normal"], group = gS) lblSz = lblSzI == "tiny" ? size.tiny : lblSzI == "small" ? size.small : size.normal bordSt = bordS == "Solid" ? line.style_solid : bordS == "Dashed" ? line.style_dashed : line.style_dotted // ───────────────────────────── tijd ───────────────────────────── tfSec = timeframe.in_seconds() secs = hour(time, tz) * 3600 + minute(time, tz) * 60 + second(time, tz) // Een vensterrand moet op een barrand vallen, anders wordt de cyclus midden in // een kaars afgesneden. 2H en 40m kunnen exact; 13,3m en 4,44m nooit, die // worden alleen op 1 minuut en lager getekend. ok2H = timeframe.isintraday and tfSec <= 3600 and 3600 % tfSec == 0 ok40 = timeframe.isintraday and tfSec <= 2400 and 2400 % tfSec == 0 okFn = timeframe.isintraday and tfSec <= 60 // Startseconde van de ster-2H per tak. Alles eronder begint op hetzelfde moment. S_AS = 64800 // 18:00 -- eerste 2H van Asia S_LO = 14400 // 04:00 -- derde 2H van Londen S_AM = 36000 // 10:00 -- derde 2H van NY AM S_PM = 43200 // 12:00 -- eerste 2H van NY PM L_2H = 7200.0 L_40 = 2400.0 L_13 = 800.0 L_44 = 800.0 / 3.0 // In welke tak zitten we op dit niveau? 0 = in geen enkele, dan sluit het blok. // De vensters van een niveau overlappen nooit; 10:00-12:00 en 12:00-14:00 raken // elkaar wel, en juist daarom moet de sleutel daar wisselen. f_tak(float len) => int b = 0 if secs >= S_AS and secs < S_AS + len b := 1 else if secs >= S_LO and secs < S_LO + len b := 2 else if secs >= S_AM and secs < S_AM + len b := 3 else if secs >= S_PM and secs < S_PM + len b := 4 b f_takAan(int b) => b == 1 ? bAS : b == 2 ? bLO : b == 3 ? bAM : b == 4 ? bPM : false f_takNaam(int b) => b == 1 ? "AS" : b == 2 ? "LO" : b == 3 ? "AM" : "PM" // ───────────────────────────── het blok ───────────────────────────── // Zijn eigen routine uit "Cycles & Dividers". Een functie met `var` krijgt in // Pine eigen state per AANROEPPLEK, en daarom staan de vier niveaus hieronder // los uitgeschreven in plaats van in een lus -- een lus zou een enkele plek // zijn en dan zouden alle vier de niveaus hetzelfde blok delen. f_starBox(bool active, int key, color bg, color bcol, string nm) => var bool inC = false var int prevK = 0 var box curB = na var label curL = na // GEEN OFFSET BIJ DEZE TWEE. Met xloc.bar_time landt een tijdstempel op de // MIDDENLIJN van zijn kaars, niet op de linkerrand -- dat geeft het gewenste // gat van een kaars al vanzelf. liveR = time + timeframe.in_seconds() * 1000 gapR = nz(time[1], time) if inC and active and key == prevK box.set_top(curB, math.max(box.get_top(curB), high)) box.set_bottom(curB, math.min(box.get_bottom(curB), low)) box.set_right(curB, liveR) if lblOn and not na(curL) label.set_x(curL, int((box.get_left(curB) + liveR) / 2)) label.set_y(curL, box.get_top(curB)) else if inC box.set_right(curB, gapR) // laatste kaars terugtrimmen -> gat if lblOn and not na(curL) label.set_x(curL, int((box.get_left(curB) + gapR) / 2)) curB := na curL := na inC := false if active and not inC curB := box.new(time, high, liveR, low, xloc = xloc.bar_time, bgcolor = bg, border_color = bordOn ? bcol : color.new(color.white, 100), border_width = 1, border_style = bordSt) if lblOn curL := label.new(time, high, nm, xloc = xloc.bar_time, style = label.style_none, textcolor = bcol, size = lblSz) prevK := key inC := true int(na) // CE10235 guard. Niet weghalen. // ───────────────────────────── tekenen ───────────────────────────── // Van buiten naar binnen, zodat de kleinere blokken bovenop komen te liggen. k2 = ok2H ? f_tak(L_2H) : 0 a2 = on2H and k2 != 0 and f_takAan(k2) f_starBox(a2, k2, color.new(starC, tr2H), color.new(starC, math.max(0, tr2H - 45)), f_takNaam(k2) + " 2H") k4 = ok40 ? f_tak(L_40) : 0 a4 = on40 and k4 != 0 and f_takAan(k4) f_starBox(a4, k4, color.new(starC, tr40), color.new(starC, math.max(0, tr40 - 45)), f_takNaam(k4) + " 40m") k1 = okFn ? f_tak(L_13) : 0 a1 = on13 and k1 != 0 and f_takAan(k1) f_starBox(a1, k1, color.new(starC, tr13), color.new(starC, math.max(0, tr13 - 45)), f_takNaam(k1) + " 13,3m") k0 = okFn ? f_tak(L_44) : 0 a0 = on44 and k0 != 0 and f_takAan(k0) f_starBox(a0, k0, color.new(starC, tr44), color.new(starC, math.max(0, tr44 - 45)), f_takNaam(k0) + " 4,44m")