Repository navigation
Backtest API: @mathieuc/tradingview/backtest (4.1.0-beta.1) - #352
Merged
Merged
Conversation
Turn the honest-backtest example (#351) into a library module: the caller writes only the entry rule, the module applies the protocol and returns a JSON report. - backtest() downloads candles once and freezes them; runBacktest() runs synchronously on candles or a saved snapshot. - Signals are { bar, direction, refs? } decided at the close of bar; the entry is always the next bar's open. - New look-ahead check: the signal is rerun on truncated history and the run stops with the new LOOK_AHEAD error code when a signal depends on later bars or repaints. - Same rules as the example: costs on both sides, same-candle stop and target as a loss, gap fills at the open, warm-up, IS/OOS split without open positions across it, four exits, seeded random-entry baseline. - examples/honest-backtest uses the module (identical report on the same snapshot); new examples/backtest-custom-signal.js. - docs/backtest.md, data API guide, llms.txt, READMEs, release notes.
- Report holds identifiers and numbers only: warnings become codes (formatWarning gives the English sentence), rows drop exitLabel, settings.signal and settings.exits carry id, kind and params. - Add createdAt, library, snapshot.fetchedAt, buyHold per segment and refBars on signals and trades. - Add chartData() for price charts and backtestMany() for several markets, with exits per market and a series column in the CSV. - rsiDivergence exposes id, params, indicators and a trendFilter option.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Turns the honest-backtest example (#351) into a library entry point,
@mathieuc/tradingview/backtest. The caller (a person or a coding agent) writes only the entry rule. The module downloads the candles, applies the whole protocol and returns a JSON report. Before this, a real agent spent about 9 of its 10 minutes writing an engine from scratch.No new dependency. Root and
/dataexports are unchanged; the only shared change is the new error codeLOOK_AHEAD.What is new compared with the example
candles[i + 1]...) or disappears when they arrive (repaint), the run stops withTradingViewErrorLOOK_AHEADanddetailslists every violation. The example relied on the author doing this right; the module enforces it.{ bar, direction, refs? }decided at the close ofbar; there is no way to enter on the signal bar.formatReport,formatTableandtradesToCsvrender it. Signalrefs(e.g. pivots) become<name>_timeCSV columns.loadSnapshotchecks the SHA-256 on replay. Snapshots saved by the examples: honest backtest protocol on getCandles data聽#351 example still load.rsiDivergence,defaultExits,fixedExit,atrExit,atrTrailingExit(stop-only variants withtargetR: null),sma/ema/rsi/atr/findPivots,simulate,randomBaseline,checkCausality...The protocol rules themselves are unchanged: frozen snapshot with the forming bar dropped, warm-up never traded, chronological 70/30 IS/OOS split with no position across it, fee and adverse slippage on both sides (baseline included), stop and target in the same candle = loss, gap through the stop = open, four interchangeable exits, 1,000 seeded random-entry runs per exit and split (percentile with strictly lower, p5/p50/p95), and metrics per segment (net return, win rate, PF with
null, max drawdown, trades).examples/honest-backtest/index.jsnow calls the module with the same CLI options;engine.jsandengine.d.tsare removed. Newexamples/backtest-custom-signal.js(an EMA cross in about 15 lines).Verification
tests/unit/backtest.test.tshas 33 deterministic tests that replace the 15 tests of the example. Ten deliberate mutations each make at least one test fail. These are the 7 from examples: honest backtest protocol on getCandles data聽#351 (backdated signal, entry at the signal close, trailing look-ahead, missing exit fee, same-candle rule counted as a win, gap filled at the stop, position across the split) plus entry on the signal bar, look-ahead check bypassed and baseline without costs.npm run check: pass (203 passed, 2 skipped; the packed-package smoke now imports/backtestunder Node and Bun, withrequire()and a TypeScript consumer, and checks thatLOOK_AHEADfires).npm run test:bun: 202 pass, 0 fail.src/backtest: 95% statements, 85% branches.node examples/honest-backtest/index.js(download and full protocol) andnode examples/backtest-custom-signal.json ETHUSDT 4H in 1.7 s, download included.runBackteston 4,583 bars with 4 exits 脳 2 splits 脳 1,000 runs takes about 0.2 s.Docs
docs/backtest.md(signal contract, look-ahead check, options, exits, protocol, report fields, how to read results). Also updated: the backtest section and error table ofdocs/data-api.md,llms.txt(an agent should write only the rule), README in EN/FR/ES/PT,examples/README.mdanddocs/release-4.1.0-beta.1.md. The docs make no profitability claim and say that a negative or inconclusive result is valid.Report format frozen for pages (4.1.0-beta.2)
So that a page template can be built on it, the report now holds identifiers and numbers only. Warnings are codes (
formatWarninggives the English sentence),exitLabelis removed from rows, andsettings.signal/settings.exitscarryid,kindandparams. New fields:createdAt,library,snapshot.fetchedAt,buyHoldper segment, andrefBarson signals and trades. New helpers:chartData(report, snapshot, signal)(candles, indicator series, split times, signals, trades by exit) andbacktestMany({ markets, exits, signal }), which takes exits per market and adds aseriescolumn to the CSV. Results are unchanged: the same rows and trades as the #351 engine.Release
4.1.0-beta.1and then4.1.0-beta.2are published under the npm dist-tagbeta.lateststays on 4.0.1 for now.