mirror of
https://github.com/TauricResearch/TradingAgents.git
synced 2026-09-19 11:15:24 +03:00
fix(dataflows): date insider rows by the trade, and say when it became public
- rows carry the transaction date; a Form 4 is filed up to two business days later - an indicator that could not be read is unavailable, not a blank value for the day
This commit is contained in:
@@ -267,8 +267,12 @@ def get_stockstats_indicator(
|
||||
except NoMarketDataError:
|
||||
raise # Unknown/delisted symbol — let the router emit the sentinel
|
||||
except Exception as e:
|
||||
logger.warning("Stockstats indicator %s failed on %s: %s", indicator, curr_date, e)
|
||||
return ""
|
||||
# An empty string renders as "2026-05-08: " in the indicator table, which
|
||||
# reads as no value that day rather than a read that failed. Raise so the
|
||||
# router can try the next vendor or report the series unavailable.
|
||||
raise NoMarketDataError(
|
||||
symbol, symbol, f"{indicator} could not be read for {curr_date}: {e}"
|
||||
) from e
|
||||
|
||||
return str(indicator_value)
|
||||
|
||||
@@ -457,6 +461,17 @@ def get_income_statement(
|
||||
return f"Error retrieving income statement for {ticker}: {str(e)}"
|
||||
|
||||
|
||||
# Rows are dated by the transaction, which is when the insider traded, not when
|
||||
# the market learned of it: a Form 4 is filed up to two business days later and
|
||||
# this vendor reports no filing date, so the most recent rows may not have been
|
||||
# public on the analysis date.
|
||||
_TRANSACTION_DATE_VINTAGE = (
|
||||
"# Rows are dated by transaction date. A trade becomes public when its Form 4 "
|
||||
"is filed, up to two business days later, so the newest rows may not have been "
|
||||
"known on this date.\n\n"
|
||||
)
|
||||
|
||||
|
||||
# This vendor dates a statement by the period it covers, not by the day it was
|
||||
# filed, and carries no filing date to do better. A company files weeks after its
|
||||
# period ends, so a run dated in that gap can be served figures that were not yet
|
||||
@@ -470,7 +485,7 @@ _PERIOD_END_VINTAGE = (
|
||||
|
||||
def get_insider_transactions(
|
||||
ticker: Annotated[str, "ticker symbol of the company"],
|
||||
curr_date: Annotated[str | None, "only filings on or before this date, yyyy-mm-dd"] = None,
|
||||
curr_date: Annotated[str | None, "only transactions on or before this date, yyyy-mm-dd"] = None,
|
||||
):
|
||||
"""Get insider transactions data from yfinance."""
|
||||
canonical = normalize_symbol(ticker)
|
||||
@@ -484,12 +499,12 @@ def get_insider_transactions(
|
||||
return f"No insider transactions reported for symbol '{canonical}'"
|
||||
|
||||
if curr_date:
|
||||
filed = data["Start Date"]
|
||||
kept = data[filed <= pd.Timestamp(curr_date)]
|
||||
traded = data["Start Date"]
|
||||
kept = data[traded <= pd.Timestamp(curr_date)]
|
||||
if kept.empty:
|
||||
return (
|
||||
f"<insider transactions unavailable for {canonical} as of {curr_date}: "
|
||||
f"Yahoo serves recent filings only (coverage starts {filed.min():%Y-%m-%d})>"
|
||||
f"Yahoo serves recent transactions only (coverage starts {traded.min():%Y-%m-%d})>"
|
||||
)
|
||||
data = kept
|
||||
|
||||
@@ -498,7 +513,8 @@ def get_insider_transactions(
|
||||
|
||||
# Add header information
|
||||
header = f"# Insider Transactions data for {canonical}\n"
|
||||
header += f"# Data retrieved on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n"
|
||||
header += f"# Data retrieved on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n"
|
||||
header += _TRANSACTION_DATE_VINTAGE
|
||||
|
||||
return header + csv_string
|
||||
|
||||
|
||||
Reference in New Issue
Block a user