What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

A useful prediction-market arbitrage scanner does more than compare two displayed prices: it checks that the contracts resolve the same way, converts each venue’s orderbook into executable prices and sizes, subtracts fees and a safety margin, and flags operational risks such as stale quotes or a one-sided fill. You can build the data and screening layers for Polymarket and Kalshi in Python, but the available official documentation does not establish that any resulting opportunity is risk-free or profitable. The title’s “Predicton” service could not be identified from authoritative API documentation, so this guide does not invent an integration for it.

What the scanner should—and should not—claim

A candidate appears when complementary positions on contracts with equivalent outcomes can be bought for less than their combined payout, after fees and other costs. That is a screening result, not a guarantee: the contracts may not be equivalent, displayed liquidity may disappear, one order may fill without the other, and settlement or access rules may differ.

Build the system as a read-only alerting tool first. Keep discovery, contract matching, price normalization, candidate calculation, and execution as separate components. Platform documentation establishes API workflows; it does not establish a profitable strategy, a universal fee formula, or a performance benchmark.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Which venues can be integrated from verified documentation?

Venue named in the title What the official documentation supports What the scanner still needs to verify
Polymarket The official Python trading quickstart demonstrates an AsyncSecureClient, retrieving a market by slug, choosing an outcome asset identifier according to market version, submitting a market buy, and awaiting asynchronous settlement. Use the current market-data documentation and SDK version for a read-only collector. Confirm market rules, applicable fees, access in the user’s jurisdiction, and the current order workflow before any live trading.
Kalshi The official “Quick Start: Market Data” guide describes unauthenticated production Trade API access for series, events, markets, and orderbooks. Its Python example uses requests, filters markets by series ticker, retrieves event details and orderbooks, and notes cursor-based pagination. Normalize its bids-only orderbook representation, fully paginate results, and verify current fees, contract rules, availability, and trading constraints.
“Predicton” Not established: no authoritative product or API documentation for a service by this name was available. Identify the exact service and its official API documentation before writing an adapter. Do not infer endpoints, market coverage, fees, or a relationship to the other venues.

The platform-specific details above are from official documentation accessed October 7, 2026. API details, fees, market availability, rules, and legal access can change; verify the current official documentation before relying on them.

Build the scanner in five layers

1. Discovery adapters collect complete market snapshots

Give each venue its own adapter. Retrieve events and markets, preserve native IDs and raw titles, record when each response was received, and follow every pagination cursor. A partial page can hide a relevant market or make an apparent price mismatch misleading.

For Kalshi, the documented public-data workflow goes from series to markets, event details, and then orderbooks. Its public market-data endpoints do not require authenticated trading credentials. Treat the API’s cursor as part of the collection state; do not assume one response contains every matching market.

Keep collection read-only and separate from order placement. Store the raw response or a durable snapshot alongside normalized fields so that a candidate can be traced back to the exact quotes and contract text that produced it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

2. Match contracts by meaning, not title similarity

Before comparing prices, map each market to a canonical proposition. A good match requires the same underlying event, threshold or outcome, time window, geography where relevant, and resolution conditions. Record the resolution authority and the exact YES/NO meaning for each venue. Preserve the original title and official rules; a similar headline is not proof that two contracts settle identically.

Have the matcher return an explicit review state—such as unmatched, needs_review, or approved_equivalent—rather than silently treating fuzzy text similarity as confirmation. Only approved pairs should reach the candidate calculator.

3. Normalize books into executable asks and depth

Represent prices consistently as a fraction from 0 to 1, and retain each price level’s available quantity. A scanner evaluating a buy must use the ask-side liquidity available to buy, not a last trade, midpoint, or the best bid on its own.

Kalshi’s official market-data guide explains that its orderbook response returns YES and NO bids rather than asks, reflecting the reciprocal relationship between binary positions. For a binary contract, a YES bid at price p corresponds to a NO ask at 1 − p, and a NO bid at q corresponds to a YES ask at 1 − q, subject to the venue’s price units and contract conventions. Convert units carefully, preserve the corresponding sizes, and verify the conversion against current official documentation before using it. Do not label a returned bid as an ask.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Normalize Polymarket’s market data into the same internal representation, but do not assume that its read-only collection methods are the same methods shown in its trading quickstart. The quickstart establishes a Python trading workflow, not the best or fastest scanner feed.

4. Calculate candidates across available levels

For a verified YES/NO pair on the same proposition, buy YES on one venue and NO on the other. At settlement, exactly one side should pay if the contracts truly are complementary. The gross payout per matched pair is therefore one unit, while the purchase cost is the sum of the two executable prices. For a target quantity, walk the available levels on both books rather than multiplying the top quote by the full desired size.

