Content is user-generated and unverified.

CEBU ALPHA TRADING OLYMPICS

Tournament Controller — Architecture Specification v1.0

Author: Coach Claude Opus 4.6

Date: March 12, 2026


1. PURPOSE

The Tournament Controller is a single Python script that orchestrates all 10 competition bots against identical market data, enforces universal safety rules, tracks independent balances, and produces scoring-ready JSON logs.

It is the stadium, the referee, and the scorekeeper — all in one file.


2. DESIGN PRINCIPLES

  • One script, one cron job. No microservices, no Docker orchestration, no Grafana. Just tournament_controller.py running on the host VPS via cron alongside the existing weather scanner.
  • Snapshot fairness. All 10 bots see the exact same market data from the exact same moment. No bot gets fresher data than another.
  • Independent state. Each bot has its own balance, trade history, and exposure tracking. One bot's decisions never affect another's.
  • LLM-optional. Bots that need Grok reasoning get it. Bots that are pure math never burn a token. The controller handles both.
  • Scoring-ready output. Every trade log is structured for the neutral scoring script to consume directly.

3. ARCHITECTURE OVERVIEW

[CRON - every 5 min during GFS windows, every 30 min otherwise]
    |
    v
tournament_controller.py
    |
    ├── 1. FETCH MARKET SNAPSHOT
    │       ├── Simmer API → temperature markets (100)
    │       ├── Simmer API → all categories (for non-weather bots)
    │       ├── Simmer briefing → high-divergence opportunities
    │       └── Freeze snapshot with UTC timestamp
    │
    ├── 2. FETCH FORECAST DATA
    │       ├── Open-Meteo GFS for all cities (cached per scan)
    │       └── Attach forecasts to snapshot
    │
    ├── 3. RUN EACH BOT (sequential, same snapshot)
    │       ├── Bot receives: snapshot + own state (balance, trades, exposure)
    │       ├── Bot returns: list of trade decisions
    │       ├── Controller validates: safety floors, position limits, exposure
    │       └── Controller executes: updates bot state, logs trade
    │
    ├── 4. LOG RESULTS
    │       ├── Per-bot JSON trade log (standardized format)
    │       ├── Master scan summary
    │       └── Portfolio snapshot per bot
    │
    └── 5. SAVE STATE
            └── tournament_state.json (all 10 bot states)

4. FILE STRUCTURE

/data/.openclaw/workspace/olympics/
├── tournament_controller.py      # The main script
├── tournament_state.json         # All 10 bot balances + positions
├── tournament_config.json        # Race parameters (capital, limits, etc.)
├── strategies/
│   ├── __init__.py
│   ├── janitor.py               # Team Pragmatist bot 1
│   ├── vulture.py               # Team Pragmatist bot 2
│   ├── clock.py                 # Team Pragmatist bot 3
│   ├── historian.py             # Team Pragmatist bot 4
│   ├── contrarian.py            # Team Pragmatist bot 5
│   ├── oracle.py                # Team Bayesian bot 1
│   ├── diver.py                 # Team Bayesian bot 2
│   ├── warden.py                # Team Bayesian bot 3
│   ├── surgeon.py               # Team Bayesian bot 4
│   └── farmer.py                # Team Bayesian bot 5
├── logs/
│   ├── janitor.json             # Trade log per bot
│   ├── vulture.json
│   ├── clock.json
│   ├── historian.json
│   ├── contrarian.json
│   ├── oracle.json
│   ├── diver.json
│   ├── warden.json
│   ├── surgeon.json
│   └── farmer.json
└── snapshots/                   # Market data snapshots (for audit)
    └── snapshot_20260312_1630.json

5. UNIVERSAL SAFETY FLOORS

Applied by the controller AFTER each bot returns its decisions, BEFORE execution. No bot can override these.

ParameterValueNotes
Starting capital per bot$100 (configurable)Same for all bots per race
Daily loss limit20% of starting capitalPortfolio basis (cash + deployed)
Max single position15% of current capitalPer trade
Max per city per day$50Weather bots only
Max deployment90% of capitalIdle cash floor = 10%
Normal max per trade$20
Aggressive max per trade$30
Min EV threshold0.04Universal floor

