# AN-M007-B-AND-A — NexaScript port of Arrow. # # The skill you get first when you say "the arrow skill". Two mirrored machines # (bull/bear): arm on a regular MACD correction against the regime, or on a # confirmed hidden divergence at a pivot; release on a signal crossover or the # hidden trigger; lock until the oscillator has recrossed zero, gated the whole # time by a three-vote range filter (ADX, EMA separation, trend strength). # # Ported against an_m007_b_and_a.py, profile XAUUSD_M5_v0_1. Every seeded # indicator here matches that module's own helpers, not TradingView: # # atr(14, seed: "window") - an_m007_b_and_a._atr # adx(14, seed: "window") - an_m007_b_and_a._dmi (its own ADX # seeding, distinct even from the other # engines' window-seeded rma - see the # comment on asl/builtins._adx) # # The pivot ties default ("right": strict left, at-or-beyond right) matches # this engine's own _pivot_low/_pivot_high, so no ties: override is needed - # unlike AN-M001-BOS, which needed "none". # # `divosc` is the fast MACD *value*, not its histogram - the engine's default # (div_source: MACD_VALUE). The port does not express the histogram variant; # nothing in the shipped profile uses it. # # Locked/armed/hidden all reduce to scalars carried per side, which is why this # is portable at all despite the length: no collection, just a lot of it. skill "Arrow" { id AN-M007-B-AND-A use XAUUSD M5 warmup 0 let fast = ema(close, 12) - ema(close, 26) let fastSig = ema(fast, 9) let slow = ema(close, 48) - ema(close, 104) let ef = ema(close, 60) let es = ema(close, 240) let atrV = atr(14, seed: "window") let adxV = adx(14, seed: "window") let strengthAvg = sma(abs(slow), 50) let esSlope = es - es[10] let slopeRatio = abs(esSlope) / max(atrV, 0.01) let bullReg = slow > 0 let bearReg = slow < 0 let emaBuyOk = ef > es and esSlope > 0 and slopeRatio >= 0.05 let emaSellOk = ef < es and esSlope < 0 and slopeRatio >= 0.05 let adxOk = adxV >= 20 let emaSepOk = abs(ef - es) / max(atrV, 0.01) >= 0.2 let strengthOk = abs(slow) > strengthAvg * 0.5 let votes = if(adxOk, 1, 0) + if(emaSepOk, 1, 0) + if(strengthOk, 1, 0) let rangeOk = votes >= 2 let pivLo = pivot_low(left: 3, right: 3) let pivHi = pivot_high(left: 3, right: 3) # The oscillator's value AT the pivot bar - not the confirming bar three bars # later - which is what fast[3] reaches back to when .confirmed is true. let oscAtPivot = fast[3] machine bull { var locked = 0 var sawPositiveAfterLock = 0 var correctionArmed = 0 var depth = 0 var hiddenArmed = 0 var hiddenArmedBar = -1000 var hiddenOrigin = -1 var prevLowPrice = 0 var prevLowOsc = 0 var prevLowBar = -1000 var lastBuyBar = -1000 let dCorrArmed = if(bullReg == 0, 0, correctionArmed) let dDepth = if(bullReg == 0, 0, depth) let dHiddenArmed = if(bullReg == 0, 0, hiddenArmed) let dHiddenOrigin = if(bullReg == 0, -1, hiddenOrigin) let sawPos = if(locked == 1, if(sawPositiveAfterLock == 1 or fast > 0, 1, 0), sawPositiveAfterLock) let unlocks = locked == 1 and sawPos == 1 and fast <= 0 and bullReg let lLocked = if(unlocks, 0, locked) let lSawPos = if(unlocks, 0, sawPos) let cCorrArmed = if(unlocks, 1, dCorrArmed) let cDepth = if(unlocks, abs(fast), dDepth) let arms = bullReg and fast < 0 and lLocked == 0 let eCorrArmed = if(arms, 1, cCorrArmed) let eDepth = if(arms, max(cDepth, abs(fast)), cDepth) let minDepth = 0.05 * max(atrV, 0.01) let depthOk = eCorrArmed == 1 and eDepth >= minDepth let pivotDist = pivLo.bar - prevLowBar let pivotDistOk = prevLowBar > -1000 and pivotDist >= 5 and pivotDist <= 100 let hiddenConfirmed = pivLo.confirmed and bullReg and lLocked == 0 and depthOk and pivotDistOk and prevLowBar > -1000 and pivLo.price > prevLowPrice and oscAtPivot < prevLowOsc let nPrevLowPrice = if(pivLo.confirmed, pivLo.price, prevLowPrice) let nPrevLowOsc = if(pivLo.confirmed, oscAtPivot, prevLowOsc) let nPrevLowBar = if(pivLo.confirmed, pivLo.bar, prevLowBar) let fHiddenArmed = if(hiddenConfirmed, 1, dHiddenArmed) let fHiddenArmedBar = if(hiddenConfirmed, bar_index, hiddenArmedBar) let fHiddenOrigin = if(hiddenConfirmed, pivLo.bar, dHiddenOrigin) let expires = fHiddenArmed == 1 and (bullReg == 0 or bar_index - fHiddenArmedBar > 20) let gHiddenArmed = if(expires, 0, fHiddenArmed) let gHiddenOrigin = if(expires, -1, fHiddenOrigin) let buyRel = bullReg and lLocked == 0 and depthOk and crossover(fast, fastSig) and fast < 0 let buyHid = gHiddenArmed == 1 and bullReg and lLocked == 0 and crossover(fast, fastSig) let buyType = if(buyRel and buyHid, 3, if(buyHid, 2, if(buyRel, 1, 0))) let buyBarsOk = bar_index - lastBuyBar >= 20 let buyFilters = bullReg and emaBuyOk and rangeOk let buyAccept = buyType > 0 and buyFilters and buyBarsOk # buyType 1/2/3 is a real distinction the engine makes in its event_type - # RELEASE (plain crossover), HIDDEN (a confirmed hidden divergence # triggered it), COMBINED (both at once) - not three names for one thing. # One transition per type, same guard split three ways. IDLE -> IDLE when buyType == 1 and buyAccept emit BA_BUY_RELEASE set locked = 1 set sawPositiveAfterLock = if(fast > 0, 1, 0) set correctionArmed = 0 set depth = 0 set hiddenArmed = 0 set hiddenArmedBar = -1000 set hiddenOrigin = -1 set prevLowPrice = nPrevLowPrice set prevLowOsc = nPrevLowOsc set prevLowBar = nPrevLowBar set lastBuyBar = bar_index IDLE -> IDLE when buyType == 2 and buyAccept emit BA_BUY_HIDDEN set locked = 1 set sawPositiveAfterLock = if(fast > 0, 1, 0) set correctionArmed = 0 set depth = 0 set hiddenArmed = 0 set hiddenArmedBar = -1000 set hiddenOrigin = -1 set prevLowPrice = nPrevLowPrice set prevLowOsc = nPrevLowOsc set prevLowBar = nPrevLowBar set lastBuyBar = bar_index IDLE -> IDLE when buyType == 3 and buyAccept emit BA_BUY_COMBINED set locked = 1 set sawPositiveAfterLock = if(fast > 0, 1, 0) set correctionArmed = 0 set depth = 0 set hiddenArmed = 0 set hiddenArmedBar = -1000 set hiddenOrigin = -1 set prevLowPrice = nPrevLowPrice set prevLowOsc = nPrevLowOsc set prevLowBar = nPrevLowBar set lastBuyBar = bar_index IDLE -> IDLE when buyType > 0 and (buyAccept == 0) reject "filtered" set locked = 1 set sawPositiveAfterLock = if(fast > 0, 1, 0) set correctionArmed = 0 set depth = 0 set hiddenArmed = 0 set hiddenArmedBar = -1000 set hiddenOrigin = -1 set prevLowPrice = nPrevLowPrice set prevLowOsc = nPrevLowOsc set prevLowBar = nPrevLowBar IDLE -> IDLE when true set locked = lLocked set sawPositiveAfterLock = lSawPos set correctionArmed = eCorrArmed set depth = eDepth set hiddenArmed = gHiddenArmed set hiddenArmedBar = fHiddenArmedBar set hiddenOrigin = gHiddenOrigin set prevLowPrice = nPrevLowPrice set prevLowOsc = nPrevLowOsc set prevLowBar = nPrevLowBar } machine bear { var locked = 0 var sawNegativeAfterLock = 0 var correctionArmed = 0 var depth = 0 var hiddenArmed = 0 var hiddenArmedBar = -1000 var hiddenOrigin = -1 var prevHighPrice = 0 var prevHighOsc = 0 var prevHighBar = -1000 var lastSellBar = -1000 let dCorrArmed = if(bearReg == 0, 0, correctionArmed) let dDepth = if(bearReg == 0, 0, depth) let dHiddenArmed = if(bearReg == 0, 0, hiddenArmed) let dHiddenOrigin = if(bearReg == 0, -1, hiddenOrigin) let sawNeg = if(locked == 1, if(sawNegativeAfterLock == 1 or fast < 0, 1, 0), sawNegativeAfterLock) let unlocks = locked == 1 and sawNeg == 1 and fast >= 0 and bearReg let lLocked = if(unlocks, 0, locked) let lSawNeg = if(unlocks, 0, sawNeg) let cCorrArmed = if(unlocks, 1, dCorrArmed) let cDepth = if(unlocks, abs(fast), dDepth) let arms = bearReg and fast > 0 and lLocked == 0 let eCorrArmed = if(arms, 1, cCorrArmed) let eDepth = if(arms, max(cDepth, abs(fast)), cDepth) let minDepth = 0.05 * max(atrV, 0.01) let depthOk = eCorrArmed == 1 and eDepth >= minDepth let pivotDist = pivHi.bar - prevHighBar let pivotDistOk = prevHighBar > -1000 and pivotDist >= 5 and pivotDist <= 100 let hiddenConfirmed = pivHi.confirmed and bearReg and lLocked == 0 and depthOk and pivotDistOk and prevHighBar > -1000 and pivHi.price < prevHighPrice and oscAtPivot > prevHighOsc let nPrevHighPrice = if(pivHi.confirmed, pivHi.price, prevHighPrice) let nPrevHighOsc = if(pivHi.confirmed, oscAtPivot, prevHighOsc) let nPrevHighBar = if(pivHi.confirmed, pivHi.bar, prevHighBar) let fHiddenArmed = if(hiddenConfirmed, 1, dHiddenArmed) let fHiddenArmedBar = if(hiddenConfirmed, bar_index, hiddenArmedBar) let fHiddenOrigin = if(hiddenConfirmed, pivHi.bar, dHiddenOrigin) let expires = fHiddenArmed == 1 and (bearReg == 0 or bar_index - fHiddenArmedBar > 20) let gHiddenArmed = if(expires, 0, fHiddenArmed) let gHiddenOrigin = if(expires, -1, fHiddenOrigin) let sellRel = bearReg and lLocked == 0 and depthOk and crossunder(fast, fastSig) and fast > 0 let sellHid = gHiddenArmed == 1 and bearReg and lLocked == 0 and crossunder(fast, fastSig) let sellType = if(sellRel and sellHid, 3, if(sellHid, 2, if(sellRel, 1, 0))) let sellBarsOk = bar_index - lastSellBar >= 20 let sellFilters = bearReg and emaSellOk and rangeOk let sellAccept = sellType > 0 and sellFilters and sellBarsOk IDLE -> IDLE when sellType == 1 and sellAccept emit BA_SELL_RELEASE set locked = 1 set sawNegativeAfterLock = if(fast < 0, 1, 0) set correctionArmed = 0 set depth = 0 set hiddenArmed = 0 set hiddenArmedBar = -1000 set hiddenOrigin = -1 set prevHighPrice = nPrevHighPrice set prevHighOsc = nPrevHighOsc set prevHighBar = nPrevHighBar set lastSellBar = bar_index IDLE -> IDLE when sellType == 2 and sellAccept emit BA_SELL_HIDDEN set locked = 1 set sawNegativeAfterLock = if(fast < 0, 1, 0) set correctionArmed = 0 set depth = 0 set hiddenArmed = 0 set hiddenArmedBar = -1000 set hiddenOrigin = -1 set prevHighPrice = nPrevHighPrice set prevHighOsc = nPrevHighOsc set prevHighBar = nPrevHighBar set lastSellBar = bar_index IDLE -> IDLE when sellType == 3 and sellAccept emit BA_SELL_COMBINED set locked = 1 set sawNegativeAfterLock = if(fast < 0, 1, 0) set correctionArmed = 0 set depth = 0 set hiddenArmed = 0 set hiddenArmedBar = -1000 set hiddenOrigin = -1 set prevHighPrice = nPrevHighPrice set prevHighOsc = nPrevHighOsc set prevHighBar = nPrevHighBar set lastSellBar = bar_index IDLE -> IDLE when sellType > 0 and (sellAccept == 0) reject "filtered" set locked = 1 set sawNegativeAfterLock = if(fast < 0, 1, 0) set correctionArmed = 0 set depth = 0 set hiddenArmed = 0 set hiddenArmedBar = -1000 set hiddenOrigin = -1 set prevHighPrice = nPrevHighPrice set prevHighOsc = nPrevHighOsc set prevHighBar = nPrevHighBar IDLE -> IDLE when true set locked = lLocked set sawNegativeAfterLock = lSawNeg set correctionArmed = eCorrArmed set depth = eDepth set hiddenArmed = gHiddenArmed set hiddenArmedBar = fHiddenArmedBar set hiddenOrigin = gHiddenOrigin set prevHighPrice = nPrevHighPrice set prevHighOsc = nPrevHighOsc set prevHighBar = nPrevHighBar } plot fast, fastSig on price plot slow as histogram in "slow" guide 0 plot adxV as line in "adx" guide 20 mark BA_BUY_RELEASE arrow_up below_bar color bull mark BA_BUY_HIDDEN arrow_up below_bar color bull mark BA_BUY_COMBINED arrow_up below_bar color bull mark BA_SELL_RELEASE arrow_down above_bar color bear mark BA_SELL_HIDDEN arrow_down above_bar color bear mark BA_SELL_COMBINED arrow_down above_bar color bear }