← Research Notes中文
Technology · 2026-04-01 · 21 min read · Deep study

Automated Trading on Prediction Markets: Mechanics, Market Making, Arbitrage, and Execution

A systematic tour of the math and engineering needed to trade automatically on a CLOB prediction market: from the platform mechanics of off-chain matching / on-chain settlement, conditional tokens, and API fees, to Avellaneda-Stoikov market making, Kelly sizing, statistical arbitrage, Bayesian signals, LMSR and Almgren-Chriss optimal execution, plus risk management and a survey of data sources.

A prediction market turns "will something happen or not" into a price you can buy and sell. As one of the largest on-chain prediction markets today, Polymarket uses a hybrid architecture: order matching lives off-chain while clearing and settlement happen on the Polygon chain, giving you the matching experience of a centralized exchange while preserving non-custodial on-chain settlement. This article systematically surveys the mathematical and engineering machinery needed to trade automatically on such a CLOB (central limit order book) prediction market — from the platform's token mechanics, API, and fees, to market making, position management, arbitrage, signal generation, and optimal execution, and on to risk control. All formulas are drawn from public quantitative-finance literature and platform documentation; the goal is to piece scattered knowledge into a single complete map.

Reading note

This article is only a research survey of market mechanics and quantitative algorithms; it does not constitute any investment advice. Prediction markets are subject to regulatory restrictions in some jurisdictions (such as CFTC scrutiny and geographic blocking); before trading, understand the compliance requirements yourself and assess the risks carefully.

1. Platform Architecture: Off-Chain Matching + On-Chain Settlement

The entire trading system runs on Polygon (PoS, Chain ID 137) and is a textbook hybrid decentralized-exchange design. Clients (SDKs in Python / Rust / TypeScript, etc.) interact over REST and WebSocket with an off-chain matching engine (the Operator). The matching engine accepts, cancels, and matches orders with zero Gas, maintains a full bid/ask order book, and pairs orders on a Maker:Taker basis of 1:1 or N:1; price improvement accrues to the Taker. Once matching completes, fills are submitted to on-chain settlement in batches.

On-chain settlement is carried out by the CTFExchange contract: it validates order signatures with EIP-712, performs non-custodial atomic token swaps, and supports three settlement modes.

ModeScenarioMechanism
NORMALA holds USDC and wants to buy YES; B holds YES and wants to sellDirect token swap
MINTA wants to buy YES @ $0.50; B wants to buy NO @ $0.50The contract collects USDC from both sides, mints a token pair, and distributes them
MERGEA wants to sell YES; B wants to sell NOThe contract takes back the tokens, merges them into USDC, and distributes it
Key insight

The MINT mode means the exchange in theory has unlimited liquidity: as long as there is simultaneously someone wanting to buy YES and someone wanting to buy NO, the system can mint a fresh token pair directly out of their combined collateral, without any pre-existing token supply. This is one of the most fundamental differences between a prediction-market CLOB and an ordinary stock order book.

Core contract addresses (Polygon mainnet, all public on-chain information):

ContractAddress
Conditional Tokens0x4D97DCd97eC945f40cF65F87097ACe5EA0476045
CTF Exchange0x4bFb41d5B3570DeFd03C39a9A4D8dE6Bd8B8982E
Neg Risk CTF Exchange0xC5d563A36AE78145C45a50134d48A1215220f80a
Neg Risk Adapter0xd91E80cF2E7be2e162c6513ceD06f1dD0dA35296
USDC.e (collateral)0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174

2. The Conditional Tokens Framework (CTF)

Outcome shares are represented as ERC-1155 tokens under the Gnosis Conditional Tokens Framework. The whole system rests on a simple identity:

1 YES + 1 NO = 1 USDC (collateral)

The token derivation chain starts from the oracle question and hashes layer by layer down to the final position ID:

questionId (hash of UMA ancillary data)
    │
    ▼
conditionId = hash(oracle, questionId, outcomeSlotCount=2)
    │
    ├── indexSet = 0b01 → YES outcome → collectionId → positionId(YES Token)
    └── indexSet = 0b10 → NO  outcome → collectionId → positionId(NO Token)

Around it there are three basic operations: Split (split/mint) — deposit 1 USDC to receive 1 YES + 1 NO; Merge (merge/redeem) — return 1 YES + 1 NO to get back 1 USDC; Resolution (settlement) — after the UMA oracle adjudicates the condition, the winning token is exchanged 1:1 for collateral.

For multi-outcome markets (e.g., 5 candidates under "Who wins the election?"), the platform uses a Neg Risk (negative risk) framework: each outcome is still an underlying binary YES/NO market, but a NO share in any one market can be converted into 1 YES share in each of all the other markets. The capital efficiency comes from this: buying up every outcome requires only 1.0 of collateral, rather than the simple sum of the individual market prices.

3. API and Data Channels

The base address of the CLOB API is https://clob.polymarket.com. Public endpoints need no authentication and can read the order book and prices; trading endpoints require an API Key and a signature.

TypeEndpointDescription
GET/book?token_id=XFull order book (bids/asks)
POST/booksBatch-query multiple order books
GET/midpoint?token_id=XBest bid/ask midpoint
GET/price?token_id=X&side=BUYBest available price
GET/spread?token_id=XBid/ask spread data
GET/price-historyHistorical prices
POST/order / /ordersPlace order / batch place orders (up to 15)
DELETE/order / /ordersCancel / batch cancel
GET/orders / /tradesQuery open orders / trade history

Authentication has three levels: L0 — no auth, read-only public data; L1 — carries an API Key Header for authenticated reads; L2 — full trading (signed orders). Rate limits differ by endpoint; for example, the order-placement endpoint has a burst cap of roughly a few thousand per 10 seconds and a sustained cap of roughly tens of thousands per 10 minutes, with batch placement on a tighter budget. When automating, you need to treat rate limiting as a first-class constraint in your scheduling.

Real-time data goes over WebSocket. The Market Channel (public) subscribes by asset ID and pushes book (L2 order-book updates), last_trade_price (the latest trade price), price_change (best bid/ask changes), and tick_size_change (dynamic tick size); the User Channel (authenticated) pushes your own order and fill updates. A typical subscription message looks like this:

{
  "auth": {},
  "markets": ["<condition_id>"],
  "assets_ids": ["<token_id>"],
  "type": "market"
}

4. Order Types and Fee Structure

Order types cover both market-making and order-taking needs: GTC (rests until filled or canceled; the default), GTD (auto-expires at a specified Unix timestamp), FOK (must fill in full immediately or the whole order is canceled), Post-Only (available only for GTC/GTD, guaranteeing the order rests on the book as a Maker), market orders sized by dollar amount, and batch placement of up to 15 orders at a time.

The fee design follows one core principle: Makers pay zero fees; only Takers pay. Fees follow a bell-shaped curve in price, peaking at 50% probability:

fee_USDC = baseFeeRate × min(price, 1 - price) × shares

With a category exponent added, the extended form is fee = C × p × feeRate × (p × (1 - p))^exponent, where different categories use different exponents to shape the curve:

ExponentCategoryEffect
1.0Crypto, sports, politics, financeStandard curve
2.0General, mentionsSteeper; lower fees in the middle
0.5Economics, weatherFlatter; more uniform overall

This yields a few direct strategy implications: use Post-Only / GTC limit orders as much as possible to be a Maker and avoid Taker fees; in evenly matched markets where probability is near 50%, fees are markedly higher, so factor them into your cost when entering; and the symmetric fee design means you cannot game the fees by "buying YES to hedge selling NO."

5. Liquidity Provision and Incentive Mechanisms

The platform rewards liquidity providers through a Q-Score mechanism: roughly every 60 seconds it takes a random snapshot of the order book and scores orders with a quadratic spread function:

S(v, s) = ((v - s) / v)² × b

Here v is the maximum qualifying spread still eligible for rewards, s is the order's spread from the (size-cutoff-adjusted) midpoint, and b is the order size. The quadratic shape heavily rewards quotes close to the midpoint — narrowing a quote from a 3-cent spread to a 1-cent spread raises the score by far more than 3×. For two-sided quoting, the score takes the minimum of the two sides, Q_final = min(Q_yes, Q_no); one-sided quoting is scored with a reduction ratio. When the midpoint sits within [0.10, 0.90], one-sided quoting still scores; in the extreme ranges ([0, 0.10) or (0.90, 1.0]) you must quote both sides for it to count. In addition, anyone can deposit USDC into the contract to sponsor a particular market, with the rewards then distributed automatically in proportion to liquidity contribution.

