Oh My Data (OMD)
ohmydata is a provisional, offline-first market-data SDK. Tushare endpoint
adapters accept an already initialized official-compatible client; credentials
are never loaded by this library.
Supported Python and installation
Python 3.11 and 3.12 are supported (>=3.11,<3.13). From a source checkout:
uv sync
uv run python -c "import ohmydata; print(ohmydata.__version__)"
The core has no runtime dependencies. Install ohmydata[tushare] for the
Pandas-backed adapter. Provider tests use fake clients and never call a network.
Phase 2 Tushare adapter (offline and injected)
Pass an already initialized official-client-compatible object. The adapter does not create clients or read credentials; this fake-client example is safe to run offline:
import pandas as pd
from ohmydata.providers.tushare import EmptyPolicy, FundDailyRequest, TushareClient
class FakeClient:
def fund_daily(self, **kwargs):
return pd.DataFrame(
{
"ts_code": ["FAKE.ETF"],
"trade_date": ["20240102"],
"open": [1.0],
"high": [1.1],
"low": [0.9],
"close": [1.05],
"pre_close": [1.0],
"change": [0.05],
"pct_chg": [5.0],
"vol": [100],
"amount": [250.0],
}
)
request = FundDailyRequest(
empty_policy=EmptyPolicy.ERROR, ts_code="FAKE.ETF", start_date="20240101", end_date="20240102"
)
result = TushareClient(FakeClient()).fetch_fund_daily(request)
Values and nulls retain Tushare's native semantics: fund daily OHLC and
change/pct_chg are provider values, vol is in hands, and amount is in
thousand yuan. Empty responses must be selected explicitly with
EmptyPolicy.ALLOW or EmptyPolicy.ERROR.
fund_share.fd_share remains provider-native in ten-thousand shares (万份);
fund_adj and fund_nav values are likewise preserved without adjustment or
imputation.
Adjusted ETF bars recipe
fetch_adjusted_etf_bars composes fund_daily with provider-native
fund_adj factors. Choose AdjustmentCoveragePolicy.STRICT (the default) or
PRESERVE_MISSING_FACTOR; raw OHLC and adj_factor remain available beside
the explicitly derived adjusted OHLC columns. The recipe is offline-testable
when supplied an injected TushareClient and does not claim point-in-time
availability.
Tushare adjustment responses may contain extra dates for the requested symbol;
the recipe ignores those factor-only dates while strict coverage still requires
a finite factor for every returned daily bar. Rows for foreign symbols fail.
from ohmydata.providers.tushare import (
AdjustmentCoveragePolicy,
AdjustedEtfBarsRequest,
EmptyPolicy,
)
request = AdjustedEtfBarsRequest(
"FAKE.ETF",
EmptyPolicy.ERROR,
AdjustmentCoveragePolicy.STRICT,
start_date="20240101",
end_date="20240131",
)
Offline weighted dividend yield recipes
build_portfolio_dividend_yield and build_index_dividend_yield calculate a
provider-semantic weighted yield from already-downloaded Pandas frames. Portfolio
mkv is yuan; index weight and daily_basic.dv_ttm are provider percentages.
The returned dividend_yield is a decimal ratio (sum((w_i / W) * dv_ttm_i) / 100),
where W is the provider-native total weight.
Choose DividendYieldCoveragePolicy.REQUIRE_COMPLETE to reject missing finite
yield coverage, PRESERVE_INCOMPLETE to return None, or the explicitly named
NORMALIZE_SUPPORTED policy to divide only by finite supported weight while
still reporting the original finite_weight_coverage. Callers own any minimum
coverage threshold and must not present a normalized partial estimate as full
coverage. Zero supported coverage remains unknown. Inputs are not modified, and
dates are identity checks only: the recipe does not infer point-in-time
availability or report selection.
from ohmydata.providers.tushare import (
DividendYieldCoveragePolicy,
build_index_dividend_yield,
)
result = build_index_dividend_yield(
index_weights_df,
daily_basic_df,
DividendYieldCoveragePolicy.REQUIRE_COMPLETE,
)
print(result.dividend_yield)
Local checks
uv lock
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv build
git diff --check
Behavioral evidence for the initial consumers is in
docs/behavioral-inventory.md. The adjusted
ETF characterization is test-only and uses synthetic JSON fixtures.
Phase 1 core is offline and explicit:
from datetime import UTC, datetime
from pathlib import Path
from ohmydata.core import RequestSpec, RetryPolicy, RateLimitPolicy, RateLimiter, execute_with_retry
from ohmydata.core import SnapshotMode, SnapshotStore
try:
RequestSpec("demo", "bars", {"api_token": "never-serialize"})
except ValueError:
pass
limiter = RateLimiter(RateLimitPolicy(0.1))
limiter.acquire()
result = execute_with_retry(lambda: "ok", RetryPolicy(max_attempts=1))
store = SnapshotStore(Path("snapshots"))
store.write(
RequestSpec("demo", "bars", {}), b"[]", datetime.now(UTC), "json-v1", SnapshotMode.APPEND
)
store.write(
RequestSpec("demo", "bars", {}), b"[]", datetime.now(UTC), "json-v1", SnapshotMode.FROZEN
)
RetryPolicy(max_attempts=3) counts the first call. APPEND preserves distinct
observations; FROZEN permits one response identity. Limiter state is per instance.
Phase 1 core (offline)
ohmydata.core provides canonical request identities, classified retry with
total-attempt semantics, explicit instance-scoped rate limiters, dataframe-free
provenance, and immutable APPEND/FROZEN snapshots. Request parameters reject
secret-bearing keys before serialization. Snapshot callers provide exact bytes;
the core never contacts providers or loads credentials.
Phase 2b Tushare endpoints
The Tushare adapter exposes typed requests for fund dividends, fund portfolios,
daily basics, and index weights through injected clients. Requests always send
an explicit ordered field list and preserve provider-native values and missing
data. fund_portfolio requires a bounded report selector (ann_date, exact
period, or a same-year start_date/end_date range); unbounded holdings are
rejected. Native units remain unchanged: dividend cash is yuan per share,
portfolio market value is yuan and amount is shares, daily-basic share and
market-value fields use Tushare's ten-thousand units, and index weights remain
provider percentages.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ohmydata-0.0.4.tar.gz.
File metadata
- Download URL: ohmydata-0.0.4.tar.gz
- Upload date:
- Size: 43.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9486457e1baeccad1c3ec48eedd5763f89a3aade524044aa71c5cdebfecdf850
|
|
| MD5 |
6293a7ab8a753cb61b72cb0eb808eade
|
|
| BLAKE2b-256 |
de7bdc929b94b0096f11f1b80bc919bc91f2f02d0cd786d37ea3c1b891fabecb
|
Provenance
The following attestation bundles were made for ohmydata-0.0.4.tar.gz:
Publisher:
publish.yml on wukong7788/omd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ohmydata-0.0.4.tar.gz -
Subject digest:
9486457e1baeccad1c3ec48eedd5763f89a3aade524044aa71c5cdebfecdf850 - Sigstore transparency entry: 2310467993
- Sigstore integration time:
-
Permalink:
wukong7788/omd@4346d0c9affdeb43601d7adbb3b9f127fa018534 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/wukong7788
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4346d0c9affdeb43601d7adbb3b9f127fa018534 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file ohmydata-0.0.4-py3-none-any.whl.
File metadata
- Download URL: ohmydata-0.0.4-py3-none-any.whl
- Upload date:
- Size: 24.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
738334ec690b6b7eaee3bde3d7583332a3d5bb78e2594533e404aba37c5b2430
|
|
| MD5 |
a7e097fbaab4d7a79c3d342ced3d3368
|
|
| BLAKE2b-256 |
9232d1d438e4748ed503119fa502b022eab73994ab8879504f7f808039d437cc
|
Provenance
The following attestation bundles were made for ohmydata-0.0.4-py3-none-any.whl:
Publisher:
publish.yml on wukong7788/omd
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ohmydata-0.0.4-py3-none-any.whl -
Subject digest:
738334ec690b6b7eaee3bde3d7583332a3d5bb78e2594533e404aba37c5b2430 - Sigstore transparency entry: 2310468026
- Sigstore integration time:
-
Permalink:
wukong7788/omd@4346d0c9affdeb43601d7adbb3b9f127fa018534 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/wukong7788
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@4346d0c9affdeb43601d7adbb3b9f127fa018534 -
Trigger Event:
workflow_dispatch
-
Statement type: