mirror of
https://github.com/shawnkim1997/All-in-one-Financial-Analysis.git
synced 2026-08-26 00:38:04 +00:00
phase 6: ownership holders
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from server.core.data_gateway import Profile, Quote, Segment
|
||||
from server.core.data_gateway import HoldersData, Profile, Quote, Segment
|
||||
from server.core.providers.base import BaseProvider, ProviderError, ProviderNotConfigured, ProviderNotImplemented
|
||||
from server.services import fmp_client
|
||||
|
||||
@@ -95,3 +95,26 @@ class FMPProvider(BaseProvider):
|
||||
"periods": periods,
|
||||
"line_items": line_items,
|
||||
}
|
||||
|
||||
async def holders(self, symbol: str) -> HoldersData:
|
||||
normalized = symbol.strip().upper()
|
||||
inst: object = []
|
||||
insider: object = []
|
||||
try:
|
||||
inst = await self._get_json(f"/institutional-holder/{normalized}", {})
|
||||
except ProviderError:
|
||||
inst = []
|
||||
try:
|
||||
insider = await self._get_json("/insider-trading", {"symbol": normalized, "limit": 25})
|
||||
except ProviderError:
|
||||
insider = []
|
||||
institutions = inst if isinstance(inst, list) else []
|
||||
insiders = insider if isinstance(insider, list) else []
|
||||
if not institutions and not insiders:
|
||||
raise ProviderError("missing holders rows")
|
||||
return HoldersData(
|
||||
symbol=normalized,
|
||||
institutions=institutions[:25],
|
||||
insiders=insiders[:25],
|
||||
source=self.name,
|
||||
)
|
||||
|
||||
@@ -5,7 +5,7 @@ from __future__ import annotations
|
||||
from datetime import date
|
||||
from typing import Any
|
||||
|
||||
from server.core.data_gateway import Fundamentals, OHLCV, OHLCVBar, Profile, Quote
|
||||
from server.core.data_gateway import Fundamentals, HoldersData, OHLCV, OHLCVBar, Profile, Quote
|
||||
from server.core.providers.base import BaseProvider, ProviderError
|
||||
from server.utils.peer_universe import peer_symbols_for_profile
|
||||
|
||||
@@ -149,6 +149,24 @@ class YFinanceProvider(BaseProvider):
|
||||
|
||||
return await self._to_thread(fetch)
|
||||
|
||||
async def holders(self, symbol: str) -> HoldersData:
|
||||
def fetch() -> HoldersData:
|
||||
import pandas as pd
|
||||
|
||||
normalized = symbol.strip().upper()
|
||||
ticker = self._ticker(normalized)
|
||||
institutions: list[dict[str, Any]] = []
|
||||
insiders: list[dict[str, Any]] = []
|
||||
inst_df = getattr(ticker, "institutional_holders", None)
|
||||
if isinstance(inst_df, pd.DataFrame) and not inst_df.empty:
|
||||
institutions = inst_df.where(inst_df.notna(), None).to_dict(orient="records")
|
||||
insider_df = getattr(ticker, "insider_roster_holders", None)
|
||||
if isinstance(insider_df, pd.DataFrame) and not insider_df.empty:
|
||||
insiders = insider_df.where(insider_df.notna(), None).to_dict(orient="records")
|
||||
return HoldersData(symbol=normalized, institutions=institutions[:25], insiders=insiders[:25], source=self.name)
|
||||
|
||||
return await self._to_thread(fetch)
|
||||
|
||||
async def history(self, symbol: str, range: str = "1y") -> OHLCV:
|
||||
def fetch() -> OHLCV:
|
||||
hist = self._ticker(symbol).history(period=range)
|
||||
|
||||
Reference in New Issue
Block a user