Skip to content

FCM

Futures Commission Merchant routes. FCM-member accounts only — non-FCM calls come back 401/403. Auth required throughout.

subtrader_id is required on positions. On orders it is required unless client_order_ids is supplied (the two filters are alternatives).

Quick reference

Method Endpoint
orders(*, subtrader_id=None, client_order_ids=None, ...) GET /fcm/orders
orders_all(*, subtrader_id=None, client_order_ids=None, ...) walks orders
fills(*, min_ts=None, max_ts=None, cursor=None) GET /fcm/fills
fills_all(*, min_ts=None, max_ts=None, max_pages=None) walks fills
positions(*, subtrader_id, ...) GET /fcm/positions
list_subtraders() GET /fcm/subtraders
create_subtrader(*, subtrader_suffix) POST /fcm/subtraders
blocked_categories(*, subtrader_id) GET /fcm/subtraders/blocked_categories
update_blocked_categories(*, subtrader_id, category, blocked) PUT /fcm/subtraders/blocked_categories
event_contract_daily_cap(*, subtrader_id=None) GET /fcm/subtraders/event_contract_daily_cap
update_event_contract_daily_cap(*, subtrader_id, limit) PUT /fcm/subtraders/event_contract_daily_cap
delete_event_contract_daily_cap(*, subtrader_id) DELETE /fcm/subtraders/event_contract_daily_cap

List orders

page = client.fcm.orders(
    subtrader_id="st_alpha",
    ticker="KXPRES-24-DJT",
    event_ticker="KXPRES-24",
    status="resting",              # OrderStatusLiteral
    min_ts=1_700_000_000,
    max_ts=1_800_000_000,
    limit=200,
)
for o in page:
    print(o.order_id, o.status, o.remaining_count)

for o in client.fcm.orders_all(subtrader_id="st_alpha", status="resting"):
    ...

Same Order model as Orders. Standard Page[Order] pagination on orders().

Fills

Fills across the member's subtraders. Query params are only min_ts, max_ts, and cursor — there is no limit or subtrader_id filter. fills() returns GetFcmFillsResponse (fills, cursor). fills_all() walks that cursor and yields each FcmFill. Prices are Decimal (yes_price accepts yes_price_dollars); count accepts count_fp.

resp = client.fcm.fills(min_ts=1_700_000_000, max_ts=1_800_000_000)
for fill in resp.fills:
    print(fill.fill_id, fill.ticker, fill.taker_outcome_side, fill.yes_price, fill.count)

for fill in client.fcm.fills_all(min_ts=1_700_000_000):
    print(fill.maker_subtrader_id, fill.taker_subtrader_id, fill.maker_fee_cost)

Positions

resp = client.fcm.positions(
    subtrader_id="st_alpha",
    event_ticker="KXPRES-24",
    count_filter="position",
    settlement_status="unsettled",     # SettlementStatusLiteral
    limit=200,
)
for mp in resp.market_positions:
    print(mp.ticker, mp.position)

positions() returns a PositionsResponse (same shape as portfolio.positions), not a Page. For cursor traversal use positions_all(), which auto-paginates /fcm/positions and yields each MarketPosition (it mirrors portfolio.positions_all() and takes the same filters — subtrader_id, ticker, event_ticker, count_filter, settlement_status, limit, max_pages):

for mp in client.fcm.positions_all(subtrader_id="st_alpha", settlement_status="unsettled"):
    print(mp.ticker, mp.position)
# async: `async for mp in client.fcm.positions_all(...)`

settlement_status is also accepted on portfolio.positions / positions_all (OpenAPI 3.32.0). Both endpoints default to unsettled when the kwarg is omitted.

Subtrader admin

List and create subtraders, block event categories, and set a daily event-contract notional cap. POST/PUT/DELETE are never retried.

owned = client.fcm.list_subtraders()
created = client.fcm.create_subtrader(subtrader_suffix="desk1")
client.fcm.update_blocked_categories(
    subtrader_id=created.subtrader_id, category="Politics", blocked=True
)
client.fcm.update_event_contract_daily_cap(
    subtrader_id=created.subtrader_id, limit="10000.00"
)

create_subtrader composes the full id server-side as {account_id}_{suffix} (suffix is 1–16 ASCII alphanumeric characters).

Reference

kalshi.resources.fcm.FcmResource

FcmResource(transport: SyncTransport)

Bases: SyncResource

Sync FCM API — orders and positions filtered by subtrader_id.

fills

fills(
    *,
    min_ts: int | None = None,
    max_ts: int | None = None,
    cursor: str | None = None,
    extra_headers: dict[str, str] | None = None
) -> GetFcmFillsResponse

