Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions massive/rest/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,16 +208,18 @@ def _get_params(
elif isinstance(val, datetime):
val = int(val.timestamp() * self.time_mult(datetime_res))
if val is not None:
for ext in ["lt", "lte", "gt", "gte", "any_of"]:
for ext in ["lt", "lte", "gt", "gte", "any_of", "all_of"]:
if argname.endswith(f"_{ext}"):
# lop off ext, then rebuild argname with ext,
# using ., and not _ (removesuffix would work)
# but that is python 3.9+
argname = argname[: -len(f"_{ext}")] + f".{ext}"
# any_of accepts a comma-separated str (per the spec) or a
# list of values; only join the latter, since joining a str
# would split it into single characters
if argname.endswith("any_of") and not isinstance(val, str):
# any_of/all_of accept a comma-separated str (per the spec)
# or a list of values; only join the latter, since joining
# a str would split it into single characters
if argname.endswith(("any_of", "all_of")) and not isinstance(
val, str
):
val = ",".join(val)
params[argname] = val

Expand Down
1 change: 1 addition & 0 deletions massive/rest/benzinga.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ def list_benzinga_consensus_ratings(
date_lt: Optional[Union[str, date]] = None,
date_lte: Optional[Union[str, date]] = None,
limit: Optional[int] = None,
date_any_of: Optional[Union[str, List[str]]] = None,
params: Optional[Dict[str, Any]] = None,
raw: bool = False,
options: Optional[RequestOptionBuilder] = None,
Expand Down
3 changes: 3 additions & 0 deletions massive/rest/futures.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def list_futures_contracts(
last_trade_date_lte: Optional[str] = None,
limit: Optional[int] = None,
sort: Optional[str] = None,
provider_id: Optional[str] = None,
provider_product_id: Optional[str] = None,
params: Optional[Dict[str, Any]] = None,
raw: bool = False,
options: Optional[RequestOptionBuilder] = None,
Expand Down Expand Up @@ -146,6 +148,7 @@ def list_futures_products(
type_any_of: Optional[str] = None,
limit: Optional[int] = None,
sort: Optional[str] = None,
provider_id: Optional[str] = None,
params: Optional[Dict[str, Any]] = None,
raw: bool = False,
options: Optional[RequestOptionBuilder] = None,
Expand Down
2 changes: 2 additions & 0 deletions massive/rest/models/aggs.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ class PreviousCloseAgg:
timestamp: Optional[float] = None
volume: Optional[float] = None
vwap: Optional[float] = None
transactions: Optional[int] = None

@staticmethod
def from_dict(d):
Expand All @@ -119,4 +120,5 @@ def from_dict(d):
d.get("t", None),
d.get("v", None),
d.get("vw", None),
d.get("n", None),
)
27 changes: 27 additions & 0 deletions massive/rest/models/contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,30 @@ def from_dict(d):
ticker=d.get("ticker", None),
underlying_ticker=d.get("underlying_ticker", None),
)


@modelclass
class OptionsOpenInterest:
"Daily open interest for a single options contract."

ticker: Optional[str] = None
underlying_ticker: Optional[str] = None
root: Optional[str] = None
contract_type: Optional[str] = None
expiration_date: Optional[str] = None
strike_price: Optional[float] = None
date: Optional[str] = None
open_interest: Optional[int] = None

@staticmethod
def from_dict(d):
return OptionsOpenInterest(
ticker=d.get("ticker"),
underlying_ticker=d.get("underlying_ticker"),
root=d.get("root"),
contract_type=d.get("contract_type"),
expiration_date=d.get("expiration_date"),
strike_price=d.get("strike_price"),
date=d.get("date"),
open_interest=d.get("open_interest"),
)
2 changes: 2 additions & 0 deletions massive/rest/models/etf_global.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ class EtfGlobalConstituent:
asset_class: Optional[str] = None
composite_ticker: Optional[str] = None
constituent_name: Optional[str] = None
constituent_rank: Optional[int] = None
constituent_ticker: Optional[str] = None
country_of_exchange: Optional[str] = None
currency_traded: Optional[str] = None
Expand All @@ -105,6 +106,7 @@ def from_dict(d):
asset_class=d.get("asset_class"),
composite_ticker=d.get("composite_ticker"),
constituent_name=d.get("constituent_name"),
constituent_rank=d.get("constituent_rank"),
constituent_ticker=d.get("constituent_ticker"),
country_of_exchange=d.get("country_of_exchange"),
currency_traded=d.get("currency_traded"),
Expand Down
88 changes: 88 additions & 0 deletions massive/rest/models/financials.py
Original file line number Diff line number Diff line change
Expand Up @@ -1306,3 +1306,91 @@ def from_dict(d):
issuer_name=d.get("issuer_name"),
ticker=d.get("ticker"),
)


@modelclass
class InsiderActivity:
"Daily insider trading activity for an issuer, aggregated across all of its insiders' open-market purchases and sales."

issuer_cik: Optional[str] = None
issuer_name: Optional[str] = None
tickers: Optional[List[str]] = None
transaction_date: Optional[str] = None
last_filing_date: Optional[str] = None
purchase_count: Optional[int] = None
purchaser_count: Optional[int] = None
purchase_shares: Optional[float] = None
purchase_value: Optional[float] = None
sale_count: Optional[int] = None
seller_count: Optional[int] = None
sale_shares: Optional[float] = None
sale_value: Optional[float] = None
net_shares: Optional[float] = None
net_value: Optional[float] = None
planned_purchase_value: Optional[float] = None
planned_sale_value: Optional[float] = None

@staticmethod
def from_dict(d):
return InsiderActivity(
issuer_cik=d.get("issuer_cik"),
issuer_name=d.get("issuer_name"),
tickers=d.get("tickers"),
transaction_date=d.get("transaction_date"),
last_filing_date=d.get("last_filing_date"),
purchase_count=d.get("purchase_count"),
purchaser_count=d.get("purchaser_count"),
purchase_shares=d.get("purchase_shares"),
purchase_value=d.get("purchase_value"),
sale_count=d.get("sale_count"),
seller_count=d.get("seller_count"),
sale_shares=d.get("sale_shares"),
sale_value=d.get("sale_value"),
net_shares=d.get("net_shares"),
net_value=d.get("net_value"),
planned_purchase_value=d.get("planned_purchase_value"),
planned_sale_value=d.get("planned_sale_value"),
)


@modelclass
class InsiderHolding:
"An insider of an issuer (one reporting owner per issuer) with their current reported holdings."

issuer_cik: Optional[str] = None
issuer_name: Optional[str] = None
tickers: Optional[List[str]] = None
owner_cik: Optional[str] = None
owner_name: Optional[str] = None
officer_title: Optional[str] = None
roles: Optional[List[str]] = None
shares_owned: Optional[float] = None
shares_owned_direct: Optional[float] = None
shares_owned_indirect: Optional[float] = None
ownership_pct: Optional[float] = None
position_count: Optional[int] = None
filing_count: Optional[int] = None
first_filing_date: Optional[str] = None
last_filing_date: Optional[str] = None
oldest_position_date: Optional[str] = None

@staticmethod
def from_dict(d):
return InsiderHolding(
issuer_cik=d.get("issuer_cik"),
issuer_name=d.get("issuer_name"),
tickers=d.get("tickers"),
owner_cik=d.get("owner_cik"),
owner_name=d.get("owner_name"),
officer_title=d.get("officer_title"),
roles=d.get("roles"),
shares_owned=d.get("shares_owned"),
shares_owned_direct=d.get("shares_owned_direct"),
shares_owned_indirect=d.get("shares_owned_indirect"),
ownership_pct=d.get("ownership_pct"),
position_count=d.get("position_count"),
filing_count=d.get("filing_count"),
first_filing_date=d.get("first_filing_date"),
last_filing_date=d.get("last_filing_date"),
oldest_position_date=d.get("oldest_position_date"),
)
9 changes: 6 additions & 3 deletions massive/rest/models/quotes.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,12 +52,13 @@ def from_dict(d):
sequence_number=d.get("q", None),
sip_timestamp=d.get("t", None),
participant_timestamp=d.get("y", None),
ask_price=d.get("P", None),
# stocks send P/p; forex snapshot quotes send a/b
ask_price=d.get("P", d.get("a")),
ask_size=d.get("S", None),
ask_exchange=d.get("X", None),
conditions=d.get("c", None),
indicators=d.get("i", None),
bid_price=d.get("p", None),
bid_price=d.get("p", d.get("b")),
bid_size=d.get("s", None),
bid_exchange=d.get("x", None),
tape=d.get("z", None),
Expand Down Expand Up @@ -102,13 +103,15 @@ class RealTimeCurrencyConversion:
initial_amount: Optional[float] = None
last: Optional[ForexQuote] = None
to: Optional[str] = None
symbol: Optional[str] = None

@staticmethod
def from_dict(d):
return RealTimeCurrencyConversion(
converted=d.get("converted", None),
from_=d.get("from_", None),
from_=d.get("from", d.get("from_")),
initial_amount=d.get("initialAmount", None),
last=None if "last" not in d else ForexQuote.from_dict(d["last"]),
to=d.get("to", None),
symbol=d.get("symbol"),
)
2 changes: 2 additions & 0 deletions massive/rest/models/snapshot.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,8 @@ class LastQuoteOptionContractSnapshot:
last_updated: Optional[int] = None
midpoint: Optional[float] = None
timeframe: Optional[str] = None
ask_exchange: Optional[int] = None
bid_exchange: Optional[int] = None

@staticmethod
def from_dict(d):
Expand Down
2 changes: 2 additions & 0 deletions massive/rest/models/tickers.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class TickerDetails:
name: Optional[str] = None
phone_number: Optional[str] = None
primary_exchange: Optional[str] = None
round_lot: Optional[int] = None
share_class_figi: Optional[str] = None
share_class_shares_outstanding: Optional[int] = None
sic_code: Optional[str] = None
Expand Down Expand Up @@ -147,6 +148,7 @@ def from_dict(d):
name=d.get("name", None),
phone_number=d.get("phone_number", None),
primary_exchange=d.get("primary_exchange", None),
round_lot=d.get("round_lot", None),
share_class_figi=d.get("share_class_figi", None),
share_class_shares_outstanding=d.get(
"share_class_shares_outstanding", None
Expand Down
31 changes: 31 additions & 0 deletions massive/rest/models/trades.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,34 @@ class CryptoTrade:
@staticmethod
def from_dict(d):
return CryptoTrade(**d)


@modelclass
class OptionsUnusualTrade:
"An unusual trade for a US options contract."

ticker: Optional[str] = None
underlying_ticker: Optional[str] = None
root: Optional[str] = None
sip_timestamp: Optional[int] = None
sequence_number: Optional[int] = None
price: Optional[float] = None
size: Optional[int] = None
exchange: Optional[int] = None
conditions: Optional[List[int]] = None
flags: Optional[List[str]] = None

@staticmethod
def from_dict(d):
return OptionsUnusualTrade(
ticker=d.get("ticker"),
underlying_ticker=d.get("underlying_ticker"),
root=d.get("root"),
sip_timestamp=d.get("sip_timestamp"),
sequence_number=d.get("sequence_number"),
price=d.get("price"),
size=d.get("size"),
exchange=d.get("exchange"),
conditions=d.get("conditions"),
flags=d.get("flags"),
)
Loading
Loading