When the Data Fails: Fallback, Freshness, and Capability
For zhulinsen/daily_stock_analysis, the hard question is not whether a provider can return a number. It is what that number means after the preferred route fails, the market supports only part of the requested analysis, or the value is older than the decision requires. Understanding the project’s fallback and capability design gives the reader a practical way to judge continuity without confusing it with freshness or completeness.
The project handles this problem through a DataFetcherManager: a common interface over several providers, with route-specific ordering, market filters, source-health tracking, and quality metadata. That design lets a watchlist continue when an endpoint is rate-limited or temporarily broken. It also creates a responsibility for the system—and for the person reading the dashboard—to preserve the fact that a fallback occurred.
Different datasets need different routes
A market-data system becomes misleading when it treats “data” as one homogeneous resource. A daily bar, a realtime quote, a registered index, and a market-wide breadth snapshot have different freshness requirements, symbols, providers, and failure modes. DSA therefore does not use one universal chain for every request.
For ordinary daily data, the manager maintains an ordered set of candidate fetchers and filters that set by market capability before trying it. A provider that cannot serve a given market should be skipped rather than called and then misclassified as a transient failure. For an ordinary A-share daily request, the available chain can include several native and general-purpose sources, and configuration can change the priority of eligible sources. For a registered mainland index, the project uses a separate fixed route—Tencent, then AkShare, TickFlow, and YFinance—rather than inheriting the ordinary stock priority settings. This is not a cosmetic distinction. An index has a different identity and provider symbol, so using the stock route could produce the wrong request or treat an index failure as a stock failure.
Realtime quotes use another route. Their job is not simply to fill a daily history table; they provide the current price and fields such as volume ratio, turnover, and sometimes valuation information. The realtime priority is controlled separately, and a provider that can contribute a field is not necessarily allowed to act as an independent quote source. In the US route, for example, Longbridge and YFinance form the main realtime path while some other services can supplement fields or participate in daily data without being presented as a standalone quote fallback when the main quote path is unavailable.
Market review is different again. It aggregates indexes, breadth, and other market-level signals. The project documents a route in which TickFlow can enhance the A-share market review when configured, with existing free sources available as fallbacks. That path is not the same as fetching one registered index, even if both eventually display an index value. The first asks for a market-wide summary; the second asks for a target-specific daily series.
The separation prevents an attractive but dangerous shortcut: “Provider X supports market Y, therefore Provider X can supply every dataset for market Y.” DSA’s read-only capability view reflects this more precise model. It reports provider and dataset coverage, source priority, configuration state, and warnings without triggering live market requests or exposing credentials. A provider can be listed for one market and dataset while being absent from another. Aggregated market labels are not permission to infer a full cross-product of all capabilities.
The same principle appears in the project’s treatment of market identity. Registered indexes are recognized as indexes only in explicit forms, while a bare code can remain a stock input. Some index-specific modules—such as chip distribution and fundamentals—are skipped because they are not meaningful for that target. This is a boundary owned by the analysis pipeline before provider calls, not a note added after an inappropriate request has already been made.
What the manager owns
The manager owns the common retrieval contract and the decision to move through an eligible route. It does not make every provider equivalent. Each fetcher adapts its native response into a shared shape, while the manager records which source succeeded and which route was attempted. The result can then be consumed by technical analysis and the dashboard without every downstream component knowing the quirks of every API.
For daily sources, health tracking adds another state layer. After three consecutive failures for a daily source and market combination, the project’s circuit breaker puts that route into a short cooldown of about five minutes. Future requests skip it temporarily, and a later recovery probe can test whether it is usable again. This protects a batch run from repeatedly waiting on the same broken endpoint. It is a latency and availability mechanism, not a correctness test: a source can answer successfully after the cooldown and still return delayed or incomplete data.
The distinction between route availability and data validity is important. A provider may be configured but not currently usable. It may be reachable but return an empty result. It may return a structurally valid table with missing fields. The manager’s job is to move the request through the configured route and preserve enough information for later layers to state what happened. It is not to turn every response into a guarantee of financial meaning.
The route can be summarized as a state transition rather than as a provider list:
The state diagram captures a useful asymmetry. The system may reach Selected through the preferred route or through a later eligible source, but those paths should not be indistinguishable. If it reaches Cached, the computation may continue with a last-good value, yet the value carries a freshness limitation. If it reaches Failed, the right output may be a stable empty state or a fetch-failed marker, not a fabricated substitute.
A fallback result carries a changed claim
A fallback is best understood as a changed statement about the evidence. “The system has a value” is weaker than “the preferred provider supplied a fresh, complete value.” DSA’s unified realtime quote records both the successful source and, when applicable, the first failed source that caused the route to fall through. It can also carry the system acquisition time, a real provider timestamp when one exists, a stale flag, elapsed staleness, market, currency, data-quality state, and missing fields.
Those fields make three situations distinguishable.
| Input state | What it means | What it does not mean |
|---|---|---|
| Available | The field or block exists and its source and timing are interpretable. | It is not a promise that the data predicts the future. |
| Fallback | A later route supplied the usable result after an earlier route was unavailable or failed. | It is not equivalent to the preferred source in freshness or completeness. |
| Stale | A value exists, but its timing is too old for the expected freshness boundary. | It is not the same as a current observation. |
| Missing | The current path needs the field but did not obtain it. | It is not evidence in favor of either direction. |
| Not supported | This market or path does not promise the capability. | It is not proof that the underlying company lacks that attribute. |
| Fetch failed | The path attempted the operation and it failed. | It does not necessarily mean the whole analysis failed. |
The context layer preserves these distinctions instead of reducing them to a Boolean success flag. For quotes, an explicit stale marker takes precedence over fallback, and fallback takes precedence over ordinary availability. That ordering reflects decision risk: a stale value may be more misleading than a current value obtained through a lower-priority route. A fallback marker without a stale marker does not prove that the data is unusable, but it tells the reader to lower the strength of an interpretation that depends on exact freshness or provider-specific completeness.
A circuit breaker adds a different piece of information. It says that the system has seen enough repeated failures to stop spending time on a route for a while. It does not say that the next provider is more accurate, nor that the failed provider is permanently unavailable. A short cooldown reduces repeated latency and pressure on a failing service; it cannot validate the replacement data. The project’s documentation is appropriately cautious about this: free sources can be rate-limited, change upstream contracts, or vary with network conditions, while token-based sources may improve stability without becoming infallible.
Capability boundaries become especially important across markets. The A-share path has the broadest native coverage for features such as capital flow, board relationships, and other mainland-specific information. Hong Kong and US analysis uses a combination of market-appropriate sources and fallback paths. Japanese and Korean suffix-form stocks currently rely on YFinance for daily and basic realtime data and use lighter offshore fundamentals; A-share-only capital-flow, Dragon Tiger, and board capabilities are marked unsupported. Taiwan symbols have a YFinance core path and can add three-institution flow data, but the project does not claim complete Taiwan market breadth, a full stock index/watchlist surface, or complete portfolio valuation.
These differences affect the claims a dashboard can make. A report for a Japanese stock with no capital-flow block has not necessarily discovered a negative capital-flow signal; that block is outside the declared capability boundary. A YFinance quote may be delayed, so “current price” should not be read as a guarantee of a live exchange tick. A market review without breadth or sector rankings is thinner than an A-share review with those inputs. The correct response is not to fill the gap with a generic conclusion, but to make the gap visible and restrict the relevant part of the interpretation.
This is also why registered indexes are handled separately from ordinary stocks. Their fixed route, canonical identity, and skipped stock-only modules reduce the risk that a code collision produces a plausible-looking but semantically wrong report. A bare six-digit code may intentionally remain in the stock path. The reader should therefore care not only about the displayed label, but also about whether the request was classified as the intended asset type.
The quality labels are most useful when they stay attached to the block they describe. Missing news should limit claims about sentiment and catalysts; it should not automatically turn a technical signal bearish. Unsupported fundamentals in a market should not be read as weak fundamentals. A stale quote should make an immediate price-level recommendation less confident; it should not be silently converted into a sell signal. The quality system changes the strength and scope of the claim rather than supplying a hidden directional answer.
The project’s design still leaves an unavoidable operational limit. The repository defines source routes and records their conditions, but it does not provide an independent benchmark showing that one provider is more accurate than another or that a fallback report produces equal investment outcomes. Nor does a configured provider guarantee entitlement, connectivity, or complete fields at the moment of a run. The system can improve continuity and make degradation legible; it cannot eliminate uncertainty at the source.
That gives the reader a simple interpretation rule for a completed dashboard: ask whether the route was preferred or fallback, whether the data is fresh enough for the decision’s time horizon, and whether the requested capability exists for this market. Only then should the headline action be considered. A non-empty report is evidence that the workflow completed far enough to produce an output. It is not evidence that every input was equally strong.
The next question follows directly: once these different source conditions reach the dashboard, how can a reader distinguish a completed operational run from a conclusion whose evidentiary basis is still limited?