GET /fcm/fills — fills across the authenticated FCM's subtraders.

fills_all

fills_all(
    *,
    min_ts: int | None = None,
    max_ts: int | None = None,
    max_pages: int | None = None,
    extra_headers: dict[str, str] | None = None
) -> Iterator[FcmFill]

Auto-paginate GET /fcm/fills, yielding each :class:FcmFill.

positions_all

positions_all(
    *,
    subtrader_id: str,
    ticker: str | None = None,
    event_ticker: str | None = None,
    count_filter: str | None = None,
    settlement_status: (
        SettlementStatusLiteral | None
    ) = None,
    limit: int | None = None,
    max_pages: int | None = None,
    extra_headers: dict[str, str] | None = None
) -> Iterator[MarketPosition]

Auto-paginate /fcm/positions, yielding each MarketPosition.

Mirrors :meth:PortfolioResource.positions_all. event_positions from the response envelope are intentionally not yielded; see that docstring for the rationale.

list_subtraders

list_subtraders(
    *, extra_headers: dict[str, str] | None = None
) -> ListFCMSubtradersResponse

GET /fcm/subtraders — list subtraders owned by the authenticated FCM.

create_subtrader

create_subtrader(
    *,
    request: CreateFCMSubtraderRequest,
    extra_headers: dict[str, str] | None = None
) -> CreateFCMSubtraderResponse
create_subtrader(
    *,
    subtrader_suffix: str,
    extra_headers: dict[str, str] | None = None
) -> CreateFCMSubtraderResponse
create_subtrader(
    *,
    request: CreateFCMSubtraderRequest | None = None,
    subtrader_suffix: str | None = None,
    extra_headers: dict[str, str] | None = None
) -> CreateFCMSubtraderResponse

POST /fcm/subtraders. Not retried.

blocked_categories

blocked_categories(
    *,
    subtrader_id: str,
    extra_headers: dict[str, str] | None = None
) -> GetFCMSubtraderBlockedCategoriesResponse

GET /fcm/subtraders/blocked_categories.

update_blocked_categories

update_blocked_categories(
    *,
    request: UpdateFCMSubtraderBlockedCategoriesRequest,
    extra_headers: dict[str, str] | None = None
) -> UpdateFCMSubtraderBlockedCategoriesResponse
update_blocked_categories(
    *,
    subtrader_id: str,
    category: str,
    blocked: bool,
    extra_headers: dict[str, str] | None = None
) -> UpdateFCMSubtraderBlockedCategoriesResponse
update_blocked_categories(
    *,
    request: (
        UpdateFCMSubtraderBlockedCategoriesRequest | None
    ) = None,
    subtrader_id: str | None = None,
    category: str | None = None,
    blocked: bool | None = None,
    extra_headers: dict[str, str] | None = None
) -> UpdateFCMSubtraderBlockedCategoriesResponse

PUT /fcm/subtraders/blocked_categories. Not retried.

event_contract_daily_cap

event_contract_daily_cap(
    *,
    subtrader_id: str | None = None,
    extra_headers: dict[str, str] | None = None
) -> GetFCMEventContractDailyCapResponse

GET /fcm/subtraders/event_contract_daily_cap.

update_event_contract_daily_cap

update_event_contract_daily_cap(
    *,
    request: UpdateFCMEventContractDailyCapRequest,
    extra_headers: dict[str, str] | None = None
) -> None
update_event_contract_daily_cap(
    *,
    subtrader_id: str,
    limit: DollarDecimal | Decimal | str | float | int,
    extra_headers: dict[str, str] | None = None
) -> None
update_event_contract_daily_cap(
    *,
    request: (
        UpdateFCMEventContractDailyCapRequest | None
    ) = None,
    subtrader_id: str | None = None,
    limit: (
        DollarDecimal | Decimal | str | float | int | None
    ) = None,
    extra_headers: dict[str, str] | None = None
) -> None

PUT /fcm/subtraders/event_contract_daily_cap. Not retried.

delete_event_contract_daily_cap

delete_event_contract_daily_cap(
    *,
    subtrader_id: str,
    extra_headers: dict[str, str] | None = None
) -> None

DELETE /fcm/subtraders/event_contract_daily_cap. Not retried.

kalshi.resources.fcm.AsyncFcmResource

AsyncFcmResource(transport: AsyncTransport)

Bases: AsyncResource

Async FCM API.

orders_all