Position Sizing Tiers (Universal)

python
if ev >= EV_AGGRESSIVE and price < AGGRESSIVE_THRESHOLD:
    trade_size = min(30.0, balance * 0.10)   # High EV + cheap price
elif ev >= EV_AGGRESSIVE:
    trade_size = min(20.0, balance * 0.08)   # High EV
else:
    trade_size = min(10.0, balance * 0.04)   # Standard EV

6. STANDARDIZED TRADE LOG FORMAT

Every bot writes trades in this exact JSON structure. This is what the scoring script reads.

json
{
  "bot_name": "janitor",
  "team": "pragmatist",
  "coach": "claude",
  "race_id": "calibration_001",
  "starting_capital": 100.00,
  "trades": [
    {
      "timestamp": "2026-03-12T16:30:01.123Z",
      "scan_id": "scan_20260312_163000",
      "market_id": "abc123-def456",
      "question": "Will the highest temperature in Buenos Aires be 27°C on March 13?",
      "category": "weather",
      "side": "yes",
      "price": 0.125,
      "shares": 40.0,
      "cost": 5.00,
      "reasoning": "GFS forecast 28.1°C, bucket prob 0.22, EV 0.095",
      "ev": 0.095,
      "forecast_prob": 0.22,
      "status": "open",
      "resolved_at": null,
      "resolution": null,
      "pnl": null
    }
  ],
  "current_balance": 95.00,
  "deployed_capital": 5.00,
  "portfolio_value": 100.00,
  "total_trades": 1,
  "city_exposure": {"buenos aires": 5.00}
}

7. THE 10 BOTS — IMPLEMENTATION CLASSIFICATION

Pure Python (No LLM needed — zero token cost)

BotTeamStrategyData Source
The JanitorPragmatistYES+NO sum ≤ $0.98 structural arbSimmer order book
The VulturePragmatistPost-resolution bonding ($0.95-$0.99)Simmer resolved markets
The ClockPragmatistGFS latency sniper (post-update windows)Open-Meteo + Simmer
The FarmerBayesianNOAA weather mispricing ≥15%Open-Meteo + Simmer
The SurgeonBayesianYES+NO ≤ 0.98 + multi-outcome arbSimmer order book
The WardenBayesianPost-event bonding + multi-outcomeSimmer resolved markets

LLM-Assisted (Requires Grok 4.1 Fast API calls)

BotTeamStrategyWhy LLM needed
The HistorianPragmatistBase rate exploitationNeeds to analyze historical resolution patterns
The ContrarianPragmatistFavorite-longshot biasNeeds to evaluate probability calibration
The OracleBayesianHierarchical Bayesian + KL divergenceMulti-source synthesis, Brier calibration
The DiverBayesianElite wallet copytradingWallet analysis, Leisen filter evaluation

LLM Call Budget Estimate (Per Scan)

  • Pure Python bots: $0.00 per scan
  • LLM bots: ~$0.01-0.05 per scan (4 bots × ~500 tokens each)
  • 68 scans/day × $0.03 avg = ~$2.04/day
  • $50 budget ÷ $2.04 = ~24 days of operation

8. STRATEGY OVERLAP RESOLUTION

The Owner ruled both teams must have meaningfully different bots. Current overlaps:

PragmatistBayesianOverlapResolution
The JanitorThe SurgeonBoth do YES+NO ≤ 0.98Surgeon adds multi-outcome markets + Monte Carlo validation. Janitor is pure spread detection only.
The VultureThe WardenBoth do post-resolution bondingWarden adds multi-outcome arb + hyperbolic discounting. Vulture is pure time-value capture only.

Both pairs are meaningfully different despite targeting similar market structures. The Pragmatist versions are intentionally simpler and cheaper to run.


9. SCORING SYSTEM

