mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-10-29 13:32:08 +00:00
* refactor openbb-sec for v5 * linting * ty * normalize compare_company_facts * add workflows * python 3.10 fix * add more thorough url validation and tests * ty check * ty for python 3.10 * reconfigure with apps * temp pyproject overrride * pyproject * pyproject * pyproject * codespell * pyproject * fix uk schema file links in schema_files * test coverage * test_cli * port #7547 into this pr * no hard coded prefix * improve filing rendering capabilities * fix xml text detection * make codeql happy * missed a file in the commit * test coverage * codespell * fix flakey test * some updates * management_ownership --> management_profiles * proxy statement markdown * ruff * fix test coverage * more tests * test coverage * fix lint errors * Add SEC adviser search, profile, and universe routes (#7559) * Add SEC institutional data fetchers * Add SEC filing index and Form D routes * Add SEC investment adviser people data * Expose SEC adviser and institutional routes * fix(sec): address adviser review feedback * refactor(sec): narrow adviser support to IAPD search * feat(sec): add adviser firm and individual searches * feat(sec): add adviser profile drill-down * fix: repair pre-commit configuration * feat(sec): add adviser universe route * feat(sec): expose complete Form ADV data --------- Co-authored-by: Danglewood <85772166+deeleeramone@users.noreply.github.com> * fix test coverage --------- Co-authored-by: deeleeramone <> Co-authored-by: Theodore Aptekarev <aptekarev@gmail.com>
68 lines
2.7 KiB
Python
68 lines
2.7 KiB
Python
"""SEC N-MFP (money market fund) filing parser."""
|
|
|
|
|
|
def _to_float(value) -> float | None:
|
|
"""Coerce a value to float, returning None when not parseable."""
|
|
try:
|
|
return float(value)
|
|
except (TypeError, ValueError):
|
|
return None
|
|
|
|
|
|
def parse_nmfp(response: dict) -> tuple[list[dict], dict]:
|
|
"""Parse an N-MFP money market fund filing into holdings and series metrics."""
|
|
form = response.get("edgarSubmission", {}).get("formData", {}) or {}
|
|
general = form.get("generalInfo", {}) or {}
|
|
series = form.get("seriesLevelInfo", {}) or {}
|
|
|
|
schedule = form.get("scheduleOfPortfolioSecuritiesInfo")
|
|
items = schedule if isinstance(schedule, list) else [schedule] if schedule else []
|
|
|
|
holdings: list[dict] = []
|
|
for item in items:
|
|
if not isinstance(item, dict):
|
|
continue
|
|
weight = _to_float(item.get("percentageOfMoneyMarketFundNetAssets"))
|
|
security_yield = _to_float(item.get("yieldOfTheSecurityAsOfReportingDate"))
|
|
holdings.append(
|
|
{
|
|
"name": item.get("nameOfIssuer"),
|
|
"title": item.get("titleOfIssuer"),
|
|
"cusip": item.get("CUSIPMember"),
|
|
"isin": item.get("ISINId"),
|
|
"lei": item.get("LEIID"),
|
|
"asset_category": item.get("investmentCategory"),
|
|
"maturity_date": item.get("finalLegalInvestmentMaturityDate"),
|
|
"value": _to_float(item.get("includingValueOfAnySponsorSupport")),
|
|
"weight": weight * 100 if weight is not None else None,
|
|
"annualized_return": (
|
|
security_yield * 100 if security_yield is not None else None
|
|
),
|
|
"currency": "USD",
|
|
}
|
|
)
|
|
holdings.sort(
|
|
key=lambda d: (d["weight"] is not None, d["weight"] or 0), reverse=True
|
|
)
|
|
|
|
yields = series.get("sevenDayGrossYield") or []
|
|
if isinstance(yields, (dict, str)):
|
|
yields = [yields]
|
|
latest = yields[-1] if yields else None
|
|
seven_day_yield = _to_float(
|
|
latest.get("sevenDayGrossYieldValue") if isinstance(latest, dict) else latest
|
|
)
|
|
|
|
metadata = {
|
|
"fund_name": general.get("nameOfSeries"),
|
|
"series_id": general.get("seriesId"),
|
|
"period_ending": general.get("reportDate"),
|
|
"net_assets": _to_float(series.get("netAssetOfSeries")),
|
|
"total_assets": _to_float(series.get("totalValuePortfolioSecurities")),
|
|
"cash_and_equivalents": _to_float(series.get("cash")),
|
|
"seven_day_gross_yield": seven_day_yield,
|
|
"weighted_average_maturity": _to_float(series.get("averagePortfolioMaturity")),
|
|
"weighted_average_life": _to_float(series.get("averageLifeMaturity")),
|
|
}
|
|
return holdings, metadata
|