orders_all(
    *,
    subtrader_id: str | None = None,
    client_order_ids: str | list[str] | None = None,
    ticker: str | None = None,
    event_ticker: str | None = None,
    status: OrderStatusLiteral | None = None,
    min_ts: int | None = None,
    max_ts: int | None = None,
    limit: int | None = None,
    max_pages: int | None = None,
    extra_headers: dict[str, str] | None = None
) -> AsyncIterator[Order]

Returns an async iterator — use async for.

fills async

fills(
    *,
    min_ts: int | None = None,
    max_ts: int | None = None,
    cursor: str | None = None,
    extra_headers: dict[str, str] | None = None
) -> GetFcmFillsResponse

Async :meth:FcmResource.fills.

fills_all

fills_all(
    *,
    min_ts: int | None = None,
    max_ts: int | None = None,
    max_pages: int | None = None,
    extra_headers: dict[str, str] | None = None
) -> AsyncIterator[FcmFill]

Async counterpart of :meth:FcmResource.fills_all. Use async for.

positions_all

positions_all(
    *,
    subtrader_id: str,
    ticker: str | None = None,
    event_ticker: str | None = None,
    count_filter: str | None = None,
    settlement_status: (
        SettlementStatusLiteral | None
    ) = None,
    limit: int | None = None,
    max_pages: int | None = None,
    extra_headers: dict[str, str] | None = None
) -> AsyncIterator[MarketPosition]

Async counterpart of :meth:FcmResource.positions_all. Use async for.

list_subtraders async

list_subtraders(
    *, extra_headers: dict[str, str] | None = None
) -> ListFCMSubtradersResponse

Async :meth:FcmResource.list_subtraders.

create_subtrader async

create_subtrader(
    *,
    request: CreateFCMSubtraderRequest,
    extra_headers: dict[str, str] | None = None
) -> CreateFCMSubtraderResponse
create_subtrader(
    *,
    subtrader_suffix: str,
    extra_headers: dict[str, str] | None = None
) -> CreateFCMSubtraderResponse
create_subtrader(
    *,
    request: CreateFCMSubtraderRequest | None = None,
    subtrader_suffix: str | None = None,
    extra_headers: dict[str, str] | None = None
) -> CreateFCMSubtraderResponse

Async :meth:FcmResource.create_subtrader.

blocked_categories async

blocked_categories(
    *,
    subtrader_id: str,
    extra_headers: dict[str, str] | None = None
) -> GetFCMSubtraderBlockedCategoriesResponse

Async :meth:FcmResource.blocked_categories.

update_blocked_categories async

update_blocked_categories(
    *,
    request: UpdateFCMSubtraderBlockedCategoriesRequest,
    extra_headers: dict[str, str] | None = None
) -> UpdateFCMSubtraderBlockedCategoriesResponse
update_blocked_categories(
    *,
    subtrader_id: str,
    category: str,
    blocked: bool,
    extra_headers: dict[str, str] | None = None
) -> UpdateFCMSubtraderBlockedCategoriesResponse
update_blocked_categories(
    *,
    request: (
        UpdateFCMSubtraderBlockedCategoriesRequest | None
    ) = None,
    subtrader_id: str | None = None,
    category: str | None = None,
    blocked: bool | None = None,
    extra_headers: dict[str, str] | None = None
) -> UpdateFCMSubtraderBlockedCategoriesResponse

Async :meth:FcmResource.update_blocked_categories.

event_contract_daily_cap async

event_contract_daily_cap(
    *,
    subtrader_id: str | None = None,
    extra_headers: dict[str, str] | None = None
) -> GetFCMEventContractDailyCapResponse

Async :meth:FcmResource.event_contract_daily_cap.

update_event_contract_daily_cap async

update_event_contract_daily_cap(
    *,
    request: UpdateFCMEventContractDailyCapRequest,
    extra_headers: dict[str, str] | None = None
) -> None
update_event_contract_daily_cap(
    *,
    subtrader_id: str,
    limit: DollarDecimal | Decimal | str | float | int,
    extra_headers: dict[str, str] | None = None
) -> None
update_event_contract_daily_cap(
    *,
    request: (
        UpdateFCMEventContractDailyCapRequest | None
    ) = None,
    subtrader_id: str | None = None,
    limit: (
        DollarDecimal | Decimal | str | float | int | None
    ) = None,
    extra_headers: dict[str, str] | None = None
) -> None

Async :meth:FcmResource.update_event_contract_daily_cap.

delete_event_contract_daily_cap async

delete_event_contract_daily_cap(
    *,
    subtrader_id: str,
    extra_headers: dict[str, str] | None = None
) -> None

Async :meth:FcmResource.delete_event_contract_daily_cap.