Skip to content

fix(ifind): legal A-share windows across a long closure are refused #483

Description

@FlyM1ss

Follow-up from #474 item 1 (PR #477). Known and documented in the code; filing so it is tracked rather than only commented.

minimum_bars_for_window derives its floor from weekdays, which cannot see exchange holidays. A window whose data is complete and correct is refused as truncated when more than half its weekdays fall inside a closure.

floor = max(4, weekdays * 4 * 0.5) → refusal whenever real_trading_days < weekdays / 2.

Measured (sweep over every legal span, both real closures):

window span floor real trading days real bars
2026-09-28 → 2026-10-09 11d 18 4 16
2026-09-25 → 2026-10-08 13d 18 4 16
2024-02-05 → 2024-02-17 12d 20 4 16

Both National Day (Oct 1–7) and Spring Festival reproduce it.

Two things worth knowing before working this:

  • It is not reachable at the full 14-day span. Refusals cluster at 11–13 days; a 14-day window picks up enough weekdays on either side of the closure to clear its own floor. The comment at ifind_ashare.py:31-42 implies the widest windows are affected — they are not.
  • The existing sweep cannot catch it. test_minimum_bars_never_exceeds_the_weekday_derived_bar_count varies weekdays only, so no closure ever enters it. Renamed in PR fix: preflight the pipeline backtest window #477 to stop it claiming coverage it does not have; the separate mutation-strength gap in that same test is test: the A-share floor sweep does not catch a restored flat constant #482.

It fails in the safe direction — a visible refusal, not a short curve charted as real — which is why it shipped. Lowering _MINIMUM_BAR_COMPLETENESS is not the fix: it trades a visible false refusal for silent acceptance of a genuinely truncated reply, which is the case the guard exists for. The fix is a CN trading calendar, which ifind_ashare.py deliberately does not carry (it would be a second, unversioned holiday table beside the exchange's own). An iFinD-served calendar would avoid that.

User-visible today: formatBacktestError names both holidays as the likely cause, so the message is accurate — the run is still refused.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions