//@version=6 // ───────────────────────────────────────────────────────────────────────────── // NS ORB — setup en niveaus // // Tekent de openingsrange van 09:30-09:45 New York, de verhoudingen erbinnen en // het doel van NomadaScalper. Meldt wanneer de setup er is. De instap blijft aan // jou: de lijnen staan er, jij kiest je prijs. // // WAT DE METING ZEGT (NQ, 5 minuten, 2021-2026, 1.203 trades, 1 punt kosten): // winrate 83,2% · break-even bij dit doel 71,4% · gemiddeld +0,029R · PF 1,18 // Over de volle 15 jaar is het netto negatief; de plus zit in de recente jaren. // Zijn eigen kaart van 58 trades heeft een 95%-interval van 69% tot 89%, en // die ondergrens ligt onder break-even -- die steekproef bewees dus niets. // Het doel op 0,205 bleek wel de beste van alle geteste afstanden. // // Bedoeld voor de 5-minutengrafiek: de trigger is "een 5-minuutcandle sluit met // zijn body buiten de range". // ───────────────────────────────────────────────────────────────────────────── indicator("NS ORB — setup en niveaus", overlay = true, max_lines_count = 500, max_labels_count = 500, max_boxes_count = 100) // ── instellingen ───────────────────────────────────────────────────────────── tzIn = input.string("America/New_York", "Tijdzone", group = "Range") orbIn = input.session("0930-0945", "Openingsrange", group = "Range") dlIn = input.session("0945-1430", "Venster voor de instap", group = "Range") sesIn = input.session("0930-1600", "Handelssessie", group = "Range") fEnt = input.float(0.125, "Instap, terug de range in", step = 0.005, group = "Niveaus") fStp = input.float(0.950, "Stop, terug de range in", step = 0.005, group = "Niveaus") fTgt = input.float(0.205, "Doel, buiten de range", step = 0.005, group = "Niveaus") shQrt = input.bool(true, "Kwarten tonen (0,25 / 0,50 / 0,75)", group = "Niveaus") shExt = input.bool(true, "50%-extensie tonen", group = "Niveaus", tooltip = "Het niveau waar de 90%-bewering over gaat. Het doel ligt er ruim onder.") bodyQ = input.bool(true, "Body moet meelopen", group = "Trigger", tooltip = "Aan: de candle moet buiten sluiten én in de richting van de uitbraak.") cUp = input.color(#26a69a, "Long", inline = "k", group = "Uiterlijk") cDn = input.color(#ef5350, "Short", inline = "k", group = "Uiterlijk") cLine = input.color(#787b86, "Hulplijnen", inline = "k", group = "Uiterlijk") shTbl = input.bool(true, "Tabel tonen", group = "Uiterlijk") // ── sessiestaat ────────────────────────────────────────────────────────────── inOrb = not na(time(timeframe.period, orbIn, tzIn)) inDl = not na(time(timeframe.period, dlIn, tzIn)) inSes = not na(time(timeframe.period, sesIn, tzIn)) var float oH = na var float oL = na var float rng = na var bool klaar = false var bool gemeld = false var int richting = 0 var box doos = na var line[] lijnen = array.new() // ── tekenhulpjes (moeten op het hoogste niveau staan, niet in een if) ──────── trek(float prijs, color kl, int breedte, string stijl, string tekst) => l = line.new(bar_index, prijs, bar_index + 1, prijs, color = kl, width = breedte, style = stijl) array.push(lijnen, l) if tekst != "" label.new(bar_index, prijs, tekst, style = label.style_label_left, color = color.new(color.black, 100), textcolor = kl, size = size.tiny) l // ── de range vormen ────────────────────────────────────────────────────────── nieuweDag = inOrb and not inOrb[1] if nieuweDag oH := high oL := low rng := na klaar := false gemeld := false richting := 0 // De lijnen van gisteren blijven staan zodat je terug kunt kijken; alleen // de verwijzingen gaan weg, Pine ruimt de oudste zelf op. array.clear(lijnen) doos := box.new(bar_index, high, bar_index, low, border_color = color.new(cLine, 40), bgcolor = color.new(cLine, 90)) if inOrb and not nieuweDag oH := math.max(oH, high) oL := math.min(oL, low) if inOrb and not na(doos) box.set_top(doos, oH) box.set_bottom(doos, oL) box.set_right(doos, bar_index + 1) // Pas áf op de eerste bar ná het venster. Eerder tekenen zou de niveaus tijdens // de vorming laten verspringen. if not inOrb and inOrb[1] rng := oH - oL klaar := true // ── niveaus berekenen ──────────────────────────────────────────────────────── pEntL = oH - fEnt * rng pEntS = oL + fEnt * rng pStpL = oH - fStp * rng pStpS = oL + fStp * rng pTgtL = oH + fTgt * rng pTgtS = oL - fTgt * rng pExtL = oH + 0.5 * rng pExtS = oL - 0.5 * rng if klaar and not klaar[1] and not na(rng) and rng > 0 trek(oH, cLine, 2, line.style_solid, "ORB hoog") trek(oL, cLine, 2, line.style_solid, "ORB laag") if shQrt trek(oH - 0.25 * rng, cLine, 1, line.style_dotted, "0,25") trek(oH - 0.50 * rng, cLine, 1, line.style_dotted, "0,50") trek(oH - 0.75 * rng, cLine, 1, line.style_dotted, "0,75") if shExt trek(pExtL, cLine, 1, line.style_dashed, "ext +50%") trek(pExtS, cLine, 1, line.style_dashed, "ext −50%") // De lijnen meeschuiven zolang de sessie loopt. Zo houdt elke dag zijn eigen // niveaus in de historie, in plaats van één set die eindeloos doorloopt. if inSes and array.size(lijnen) > 0 for l in lijnen line.set_x2(l, bar_index + 1) // ── trigger ────────────────────────────────────────────────────────────────── // Alleen op een afgesloten bar: tijdens de vorming kan een candle over de rand // heen en weer wippen en zou het signaal knipperen. bodyUp = not bodyQ or close > open bodyDn = not bodyQ or close < open upTrig = klaar and inDl and barstate.isconfirmed and close > oH and bodyUp and richting == 0 dnTrig = klaar and inDl and barstate.isconfirmed and close < oL and bodyDn and richting == 0 if upTrig richting := 1 gemeld := true trek(pEntL, cUp, 2, line.style_solid, "instap 0,125") trek(pStpL, cDn, 2, line.style_solid, "stop 0,95") trek(pTgtL, cUp, 3, line.style_solid, "doel") label.new(bar_index, low, "ORB long", style = label.style_label_up, color = color.new(cUp, 20), textcolor = color.white, size = size.small) if dnTrig richting := -1 gemeld := true trek(pEntS, cDn, 2, line.style_solid, "instap 0,125") trek(pStpS, cUp, 2, line.style_solid, "stop 0,95") trek(pTgtS, cDn, 3, line.style_solid, "doel") label.new(bar_index, high, "ORB short", style = label.style_label_down, color = color.new(cDn, 20), textcolor = color.white, size = size.small) alertcondition(upTrig, "ORB long", "5-min body sluit boven de openingsrange") alertcondition(dnTrig, "ORB short", "5-min body sluit onder de openingsrange") // ── tabel ──────────────────────────────────────────────────────────────────── // Zijn doel is een VASTE PRIJS, geen vaste R. Stap jij ergens anders in dan op // de 0,125, dan verschuift je verhouding mee -- en daarmee de winrate die je // nodig hebt om quitte te spelen. Dat laatste getal is het nuttigste op het // scherm: zet het naast de 83% die de setup haalt en je ziet of er marge is. var table tb = table.new(position.top_right, 2, 7, border_width = 1) zet(int r, string a, string b, color kl) => table.cell(tb, 0, r, a, text_size = size.small, text_color = color.gray, text_halign = text.align_left) table.cell(tb, 1, r, b, text_size = size.small, text_color = kl, text_halign = text.align_right) if shTbl and barstate.islast and klaar and not na(rng) and rng > 0 stop = richting == -1 ? pStpS : pStpL doel = richting == -1 ? pTgtS : pTgtL instap = richting == -1 ? pEntS : pEntL risico = math.abs(close - stop) beloning = math.abs(doel - close) rr = risico > 0 ? beloning / risico : na be = na(rr) ? na : 100 / (1 + rr) kleur = richting == 1 ? cUp : richting == -1 ? cDn : color.gray status = richting == 1 ? "LONG actief" : richting == -1 ? "SHORT actief" : inDl ? "wachten op trigger" : "geen setup" zet(0, "ORB-range", str.tostring(rng, "#.##") + " pt", color.gray) zet(1, "status", status, kleur) zet(2, "instap 0,125", str.tostring(instap, format.mintick), color.gray) zet(3, "stop 0,95", str.tostring(stop, format.mintick), cDn) zet(4, "doel", str.tostring(doel, format.mintick), cUp) zet(5, "R:R vanaf nu", na(rr) ? "—" : str.tostring(rr, "0.00") + "R", kleur) zet(6, "nodig om quitte te zijn", na(be) ? "—" : str.tostring(be, "#.#") + "%", color.gray)