# Polymarket + Kalshi Arb Monitor (Fee-Aware) (`weighty_suona/prediction-market-arb-monitor`) Actor

Scans Polymarket and Kalshi, matches the same games on both venues, and reports arbitrage edges net of Kalshi's official fee schedule. Deterministic matching, honest gross-vs-net math, MCP-friendly summary. For traders, quants and AI agents.

- **URL**: https://apify.com/weighty_suona/prediction-market-arb-monitor.md
- **Developed by:** [Andrew Goodrich](https://apify.com/weighty_suona) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Polymarket + Kalshi Arb Monitor (Fee-Aware)

Scans Polymarket and Kalshi, matches the same game on both venues, and reports
arbitrage opportunities with **real net-of-fees edges** — Kalshi's official fee
schedule (0.07 × P × (1-P) per contract) is deducted before anything is called
an opportunity.

### Why this one is different

- **Deterministic event matching.** Joins venues on slug/ticker structure
  (sport + team codes + date), not fuzzy title soup — then verifies each team
  mapping by name. Ambiguous matches are skipped, never guessed.
- **Honest math.** Gross edge is a lie. Every quote shows gross edge, Kalshi
  fees, and net edge side by side. Most "arbs" you see elsewhere die here.
- **Built for the Kalshi API migration.** Kalshi's `/markets` endpoint now
  returns only parlay collections; this actor pulls standard game markets from
  the events API and handles the new dollar-denominated price fields.
- **Agent-ready.** Machine-readable run summary in the key-value store
  (`last-run-summary.json`), clean dataset schema, no login required.

### Input

| Field | Default | Meaning |
|---|---|---|
| `minNetEdgeBps` | 50 | Report only edges above this, net of Kalshi fees (100 bps = 1%) |
| `minVolumeUsd` | 1000 | Liquidity floor on Polymarket side |
| `maxMarketsPerVenue` | 2000 | Scan cap per venue |
| `matchThreshold` | 0.85 | Reserved for fuzzy fallback (matching is structural) |

### Output

Dataset rows (one per qualifying opportunity):

```
polymarketTitle, kalshiEventTitle, kalshiEventTicker, kalshiTeamMarket,
direction, polymarketPrice, kalshiNoPrice,
grossEdgeBps, kalshiFeesBps, netEdgeBps, tieRisk,
polymarketUrl, kalshiUrl, scannedAt
```

Plus `last-run-summary.json` in the key-value store: venues scanned, matches,
opportunities, best net edge.

### Scope (v1)

- Game moneylines: NFL, MLB, NHL, NBA (`KX<LEAGUE>GAME` ↔ Polymarket game slugs)
- Spreads/totals/player props are roadmap v2 (line alignment required)
- `tieRisk: true` flags sports where a draw kills both legs (NFL overtime rules,
  soccer draws) — price that risk or skip those rows

### Pricing

Pay-per-event: small per-run charge + per matched pair delivered.
Schedule it (e.g. hourly) to watch edges appear and vanish around team news.

### Disclaimer

Data is provided as-is from public venue APIs. Prices move fast; verify on the
venue before trading. Nothing here is financial advice. Bet responsibly.

# Actor input Schema

## `minNetEdgeBps` (type: `integer`):

Only report opportunities whose edge AFTER Kalshi fees exceeds this. 50 bps = 0.5%.

## `minVolumeUsd` (type: `integer`):

Filters out illiquid markets where the printed price is fantasy.

## `maxMarketsPerVenue` (type: `integer`):

Scan cap. 2000 covers all liquid markets on both venues; runs in seconds.

## `matchThreshold` (type: `number`):

0-1. Conservative matching: false positives are worse than missed pairs. Both source titles are always included so you can verify.

## Actor input object example

```json
{
  "minNetEdgeBps": 50,
  "minVolumeUsd": 1000,
  "maxMarketsPerVenue": 2000,
  "matchThreshold": 0.85
}
```

# Actor output Schema

## `arbOpportunities` (type: `string`):

One dataset row per qualifying opportunity: matched market titles, trade direction, both prices, gross edge, Kalshi fees, net edge in bps, tie-risk flag, and direct venue URLs.

## `runSummary` (type: `string`):

Machine-readable summary: venues scanned, markets fetched, games matched, opportunities found, best net edge. Designed for AI-agent consumption.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("weighty_suona/prediction-market-arb-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("weighty_suona/prediction-market-arb-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call weighty_suona/prediction-market-arb-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,weighty_suona/prediction-market-arb-monitor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/TlGxwzpxktDxdeM4c/builds/Mm6iiJ3LPYsEJkchl/openapi.json