Subtract venue-specific fees using the current official fee rules for the relevant market and order type. Also reserve a safety margin for slippage, quote age, partial fills, and other execution costs. The available documentation does not establish a universal fee schedule or a single formula covering all markets, so keep the fee calculation configurable and do not publish a profit estimate from gross prices alone.

from dataclasses import dataclass
from typing import Callable, Iterable

@dataclass(frozen=True)
class Level:
    price: float       # normalized price from 0 to 1
    quantity: float    # units available at this price

@dataclass(frozen=True)
class Quote:
    venue: str
    outcome: str       # "YES" or "NO"
    asks: tuple[Level, ...]  # normalized executable buy-side levels
    age_seconds: float


def buy_cost(levels: Iterable[Level], quantity: float) -> float | None:
    """Return total cost to buy quantity, or None if depth is insufficient."""
    remaining = quantity
    total = 0.0
    for level in sorted(levels, key=lambda item: item.price):
        take = min(remaining, level.quantity)
        total += take * level.price
        remaining -= take
        if remaining <= 0:
            return total
    return None


def screen_pair(
    yes: Quote,
    no: Quote,
    quantity: float,
    fee_cost: Callable[[Quote, float, float], float],
    safety_cost: float,
    max_quote_age_seconds: float,
    contracts_approved_equivalent: bool,
) -> dict | None:
    """Screen a proposed YES/NO purchase; this is not an order instruction."""
    if not contracts_approved_equivalent:
        return None
    if yes.outcome != "YES" or no.outcome != "NO":
        return None
    if max(yes.age_seconds, no.age_seconds) > max_quote_age_seconds:
        return None

    yes_cost = buy_cost(yes.asks, quantity)
    no_cost = buy_cost(no.asks, quantity)
    if yes_cost is None or no_cost is None:
        return None

    fees = fee_cost(yes, quantity, yes_cost) + fee_cost(no, quantity, no_cost)
    net_cost = yes_cost + no_cost + fees + safety_cost
    payout = quantity  # only if the approved contracts are complementary
    return {
        "yes_venue": yes.venue,
        "no_venue": no.venue,
        "quantity": quantity,
        "net_cost": net_cost,
        "payout_if_contracts_settle_as_matched": payout,
        "screened_edge": payout - net_cost,
    }

This core deliberately leaves fee_cost, the equivalence approval, quote collection, and alert thresholds to the implementation. Set the quantity from the depth you can actually buy on both venues, not from the larger book alone. A positive screened_edge is only a candidate for further review; it is not proof that both legs can be executed or that the settlement assumptions are sound.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

5. Alert, reconcile, and only then consider execution

Start with alerts or paper trading. Each alert should include the two native market IDs, raw contract titles, the approved matching rationale, source timestamps, quote ages, level-by-level depth used, fee inputs, and the candidate’s net calculation. Keep the calculation reproducible from saved snapshots.

If you later implement live orders, design for the case where one leg fills and the other does not. Define limits for unhedged exposure, order size, quote age, retries, and cancellation before enabling submission. Reconcile submitted orders, fills, cancellations, positions, and eventual settlement against each venue’s own identifiers and lifecycle.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Authentication and operational safeguards

Keep public collection separate from trading credentials

Kalshi documents public access for market data and a distinct authenticated-request flow for trading. Its authentication guide requires an API key ID, a millisecond timestamp, and a signature. The signed message combines the timestamp, HTTP method, and path without query parameters; the guide describes RSA-PSS/SHA-256 or Ed25519 signing. Follow the current official guide for exact headers and environment-specific details.

Polymarket’s Python trading quickstart constructs its secure client using a private key and wallet address. That example is a trading workflow, not a reason to put a wallet key in a market-data collector. Keep private keys outside source code, restrict access, and use separate credentials and processes for collection and any permitted trading.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make failures visible

  • Log API errors, pagination cursors, snapshot timestamps, and the last successful update per venue.
  • Reject stale or incomplete books instead of silently reusing old prices.
  • Set exposure and candidate-size limits, and stop alerting or execution when data freshness or contract matching falls below your policy.
  • Track partial fills and unresolved orders explicitly; do not assume that a submitted order filled or that a cancellation removed all risk.
  • Recheck current fee schedules, market rules, settlement procedures, and jurisdictional availability before deploying changes.

How to judge a candidate before acting on it

Review each opportunity against the same six questions: do the event definitions and resolution conditions match; are the displayed prices executable with enough depth; are the orderbook sides normalized correctly; have current fees and required capital been included; can either leg remain exposed if the other fails; and are both markets available to you under their current rules and jurisdictional restrictions? A failure on any of these checks means the price difference is not yet a usable arbitrage candidate.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.