Skip to content

Feature/go runner error handling - #4

Open
bvasilenko wants to merge 24 commits into
masterfrom
feature/go-runner-error-handling
Open

Feature/go runner error handling#4
bvasilenko wants to merge 24 commits into
masterfrom
feature/go-runner-error-handling

Conversation

@bvasilenko

Copy link
Copy Markdown
Collaborator

Acceptance Criteria / QA

  • A. All ten top10 strategies are classified -- each strategy is in exactly one of: strict-verified, by-design no-trades, or has a closure-gated leaf above with a named blocker
  • B. Eight of ten are TV-strict-verified -- hull, ut+, alpha, ann, moon, ut, aostoch, plus the two real-codegen-gap strategies once their fixes land, all carry a TV reference capture and a passing strict alignment ratchet within policy caps
  • C. One of ten is documented by-design -- ultima is annotated in the regression suite as a known by-design no-trade case so the "0 trades" observation does not regress into a phantom defect
  • D. No stale .pine.skip sidecars -- the stale-skip guard runs green and the top10/ directory contains no .pine.skip for any strategy that executes end-to-end
  • E. No golden regressions -- every TV-strict-verified strategy keeps its golden trade list bit-for-bit stable across the closing commit; the golden-mutation gate fired (and was explicitly approved) exactly for the strategies in items 3 and 4 above
  • F. Branch-wide guards still green -- the six guards in item 6 above each have a passing test in the regression suite and none has been weakened to admit the new strategies

… configOverride/index-bak.html/TradeTableRenderer dead code, fix currency sign ordering and empty indicator pane rendering, and node:test marker regression suite
…derer, fix dead profitClass ternary, and node:test renderer/transformer regression suites
…aggable pane resize handles with PaneResizeCalculator/Handle/Controller, sort toggle and trade-pair sub-row ordering, extract CSS design tokens to tokens.css/styles.css with zero hardcoded literals, fix table hover/muted-text/focus-visible, delete _setupEventListeners leak via WindowResizeHandler, and node:test regression suites for all new modules
…nd Pine v5 with all-7-days default via codegen version threading, add strategy.risk.allow_entry_in direction filter, fix pyramiding cap so N means N concurrent same-side trades, fix intrabar stop-over-limit fill priority so stop wins when both breach same bar, add STDEV TV-epsilon precision, generalize security TA inputs from identifier-only to any expression across 10 state managers, refactor pivot/valuewhen into ForwardSeriesBuffer with nested-TA-call precomputer for Hull-style HMA, add ta.pivot_point_levels and Identity/Transformed/Range security bar mapping, regenerate BB7/BB9/Aostoch/Hull/BB-RSI/UtPlus goldens to TradingView Strategy Tester output, plus regression suites for every change
…YS=23456 (weekdays) versus v5 all-7-days, decompose session into timeRange and weekdayMask, fix calendar millisecond/second mismatch, replace silent NaN stubs with featuregap recording, and add BB7 phantom-bar, direction-trace, and Pine-version session ratchets
…ar timestamp in seconds so `year()`/`month()`/`hour()` and other calendar functions return correct values, unify the three codegen paths under one shared millisecond expression, and add a three-form end-to-end ratchet plus table-driven unit tests
… bar stream by adding a `SessionWindow{07:00,23:50}` to the regular MOEX calendar with a `DefaultReferenceSession(MOEX)=Regular` auto-default, removing the bar 4521 phantom UtPlus entry, regenerating `ut-plus-sberp-1h.json` from 688 to 650 trades, and adding ratchet tests guarding the filter against regression
…ts, with tests that fail loudly when parity breaks
…the updated value (arrow-if dual-storage), fixing max.pine getMA returning 0 and yielding 62 SBERP-1h trades; chart-only label/security calls stubbed so they no longer abort the run, plus negative-defval inputs, MatchSize per-trade parity assertions, top10 stale-skip guard, version-threaded time() extraction, and chart-UI toggle aria-pressed state
@bvasilenko bvasilenko self-assigned this Jun 14, 2026
@github-actions

Copy link
Copy Markdown

⏱️ Time Estimation

Scope: Branch commits only (26a3c62..7a32cf9)

Based on commit timestamp analysis (0.5h session threshold)

  • Boris Vasilenko: 4.5h (9 commits)

