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
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,19 @@ All notable changes to kalshi-sdk will be documented in this file.

### Changed

- **Count/size/volume response fields retyped from `DollarDecimal` to
`FixedPointCount` (#90).** Fields with `_fp` wire aliases were annotated
as `DollarDecimal` — the type that signals "dollar amount." Runtime
behavior is unchanged (both validators are byte-identical and parse the
same wire strings into `Decimal`), but the annotation now communicates
the correct semantics and prevents silent corruption if either parser
ever diverges. Affected: `Market.{yes_bid_size, yes_ask_size, no_bid_size,
no_ask_size, volume, volume_24h, open_interest}`, `Candlestick.{volume,
open_interest}`, `OrderbookLevel.quantity`, `Fill.count`, `Trade.count`,
`MarketPosition.position`, `EventPosition.total_cost_shares`,
`Settlement.{yes_count, no_count}`, `Series.volume`. Both types resolve
to `Decimal` at the type level, so user code that handles these fields
as `Decimal` is unaffected.
- **`*_all()` methods are now unbounded by default.** Previously, internal
`_list_all` had an invisible 1000-page safety cap that silently truncated
callers iterating beyond ~100k items. The cap is gone; the cursor-repeat
Expand Down
4 changes: 2 additions & 2 deletions kalshi/models/historical.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from pydantic import AliasChoices, BaseModel, Field

from kalshi.types import DollarDecimal
from kalshi.types import DollarDecimal, FixedPointCount

# Single-value enum per spec (MveHistoricalFilterQuery). mypy rejects plain
# `str` here even if it holds "exclude" at runtime — pass the literal directly.
Expand All @@ -30,7 +30,7 @@ class Trade(BaseModel):

trade_id: str
ticker: str | None = None
count: DollarDecimal | None = Field(
count: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("count_fp", "count"),
)
Expand Down
26 changes: 13 additions & 13 deletions kalshi/models/markets.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from pydantic import AliasChoices, BaseModel, Field

from kalshi.types import DollarDecimal, NullableList
from kalshi.types import DollarDecimal, FixedPointCount, NullableList

MarketStatusLiteral = Literal["unopened", "open", "paused", "closed", "settled"]
"""Market status filter for GET /markets. Spec: MarketStatusQuery enum."""
Expand Down Expand Up @@ -81,31 +81,31 @@ class Market(BaseModel):
)

# Size/volume fields (FixedPointCount)
yes_bid_size: DollarDecimal | None = Field(
yes_bid_size: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("yes_bid_size_fp", "yes_bid_size"),
)
yes_ask_size: DollarDecimal | None = Field(
yes_ask_size: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("yes_ask_size_fp", "yes_ask_size"),
)
no_bid_size: DollarDecimal | None = Field(
no_bid_size: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("no_bid_size_fp", "no_bid_size"),
)
no_ask_size: DollarDecimal | None = Field(
no_ask_size: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("no_ask_size_fp", "no_ask_size"),
)
volume: DollarDecimal | None = Field(
volume: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("volume_fp", "volume"),
)
volume_24h: DollarDecimal | None = Field(
volume_24h: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("volume_24h_fp", "volume_24h"),
)
open_interest: DollarDecimal | None = Field(
open_interest: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("open_interest_fp", "open_interest"),
)
Expand Down Expand Up @@ -141,12 +141,12 @@ class Market(BaseModel):
class OrderbookLevel(BaseModel):
"""A single price level in the orderbook.

Quantity is DollarDecimal to support fractional contracts
(FixedPointCount strings like ``"100.50"`` from the API).
Quantity is FixedPointCount — fractional contract counts are sent as
FixedPointCount strings like ``"100.50"`` from the API.
"""

price: DollarDecimal
quantity: DollarDecimal
quantity: FixedPointCount


class Orderbook(BaseModel):
Expand Down Expand Up @@ -217,11 +217,11 @@ class Candlestick(BaseModel):
yes_bid: BidAskDistribution | None = None
yes_ask: BidAskDistribution | None = None
price: PriceDistribution | None = None
volume: DollarDecimal | None = Field(
volume: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("volume_fp", "volume"),
)
open_interest: DollarDecimal | None = Field(
open_interest: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("open_interest_fp", "open_interest"),
)
Expand Down
2 changes: 1 addition & 1 deletion kalshi/models/orders.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ class Fill(BaseModel):
side: str | None = None
action: str | None = None
is_taker: bool | None = None
count: DollarDecimal | None = Field(
count: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("count_fp", "count"),
)
Expand Down
10 changes: 5 additions & 5 deletions kalshi/models/portfolio.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from pydantic import AliasChoices, BaseModel, Field

from kalshi.types import DollarDecimal, NullableList
from kalshi.types import DollarDecimal, FixedPointCount, NullableList

SettlementStatusLiteral = Literal["all", "unsettled", "settled"]
"""Position settlement status filter for GET /fcm/positions. Spec: settlement_status query enum."""
Expand Down Expand Up @@ -43,7 +43,7 @@ class MarketPosition(BaseModel):
default=None,
validation_alias=AliasChoices("total_traded_dollars", "total_traded"),
)
position: DollarDecimal | None = Field(
position: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("position_fp", "position"),
)
Expand Down Expand Up @@ -73,7 +73,7 @@ class EventPosition(BaseModel):
default=None,
validation_alias=AliasChoices("total_cost_dollars", "total_cost"),
)
total_cost_shares: DollarDecimal | None = Field(
total_cost_shares: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("total_cost_shares_fp", "total_cost_shares"),
)
Expand Down Expand Up @@ -113,15 +113,15 @@ class Settlement(BaseModel):
ticker: str
event_ticker: str | None = None
market_result: str | None = None
yes_count: DollarDecimal | None = Field(
yes_count: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("yes_count_fp", "yes_count"),
)
yes_total_cost: DollarDecimal | None = Field(
default=None,
validation_alias=AliasChoices("yes_total_cost_dollars", "yes_total_cost"),
)
no_count: DollarDecimal | None = Field(
no_count: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("no_count_fp", "no_count"),
)
Expand Down
4 changes: 2 additions & 2 deletions kalshi/models/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from pydantic import AliasChoices, BaseModel, Field

from kalshi.models.markets import Candlestick
from kalshi.types import DollarDecimal, NullableList
from kalshi.types import FixedPointCount, NullableList

# Fee type constants (use str fields, not StrEnum, for forward-compat)
FEE_TYPE_QUADRATIC = "quadratic"
Expand All @@ -31,7 +31,7 @@ class Series(BaseModel):
fee_type: str = ""
fee_multiplier: float = 0.0
additional_prohibitions: NullableList[str] = []
volume: DollarDecimal | None = Field(
volume: FixedPointCount | None = Field(
default=None,
validation_alias=AliasChoices("volume_fp", "volume"),
)
Expand Down
Loading