6. Market-Making Algorithm: The Avellaneda-Stoikov Model

The classic market-making framework comes from Avellaneda and Stoikov (2008). It assumes the midpoint S(t) follows arithmetic Brownian motion dS(t) = σ dW(t), the market maker holds inventory q(t), and maximizes the exponential utility of terminal wealth u(W) = -exp(-γ W), where γ is the risk-aversion parameter.

Reservation Price

The price at which the market maker is "indifferent" to being filled or not is called the reservation price, obtained by solving the corresponding HJB equation:

r(s, q, t) = s - q · γ · σ² · (T - t)

Here s is the current midpoint, q is inventory (positive for long, negative for short), γ is the risk-aversion coefficient, σ² is the variance of the midpoint process, and T - t is the time remaining to the terminal horizon. The intuition: when holding a long position (q > 0), the reservation price is below the midpoint, so you sell down inventory more aggressively; when short, it is the reverse — the reservation price is above the midpoint to encourage buying to cover.

Optimal Spread and Quotes

δ* = γ · σ² · (T - t) + (2/γ) · ln(1 + γ/k)

Here k is the market-order arrival-intensity parameter, with the arrival-rate model λ(δ) = A · exp(-k · δ). The final bid and ask quotes are laid out symmetrically around the reservation price:

p_ask = r(s, q, t) + δ*/2
p_bid = r(s, q, t) - δ*/2

Expanded:
δ_bid = (1/2)·γσ²(T-t) + (1/γ)·ln(1+γ/k) + (1/2)·q·γσ²(T-t)
δ_ask = (1/2)·γσ²(T-t) + (1/γ)·ln(1+γ/k) - (1/2)·q·γσ²(T-t)

Inventory-Penalty Extension

To suppress inventory buildup more strongly, you can add a running inventory-penalty term to the objective:

max E[W(T) - γ·Var(W(T)) - φ·∫₀ᵀ q(t)² dt]

Correspondingly, the reservation price gains an extra drift term proportional to inventory: r(s, q, t) = s - q·γσ²(T-t) - q·φ·(T-t).

Adapting to Prediction Markets

Prediction-market prices are confined to the [0, 1] interval, so applying unbounded Brownian motion directly is inappropriate. A common approach is to first apply a logit transform, run the model in the unbounded space, and then transform back:

r_logit = logit(s) - q · γ · σ²_logit · (T - t)
r = sigmoid(r_logit) = 1 / (1 + exp(-r_logit))
where logit(s) = ln(s / (1 - s))

7. The Kelly Criterion and Position Management

Market making decides "how to quote"; the Kelly criterion decides "how big to bet." For a binary bet at odds of b:1 with true win probability p, the optimal bet fraction is:

f* = (b·p - q) / b = p - (1 - p) / b   (where q = 1 - p)

It comes from maximizing the expected logarithmic growth of wealth: G(f) = p·ln(1 + f·b) + (1-p)·ln(1 - f), obtained by setting dG/df = pb/(1+fb) - (1-p)/(1-f) = 0. Carried over to prediction markets, if you buy YES at price P (with true probability estimated as p_true), the net odds are b = (1-P)/P, so:

Buy YES @ P:  f* = (p_true - P) / (1 - P)
Buy NO  @ P:  f* = (P - p_true) / P

Why Use Fractional Kelly

In practice one rarely uses full Kelly, instead taking f_fractional = α · f* with 0 < α ≤ 1, commonly in the range of one-quarter to one-half Kelly. There are four reasons: full Kelly assumes you know the true probability for certain, and estimation error leads to systematic over-betting; G(f) is approximately parabolic near its maximum, so halving f loses only about a quarter of the expected growth (G(f*/2) ≈ G(f*)·(3/4)); trimming size significantly lowers variance and maximum drawdown; and it sharply reduces the risk of ruin when the probability estimate is wrong. Trading a little growth for order-of-magnitude smaller volatility is usually a good deal.

Multiple Outcomes and Multiple Markets

For n mutually exclusive outcomes (with true probabilities pᵢ and prices Pᵢ), Kelly becomes a constrained convex-optimization problem, solvable with a standard solver:

max Σᵢ pᵢ · ln(1 + Σⱼ fⱼ · (δᵢⱼ/Pⱼ - 1))
subject to: Σ fⱼ ≤ 1,  fⱼ ≥ 0

If you face N mutually independent binary markets, the problem decomposes into N independent Kelly subproblems solved separately; but as soon as there is any correlation between markets, you must return to the full joint distribution and optimize jointly, rather than computing each in isolation.

8. Statistical Arbitrage Strategies

The pricing-consistency constraints of prediction markets naturally give rise to a class of (approximately) risk-free arbitrage structures.

Complementary-Outcome Arbitrage (Dutch Book)

In a binary market, the prices of YES and NO should compose to exactly $1. When the sum of the two sides' best ask prices is below 1 (after fees), buying both sides simultaneously locks in a profit:

If P_yes + P_no < 1 - fees  →  risk-free arbitrage
Profit per pair: π = 1 - P_yes - P_no - transaction costs

Partition-Consistency Arbitrage

A mutually exclusive and exhaustive outcome set {O₁, …, Oₙ} should satisfy Σ P(Oᵢ) = 1. From this you can run arbitrage on either the buy or the sell side:

Buy-side arb:  π = 1 - Σᵢ P_ask(Oᵢ) - fees   (when Σ P_ask < 1)
Sell-side arb: π = Σᵢ P_bid(Oᵢ) - 1 - fees   (when Σ P_bid > 1)

Cross-Platform and Multi-Leg Arbitrage

Placing the quotes for the same event across different platforms (such as another regulated event-contract exchange) side by side, a cross-platform risk-free profit exists whenever P_A(YES) + P_B(NO) < 1.00. More generally, given m markets, n world states, and a payoff matrix A (m×n), finding a portfolio vector x that yields non-negative payoffs in all states, non-positive cost, and at least one strict inequality — this is exactly the linear-programming feasibility problem under the fundamental theorem of asset pricing:

Ax ≥ 0   (non-negative payoff in all states)
P·x ≤ 0  (non-positive cost)
at least one strict inequality → arbitrage exists

Cointegration Statistical Arbitrage

For markets that are correlated but not the same event, a cointegration approach works: first test the cointegration relationship with Engle-Granger or Johansen, construct the stationary spread z(t) = P₁(t) - β·P₂(t), then model it with an OU process and trade by z-score:

dz = θ(μ - z)dt + σ_z dW
Half-life: t_half = ln(2) / θ
z-score = (z(t) - μ) / σ_z

Trading rules:
  z > +threshold: sell (spread too wide)
  z < -threshold: buy (spread too narrow)

The OU parameters can be calibrated by the regression ΔP(t) = a + b·P(t-1) + ε(t), giving θ = -b/Δt, μ = -a/b, and σ = std(ε)/√Δt.

9. Bayesian Updating and Signal Generation

When folding new information (polls, news, the order book) into a probability estimate, the Bayesian framework provides a self-consistent update rule.

Beta-Binomial (Binary Events)

Taking a prior p ~ Beta(α, β), after observing s positives among n signals:

Posterior: p | data ~ Beta(α + s, β + n - s)
Posterior mean = (α + s) / (α + β + n)
               = w · prior mean + (1 - w) · observed frequency,  w = (α+β)/(α+β+n)

Continuous Updating with Gaussian Signals

If the prior is p ~ N(μ₀, σ₀²) and the signal x|p ~ N(p, σ_x²), the posterior is still Gaussian:

μ₁ = (σ_x²·μ₀ + σ₀²·x) / (σ₀² + σ_x²)
σ₁² = (σ₀²·σ_x²) / (σ₀² + σ_x²)

Sequential update over K signals (precision form):
τ_posterior = τ_prior + Σᵢ τᵢ
μ_posterior = (τ_prior·μ_prior + Σᵢ τᵢ·xᵢ) / τ_posterior

Thompson Sampling: Balancing Exploration and Exploitation

Maintain a Beta(α, β) posterior for each market; at each step sample from the posterior, estimate expected profit as E[π] = |p̃ - P_market|, allocate capital to the market with the highest expected profit, and update α and β after observing the outcome. This mechanism automatically trims size in uncertain markets and concentrates bets in markets you are confident about, with no need to hand-tune the exploration intensity.

10. LMSR: The Logarithmic Market Scoring Rule

Besides the CLOB, the other classic pricing route for prediction markets is Hanson's Logarithmic Market Scoring Rule (LMSR). Given n outcomes and outstanding shares q = (q₁, …, qₙ), the cost function is:

C(q) = b · ln(Σᵢ exp(qᵢ / b))

Here b is the liquidity parameter. The price is the partial derivative of the cost function — exactly a softmax — which naturally sums to 1 and lies within (0,1):

pᵢ(q) = ∂C/∂qᵢ = exp(qᵢ/b) / Σⱼ exp(qⱼ/b)

The trading cost of moving from q to q′ is the difference of the cost function at the two points; the cost of buying Δ shares of outcome k can be written as Cost = b · ln(1 + p_k · (exp(Δ/b) - 1)). The binary market is a special case, where the price degenerates to a sigmoid: p_yes = 1 / (1 + exp(-(q_y - q_n)/b)). The market maker's maximum loss is bounded: L_max = b · ln(n), which for a binary market is b · ln(2) ≈ 0.693b — this is also the central trade-off in choosing b: the larger b is, the deeper the book and the harder it is to move, but the larger the potential maximum loss.

11. Technical Indicators and Alpha Generation

Classic technical analysis on the price time series applies here too, but it should be used with care given prediction-market characteristics (bounded prices, event-driven volume).

Moving-average crossover: with fast and slow moving averages (or EMAs, EMA(t) = α·P(t) + (1-α)·EMA(t-1), α = 2/(n+1)), a golden cross buys YES and a death cross buys NO.

Momentum: RSI = 100 - 100/(1 + RS), RS = avg_gain(n)/avg_loss(n); RSI > 70 is treated as overbought (probability may have moved up too far) and RSI < 30 as oversold. MACD gauges momentum via the difference between EMA_12 - EMA_26 and its 9-period signal line.

Mean reversion: when the market price deviates from a fundamentals-model estimate, use the standardized deviation z(t) = (P_market - P_model)/σ_historical to trigger a contrarian trade — z > +threshold sells YES, z < -threshold buys YES, with position size scaled by |z| or Kelly.

Volume signals: VWAP gives the volume-weighted price anchor, and the volume-price trend VPT(t) = VPT(t-1) + V(t)·(P(t)-P(t-1))/P(t-1) captures the direction of capital flow.

12. Execution Algorithms

With a signal and a target position in hand, you still have to execute the order with as little impact as possible.

TWAP splits the total quantity Q into N equal parts and the total time T into N equal slices; the prediction-market adaptation is to skip a slice when there is no liquidity and use limit orders instead of market orders. VWAP allocates according to the historical volume distribution, q(t) = Q · V_hist(t) / Σ V_hist(t); but prediction-market volume is highly event-driven, so you should switch to an adaptive VWAP based on recent patterns rather than long-term history.

Almgren-Chriss optimal execution models impact as a temporary component h(v) = η·v and a permanent component g(v) = γ·v, and under min E[Cost] + λ·Var[Cost] solves for the optimal trajectory of liquidating Q shares:

x(t) = Q · sinh(κ(T-t)) / sinh(κT)
v(t) = -Q·κ · cosh(κ(T-t)) / sinh(κT)
κ = √(λ·σ² / η)

The two extremes are intuitive: λ → 0 (risk-neutral) degenerates to uniform execution (TWAP); λ → ∞ (extremely risk-averse) tends toward immediate liquidation.

Slippage estimation can go from coarse to fine: a linear model slippage = Q/(2·L) (L is the total liquidity within the price range); a square-root model slippage = η·σ·√(Q/ADV) (η around 0.1–0.5, ADV is average daily volume); and, most precisely, directly simulating level-by-level fills on the order book, AvgPrice = Σᵢ Pᵢ·min(qᵢ, Q_remaining)/Q, where slippage is AvgPrice - BestPrice.

13. Open-Source Ecosystem and Market-Making Strategies

A fairly complete open-source toolchain has formed around this platform. The official team and the community each provide SDKs, CLIs, market-making bots, real-time data clients, and unified trading abstractions. Below are some representative projects as of the time of research (star counts change over time):

ProjectLanguagePurpose
Official agents frameworkPythonAI-agent framework; autonomous trading with LLM + RAG
Official CLIRustCommand-line tool
py-clob-clientPythonCore Python SDK
rs-clob-client / clob-clientRust / TypeScriptMulti-language clients
poly-market-makerPythonOfficial market-making bot (AMM + Bands strategies)
ctf-exchangeSolidityCore exchange contract
real-time-data-clientTypeScriptWebSocket real-time data

The community side also has plenty of projects worth studying: a unified API layer that bills itself as "the CCXT of prediction markets"; a battle-tested market-making bot (whose author candidly admits competition has noticeably eroded profits); a large public historical dataset (on the order of tens of GiB); a real-time assistant aimed at short-horizon crypto markets; an enterprise-grade microservice architecture implementation; a project that wraps trading capabilities into an MCP server for AI assistants to call directly; and cross-platform arbitrage bots, among others. These projects are very helpful for understanding the engineering details of real-world market making and arbitrage.

Breaking Down the Official Market-Making Strategies

The official market-making bot ships with two strategies. The AMM strategy mimics the behavior of a concentrated-liquidity AMM: parameterized by p_min, p_max, spread, delta, depth, and max_collateral, it lays buy orders from price - spread to price - depth at delta intervals, and symmetrically lays sell orders above. The Bands strategy is a margin-based band method: it uses minMargin/avgMargin/maxMargin and minSize/avgSize/maxSize to define several price bands, ensuring the net order quantity within each band falls between [minSize, maxSize]. Both strategies re-sync their quotes every 30 seconds by default.

14. Risk-Management Framework

Even the best signal needs to be paired with disciplined risk control. On position management, common practice is to size each trade with Kelly (or its fractional version), control per-trade risk exposure with a fixed-fraction method, and set an absolute cap per individual market (an example range is on the order of a few hundred dollars per market). On stops and take-profits, market making typically uses tighter take-profits and relatively tight stops, while directional trades loosen them; after a stop triggers, set a cooldown period to pause trading, and impose a hard cap on total exposure across markets.

Prediction markets also have several distinctive risk types that call for dedicated mitigation:

Risk typeDescriptionMitigation
Binary settlement riskPositions jump to $0 or $1 at settlementTrim size before settlement; use fractional Kelly
Liquidity riskThin order book; large orders incur heavy slippageCheck market depth before ordering; set a minimum liquidity threshold
Correlation riskMultiple markets on the same event are highly correlatedUse the Neg Risk framework; cap total exposure per event
Volatility riskRisk intensifies during high-volatility periodsVolatility filter; pause when necessary
Smart-contract riskReliance on the execution safety of on-chain contractsCap total deposits; use audited contracts
Regulatory riskCompliance scrutiny and geographic restrictionsContinuously monitor policy developments

Capital efficiency is also part of risk control: using Merge to combine a paired YES + NO back into USDC is especially crucial for market makers; and in multi-outcome events you can use Neg Risk conversion to shuffle NO positions across markets. Finally, before any strategy goes live, run through its break-even margin: roughly, you want required margin > fee_rate × E[|payout - cost|] / E[|profit|], to ensure the edge is enough to cover fees and friction.

15. Data Sources and Alpha Sources

The official data interfaces form the first layer of signal sources: the CLOB API provides the order book, prices, and trade execution; the Gamma API provides market/event metadata and search; the Data API provides positions, fills, and leaderboards; and two WebSockets push, respectively, real-time trade/order updates and on-chain/equity market data.

More valuable alpha often comes from comparing external data against the market price: news (vectorized and run through RAG analysis), polling data against political-market pricing, the gap between sports betting lines and the order book, the BTC/USD price from on-chain oracles, spot prices from major exchanges as a reference for crypto markets, and activity, position, and PnL data from an on-chain Subgraph. In addition, leaderboard and "whale tracking" interfaces (ranking by profit/volume, querying specific addresses, looking up large holders by condition_id) can extract extra signal from the behavior of smart money.

16. References

The formulas and methods cited in this article come mainly from the following academic literature:

On the tools-and-frameworks side, Hummingbot provides an open-source market-making bot that includes an Avellaneda-Stoikov implementation, the Gnosis Conditional Tokens repository offers reference implementations of LMSR and a fixed-product market maker, and prediction-market-specific SDKs and unified trading APIs sharply lower the cost of integration. Piecing these theories and tools together gives you a complete scaffold for systematic trading on a CLOB prediction market — but as community practice repeatedly reminds us: a public edge is quickly ground down by competition, and the real moat always lies in data, execution details, and discipline.

Amos · research.xishe.ai · Please credit when sharing