Total: 4.5h across 9 commits

…pts numeric timeframe tokens like as real periods reused from same-resolution data, and resolves string variables — but the ticker-string codegen emits a symbol name declared in the wrong scope, so zigzag generates Go that does not compile; max stays end-to-end with its 62-trade golden
… symbol's real trading-day session open (MOEX, NYSE, or any exchange's observed first bar) instead of UTC midnight, so coarser-secondary `security()` values gate on the correct bar; zigzag compiles and runs via package-scope `syminfo_tickerid` and same-resolution fixture reuse; end-to-end witness on a compiled AAPL binary is not yet present
…y symbol's own exchange session-open boundary instead of UTC midnight, so a MOEX-primary strategy reading an NYSE secondary anchors that secondary to its real trading-day open even when the secondary fixture declares only an exchange and no timezone, proven by a compiled-binary cross-exchange witness.
…lues stay correct across multi-bar secondary series; eliminate silent strategy.Long direction fallback so named-argument shorts no longer reverse to long; de-skip Supertrend reversal test and assert equity against each strategy's own declared initial capital plus open-position unrealized P&L
…lace the greedy trade matcher with maximum-cardinality bipartite matching so divergence is never overstated; and document via compiled-binary tests that zigzag and moon cannot reach TV parity
…ment fixture whose bar count is below its in-window reference trade count, whose flat O=H=L=C fraction exceeds 5% for a strategy proven sensitive to flat bars, whose cross-symbol family shares identical OHLCV content, or whose price scale diverges from the reference, and tighten the TV-only discrepancy cap from 5 to 4 with the one pre-existing exception marked as operator-approved
…sion normalization

Remove the escalation flags that had forced three over-cap TV-alignment cases
green. Hull, UtPlus, and Alpha on the real 5.5-year MOEX SBERP-1h fixture now
report their true divergence (Hull runner-only=6/tv-only=17; UtPlus
runner-only=6 with export-horizon=12; Alpha 4/4). The absolute policy caps
(runner-only<=2, tv-only<=4, time<=2h, price<=2.00) are retained as the
correctness standard; no rate-floor or scaled tolerance is introduced. The three
over-cap strategies remain wired and are reported over cap until their behavioral
root cause is fixed.

Land the MOEX WeekSchedule reference-session model: user-facing and generated
paths normalize strategy-visible bars through NormalizeBarsWithMetadataE
(strict, exit-on-error); SBERP/CNRU fixture metadata gains explicit openDates;
goldens regenerated against the normalized bar stream; fixture-quality preflight
and exemption-budget ratchets bound the FixtureEndOpen/FixtureStartWarmup/
ExportHorizon levers so tolerance cannot silently absorb genuine divergence.

Golden and data mutation is operator-authorized.
…session-open anchors

Extract the four-case order-execution switch shared by OnBarUpdate (open-price
fills) and OnBarClose (close-price fills) into one dispatchOrder method with an
explicit fill time, removing a ~28-line duplication and a stored-field entry-time
trap. Behavior is unchanged: the generator passes the same bar time to both
paths, verified against the full golden suite (moon uses process_orders_on_close).

Make runtime/calendar the single source of Pine timestamp() layout parsing: add
ParsePineTimestampMillisUTC over the shared dateFormats table (extended with the
minute-precision layouts the codegen extractor previously carried in a separate
table) and have the input.int/input.time constant folder call it instead of a
private duplicate. The compile-time fold remains UTC; a timezone-sensitive default
is not emitted by any current strategy and is documented as requiring runtime
evaluation via TimestampFromString for full timezone fidelity.

Add a ratchet pinning each known exchange's session-open minute (MOEX 07:00,
NYSE 09:30, Binance 00:00) to its reference open, so a curated-table drift fails
loudly rather than silently mis-tiling multi-hour security() grids after the
known-exchange observation fallback was removed.

Compute the fixture candidate path list once in readFixture.

No golden or trade output changes; the only failing test remains the by-design
policy-cap check on the three known-divergent strategies.
… casting

Pine casts a fractional wma length to int by truncation, so a call like
wma(src, 55/2) uses period 27 for both the term count and the triangular weights.
The inline wma generator truncated only the loop bound while using the raw float
length (27.5) in the weight, offsetting every weight by the fractional part. Use
the truncated int period for the weight base too.

