Research briefing

C00060 / managed-policy-01

Campaign campaign-v5-20260811-0002-05dfbc24: C00060/managed-policy-01

Archived MaterializedHistorically promising, limited sample

Total returnTWR
95.28%
AnnualizedTWR
13.57%
Max DDObserved
22.40%
SharpeNet
0.82
K-ratioNet
1.36
TradesClosed
136

What is VESTROS?

This public archive preserves C00060/managed-policy-01 from campaign campaign-v5-20260811-0002-05dfbc24.

Strategy origin

Campaign campaign-v5-20260811-0002-05dfbc24 materialized C00060/managed-policy-01. The frozen managed program contains 1 Pine calculation and 1 trading route.

  • Pine port zone-radar (Zone Radar [DefinedEdge]), Pine v6, MPL-2.0, parity-verified, applied to bybit mainnet linear ETHUSDT 4h. Configuration: atrLength=14, averageLength=20, breakBufferAtr=0.15, coilReferenceBars=50, cooldownBars=3, edgeTouchToleranceAtr=0.2, maxDrift=0.7, maxZoneHeightAtr=5, minZoneBars=50, strongBreakThreshold=55. Original public Pine source: TradingView publication by DefinedEdge. Its retained parity profile used TradingView's selected chart interval with no internal timeframe override; this calculation instance is applied to ETHUSDT 4h.

The frozen signal program defines the setup and its original exit actions. The managed execution policy below controls order placement and whether protective exits are added.

Strategy logic

Route 1: ETHUSDT 4h long

Signal decisions use bybit mainnet linear ETHUSDT 4h. Managed order placement and exits follow the trade-management policy below.

  • Signal long entry: any of (change of (zone-radar.zoneMiddle) crosses below 0, prior percentile rank of (zone-radar.breakStrength) with window 60 is greater than 0.6, current value relative to the complete prior 60-value median and median absolute deviation of (zone-radar.volumeAverage), using the normal-consistency scale 1.4826; current value excluded from the baseline crosses above 3).
  • Signal entry gate: none.
  • Signal entry risk scale: none.
  • Signal exit 1: change of (zone-radar.zoneMiddle) crosses above 0.
  • Signal exit 2: close after 4 confirmed bars.

Trade management

This is the market-entry/original-exit control policy. The route-level exits above remain the original signal-program exits; this policy adds no resting entry or protective exit orders.

The frozen policy declares the strictly prior 14-bar Wilder ATR at the signal as its risk-unit reference. This control does not consume it for added protection.

Entry: submit the full planned quantity as a market order when the signal becomes actionable.

Exit: use the signal program's original exit actions with no added protective orders.

Sizing distinction

Sealed campaign sizing: 100% shared gross exposure without compounding, equal weighting.

Managed replay sizing: 100% shared gross exposure with compounding, equal weighting.

The managed replay changes only sizing. Its calculation configuration, features, entries, gates, exits, markets, and schedules match the sealed campaign program.

Managed replay

The managed replay covers 2021-05-04T08:00:00.000Z to 2026-08-07T00:00:00.000Z (end exclusive) with 100% shared gross exposure and compounding. It starts with 10000 USDT and finishes with 19528.0319 USDT: 95.28% net return, 22.40% maximum drawdown, and 136 completed trades.

Extended-history decision

The retained campaign marked this subject as qualified. Blocking policies: none. Cautions: none. This archive replays the same extended-history range and sizing. The public-system report has its own identity. The original campaign decision and report hash are retained in evidence/extended-history.json.

Execution assumptions

Both O-H-L-C and O-L-H-C candle paths were retained. Screening uses the worse path and final eligibility requires both paths. This market-entry/original-exit control places no resting entry or protective exit orders. Its frozen execution settings nevertheless retain full-touch for resting limits and strict-cross for robustness. No queue, depth, or maker rebate claim is made from OHLC data.

Run tvt system backtest ethusdt-1h-4h-c00060-managed-policy-01-v1 --tear-sheet tmp/ethusdt-1h-4h-c00060-managed-policy-01-v1-tear-sheet.html to reproduce it from public candles.

The archive contains the exact materialized campaign source, frozen managed replay and sealed campaign strategy programs, public Pine runtime source, dataset definitions, economics, sealed selection evidence, expected results, and one canonical RunReport v2 tear sheet. Provider candle cache and campaign workspace files are excluded. Exact report-scoped market bars remain for offline chart verification.

OOS update

Refresh through the latest confirmed history

Run the same archived design through the start of the current UTC day and publish its OOS continuation. Only confirmed history is included.

vst system backtest ethusdt-1h-4h-c00060-managed-policy-01-v1 --to "$(date -u +%Y-%m-%dT00:00:00Z)" --publish-oos

Portable strategy

Use this archived strategy

Generate a verified standalone TypeScript workspace with the archived defaults and no VESTROS runtime dependency.

vst system extract ethusdt-1h-4h-c00060-managed-policy-01-v1 --output portable-strategies

Add --offline when the required dataset is cached, or --cache <path> to select a cache.

Research evidence only. External execution is not authorized.

system.pine

C00060 / managed-policy-01 Pine Script v6

Archive defaults: ETHUSDT 4h decisions 1h execution. Uses the current chart symbol and timeframe.

Regenerated from the installed original archive. TradingView verification on 47,304 identical original candles, including seed history, matched trade decisions and quantities, with equity within 0.0000001. The Archive rules table and native fill markers use loaded chart candles with the archive calculation and account rules. Use the archived execution timeframe and the same candle history from the same origin to compare results. Changed charts or inputs are fresh exploratory runs. Optional Strategy Tester orders approximate sizing and percentage slippage; broker settings are separate from the Archive account inputs.

//@version=6// SPDX-License-Identifier: MPL-2.0// This Pine Script code is subject to the Mozilla Public License 2.0.// https://mozilla.org/MPL/2.0/// Zone Radar calculation derived from Zone Radar [DefinedEdge].// https://www.tradingview.com/script/Dx4yfv9J-Zone-Radar-DefinedEdge///// Public archive: ethusdt-1h-4h-c00060-managed-policy-01-v1// Regenerated from the installed original calculation and trading contracts.// The Archive rules table applies the archive's quantity, fee, slippage and// execution rules to the loaded chart candles. A changed chart, date window or// input is a fresh exploratory run. Full archive results require the same data// and calculation origin. Optional Strategy Tester orders are approximate.strategy("VESTROS C00060-MANAGED-POLICY-01: archive rules", overlay = true, initial_capital = 10000,     default_qty_type = strategy.percent_of_equity, default_qty_value = 100,     commission_type = strategy.commission.percent, commission_value = 0.08,     slippage = 0, pyramiding = 100, margin_long = 0, margin_short = 0,     process_orders_on_close = false, calc_on_every_tick = false,     calc_on_order_fills = false, max_bars_back = 5000)// Arithmetic follows the installed archive's original calculation runtime.// math.sign avoids Pine's rounded float comparisons at strict boundaries.f_gt(float a, float b) =>    math.sign(a - b) == 1f_lt(float a, float b) =>    math.sign(a - b) == -1f_eq(float a, float b) =>    math.sign(a - b) == 0f_ge(float a, float b) =>    not na(a) and not na(b) and math.sign(a - b) >= 0f_le(float a, float b) =>    not na(a) and not na(b) and math.sign(a - b) <= 0f_number(bool value) =>    value ? 1.0 : 0.0type Samples    array<float> valuesf_samples() =>    Samples.new(array.new<float>())method add(Samples self, float value, int capacity = 82) =>    self.values.push(value)    if self.values.size() > capacity        self.values.shift()method lag(Samples self, int offset = 0) =>    self.values.size() > offset ? self.values.get(self.values.size() - 1 - offset) : na// Strict, contiguous, oldest-to-newest windows preserve initialization and// floating-point operation order. Missing values propagate.method stats(Samples self, int length, int offset = 0) =>    float average = na    float deviation = na    if self.values.size() >= length + offset        float total = 0        for i = length - 1 to 0            total += self.lag(i + offset)        average := total / length        float squares = 0        for i = length - 1 to 0            float delta = self.lag(i + offset) - average            squares += delta * delta        deviation := math.sqrt(squares / length)    [average, deviation]method zscore(Samples self, int length) =>    [average, deviation] = self.stats(length)    (self.lag() - average) / deviationmethod volatility(Samples self, int length, int offset = 1) =>    [average, deviation] = self.stats(length, offset)    deviationmethod rangePosition(Samples self, int length) =>    float minimum = self.lag(1)    float maximum = self.lag(1)    for i = 2 to length        minimum := math.min(minimum, self.lag(i))        maximum := math.max(maximum, self.lag(i))    2 * (self.lag() - minimum) / (maximum - minimum) - 1method rank(Samples self, int length) =>    float current = self.lag()    bool complete = not na(current)    int less = 0    int equal = 0    for i = 1 to length        float prior = self.lag(i)        complete := complete and not na(prior)        less += f_lt(prior, current) ? 1 : 0        equal += f_eq(prior, current) ? 1 : 0    complete ? 2.0 * (less + equal / 2.0) / length - 1 : namethod persistence(Samples self, int length, float threshold) =>    bool complete = true    bool passed = true    for i = 0 to length - 1        float value = self.lag(i)        complete := complete and not na(value)        passed := passed and (threshold >= 0 ? f_gt(value, threshold) : f_lt(value, threshold))    complete ? f_number(passed) : naf_relative(Samples left, Samples right, int length) =>    (left.lag() - left.lag(length)) / math.abs(left.lag(length)) - (right.lag() - right.lag(length)) / math.abs(right.lag(length))f_cross(Samples left, Samples right, bool above) =>    bool complete = not na(left.lag()) and not na(right.lag()) and not na(left.lag(1)) and not na(right.lag(1))    complete ? f_number(above ? f_gt(left.lag(), right.lag()) and f_le(left.lag(1), right.lag(1)) : f_lt(left.lag(), right.lag()) and f_ge(left.lag(1), right.lag(1))) : naf_compare(float left, float right, string comparison) =>    not na(left) and not na(right) ? f_number(comparison == "gt" ? f_gt(left, right) : comparison == "lt" ? f_lt(left, right) : comparison == "ge" ? f_ge(left, right) : f_le(left, right)) : naf_votes(array<float> values, int required) =>    int passed = 0    int unknown = 0    for value in values        passed += value == 1 ? 1 : 0        unknown += na(value) ? 1 : 0    passed >= required ? 1.0 : passed + unknown < required ? 0.0 : namethod riskScale(Samples self) =>    Samples returns = f_samples()    bool positive = true    for i = 80 to 1        float previous = self.lag(i)        float current = self.lag(i - 1)        positive := positive and f_gt(previous, 0) and f_gt(current, 0)        returns.add(current / previous - 1)    [slowMean, slow] = returns.stats(60, 20)    [fastMean, fast] = returns.stats(20)    positive and f_gt(slow, 0) and f_gt(fast, 0) ? math.min(1, math.max(0.25, slow / fast)) : naf_histories(int count) =>    array<Samples> result = array.new<Samples>()    for i = 1 to count        result.push(f_samples())    resultf_median(array<float> values) =>    array<float> ordered = values.copy()    ordered.sort()    int middle = int(math.floor(ordered.size() / 2))    float lower = ordered.get(math.max(0, middle - 1))    float upper = ordered.get(middle)    ordered.size() % 2 == 1 ? upper : f_lt(lower, 0) and f_gt(upper, 0) ? lower / 2 + upper / 2 : lower + (upper - lower) / 2method priorMad(Samples self, int length) =>    array<float> prior = array.new<float>()    bool complete = not na(self.lag())    for i = length to 1        float value = self.lag(i)        complete := complete and not na(value)        prior.push(value)    float result = na    if complete        float center = f_median(prior)        array<float> deviations = array.new<float>()        for value in prior            deviations.push(math.abs(value - center))        result := (self.lag() - center) / (1.482602218505602 * f_median(deviations))    resultmethod downsideShare(Samples self, int length) =>    float downside = 0    float total = 0    bool complete = true    for i = length to 1        float previous = self.lag(i + 1)        float current = self.lag(i)        complete := complete and f_gt(previous, 0) and f_gt(current, 0)        float change = math.log(current) - math.log(previous)        float square = change * change        total += square        if f_lt(change, 0)            downside += square    complete ? downside / total : naf_pairStats(Samples left, Samples right, int length, int offset) =>    [leftMean, leftDeviation] = left.stats(length, offset)    [rightMean, rightDeviation] = right.stats(length, offset)    float covariance = 0    float leftVariance = 0    float rightVariance = 0    for i = length - 1 to 0        float leftDelta = left.lag(i + offset) - leftMean        float rightDelta = right.lag(i + offset) - rightMean        covariance += leftDelta * rightDelta        leftVariance += leftDelta * leftDelta        rightVariance += rightDelta * rightDelta    [leftMean, rightMean, covariance, leftVariance, rightVariance]f_correlation(Samples left, Samples right, int length) =>    [leftMean, rightMean, covariance, leftVariance, rightVariance] = f_pairStats(left, right, length, 0)    covariance / math.sqrt(leftVariance * rightVariance)f_regression(Samples left, Samples right, int length) =>    [leftMean, rightMean, covariance, leftVariance, rightVariance] = f_pairStats(left, right, length, 1)    float beta = covariance / leftVariance    right.lag() - (rightMean - beta * leftMean + beta * left.lag())f_region(float value, float lower, float upper) =>    na(value) or na(lower) or na(upper) ? na : f_gt(value, upper) ? 1.0 : f_lt(value, lower) ? -1.0 : 0.0f_breakout(Samples price, Samples lower, Samples upper) =>    float current = f_region(price.lag(), lower.lag(), upper.lag())    float previous = f_region(price.lag(1), lower.lag(1), upper.lag(1))    na(current) ? na : na(previous) ? 0.0 : current == 1 and previous != 1 ? 1.0 : current == -1 and previous != -1 ? -1.0 : 0.0type AtrRatio    float previousClose = na    float atr = na    float seedSum = 0    int count = 0// Feature-level prior ATR used multiply/add/divide, independently of the// alpha-form ATR inside the archived Zone Radar port.method calculate(AtrRatio self, float highPrice, float lowPrice, float closePrice, int period) =>    float trueRange = na(self.previousClose) ? highPrice - lowPrice : math.max(highPrice - lowPrice, math.abs(highPrice - self.previousClose), math.abs(lowPrice - self.previousClose))    float result = trueRange / self.atr    if na(self.atr)        self.seedSum += trueRange        self.count += 1        if self.count == period            self.atr := self.seedSum / period    else        self.atr := (self.atr * (period - 1) + trueRange) / period    self.previousClose := closePrice    result// Calculation adapted from the retained public Zone Radar [DefinedEdge] port.// https://www.tradingview.com/script/Dx4yfv9J-Zone-Radar-DefinedEdge/type ZoneState    int atrLength    int averageLength    int minZoneBars    float maxZoneHeightAtr    float maxDrift    float breakBufferAtr    float edgeTouchToleranceAtr    int cooldownBars    float strongBreakThreshold    int coilReferenceBars    int barIndex = 0    Samples closes    Samples highs    Samples lows    Samples ranges    Samples volumes    float atr = na    float atrSeedSum = 0    int atrSeedCount = 0    bool inZone = false    float retainedTop = na    float retainedBottom = na    float zoneAtr = na    int zoneStart = 0    int cooldownUntil = 0    float zoneTop = na    float zoneBottom = na    float zoneMiddle = na    float trueRange = na    float averageRange = na    float volumeAverage = na    float breakStrength = 0    int breakDirection = 0    bool zoneBorn = falsef_zone(int atrLength, int averageLength, int minZoneBars, float maxZoneHeightAtr, float maxDrift, float breakBufferAtr, float edgeTouchToleranceAtr, int cooldownBars, float strongBreakThreshold, int coilReferenceBars) =>    ZoneState.new(atrLength, averageLength, minZoneBars, maxZoneHeightAtr, maxDrift, breakBufferAtr, edgeTouchToleranceAtr, cooldownBars, strongBreakThreshold, coilReferenceBars, closes = f_samples(), highs = f_samples(), lows = f_samples(), ranges = f_samples(), volumes = f_samples())method calculate(ZoneState self, float highPrice, float lowPrice, float closePrice, float volumeValue) =>    float previousClose = self.closes.lag()    self.trueRange := na(previousClose) ? highPrice - lowPrice : math.max(highPrice - lowPrice, math.abs(highPrice - previousClose), math.abs(lowPrice - previousClose))    if na(self.atr)        self.atrSeedSum += self.trueRange        self.atrSeedCount += 1        if self.atrSeedCount == self.atrLength            self.atr := self.atrSeedSum / self.atrLength    else        float alpha = 1.0 / self.atrLength        self.atr := alpha * self.trueRange + (1 - alpha) * self.atr    self.closes.add(closePrice, self.minZoneBars + 1)    self.highs.add(highPrice, self.minZoneBars)    self.lows.add(lowPrice, self.minZoneBars)    self.ranges.add(self.trueRange, self.averageLength)    self.volumes.add(volumeValue, self.averageLength)    [averageRange, rangeDeviation] = self.ranges.stats(self.averageLength)    [volumeAverage, volumeDeviation] = self.volumes.stats(self.averageLength)    self.averageRange := averageRange    self.volumeAverage := volumeAverage    bool hasVolume = f_gt(volumeAverage, 0)    float highest = self.highs.values.max()    float lowest = self.lows.values.min()    self.zoneBorn := false    self.breakStrength := 0    self.breakDirection := 0    if f_gt(self.atr, 0)        if not self.inZone            if self.barIndex >= self.cooldownUntil and self.barIndex > self.minZoneBars                float windowRange = highest - lowest                float drift = math.abs(closePrice - self.closes.lag(self.minZoneBars))                if f_le(windowRange, self.maxZoneHeightAtr * self.atr) and f_le(drift, windowRange * self.maxDrift)                    self.inZone := true                    self.retainedTop := highest                    self.retainedBottom := lowest                    self.zoneStart := self.barIndex - self.minZoneBars + 1                    self.zoneAtr := self.atr                    self.zoneBorn := true        else            bool upBreak = f_gt(closePrice, self.retainedTop + self.breakBufferAtr * self.zoneAtr)            bool downBreak = f_lt(closePrice, self.retainedBottom - self.breakBufferAtr * self.zoneAtr)            if upBreak or downBreak                float displacement = upBreak ? closePrice - self.retainedTop : self.retainedBottom - closePrice                float displacementTerm = math.min(displacement / self.zoneAtr, 1)                float expansionTerm = f_gt(averageRange, 0) ? math.min(self.trueRange / averageRange / 2, 1) : 0                float volumeTerm = hasVolume ? math.min(volumeValue / volumeAverage / 2, 1) : na                float coilTerm = math.min((self.barIndex - self.zoneStart) / float(self.coilReferenceBars), 1)                float baseTerm = 0.35 * displacementTerm + 0.3 * expansionTerm + 0.15 * coilTerm                self.breakStrength := hasVolume ? (baseTerm + 0.2 * volumeTerm) * 100 : baseTerm / 0.8 * 100                self.breakDirection := upBreak ? 1 : -1                self.inZone := false                self.cooldownUntil := self.barIndex + self.cooldownBars            else                float newTop = math.max(self.retainedTop, highPrice)                float newBottom = math.min(self.retainedBottom, lowPrice)                if f_le(newTop - newBottom, self.maxZoneHeightAtr * self.zoneAtr)                    self.retainedTop := newTop                    self.retainedBottom := newBottom    self.barIndex += 1    self.zoneTop := self.inZone ? self.retainedTop : na    self.zoneBottom := self.inZone ? self.retainedBottom : na    self.zoneMiddle := self.inZone ? (self.retainedTop + self.retainedBottom) / 2 : na// Candle accounting is separate from TradingView's broker emulator because// the archive sizes at the execution open and applies percentage slippage.type Holding    int steps = 0    float average = 0    bool pending = false    int targetDirection = 0    float allocation = 1    float executedDelta = 0    float executedPrice = na    float markedPrice = na    float referencePrice = na    float plannedPrice = 0type Account    float initial    float wallet    float equity    float peak    float drawdown = 0    float fees = 0    float slippage = 0    int fills = 0    int closed = 0    array<Holding> holdings    string mode = "combination"f_account(float capital, int routes = 1, string mode = "combination") =>    array<Holding> holdings = array.new<Holding>()    for i = 1 to routes        holdings.push(Holding.new(allocation = 1.0 / routes))    Account.new(capital, capital, capital, capital, holdings = holdings, mode = mode)method valueAt(Account self, float price, float quantityStep) =>    float value = self.wallet    for holding in self.holdings        value += holding.steps * quantityStep * (price - holding.average)    valuemethod observe(Account self, float quantityStep) =>    self.equity := self.wallet    for holding in self.holdings        if holding.steps != 0            self.equity += holding.steps * quantityStep * (holding.markedPrice - holding.average)    self.peak := math.max(self.peak, self.equity)    self.drawdown := math.max(self.drawdown, (self.peak - self.equity) / self.peak)method mark(Account self, float price, float quantityStep) =>    for holding in self.holdings        holding.markedPrice := price    self.observe(quantityStep)method execute(Account self, float openPrice, float quantityStep, float feeRate, float slipRate) =>    // Simultaneous route targets use the same equity marked before their fills.    float sizingEquity = self.valueAt(openPrice, quantityStep)    for holding in self.holdings        holding.executedDelta := 0        holding.executedPrice := na        if holding.pending            float sizingPrice = openPrice            float sizingNotional = math.max(sizingEquity, 0) * holding.allocation            if self.mode == "managed"                // Managed v2 reserves planned entry exposure at the signal close.                // The next route sees the account after earlier route fills.                float reserved = 0                for other in self.holdings                    reserved += math.abs(other.steps) * quantityStep * other.plannedPrice                sizingPrice := holding.referencePrice                sizingNotional := math.min(math.max(self.equity, 0) * holding.allocation, math.max(self.equity - reserved, 0))            int target = holding.targetDirection == 0 ? 0 : holding.targetDirection * int(math.floor(sizingNotional / (sizingPrice * quantityStep)))            int before = holding.steps            int deltaSteps = target - before            if deltaSteps != 0                float delta = deltaSteps * quantityStep                float fill = openPrice * (deltaSteps > 0 ? 1 + slipRate : 1 - slipRate)                float fee = math.abs(delta) * fill * feeRate                self.wallet -= fee                self.fees += fee                self.slippage += math.abs(delta) * math.abs(fill - openPrice)                self.fills += 1                holding.executedDelta := delta                holding.executedPrice := fill                if before == 0 or math.sign(before) == math.sign(deltaSteps)                    holding.average := (math.abs(before) * quantityStep * holding.average + math.abs(delta) * fill) / (math.abs(target) * quantityStep)                else                    int closing = math.min(math.abs(before), math.abs(deltaSteps))                    self.wallet += closing * quantityStep * math.sign(before) * (fill - holding.average)                    if target == 0 or math.sign(target) != math.sign(before)                        self.closed += 1                        holding.average := target == 0 ? 0 : fill                holding.steps := target                holding.markedPrice := fill                if before == 0 or math.sign(before) != math.sign(target)                    holding.plannedPrice := target == 0 ? 0 : holding.referencePrice                if self.mode == "combination"                    self.mark(fill, quantityStep)                else if self.mode == "managed"                    self.observe(quantityStep)            holding.pending := false    if self.mode == "open"        self.mark(openPrice, quantityStep)type Member    bool active = false    int enteredAt = na    int heldBars = 0    bool changed = false    float entryPrice = na    float highestClose = na    float lowestClose = na    bool pendingReference = falsemethod fillReference(Member self, float openPrice, float slipRate, int direction) =>    if self.pendingReference        self.entryPrice := openPrice * (direction == 1 ? 1 + slipRate : 1 - slipRate)        self.pendingReference := falsemethod decide(Member self, bool entry, bool exit, int closeAt) =>    bool before = self.active    if self.active        self.heldBars += 1        if exit            self.active := false            self.enteredAt := na            self.heldBars := 0            self.highestClose := na            self.lowestClose := na            self.entryPrice := na    else if entry        self.active := true        self.enteredAt := closeAt        self.heldBars := 0        self.pendingReference := true    self.changed := self.active != beforetype Incumbent    int member = 0    int inactive = 0    bool desired = false    bool changed = falsemethod combine(Incumbent self, Member a, Member b) =>    bool event = a.changed or b.changed    bool before = self.desired    self.changed := false    if event or (self.desired and self.member != 0 and not a.active and not b.active)        if a.active or b.active            bool keep = (self.member == 1 and a.active) or (self.member == 2 and b.active)            if not keep                self.member := a.active and b.active ? (a.enteredAt <= b.enteredAt ? 1 : 2) : a.active ? 1 : 2            self.inactive := 0            self.desired := true        else if self.desired and self.member != 0            self.inactive += 1            if self.inactive >= 2                self.member := 0                self.desired := false        else            self.member := 0            self.inactive := 0            self.desired := false        self.changed := event or self.desired != beforetype Program0    ZoneState calculation    array<Samples> history    AtrRatio atrRatio    bool entry = false    bool exit = falsemethod features(Program0 self, float openPrice, float highPrice, float lowPrice, float closePrice, float volumeValue, bool available = true) =>    float n0 = available ? self.calculation.zoneMiddle : na    self.history.get(0).add(n0)    float n1 = available ? self.calculation.breakStrength : na    self.history.get(1).add(n1)    float n2 = available ? self.calculation.volumeAverage : na    self.history.get(2).add(n2)    float n3 = 0.0    self.history.get(3).add(n3)    float n4 = 0.6    self.history.get(4).add(n4)    float n5 = 3.0    self.history.get(5).add(n5)    float n6 = n0 - self.history.get(0).lag(1)    self.history.get(6).add(n6)    float n7 = self.history.get(1).rank(60)    self.history.get(7).add(n7)    float n8 = self.history.get(2).priorMad(60)    self.history.get(8).add(n8)    float n9 = f_cross(self.history.get(6), self.history.get(3), true)    self.history.get(9).add(n9)    float n10 = f_cross(self.history.get(6), self.history.get(3), false)    self.history.get(10).add(n10)    float n11 = f_compare(n7, n4, "gt")    self.history.get(11).add(n11)    float n12 = f_cross(self.history.get(8), self.history.get(5), true)    self.history.get(12).add(n12)    float n13 = f_votes(array.from(n10, n11, n12), 1)    self.history.get(13).add(n13)    self.entry := n13 == 1    self.exit := n9 == 1type MultiClock    int lastCalculationAt = na    int desired = 0method advance(Account account, Program0 a, Member aMember, MultiClock clock, float openPrice, float highPrice, float lowPrice, float closePrice, float volumeValue, int openAt, int closeAt, bool scored, bool mayDecide, float quantityStep, float feeRate, float slipRate, bool decisionClosed, float decisionOpen, float decisionHigh, float decisionLow, float decisionClose, float decisionVolume, int decisionAt, int maximumAge) =>    aMember.changed := false    if scored        account.execute(openPrice, quantityStep, feeRate, slipRate)        aMember.fillReference(openPrice, slipRate, 1)    if decisionClosed        a.calculation.calculate(decisionHigh, decisionLow, decisionClose, decisionVolume)        clock.lastCalculationAt := decisionAt        a.features(decisionOpen, decisionHigh, decisionLow, decisionClose, decisionVolume)        if mayDecide            if aMember.active                aMember.highestClose := na(aMember.highestClose) ? decisionClose : math.max(aMember.highestClose, decisionClose)                aMember.lowestClose := na(aMember.lowestClose) ? decisionClose : math.min(aMember.lowestClose, decisionClose)            aMember.decide(a.entry, a.exit or (aMember.heldBars + 1 >= 4), closeAt)            if aMember.changed                Holding holding = account.holdings.get(0)                holding.pending := true                holding.targetDirection := aMember.active ? 1 : 0                holding.referencePrice := decisionClose    if scored        account.mark(closePrice, quantityStep)useWindow = input.bool(true, "Use archive date window", group = "Replay")startAt = input.time(1620115200000, "First scored open", group = "Replay")endAt = input.time(1786060800000, "End (exclusive)", group = "Replay")initialCapital = input.float(10000, "Initial equity", minval = 1, group = "Archive account")quantityStep = input.float(0.01, "Quantity step", minval = 0.000001, group = "Archive account")feeRate = input.float(0.06, "Fee (%)", minval = 0, group = "Archive account") / 100slipRate = input.float(0.02, "Slippage (%)", minval = 0, group = "Archive account") / 100showOrders = input.bool(false, "Show approximate broker orders", group = "Display")showNativeFills = input.bool(true, "Show native fill markers", group = "Display")scored = not useWindow or time >= startAt and time < endAtmayDecide = scored and (not useWindow or time_close < endAt)var int origin = timevar int scoredCount = 0aatrLength = input.int(14, "Atr length", minval = 1, group = "Zone 1")aaverageLength = input.int(20, "Average length", minval = 1, group = "Zone 1")aminZoneBars = input.int(50, "Min zone bars", minval = 1, group = "Zone 1")amaxZoneHeightAtr = input.float(5, "Max zone height atr", minval = 0.001, group = "Zone 1")amaxDrift = input.float(0.7, "Max drift", minval = 0.001, group = "Zone 1")abreakBufferAtr = input.float(0.15, "Break buffer atr", minval = 0, group = "Zone 1")aedgeTouchToleranceAtr = input.float(0.2, "Edge touch tolerance atr", minval = 0, group = "Zone 1")acooldownBars = input.int(3, "Cooldown bars", minval = 0, group = "Zone 1")astrongBreakThreshold = input.float(55, "Strong break threshold", minval = 0.001, group = "Zone 1")acoilReferenceBars = input.int(50, "Coil reference bars", minval = 1, group = "Zone 1")var ZoneState aCalculation = f_zone(aatrLength, aaverageLength, aminZoneBars, amaxZoneHeightAtr, amaxDrift, abreakBufferAtr, aedgeTouchToleranceAtr, acooldownBars, astrongBreakThreshold, acoilReferenceBars)var Program0 a = Program0.new(aCalculation, f_histories(14), AtrRatio.new())var Member aMember = Member.new()var Account account = f_account(initialCapital, 1, "managed")var MultiClock clock = MultiClock.new()decisionTimeframe = input.timeframe("240", "Higher decision timeframe (archive: 4h)", group = "Decision clocks")if timeframe.in_seconds(decisionTimeframe) < timeframe.in_seconds()    runtime.error("Use a chart timeframe at or below the higher decision timeframe. The archive executes on 1h candles.")[dOpenAt, dCloseAt, dOpen, dHigh, dLow, dClose, dVolume] = request.security(syminfo.tickerid, decisionTimeframe, [time, time_close, open, high, low, close, volume], gaps = barmerge.gaps_off, lookahead = barmerge.lookahead_off)decisionClosed = time_close == dCloseAt and (na(clock.lastCalculationAt) or dCloseAt > clock.lastCalculationAt)if barstate.isconfirmed    account.advance(a, aMember, clock, open, high, low, close, volume, time, time_close, scored, mayDecide, quantityStep, feeRate, slipRate, decisionClosed, dOpen, dHigh, dLow, dClose, dVolume, dCloseAt, int(timeframe.in_seconds(decisionTimeframe) * 1000))    if scored        scoredCount += 1    if showOrders and mayDecide        float target = 0        bool change = false        for holding in account.holdings            target += holding.pending ? holding.targetDirection * math.floor(math.max(account.equity, 0) * holding.allocation / (close * quantityStep)) * quantityStep : holding.steps * quantityStep            change := change or holding.pending        float delta = target - strategy.position_size        if change and f_gt(delta, 0)            strategy.order("Buy delta", strategy.long, qty = delta)        else if change and f_lt(delta, 0)            strategy.order("Sell delta", strategy.short, qty = -delta)var table summary = table.new(position.top_right, 2, 8, bgcolor = color.new(color.black, 10))if barstate.islast    table.cell(summary, 0, 0, "Archive rules", text_color = color.white)    table.cell(summary, 1, 0, "Loaded chart candles", text_color = color.white)    table.cell(summary, 0, 1, "Equity", text_color = color.white)    table.cell(summary, 1, 1, str.tostring(account.equity, "#.########"), text_color = color.white)    table.cell(summary, 0, 2, "Net return", text_color = color.white)    table.cell(summary, 1, 2, str.tostring((account.equity / initialCapital - 1) * 100, "#.########") + "%", text_color = color.white)    table.cell(summary, 0, 3, "Maximum drawdown", text_color = color.white)    table.cell(summary, 1, 3, str.tostring(account.drawdown * 100, "#.########") + "%", text_color = color.white)    table.cell(summary, 0, 4, "Closed trades / fills", text_color = color.white)    table.cell(summary, 1, 4, str.tostring(account.closed) + " / " + str.tostring(account.fills), text_color = color.white)    table.cell(summary, 0, 5, "Fees", text_color = color.white)    table.cell(summary, 1, 5, str.tostring(account.fees, "#.########"), text_color = color.white)    table.cell(summary, 0, 6, "Calculation origin", text_color = color.white)    table.cell(summary, 1, 6, str.format_time(origin, "yyyy-MM-dd HH:mm", "UTC"), text_color = color.white)    table.cell(summary, 0, 7, "Scored candles", text_color = color.white)    table.cell(summary, 1, 7, str.tostring(scoredCount), text_color = color.white)plot(account.equity, "native_equity", display = display.data_window)plot(account.fees, "native_fees", display = display.data_window)plot(account.drawdown, "native_drawdown", display = display.data_window)plot(account.fills, "native_fills", display = display.data_window)plot(account.closed, "native_closed", display = display.data_window)plot(aMember.active ? 1 : 0, "native_a_active", display = display.data_window)plot(account.holdings.get(0).steps * quantityStep, "native_quantity_0", display = display.data_window)plotshape(showNativeFills and scored and barstate.isconfirmed and (f_gt(account.holdings.get(0).executedDelta, 0)), "Native buy fill", shape.triangleup, location.belowbar, color.teal, size = size.tiny)plotshape(showNativeFills and scored and barstate.isconfirmed and (f_lt(account.holdings.get(0).executedDelta, 0)), "Native sell fill", shape.triangledown, location.abovebar, color.red, size = size.tiny)plot(a.history.get(0).lag(), "a_feature_001", display = display.data_window)plot(a.history.get(1).lag(), "a_feature_002", display = display.data_window)plot(a.history.get(2).lag(), "a_feature_003", display = display.data_window)plot(a.history.get(3).lag(), "a_feature_004", display = display.data_window)plot(a.history.get(4).lag(), "a_feature_005", display = display.data_window)plot(a.history.get(5).lag(), "a_feature_006", display = display.data_window)plot(a.history.get(6).lag(), "a_feature_007", display = display.data_window)plot(a.history.get(7).lag(), "a_feature_008", display = display.data_window)plot(a.history.get(8).lag(), "a_feature_009", display = display.data_window)plot(a.history.get(9).lag(), "a_feature_010", display = display.data_window)plot(a.history.get(10).lag(), "a_feature_011", display = display.data_window)plot(a.history.get(11).lag(), "a_feature_012", display = display.data_window)plot(a.history.get(12).lag(), "a_feature_013", display = display.data_window)plot(a.history.get(13).lag(), "a_feature_014", display = display.data_window)plot(a.calculation.zoneTop, "zoneTop")plot(a.calculation.zoneMiddle, "zoneMiddle")plot(a.calculation.zoneBottom, "zoneBottom")