//@version=6 // ============================================================================= // Genesis Delivery Array — 40m cycle-open order block (validated build) // ----------------------------------------------------------------------------- // Concept: the OPEN of a 40-minute TMU cycle is an order block. After price // DISPLACES away from it (bias set), a RETEST of the open within the cycle // window tends to continue in the displacement direction. The array is only // live for its window; after that it is inert. // // Backtest (14y NQ, strictly causal, 1pt cost): the edge is real, direction- // dependent (fading it collapses), robust per-year + walk-forward, and lives // in specific cycles — 10:00 (PF 1.48), 14:00 (1.37), 10:40 (1.31) ET — NOT in // every cycle, and NOT on PO3/243 price levels (those did not help). // Defaults below reflect that: displacement 25pt, window 80m, star cycles. // Use on a 1-5 minute chart. // ============================================================================= indicator("Genesis Delivery Array", overlay = true, max_lines_count = 500, max_boxes_count = 500, max_labels_count = 500) tz = "America/New_York" // ── Inputs ── gC = "Cycle" cycleMin = input.int(40, "Cycle length (min)", minval = 5, group = gC, tooltip = "TMU time cycle. 40 = the validated one.") filterMode = input.string("Star cycles (10:00, 10:40, 14:00)", "Which cycles", options = ["All cycles", "RTH 09:30-16:00", "Star cycles (10:00, 10:40, 14:00)"], group = gC) gS = "Setup" dispPts = input.float(25.0, "Displacement to set bias (pts)", minval = 1, group = gS, tooltip = "Price must move this far from the open before a retest counts. Validated ~22-25pt on NQ.") winMin = input.int(80, "Array active window (min)", minval = 5, group = gS, tooltip = "After this many minutes the array is inert (frozen, no more retests).") rr = input.float(1.0, "Take-profit (R)", minval = 0.1, step = 0.1, group = gS, tooltip = "1R validated best; 2R degraded.") keepN = input.int(6, "Setups kept on chart", minval = 1, maxval = 50, group = gS) gV = "Style" showZone = input.bool(true, "Show open zone (first candle)", group = gV) showRisk = input.bool(true, "Show SL / TP on retest", group = gV) cUp = input.color(#2f9e5f, "Bull", inline = "c", group = gV) cDn = input.color(#d1584f, "Bear", inline = "c", group = gV) cIdle = input.color(color.new(#8892a0, 0), "Idle / no bias", group = gV) cZone = input.color(color.new(#8892a0, 82), "Zone fill", group = gV) cInert= input.color(color.new(#8892a0, 40), "Inert (expired)", group = gV) // ── Cycle boundary on NY wall clock ── mm = hour(time, tz) * 60 + minute(time, tz) mmChg = ta.change(mm) // computed every bar (CW10002 fix) newCyc = (mm % cycleMin == 0) and mmChg != 0 and timeframe.isintraday isStar = mm == 600 or mm == 640 or mm == 840 // 10:00 / 10:40 / 14:00 ET inRTH = mm >= 570 and mm < 960 // 09:30-16:00 ET cycleOK = filterMode == "All cycles" ? true : filterMode == "RTH 09:30-16:00" ? inRTH : isStar // ── Genesis object ── type G int bornT float o float zHi float zLo int bias // 0 none, 1 up, -1 down bool fired bool inert line lvl box zone line sl line tp label mark var array gs = array.new() winMs = winMin * 60000 barMs = math.max(1, time - time[1]) f_kill(G g) => if not na(g.lvl) line.delete(g.lvl) if not na(g.zone) box.delete(g.zone) if not na(g.sl) line.delete(g.sl) if not na(g.tp) line.delete(g.tp) if not na(g.mark) label.delete(g.mark) // ── New array on a qualifying cycle open ── if newCyc and cycleOK line lv = line.new(bar_index, open, bar_index + 2, open, xloc = xloc.bar_index, color = cIdle, width = 2) box bx = na if showZone bx := box.new(bar_index, high, bar_index + 2, low, xloc = xloc.bar_index, bgcolor = cZone, border_color = na) gs.unshift(G.new(time, open, high, low, 0, false, false, lv, bx, na, na, na)) while gs.size() > keepN f_kill(gs.pop()) // ── Update all active arrays each bar ── bool firedNow = false if gs.size() > 0 for i = 0 to gs.size() - 1 G g = gs.get(i) if not g.inert bool expired = (time - g.bornT) > winMs // extend the level / zone to the current bar while live if not na(g.lvl) g.lvl.set_x2(bar_index + 2) if not na(g.zone) g.zone.set_right(bar_index + 2) // displacement -> set bias if g.bias == 0 and not expired if high >= g.o + dispPts g.bias := 1 g.lvl.set_color(cUp) else if low <= g.o - dispPts g.bias := -1 g.lvl.set_color(cDn) // retest of the open within the window -> fire once else if g.bias != 0 and not g.fired and not expired bool hit = g.bias == 1 ? low <= g.o : high >= g.o if hit g.fired := true firedNow := true float risk = g.bias == 1 ? g.o - g.zLo : g.zHi - g.o float tpP = g.o + rr * risk * g.bias color col = g.bias == 1 ? cUp : cDn g.mark := label.new(bar_index, g.o, "Genesis", xloc = xloc.bar_index, style = g.bias == 1 ? label.style_label_up : label.style_label_down, color = color.new(col, 20), textcolor = color.white, size = size.small) if showRisk and risk > 0 g.sl := line.new(bar_index, g.bias == 1 ? g.zLo : g.zHi, bar_index + 20, g.bias == 1 ? g.zLo : g.zHi, xloc = xloc.bar_index, color = color.new(cDn, 20), style = line.style_dashed) g.tp := line.new(bar_index, tpP, bar_index + 20, tpP, xloc = xloc.bar_index, color = color.new(cUp, 20), style = line.style_dashed) // expiry -> freeze, go inert if expired g.inert := true if not na(g.lvl) g.lvl.set_color(cInert) // ── Alerts ── alertcondition(firedNow, "Genesis retest fired", "Genesis Delivery Array: open retested after displacement — continuation expected")