Skip to main content

prediction-fees

Exact trading fees for Kalshi and Polymarket, from a dated schedule. No dependencies, MIT.

pip install prediction-fees
from prediction_fees import kalshi_fee, kalshi_fee_levels, polymarket_fee, polymarket_rebate

kalshi_fee(0.50, 100)  # Decimal('1.75')  taker
kalshi_fee(0.50, 1)  # Decimal('0.02')  0.0175 rounds up to the cent
kalshi_fee(0.50, 100, maker=True)  # Decimal('0.44')
kalshi_fee(0.50, 100, as_of="2026-11-03")

# one order that walked three levels: summed first, rounded once
kalshi_fee_levels([(0.45, 10), (0.46, 20), (0.48, 5)])  # Decimal('0.61')

# a series without maker fees (Kalshi GET /series/{ticker} fee_type "quadratic")
kalshi_fee(0.50, 100, maker=True, fee_type="quadratic")  # Decimal('0.00')

polymarket_fee(0.50, 100, category="crypto")  # Decimal('1.75000') USDC
polymarket_fee(0.50, 100, rate=0.03)  # Decimal('0.75000')  the market's own feeSchedule.rate
polymarket_fee(0.50, 100, maker=True)  # Decimal('0.00000')
polymarket_rebate(0.60, 100, category="politics")  # Decimal('0.240000')  maker rebate

Every function returns a Decimal. Prices are in dollars (0 to 1). Inputs can be int, float, str or Decimal; floats are read through their shortest repr, so 0.07 is exactly 0.07 and there is no float error in the round-up (a naive math.ceil charges a cent too many on, for example, 100 contracts at 0.10).

The rules

Kalshi. Per order execution (one order matched at one time, across however many price levels it took):

fee = round_up_to_cent( rate × multiplier × Σ C × P × (1 − P) )

rate is 0.07 for takers and 0.0175 for makers. multiplier is the series' fee_multiplier and applies to takers and makers (1 for most series; some 0.5, a few 0). Makers pay only on series whose fee_type charges makers (quadratic_with_maker_fees, quadratic_with_combo_maker_fees); a quadratic series charges makers 0. On 2 Nov 2026 that was 163 of Kalshi's 15,600 series. Read both from Kalshi's public GET /trade-api/v2/series/{series_ticker} (the series is the market ticker up to the first -) and pass them: fee_type="quadratic" makes a maker fill cost 0, and kalshi_multipliers(fee_type, fee_multiplier) gives the (taker, maker) multipliers. Without fee_type makers are charged (the conservative side).

Polymarket. Takers, per execution:

fee = round_down_to_0.00001( rate × Σ C × P × (1 − P) )

rate is the market's own coefficient: Gamma GET /markets?id= returns it as feeSchedule.rate (0 when feesEnabled is false), and some older sports markets still carry 0.03. Without it, the category table:

category taker coefficient maker rebate share
crypto 0.07 0.20
sports 0.05 0.15
economics, culture, weather, other 0.05 0.25
combos 0.05 0
finance, politics, mentions, tech 0.04 0.25
geopolitics 0 0

Pass the market's own coefficient as rate or category (case-insensitive); polymarket_market_terms(market) reads a Gamma row (its feeSchedule, else the category its feeType names, e.g. politics_fees). Fees are rounded to 5 decimals, down: Polymarket's docs say anything below 0.00001 USDC rounds to zero.

Makers pay 0 and earn a rebate, polymarket_rebate:

rebate = rebate_share × rate × Σ C × P × (1 − P)

Each market's daily rebate pool is its rebate share of the taker fees paid there, split pro rata by each maker's fee-equivalent, so a maker's rebate is exactly the share of its own fee-equivalent. Pass the market's feeSchedule.rebateRate as rebate_share (or a category). The rebate is not rounded (it is paid daily in aggregate) and the $1 minimum payout is not modelled.

Edge cases. A price of exactly 0 or 1 costs nothing (P × (1 − P) is 0). A price outside [0, 1], a negative size or rate, NaN or infinity raises FeeError (a ValueError). Zero contracts cost nothing.

Dates

The table (fees.json, shipped inside the package) lists each venue's rates with the date they took effect. as_of= takes a date, a datetime (read in UTC) or an ISO string and picks the entry in force that day; without it you get the latest entry. A date before the first entry raises FeeError rather than guessing; pass rate= to price an older trade.

venue effective rates
Kalshi 2026-07-07 taker 0.07, maker 0.0175
Polymarket 2026-07-10 the category table above, makers 0 plus the rebate share

prediction_fees.table() returns the whole table, sources and notes included.

What is not certain

Checked on 2026-11-01 (Polymarket and the Kalshi series rule on 2026-11-02):

  • Kalshi's taker formula and 0.07 are well established. The maker coefficient 0.0175 and the 2026-07-07 effective date come from secondary sources quoting Kalshi's fee schedule PDF (kalshi.com/docs/kalshi-fee-schedule.pdf), which could not be fetched to confirm.
  • Kalshi's API docs describe fees accrued to $0.000001 with a per-order rounding accumulator that refunds over-rounding. This library follows the published schedule (round up to the cent per execution), so a fill split across several executions may show a cent or two more than Kalshi's final charge.
  • Polymarket's coefficients and rebate shares are as read from docs.polymarket.com on 2026-11-02. 2026-07-10 is the date of the last change in the published timeline (sports 0.03 to 0.05); earlier periods are not tabulated, and a market's own feeSchedule can still differ from the table (0.03 on some older sports markets), so prefer it. The docs say fees are rounded to 5 decimals and that anything below 0.00001 USDC rounds to zero; this library reads that as rounding down, which the docs do not state in so many words.
  • Not covered: the $1 minimum rebate payout, taker volume rebates, Polymarket US (a separate exchange with its own schedule), Kalshi incentive programs and perpetuals.

Corrections with a source are welcome: hello@langbot.ai.

The same table and functions ship for JavaScript/TypeScript as prediction-fees on npm.

License

MIT. Maintained by Langbot.

Metadata

Release files for prediction-fees 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for prediction-fees 0.2.0
File Size Uploaded Provenance Actions
prediction_fees-0.2.0.tar.gz 14.5 kB Without provenance Details for prediction_fees-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for prediction-fees 0.2.0
File Interpreter ABI Platform Actions
prediction_fees-0.2.0-py3-none-any.whl Python 3 none any Details for prediction_fees-0.2.0-py3-none-any.whl

Total release size: 25.5 kB

Release files / prediction_fees-0.2.0.tar.gz

Download URL prediction_fees-0.2.0.tar.gz
Size 14.5 kB
Tags Source
SHA-256 checksum
How to use checksums
d2263a2bda8febfb994dd9ead39cbf0a8bd3db825fa823dd966e35554dec7e96
BLAKE2b-256 checksum
How to use checksums
1378169fd63fc5ae080aaa18a7c191799e9ba062f38c5ab1f80b6398818e3257
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / prediction_fees-0.2.0-py3-none-any.whl

Download URL prediction_fees-0.2.0-py3-none-any.whl
Size 11.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
08d8aea066fb7553d1002f188fceb4a5ba48965c5a96084e935b526dd29f8ba4
BLAKE2b-256 checksum
How to use checksums
a21ef9b69a44c9c27c356f663fa7b1eaad5289a1b13ecf497d3cfa0a32179a9d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for prediction-fees 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page