No current golden or TV-alignment output changes: existing fractional-length wma
strategies are crossover-based, where the near-uniform level offset cancels in the
signal. This prevents divergence for any level-sensitive fractional-length wma.
The inline WMA generator now uses the truncated integer period for the weight
base (float64(int(period))) so fractional lengths like wma(src, 55/2) match
TradingView. The type-safe-weight test still asserted the prior float64(period)
form and had been left failing. Update its expected patterns to the int-
truncated form; the type-safety intent (float64 subtraction, never int-domain
subtraction) is preserved by the unchanged forbidden-pattern assertions.
@github-actions

Copy link
Copy Markdown

⏱️ Time Estimation

Scope: Branch commits only (26a3c62..c09dbae)

Based on commit timestamp analysis (0.5h session threshold)

  • Boris Vasilenko: 10.2h (20 commits)

Total: 10.2h across 20 commits

…om Alpha entries, and bring all three SBERP TV-alignment cases within policy caps (Alpha via the codegen fix, Hull via golden refresh, UtPlus via shared tolerance normalization plus dated truncated-reference exemption)
…ess gate passes

contribot's assertWorkspaceReadyForContribot requires every runtime artifact path
it writes to be gitignored, and it throws when any is missing. AGENTS.md was the
one path in that set the runner did not ignore, so a launch against this workspace
would have failed the readiness gate before reaching the pipeline. Grouping it with
the other contribot runtime artifacts keeps the agent's scratch surface untracked.
…nce test, and close the stale-skip guard's blind spot

top10/ultima.pine executes end-to-end on SBERP-1h but places no orders: entries
gate on ext_source == 1 and ext_source == -1, where ext_source resolves to
nz(close) on a 100-300 RUB instrument, so both gates are permanently false. It is
a signal-adapter template awaiting an external +/-1 source. Its .pine.skip claimed
"time() IIFE not implemented", which is stale, since the strategy now compiles and
runs over the full series.

Asserting only that the run yields zero trades does not prove any of this. Deleting
both strategy.entry calls from the Pine source produces byte-identical output on
trade count, open trades, net profit, and equity, so such a test cannot tell an
inert-by-design strategy apart from one whose entry orders were silently dropped by
codegen. That failure mode is live in this file already: four of six plot() calls
and the id argument of strategy.close() are dropped today.

The test therefore binds its assertions to the causal mechanism instead. It reads
the generated Go and requires both entry sites and both +/-1 gate literals to
survive codegen, and it runs a positive control that relaxes the long gate to
ext_source > 0 and requires that variant to trade. Either mutation now fails the
test. Net profit and equity assertions are dropped: every ultima trade carries
size 0 because strategy() header args are not threaded, so those assertions could
never fail and only conveyed false confidence.

The emitted series length is pinned at 21436 bars, the session and warmup trim of
the 21927-bar fixture, so any pipeline truncation surfaces immediately.

TestTop10_StaleSkipGuard could not have caught this sidecar. It iterates only
tvAlignmentCases() and returns early when a TV reference CSV is absent, and ultima
appears in neither. A by-design strategy will never have a reference CSV, so that
whole class was unguarded. An explicit inert-by-design registry now covers it,
while strategies in neither list stay unflagged as legitimately pending.
Emit input.float defaults with exact shortest-form values instead of rounding to two decimals. Refresh the zigzag SBERP baseline to the resulting 484 trades and add current-source pivot, sizing, timestamp, and typed-input ratchets.
Carry source-located compatibility diagnostics from parse, codegen, and runtime into chart output. Preserve independent indicators while omitting strategy results when unsupported provenance reaches execution-critical sinks, and keep parser failures structured.
@bvasilenko
bvasilenko force-pushed the feature/go-runner-error-handling branch from c09dbae to fe641cd Compare September 7, 2026 13:47
@github-actions

github-actions Bot commented Sep 7, 2026

Copy link
Copy Markdown

⏱️ Time Estimation

Scope: Branch commits only (26a3c62..fe641cd)

Based on commit timestamp analysis (0.5h session threshold)

  • Boris Vasilenko: 13.0h (24 commits)

Total: 13.0h across 24 commits

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant