You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

58 lines
2.0 KiB
Python

"""Oracle insider transactions (Form 4) and activist ownership (13D/G) service."""
from __future__ import annotations
import datetime as dt
from typing import Any
from libs.oracle_client.client import OracleClient
from libs.oracle_client.models import (
Form4Transaction,
Form4AggregateResult,
ActivistEvent,
)
class InsiderService:
def __init__(self, client: OracleClient) -> None:
self._client = client
async def get_form4(
self,
ticker: str,
as_of: dt.date,
start: dt.date | None = None,
buy_only: bool = False,
csuite_only: bool = False,
) -> list[Form4Transaction]:
"""PIT-safe Form 4 transactions (filing_date <= as_of)."""
params: dict[str, Any] = {"as_of": str(as_of), "buy_only": buy_only, "csuite_only": csuite_only}
if start:
params["start"] = str(start)
data = await self._client.get(f"/api/v1/insider/form4/{ticker}", params=params)
return [Form4Transaction.model_validate(t) for t in data.get("transactions", [])]
async def get_form4_aggregate(
self,
ticker: str,
as_of: dt.date,
window_days: int = 30,
) -> Form4AggregateResult:
"""Aggregated insider buy metrics (P-code only, PIT-safe)."""
params: dict[str, Any] = {"as_of": str(as_of), "window_days": window_days}
data = await self._client.get(f"/api/v1/insider/form4/aggregate/{ticker}", params=params)
return Form4AggregateResult.model_validate(data)
async def get_activist_events(
self,
ticker: str,
as_of: dt.date,
start: dt.date | None = None,
) -> list[ActivistEvent]:
"""SC 13D/13G activist ownership events (filing_date <= as_of)."""
params: dict[str, Any] = {"as_of": str(as_of)}
if start:
params["start"] = str(start)
data = await self._client.get(f"/api/v1/ownership/13dg/{ticker}", params=params)
return [ActivistEvent.model_validate(e) for e in data.get("events", [])]