From ec20fef960ee3b73e9f4351e72a12203c7e95200 Mon Sep 17 00:00:00 2001 From: kel Date: Thu, 19 Oct 2023 14:02:19 +0800 Subject: [PATCH] added method for insider roster --- yfinance/base.py | 10 ++++++++++ yfinance/scrapers/insider.py | 35 +++++++++++++++++++++++++++++++++++ yfinance/ticker.py | 4 ++++ 3 files changed, 49 insertions(+) create mode 100644 yfinance/scrapers/insider.py diff --git a/yfinance/base.py b/yfinance/base.py index 52e0e8ecf..c090bdb51 100644 --- a/yfinance/base.py +++ b/yfinance/base.py @@ -40,6 +40,7 @@ from .scrapers.analysis import Analysis from .scrapers.fundamentals import Fundamentals from .scrapers.holders import Holders +from .scrapers.insider import Insider from .scrapers.quote import Quote, FastInfo from .const import _BASE_URL_, _ROOT_URL_ @@ -73,6 +74,7 @@ def __init__(self, ticker, session=None, proxy=None): self._analysis = Analysis(self._data) self._holders = Holders(self._data) + self.insider = Insider(self.data) self._quote = Quote(self._data) self._fundamentals = Fundamentals(self._data) @@ -1733,6 +1735,14 @@ def get_mutualfund_holders(self, proxy=None, as_dict=False): if as_dict: return data.to_dict() return data + + def get_insider_roster(self, proxy=None, as_dict=False): + self._insider.proxy = proxy or self.proxy + data = self._insider.roster + if data is not None: + if as_dict: + return data.to_dict() + return data def get_info(self, proxy=None) -> dict: self._quote.proxy = proxy or self.proxy diff --git a/yfinance/scrapers/insider.py b/yfinance/scrapers/insider.py new file mode 100644 index 000000000..a142d1ece --- /dev/null +++ b/yfinance/scrapers/insider.py @@ -0,0 +1,35 @@ +import pandas as pd + +from yfinance.data import TickerData + + +class Insider: + _SCRAPE_URL_ = 'https://finance.yahoo.com/quote' + + def __init__(self, data: TickerData, proxy=None): + self._data = data + self.proxy = proxy + + self._insider_roster = None + + @property + def roster(self) -> pd.DataFrame: + if self._insider_roster is None: + self._scrape(self.proxy) + return self._insider_roster + + def _scrape(self, proxy): + ticker_url = f"{self._SCRAPE_URL_}/{self._data.ticker}" + try: + resp = self._data.cache_get(ticker_url + '/insider-roster', proxy=proxy) + insider_roster = pd.read_html(resp.text) + except Exception: + insider_roster = [] + + if len(insider_roster) >= 1: + self._insider_roster = insider_roster[0] + + if self._insider_roster is not None: + if 'Date' in self._insider_roster: + self._insider_roster['Date'] = pd.to_datetime( + self._insider_roster['Date']) diff --git a/yfinance/ticker.py b/yfinance/ticker.py index af8dd750c..2404e3138 100644 --- a/yfinance/ticker.py +++ b/yfinance/ticker.py @@ -117,6 +117,10 @@ def institutional_holders(self) -> _pd.DataFrame: def mutualfund_holders(self) -> _pd.DataFrame: return self.get_mutualfund_holders() + @property + def insider_roster(self) -> _pd.DataFrame: + return self.get_insider_roster() + @property def dividends(self) -> _pd.Series: return self.get_dividends()