Documentation

The full documentation ships inside the package (bilingual EN/ES). This page covers what you need to decide whether it's for you, plus the quickstart.

Requirements

Quickstart (dry-run, no money)

cd uruguabot
pip install -r requirements.txt
cp .env.example .env        # Windows: copy .env.example .env
python uruguabot.py

The bot discovers live 5-minute markets, applies the real entry gates, and simulates fills using slippage distributions measured from real trades. Every 30 seconds it prints a diagnostic "funnel" showing exactly which gate filtered which candidate — you always know why it is or isn't trading.

Optional monitor panel (measures the real accuracy of every signal, including your own manual picks):

python monitor_server.py    # then open http://localhost:8770

The default configuration is the validated one

The shipped .env.example is exactly the configuration that was profitable in our live testing ("Hypothesis B"):

Going live (only after dry-run convinces you)

  1. Create a dedicated Polymarket wallet. Never use your main wallet. Fund it small.
  2. Set WALLET_ADDRESS, PRIVATE_KEY and POLY_SIG_TYPE in .env (1 = email/proxy wallet, 0 = MetaMask/EOA).
  3. Verify everything first: python check_wallet.py
  4. Set DRY_RUN=false and LIVE_CONFIRM=YES. The bot refuses to start live without both — that's deliberate.
  5. Start at BET_USD=2 and watch the first hours against your Polymarket activity page.

What's included

~15 core Python files: trading engine, CLOB V2 execution layer with ghost-fill protection, multi-timeframe signals, Chainlink oracle feed, optional ML gate with retraining script, calibrated dry-run simulator, risk rails, monitor panel, and ops tooling (check_status.py, check_wallet.py, compare_dry_vs_live.py, diagnose_orphan_shares.py). Plus bilingual READMEs, a full strategy & results document, EULA and risk disclosure.

Read the source before you buy it

You are buying readable Python, so here is what that actually looks like — the real file listing, and one real function copied byte-for-byte out of the package. Nothing here is minified, obfuscated or compiled.

uruguabot/  # 21 Python files, 6735 lines, nothing compiled   # core engine (15)    420  uruguabot.py               # main loop, market discovery, the 30s diagnostic funnel    608  urubot_actions.py          # evaluate / execute - every entry gate lives in here   1105  execution.py               # Polymarket CLOB V2: FOK buys, ghost-fill verification, exits    340  polymarket.py              # read-only Gamma client: slug generation, market discovery    154  signals.py                 # multi-timeframe consensus engine (30s / 1m / 5m)    171  market_features.py         # the 11 market features recorded at decision time    100  simulator.py               # dry-run fills drawn from the measured slippage distributions    144  price_feed.py              # price thread: Chainlink -> Binance -> Coinbase -> CoinGecko    472  chainlink_feed.py          # reads Polymarket's own resolution oracle over public RPC    337  risk_rails.py              # daily-loss / losing-streak / unfilled-ratio circuit breakers    208  logger.py                  # atomic bet log: tmp + rename, keeps a .bak, survives a kill -9    247  brain.py                   # optional ML gate - ships untrained and off unless you enable it    292  retrain_v3.py              # retrains that gate on your own data    191  snipe.py                   # optional T-10s late entry on observed Chainlink delta (off)    659  monitor_server.py          # the local accuracy monitor that serves monitor.html   # ops tooling (6)    302  check_wallet.py            # verifies wallet + auth before you are ever allowed to go live    387  check_status.py            # status report computed over the bet log    129  check_polymarket.py        # "what is Gamma answering right now?" diagnostic    188  compare_dry_vs_live.py     # measures dry-run vs live drift    112  diagnose_orphan_shares.py  # finds shares the bot bought but could not sell    169  close_stale_bets.py        # closes bets stuck OPEN when the monitor could not resolve them    6735  total
The whole package, file by file. Real wc -l counts of the shipped source — 15 core modules, 6 ops scripts, 6,735 lines. The grouping and the one-line comments were added by hand; the filenames and the line counts were not.
                            else:
                                # /positions no muestra las shares todavia. La
                                # FUENTE DE VERDAD es el USDC: si la plata SALIO de
                                # la wallet, el FOK llenó y las shares SON nuestras
                                # (la data-api /positions laggea en mercados de 5m).
                                # Solo es NO_MATCH si el USDC quedó intacto.
                                now_usdc = self.get_balance_usdc()
                                delta = None
                                if (pre_usdc is not None and now_usdc is not None
                                        and pre_usdc >= 0 and now_usdc >= 0):
                                    delta = float(pre_usdc) - float(now_usdc)
                                if delta is not None and delta < bet_usd * 0.5:
                                    # Plata intacta -> el FOK realmente no matcheó.
                                    return BuyResult(ok=False, no_match=True,
                                        error=f"NO_MATCH (usdc intact, delta=${delta:.3f})")
                                # Fix May 30: FILL REAL con lag de /positions. NO
                                # abandonar (antes -> GHOST_FILL, sin SL, perdida
                                # del stake completo). Un FOK success llena al 100%,
                                # asi que trackeamos las shares pedidas para que la
                                # posicion reciba SL y monitoreo normal.
                                spent = delta if delta is not None else bet_usd
                                self.log.warn(
                                    f"[exec] positions-api lag: FOK success + USDC "
                                    f"-${spent:.2f} pero /positions={verified_size} "
                                    f"({vmethod}). Asumo fill real de {shares} shares "
                                    f"y trackeo la posicion para SL/monitoreo.")
                                return BuyResult(
                                    ok=True, exec_price=exec_price,
                                    shares=shares, bet_usd=bet_usd,
                                    order_id=str(order_id),
                                    slippage=exec_price - chosen_price,
                                    positions_lag=True)
2. The fix for the bug that cost more than the strategy earned. execution.py, lines 684–715, copied byte-for-byte: original indentation, original comments, original “Fix May 30” note. This is the ghost-fill verification the audit is about — when Polymarket’s /positions endpoint has not caught up, the USDC balance delta decides whether the order really filled, instead of the bot abandoning a live position with no stop-loss on it. And note the comments are in Spanish: the author is Argentine and wrote the trading core in his own language. The README, the strategy document and the config file are fully bilingual — the in-code comments are not. Better you know that now than after paying.
git clone https://github.com/Emi-db/polymarket-bot-audit
cd polymarket-bot-audit
python analysis/compute_summary.py    # standard library only, nothing to install
And you do not have to take the results table on trust either. The audit repository ships every fill from both bot generations, plus the 1,934-window signal study, as raw CSVs under CC BY 4.0 — losing rows included — and compute_summary.py (MIT, standard library only) recomputes every headline number from them, sample sizes included. No dependencies, no account. If our arithmetic is wrong, that script is how you find out.

Support policy

One-time purchase, sold as-is: no support service, no update subscription, no server dependency. The code is deliberately small and heavily commented so you can own and maintain it. That policy is what keeps the price at $99 instead of $99/month.

Refunds: there are no refunds once the source has been downloaded — it is delivered source code. That is why dry-run is the default mode: you can run the real bot on real live markets, with no wallet and no money, for as long as you like before you buy.

Get Uruguabot — $99, one-time