Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.predexon.com/llms.txt

Use this file to discover all available pages before exploring further.

Smart-money flow is one of the most consistent prediction-market signals. Build an alerter that fires when net buying by profitable wallets accelerates into a market — then act on it. You’ll build:
  1. A poller that ranks markets by smart-money inflow
  2. An alert path (Discord / Slack / email)
  3. (Optional) A sizing rule that opens a position when the signal fires
Endpoints used: 2 REST calls per cycle. Free + Dev plan; runs on Dev because Smart Money is a gated feature.

Architecture


Step 1 — Find markets smart money is entering

The smart-activity endpoint ranks markets by recent activity from top-performing wallets. Pull the leaderboard once per cycle.
import os, requests, time

BASE = "https://api.predexon.com"
H = {"x-api-key": os.environ["PREDEXON_API_KEY"]}

def top_smart_markets(window_hours=4, limit=20):
    return requests.get(
        f"{BASE}/v2/polymarket/markets/smart-activity",
        headers=H,
        params={"window_hours": window_hours, "limit": limit},
    ).json()["markets"]
This already filters to wallets with positive realized P&L. You get a ranked list of markets they’re trading in the last 4 hours.

Step 2 — Read the net positioning

For each candidate, ask: are they net buying or net selling, and by how much?
def smart_money(condition_id):
    return requests.get(
        f"{BASE}/v2/polymarket/market/{condition_id}/smart-money",
        headers=H,
    ).json()

def evaluate(candidates):
    signals = []
    for m in candidates:
        sm = smart_money(m["condition_id"])
        pos = sm["positioning"]                       # SmartMoneyPositioning
        net_usd = pos["total_smart_buy_volume"] - pos["total_smart_sell_volume"]
        wallet_count = pos["smart_wallet_count"]
        if abs(net_usd) > 25_000 and wallet_count >= 5:
            signals.append({
                "market": m["title"],
                "condition_id": m["condition_id"],
                "market_slug": m["market_slug"],
                "side": "yes" if net_usd > 0 else "no",
                "flow_usd": net_usd,
                "wallets": wallet_count,
                "net_buyers_pct": pos["net_buyers_pct"],
                "avg_buy_price": pos["avg_smart_buy_price"],
            })
    return signals
The thresholds ($25k, 5 wallets) are starting points. Tune to your appetite.

Step 3 — Alert

Plug into whatever channel you live in.
import json
import urllib.request

DISCORD_WEBHOOK = os.environ["DISCORD_WEBHOOK"]

def alert(signal):
    msg = (
        f"**Smart money signal: {signal['side'].upper()}**\n"
        f"{signal['market']}\n"
        f"Net flow: ${signal['flow_usd']:+,.0f} from {signal['wallets']} smart wallets "
        f"({signal['net_buyers_pct']*100:.0f}% net buyers)\n"
        f"Avg smart-money buy price: ${signal['avg_buy_price']:.2f}\n"
        f"https://polymarket.com/market/{signal['market_slug']}"
    )
    req = urllib.request.Request(
        DISCORD_WEBHOOK,
        data=json.dumps({"content": msg}).encode(),
        headers={"Content-Type": "application/json"},
    )
    urllib.request.urlopen(req)

Step 4 — Optional: auto-size into the signal

If you trust the signal enough to commit capital, place an order. Since smart-money runs on Polymarket data, the simplest path is a venue-specific Polymarket order — fetch the right token_id by condition_id, then place.
TRADE = "https://trade.predexon.com"
ACCOUNT_ID = "your-account-id"
SIZE_USD = 100

def maybe_trade(signal):
    # look up the YES/NO token_ids for this market
    market = requests.get(
        f"{BASE}/v2/polymarket/markets",
        headers=H,
        params={"condition_id": signal["condition_id"], "limit": 1},
    ).json()["markets"][0]
    token_id = next(
        o["token_id"] for o in market["outcomes"]
        if o["label"].lower() == signal["side"]
    )
    current_price = next(
        o["price"] for o in market["outcomes"]
        if o["label"].lower() == signal["side"]
    )

    shares = SIZE_USD / current_price
    return requests.post(
        f"{TRADE}/api/accounts/{ACCOUNT_ID}/orders",
        headers={**H, "Content-Type": "application/json"},
        json={
            "venue": "polymarket",
            "market": {"tokenId": token_id},
            "side": "buy",
            "type": "market",
            "size": f"{shares:.2f}",
        },
    ).json()
If you want the Order Router to pick the best venue (cross-venue arb-aware), look up the canonical predexon_id from each outcome (market["outcomes"][i]["predexon_id"]) and POST to /router/orders with predexonId instead.

The full loop

SEEN = set()  # don't re-alert on the same signal

while True:
    for s in evaluate(top_smart_markets()):
        key = (s["condition_id"], s["side"])
        if key in SEEN:
            continue
        SEEN.add(key)
        alert(s)
        # maybe_trade(s)  # uncomment to auto-execute
    time.sleep(600)        # 10 min cadence
Reset SEEN periodically (every few hours) if you want re-alerts for sustained signals.

Tuning

KnobTighter signalLooser signal
window_hours1–2 hrs (recent activity only)24 hrs (broader)
net_usd threshold$100k+$5k+
wallet_count floor10+ unique wallets2+
Cycle cadenceevery 1 minevery 30 min
realized_profit_min for the smart-money pool$500k+$10k+
Backtest before going live — see Signal Backtesting for how to honestly measure whether the signal predicts forward returns at your horizon.

Reference