Repository navigation
Apply syminfo.mincontract as the engine's lot grid in the harness - #21
Closed
luisleo526 wants to merge 1 commit into
Closed
luisleo526 wants to merge 1 commit into
luisleo526 wants to merge 1 commit into
Conversation
The harness applied only mintick, pointvalue, timezone and session from the --syminfo file, so a percent-of-equity strategy traded sub-lot quantities that the instrument does not allow. A positive finite mincontract is now set as the engine's qty_step metadata (order quantities are floored to it) and as the mincontract metadata, before the other setters. Absent or null changes nothing; any other value, or a library without the metadata setter, fails the run with the structured error line, which shows the value's JSON text. An applied grid is recorded as applied_runtime.syminfo and so in the fingerprint. docker/run_json.py is vendored from the pineforge-engine tag at every release: keep the lot-grid handling identical in both repos.
This was referenced Oct 3, 2026
Contributor
Author
|
Superseded: the lot grid ships in the engine harness (engine #322), synced into the release image; verified on pineforge-release:1.1.0 (qty-step case passed). |
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.
What
docker/run_json.py(--syminfo FILE, entrypoint envPINEFORGE_SYMINFO) now applies the instrument lot-size grid from the catalog'ssyminfo.mincontract, so the engine floors order quantities to it, as the MCP servers already do.Without the grid, a percent-of-equity strategy trades sub-lot "dust" quantities that TradingView never shows. Example (BTCUSDT 4h, EMA 20/50 crossover, 100 % of equity, 0.1 % commission, 2,188 bars): 27 trades without the grid, 22 with it; 5 of the 27 are below one lot (about 3e-08 BTC).
Behaviour
mincontractis read from the--syminfoJSON (flat object or{"syminfo": {...}}; a catalog object can be passed as is, other keys are ignored).null: nothing changes, no setter is called.strategy_set_syminfo_metadata(strat, "qty_step", v)(the engine floors order quantities to this grid), thenstrategy_set_syminfo_metadata(strat, "mincontract", v)(sosyminfo.mincontractreads in a script return the catalog value, as on TradingView), before mintick, pointvalue, timezone and session, after inputs and overrides.0,-1,"0.001",true,NaN,Infinity, a list, an object): rejected, never applied. The harness prints one line{"engine":"pineforge","error":"syminfo.mincontract must be a positive finite number, got <value>"}and exits 1 (the entrypoint exits 4);<value>is the value's JSON text cut to 80 characters.strategy_set_syminfo_metadatafails the same way whenmincontractis present. The harness never runs without a grid it was given.applied_runtime.syminfo = {"qty_step": v, "mincontract": v}, so it is in the report and infingerprint.provenance.runtime: the fingerprint digest of a run with the grid differs from the gridless run's (its trades differ). Without a grid the key is absent and the report, fingerprint included, is unchanged (see Evidence). mintick, pointvalue, timezone and session stay unrecorded, as before.Evidence
Release image built from this branch (engine 1.0.1, codegen 1.0.1) on a clean Linux x86_64 host; the published 1.0.1 image is the baseline (it is today's
main).mincontractnull or absentmincontract1e-05report.trades)applied_runtime.syminfo{"qty_step": 1e-05, "mincontract": 1e-05}fingerprint.digestsha256:e4315ec21e0717ad7d1f06f67d671743e162480b4d3b3464b48587a0a2d86f69sha256:b9e00cb9b60f54352e8a3243eb77bb8257ef53e408ba83483aba9c0a19aaa503POST /backtest, public mode, the catalogsyminfoobject sent as is), row by row against the rows of an earlier engine 1.0.1 run (8 columns, 1e-9 relative).mainimage the grid case returns the gridless 27 rows (the key is ignored): the end-to-end run fails there for that reason and passes on this branch.mincontract: null; the same with the key absent) the baseline image and this branch's image give identical stdout bytes,fingerprint.tokenandfingerprint.digestincluded, onceelapsed_seconds(the run time) is set to 0.-1,0,"0.001",trueexit 4 with the one-line error above.python3 tests/test_fingerprint_canonical.py(31 checks before, 73 with this change; they driveapply_syminfoandmain()with a fake strategy library: order and values of the calls, null/absent/invalid values, missing setter,--bench, the recorded grid and digest), andpython3 -m unittest discover -s tests -p 'test_release_*.py'(66 tests), the two commands ofpython-test.yml.apply_syminfois unaffected: its build gate (pf_run_json.py --check) printshooks OKagainst thisrun_json.py, and its 23 unit tests pass against this file.Please note
docker/run_json.pyis vendored from the pinnedpineforge-enginetag (scripts/sync-harness.sh,handle-upstream.yml): today it is byte-identical to the engine's v1.0.1 copy, and the next release sync copies the engine's file over this one. This change takes effect in a published image only if the same diff also lands inpineforge-engine'sdocker/run_json.py(this diff applies to the v1.0.1 file withgit apply -p1and reproduces this file byte for byte). The file and the README say so.qty_step(the lot grid), the harness also sets the metadata keymincontract, as the hosted shim does, so a script'ssyminfo.mincontractreads the catalog value instead ofna. Drop that second call (and themincontractentry of the recorded dict) if only the grid is wanted.mincontractis an error rather than a warning, so that a bad catalog value is never silently run without its grid. mintick, pointvalue, timezone and session keep their old, unvalidated handling.mainare: the bench and body runs sit inside onetry(re-indented, otherwise unchanged),_make_statekeeps whatapply_syminforeturned (a replacementapply_syminfothat returnsNoneor any non-dict is tolerated), and one line adds it toapplied_runtime. The hooks the hosted shim's build gate asserts are intact.🤖 Generated with Claude Code