Skip to content

go-yfinance v1.7.0 Development Progress

Last Updated: 2026-08-27

Tracking: go-yfinance issue #14

Overview

This document tracks Python yfinance v1.7.0 parity work. Python yfinance 1.7.0 was released on 2026-08-26 from 3d9d2f0. The audit baseline is the complete upstream 1.6.0...1.7.0 comparison and changelog PR #2959, not only the short release notes.

The Go branch starts from main at 94e7b45, tagged v1.6.1. That baseline already includes Go-specific authentication hardening, complete CycleTLS cookie preservation, protobuf/WebSocket safety fixes, and cache immutability. The v1.7.0 work must preserve those guarantees while adding only behavior that maps from the upstream release.

Branch Structure

main (v1.6.1, 94e7b45)
 └── feature/parity-1.7.0

Upstream Release Scope

The upstream comparison contains 13 commits:

Commit Item Final Go disposition
1d2cfda, e9fd382 Lazy-load history_metadata["tradingPeriods"] (#2922) Adapted in 1a6da9f: explicit typed lazy accessor, cache-only legacy getter, deep-copy cache boundaries.
ea30eee Merge main into the upstream development line Audit contained commits; no standalone Go change.
5261b4d, baeca64 Remove nospam extra and Python 2 setup cruft (#2918) N/A: Python packaging only.
0f29c85, c732994, 5c1f64e Stock-split volume-validation repair and follow-up (#2958) Implemented in c8489cd: final range logic, suppressors, .2 threshold, NRDY full/last-27 goldens, half-even integer-volume adaptation.
ba7b650, fdede94 Preserve proxies and degrade cookie/crumb acquisition failures (#2953) Implemented/adapted in 7042a4e: shared GET/JSON-POST behavior across eight paths; immutable Go proxy retained and covered.
686a031 Minor upstream test correction N/A runtime; Go's deterministic zero-repair test already chooses an explicitly positive-volume row (TestShouldRepairZero).
43f3021 Release aggregation merge PR #2959 No standalone runtime change; audit the contained feature commits without double-counting them.
3d9d2f0 Version 1.7.0 Code parity complete; Go release documentation and tag remain in T12-T13.

Changed upstream files:

CHANGELOG.rst
meta.yaml
tests/context.py
tests/data/NRDY-1d-bad-stock-split.csv
tests/data/NRDY-1d-bad-stock-split-fixed.csv
tests/test_cookie_crumb_degradation.py
tests/test_price_repair.py
yfinance/data.py
yfinance/scrapers/history.py
yfinance/version.py

Every commit and changed behavior must finish with one of: implemented, adapted, intentionally N/A, or deferred with a concrete reason.

Current Go Gap Assessment

Area v1.6.1 behavior v1.7.0 target
Trading periods ChartMeta has no typed schedule. GetHistoryMetadata returns cached metadata without fetching and currently exposes its ValidRanges slice by reference. Add typed regular/pre/post periods and an explicit lazy accessor. Preserve cache-only behavior and clone metadata/slices on cache boundaries. Never introduce a hidden intraday request into normal daily history or fast-info calls.
Crumb degradation Eight direct paths (getWithCrumb plus sector, industry, calendars, analysis, options, and two financials paths) abort before the target request on every crumb error. Degrade only rate-limit/network/timeout crumb failures for endpoints that can work without a crumb. Preserve non-transient auth failures and target error types.
Proxy preservation Client.proxy is an immutable configuration snapshot passed to every CycleTLS request. Keep implementation; add SOCKS5/SOCKS5h auth-and-target request regression coverage.
Split repair Detection and volume confirmation are centered on one split boundary and correction can rescale the whole pre-split range. Detect anomalous ranges and repair only missing/doubly adjusted ranges or cells.
Volume threshold volumeChangeThreshold uses the v1.6 coefficient 0.333. Use the finalized v1.7 coefficient 0.2, with regression tests.

Locked Design Decisions

  • Keep Ticker.GetHistoryMetadata() *models.ChartMeta cache-only and network-free. Return a deep copy so callers cannot mutate ticker cache state.
  • Add an explicit Ticker.GetTradingPeriods() ([]models.TradingPeriod, error) accessor. Network access and retryable failure are visible in its signature.
  • Represent each schedule row with epoch-second regular Start/End fields and optional pre/post epoch fields, consistent with existing ChartMeta timestamps. Decode Yahoo's regular-only list shape, grouped pre/regular/post shape, empty values, and the {pre:[],post:[]} sentinel.
  • Store only a successful schedule enrichment. Coalesce concurrent loads, return cloned slices, preserve base metadata on error, and clear all enrichment state in ClearCache().
  • Put the shared authenticated GET primitive in pkg/client, next to the authentication/error taxonomy it coordinates. Clone all query values.
  • Match upstream's one alternate-strategy retry after a target HTTP error. Preserve the final target status classification, never retry transport errors implicitly, and never add an empty crumb.
  • Treat Python user-session proxy ownership as N/A. Go's immutable configured proxy already reaches every CycleTLS request; protect that behavior with SOCKS5/SOCKS5h regression tests.
  • Port #2958 from the final 0f29c859 plus 5c1f64e state. Use range-based selective repair and rounded integer-volume golden expectations; do not truncate upstream fractional intermediate volumes.

Task Plan

Each task must end with its focused tests passing and a reviewable commit (or an explicit N/A record). A task is not complete merely because its code has

T00: Freeze the upstream parity oracle

  • [x] Read the complete patches for #2922, #2953, #2958 and their follow-ups, including upstream tests and both NRDY fixtures.
  • [x] Build a commit/file/behavior matrix for all 13 upstream commits.
  • [x] Classify every item as implemented, adapted, N/A, or deferred with evidence; record Python-only packaging and merge commits explicitly.
  • Deliverable: committed parity-audit section or companion document.
  • Validation: every changed upstream file and commit has one disposition.

T01: Map current Go behavior and lock API decisions

  • [x] Map the relevant yfinance/data.py and history.py branches to all Go call sites and existing tests.
  • [x] Decide exported trading-period names, return shape, zero-value behavior, JSON shape, and compatibility behavior for GetHistoryMetadata().
  • [x] Decide ownership of the shared degradable-request helper so ticker, sector, industry, and calendars do not duplicate retry rules.
  • Deliverable: documented API/request design with affected packages.
  • Validation: compile-time API sketch plus focused design review; no runtime implementation starts before public API questions are closed.

Trading-period parity

T02: Add typed trading-period models and decoding tests

  • [x] Add typed regular/pre/post schedule models.
  • [x] Decode normal, absent, sparse, and upstream variant payload shapes.
  • [x] Keep this task free of network and cache behavior.
  • Deliverable: models and table-driven decoding tests.
  • Validation: focused model tests and go vet for affected packages.

T03: Implement explicit lazy enrichment and cache lifecycle

  • [x] Preserve Ticker.GetHistoryMetadata() as a cache-only, no-network API.
  • [x] Add an explicit lazy accessor that consumes cached intraday metadata or requests range=5d, interval=1h, and includePrePost=true.
  • [x] Coalesce concurrent successful first loads into one request.
  • [x] Merge only enrichment fields; never replace valid base metadata with a sparse response.
  • [x] Cache success, preserve base metadata after failure, allow retry, and reset enrichment state in ClearCache().
  • Deliverable: accessor/cache implementation and deterministic request tests.
  • Validation: no hidden daily-history/FastInfo request, first fetch, cache hit, concurrency, sparse response, failure/retry, and clear-cache tests with race.

Crumb and proxy parity

T04: Build and prove the shared degradable request primitive

  • [x] Clone caller url.Values; never mutate input or emit an empty crumb.
  • [x] Degrade only rate-limit, network, and timeout crumb-acquisition errors.
  • [x] Propagate parse, invalid-response, and other non-transient auth errors.
  • [x] Send the target request crumb-less after a degradable acquisition error; do not report crumb endpoint 429 as a target 429.
  • [x] Preserve target error classifications and cap any upstream-required alternate-strategy retry at one.
  • [x] Prevent concurrent crumb-refresh stampedes.
  • Deliverable: shared primitive with scripted deterministic tests.
  • Validation: upstream six cases, non-transient errors, alternate retry, immutable input, no empty crumb, and concurrent race tests.

T05: Migrate every crumb call site

  • [x] Migrate ticker.getWithCrumb, sector, industry, calendars, analysis, options, and both financials paths.
  • [x] Remove bypasses and duplicated fallback logic.
  • Deliverable: complete call-site migration as a separate commit.
  • Validation: call-site inventory has zero unexplained direct paths; affected package tests and race tests pass.

T06: Lock proxy-preservation behavior with regressions

  • [x] Prove WithProxy("socks5h://...") and config-provided SOCKS5 values are unchanged on auth and target requests.
  • [x] Verify no request or crumb fallback overwrites the configured proxy.
  • [x] Do not port Python session-ownership behavior with no Go analogue.
  • Deliverable: proxy-focused regression tests; runtime change only if a real Go gap is demonstrated.
  • Validation: SOCKS5/SOCKS5h tests pass under race detection.

Stock-split repair parity

T07: Import and adapt the NRDY oracle fixtures

  • [x] Import both upstream NRDY CSVs into pkg/repair/testdata with source attribution.
  • [x] Document conversion of Python's temporary fractional internal volume to public integer models.Bar.Volume semantics.
  • [x] Add the golden harness and fixture parser before changing the repair algorithm; record the observed parity gap without committing a failing test.
  • Deliverable: fixture/parser commit plus a precise note of the current gap.
  • Validation: fixture parsing and input-invariant tests pass; the recorded gap is narrow and attributable to #2958 behavior.

T08: Implement range detection and volume validation

  • [x] Detect contiguous anomalous ratio/reciprocal ranges, including isolated and alternating rows, without requiring an anomaly on the split event row.
  • [x] Gather representative positive-volume samples across adjacent ranges and gaps, denoise them, preserve the all-zero guard, and avoid veto when a meaningful comparison cannot be calculated.
  • [x] Use threshold 1 + (splitMax - 1 + largestVolumeChangePct) * 0.2.
  • Deliverable: detection/validation implementation and unit tests.
  • Validation: focused forward/reverse split, sparse volume, all-zero, boundary, and false-positive tests pass.

T09: Implement selective repair and golden verification

  • [x] Correct only identified missing or double-adjusted ranges/cells; never rescale every pre-split row in mixed data.
  • [x] Preserve dividend scaling, repaired markers, FX exclusion, and existing forward/reverse split behavior.
  • [x] Verify full NRDY and last-27-row outputs plus already-correct fixtures.
  • Deliverable: selective repair and golden tests in a reviewable commit.
  • Validation: expected NRDY output matches value-for-value and existing repair tests pass under race detection.

Integration and release preparation

T10: Reconcile feature findings and run integration regression

  • [x] Resolve accepted findings from the feature checkpoints below with new deterministic regression tests.
  • [x] Run focused history, ticker, client, repair, cache, and integration tests.
  • [x] Audit that v1.6.1 cookie, WebSocket, protobuf, and cache guarantees remain.
  • Deliverable: small corrective commits, never one mixed review-fix commit.
  • Validation: affected package tests, race tests, go vet, and git diff --check pass.

T11: Close the upstream audit

  • [x] Revisit the T00 matrix against the final code and tests.
  • [x] Close every upstream behavior as implemented, adapted, N/A, or deferred.
  • [x] Confirm no Python-only concern was accidentally introduced into Go.
  • Deliverable: final parity audit suitable for release notes and PR body.
  • Validation: no unresolved or evidence-free matrix entry.

T12: Produce release and generated documentation

  • [x] Add docs/releases/RELEASE_NOTES_v1.7.0.md with exact dispositions.
  • [x] Update README, docs/index.md, and mkdocs.yml parity/release content.
  • [x] Regenerate GoDoc/API pages from the final public API and commit drift.
  • Deliverable: independent release-documentation commit(s).
  • Validation: README/docs sync check and make docs-build pass.

T13: Execute the release-readiness gate

  • [ ] Re-read docs/development/release-readiness-checklist.md before opening or marking the release PR ready, before merging, and before tagging.
  • [ ] Run every local command in Verification And Release Gates.
  • [ ] Push, open/refresh the PR, and require clean remote CI and review status.
  • [ ] After approval, merge to main, validate final-main CI, then create the annotated v1.7.0 tag on the verified release commit.
  • Deliverable: mergeable release PR, final-main evidence, and guarded tag.
  • Validation: checklist complete with exact commit/tag targets recorded.

Cross-Verification Checkpoints

Cross-verification is intentionally incremental. Waiting until all features are combined would make API mistakes and upstream-semantic drift expensive to isolate. Claude Code and Codex reviews must be blind: give both the same upstream oracle and branch diff, but do not expose either review to the other until both reports are complete.

Checkpoint Timing Review focus Required before
CV0: design After T00-T01 Completeness of upstream matrix, Go API shape, compatibility and hidden-network risks T02
CV1: metadata After T02-T03 Upstream #2922 semantics, sparse decoding, cache state machine, concurrency and API compatibility T04 or acceptance of metadata work
CV2: auth/proxy After T04-T06 Error taxonomy, crumb-less fallback, retry bounds, parameter immutability, stampede and proxy preservation T07 or acceptance of auth work
CV3: repair After T07-T09 #2958 range semantics, integer-volume adaptation, false positives and golden fixture fidelity T10
CV4: integrated parity After T10-T11 Full 1.6.0...1.7.0 behavioral coverage, cross-feature regressions and omitted upstream changes T12
CV5: release candidate After T12 and all local gates Release diff, public API/docs sync, CI-command drift, tag target and release checklist main merge/tag

For CV1-CV3, a single verifier may perform the first focused review when the change is small, but the other verifier must independently review before T10. CV0, CV4, and CV5 require both reviewers because they guard irreversible API or release decisions. Every checkpoint produces a short ledger of accepted, rejected, and deferred findings with evidence. Accepted findings require a regression test and re-running the checkpoint's focused race tests.

Completed checkpoint ledger

Checkpoint Status Result
CV0 Complete Codex audited all 13 commits and Claude reviewed the locked semantics. Accepted: explicit error-returning trading-period accessor, deep-copy cache boundaries, eight auth paths, shared GET/JSON-POST primitive, and final 0f29c859 + 5c1f64e split oracle. Corrected 43f3021 from docs-only to aggregation merge.
CV1 Complete Codex accepted decoding/coalescing and found JSON round-trip plus ClearCache/in-flight gaps; both were fixed with tests. Claude raised cached-shape, metadata-merge, and empty-result concerns; rejected because upstream HistoryMetadata also returns an existing key as-is, merges lazy periods into _history_metadata, and treats an existing empty sentinel as loaded.
CV2 Complete Codex found caller-supplied stale crumb and nil-response gaps; fixed by rejecting manual crumbs and returning typed invalid-response errors. All eight direct paths now use the shared primitive. Claude found no blocker; its suggestion that upstream does not retry all 400/404 responses was rejected because data.py::_make_request retries every status_code >= 400 once.
CV3 Complete Codex found interday gate, cutoff, adjusted-OHLC, local-volatility, and volume-spike suppression gaps; all were ported with regressions. Claude found no semantic blocker and identified Go half-away rounding; fixed with math.RoundToEven and an exact .5 test. NRDY full and last-27 goldens pass.
CV4 Complete Codex caught and prompted repair of a duplicated progress block. Its split-volume blocker was rejected against final upstream control flow: all-zero volume exits before detection, while the later range-volume continue occurs in a non-mutating first loop and the second loop applies every mapped range. Claude found no code blocker; 686a031 was closed against Go's explicit positive-volume zero-repair test. Full network tests, vet, race, and both lint gates pass.
CV5 Complete Codex and Claude independently found no release blocker. Codex confirmed a clean candidate, README/docs sync, workflow-command alignment, public API documentation, no local or remote tag collision, and byte-identical regenerated API docs after normalizing expected branch source links. Both reviewers independently upheld the CV4 split-volume conclusion against exact upstream runtime control flow. Remaining work is limited to remote PR/CI, main merge, and tagging.

Feature commits:

  • 1a6da9f — typed/lazy trading-period metadata and cache immutability.
  • c8489cd — range-based split repair and upstream NRDY oracle fixtures.
  • 7042a4e — crumb degradation, bounded retry, proxy regressions, and call-site migration.

Acceptance Criteria

  • [x] Daily history and FastInfo gain no hidden intraday enrichment request.
  • [x] First trading-period access performs one enrichment fetch; repeated and concurrent successful access is cached.
  • [x] Failed enrichment preserves base metadata and can be retried.
  • [x] Auth tests cover cookie timeout, crumb 429, transient crumb failure, target 429, SOCKS proxy preservation, and no proxy overwrite.
  • [x] Auth tests cover non-transient propagation, alternate retry, no empty crumb, caller parameter immutability, and concurrent callers.
  • [x] Full and last-27-row NRDY inputs match expected fixed outputs.
  • [x] Already-correct split inputs remain unchanged.
  • [x] Existing history, auth, repair, WebSocket, cache, and integration tests remain green.

Verification And Release Gates

Before merging to main or creating v1.7.0:

  • [x] GOCACHE=/tmp/go-build-cache go test ./...
  • [x] GOCACHE=/tmp/go-build-cache go vet ./...
  • [x] GOLANGCI_LINT_CACHE=/tmp/golangci-lint-cache golangci-lint run ./...
  • [x] make lint
  • [x] GOCACHE=/tmp/go-build-cache go test -v -race -coverprofile=coverage.out ./...
  • [x] GOMARKDOC=/tmp/gobin/gomarkdoc make docs
  • [x] cp README.md docs/index.md
  • [x] make docs-build
  • [x] git diff --check
  • [x] Verify local commands match .github/workflows/test.yml and .github/workflows/docs.yml.
  • [x] Push the branch, verify the release PR is mergeable, and require remote test/lint success.
  • [ ] Merge to main, wait for the final main Tests and docs workflows, then create annotated v1.7.0 on the final intended release commit.

Guardrails

  • Do not tag or publish from the parity branch.
  • Do not move or recreate an existing release tag.
  • Do not treat a crumb-endpoint 429 as proof that the target endpoint is rate limited.
  • Do not swallow non-transient authentication or target errors.
  • Do not add an automatic intraday request to ordinary history or FastInfo.
  • Do not broaden this release with Python-only packaging/CI changes or the previously deferred timezone location cache.
  • Keep unrelated dirty files out of parity and release commits.

Status Legend

  • [x] Done
  • [ ] Pending
  • N/A: verified not applicable, with the reason recorded inline