Per Race

  • Gold (1st place by P&L %): 3 points
  • Silver (2nd place): 2 points
  • Any bot with ≥ 1% return: 1 bonus point

Championship (4 races)

  • Highest cumulative points wins
  • Tiebreakers: Total P&L → Sharpe ratio → Profit factor → Win rate

Scoring Script

The neutral scoring script reads all 10 bot log files, calculates final P&L (including resolved positions), and assigns points. Both coaches must approve the script before Phase 0 begins.

python
# Pseudocode for scoring
for bot in all_bots:
    log = load_json(f"logs/{bot}.json")
    final_value = log["current_balance"]
    for trade in log["trades"]:
        if trade["status"] == "resolved" and trade["resolution"] == "won":
            final_value += trade["shares"] - trade["cost"]  # net profit
        # Lost trades already deducted from balance at purchase
    pnl_pct = (final_value - log["starting_capital"]) / log["starting_capital"]
    results[bot] = pnl_pct

10. RACE SCHEDULE

PhaseDurationCapitalModel (All Bots)Purpose
Phase 024 hours$100 paperBoth (test)Calibration — verify logging, execution, scoring
Race 172 hours$100 paperGrok 4.1 FastChampionship
Race 272 hours$100 paperClaude HaikuChampionship
Race 372 hours$100 paperGrok 4.1 FastChampionship
Race 472 hours$100 paperClaude HaikuChampionship

Total duration: 13 days (24h + 4×72h)


11. CRON INTEGRATION

The tournament controller runs alongside the existing weather scanner on the host VPS. Separate cron entries, separate state files, no conflicts.

bash
# Existing weather scanner (keep running independently)
0,5,10,15,20 4 * * * /root/run_scanner.sh
# ... (existing schedule unchanged)

# Tournament controller (add when ready)
*/5 4,10,16,22 * * * /root/run_tournament.sh   # Every 5 min during GFS windows
*/30 0-3,5-9,11-15,17-21,23 * * * /root/run_tournament.sh  # Every 30 min otherwise

12. BUILD ORDER

  1. tournament_controller.py — Core orchestrator (fetch, distribute, validate, log)
  2. Pure Python strategies — Janitor, Vulture, Clock, Farmer, Surgeon, Warden (6 bots)
  3. Scoring script — Neutral, agreed by both coaches
  4. Phase 0 dry run — 24 hours, verify everything works
  5. LLM strategies — Oracle, Diver, Historian, Contrarian (4 bots, requires Grok API)
  6. Championship races — Go live with all 10

Steps 1-4 can be done without burning any Grok API tokens. LLM bots come last because they're the most expensive to test and debug.


13. OPEN QUESTIONS FOR THE OWNER

  1. Should the tournament controller replace the existing weather scanner, or run alongside it? (Recommendation: alongside, then retire scanner after Olympics prove the controller works)
  2. For the Claude Haiku races (2 & 4), do we need a Claude API key? The Owner has a Claude Pro subscription but noted it's not compatible with OpenClaw API requirements. We may need to use Claude via OpenRouter or similar.
  3. What happens to the weather scanner's paper trades when the Olympics start? Do they count, or is the Olympics a fresh system?
  4. Should we implement a Telegram notification system for the tournament? (e.g., scan summary every hour, alert on big trades)

14. RISK ASSESSMENT

RiskProbabilityImpactMitigation
Simmer API downtimeMediumHighCache last known prices, skip scan
Grok API budget exhaustionLowMediumLLM bots auto-degrade to simplified logic
VPS restart loses cronLowHighVerify cron survives reboot with @reboot entry
Bot logic error causes bad tradesMediumMediumSafety floors catch runaway positions
Market data stale/incorrectLowHighCross-validate Simmer vs Open-Meteo before trading
Strategy overlap disputeLowLowAlready resolved — documented in Section 8

This specification is subject to review and approval by both Coach Claude and Coach Grok (Professor Stephen Hawking) before implementation begins.

Content is user-generated and unverified.
    Tournament Controller Architecture Spec for Trading Bots | Claude