Skip to content
 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

30 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Elon Tweet Count Market Backtesting

This repo contains a latency-aware backtesting engine for the Polymarket event:

  • Will Elon Musk post X tweets from Jan 27 to Feb 3, 2026?

The repo now also contains convert strategy research, live convert services, and crypto arbitrage engines. For the active design-doc set, use /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/docs/README.md. Historical probability-websocket docs were moved under /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/docs/archive/20260307/.

Config-Driven Offline/Live Modes

You can now run both offline backtests and live paper simulations from one entrypoint:

  • run_simulation.py
  • Mode is controlled by JSON config: mode = offline | live
  • Data adapters are standalone modules and selected by config:
    • sources.clob.type = offline_csv | live_clob
    • sources.xtracker.type = offline_csv | live_xtracker

Standalone modules:

  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/simulation/clob_data.py
  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/simulation/xtracker_data.py

Example configs:

  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/simulation_offline.example.json
  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/simulation_live.example.json

Run offline:

python3 /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/run_simulation.py \
  --config /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/simulation_offline.example.json

Run live:

python3 /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/run_simulation.py \
  --config /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/simulation_live.example.json

Live Simulation Dashboard

Live mode starts a local dashboard server (default http://127.0.0.1:8787) and updates it every loop.

The live dashboard now shows trigger auditing for each trade lifecycle:

  • Buy trigger condition + buy trigger reason (entry)
  • Sell trigger condition + sell trigger reason (exit)
  • Planned sell conditions for open positions
  • Recent entry signal stream with trigger details

Dashboard files:

  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/simulation/live_dashboard.py
  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/simulation/live_dashboard.html

Live outputs:

  • live_dashboard_state.json
  • live_closed_trades.csv
  • live_signals.csv

Probability WebSocket Publisher (For External Trading Team)

If your team only needs tweet-driven probability updates (and will handle orderbook execution separately), run the standalone websocket publisher:

python3 /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/run_probability_ws.py \
  --config /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/probability_ws.example.json

Config:

  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/probability_ws.example.json
  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/probability_ws.cheap_v0.feb27_mar6.production.json
  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/probability_ws.tp_mid_v1.feb27_mar6.production.json
  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/probability_ws.no_v0.feb27_mar6.production.json
  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/probability_ws.no_v1.feb27_mar6.production.json
  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/elon_tweets_feb27_mar6_2026.mapping.csv

Live data sources in this publisher:

  • Tweet stream source is configurable:
    • tweet_source_mode=xtracker for direct xTracker polling
    • tweet_source_mode=twitter_relay for websocket relay ingest (used in the canonical production config)
    • tweet_source_mode=placeholder_zero for dry placeholder input
  • Tweet count correction uses xtracker reconciliation (enabled in the provided configs):
    • live xTracker polling (probability_ws.xtracker.poll_interval_seconds)
    • periodic full-window xTracker backfill/reconciliation (probability_ws.xtracker.reconciliation.*)
    • startup historical backfill from xTracker (startup_backfill=true)
  • Twitter relay websocket source: probability_ws.twitter_relay (url, key or key_env, reconnect/read timeouts)
  • Polymarket CLOB market websocket (live stream): probability_ws.polymarket
  • Event link metadata (display + runtime update): probability_ws.event_url, probability_ws.event_slug, probability_ws.event_title

Example production command for https://polymarket.com/event/elon-musk-of-tweets-february-27-march-6:

python3 /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/run_probability_ws.py \
  --config /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/configs/probability_ws.cheap_v0.feb27_mar6.production.json

Websocket payload shape (payload_mode=flat):

{
  "market": "0xa5b8958ca1bdd0b7bc09629c49f1c880e6ce214e485066f5a38092a77ba3a400",
  "timestamp": "1772150400000",
  "event_type": "trade_signal",
  "model_version": "cheap_v0",
  "token_id": "<token_id>",
  "possibility": "0.52"
}

Notes:

  • Example production configs use:
    • tweet_source_mode=twitter_relay
    • emit_only_on_twitter_change=true
    • emit_initial_snapshot=true
    • payload_include_meta=false
  • probability_ws.payload_mode supports:
    • batch: one websocket message with signals array
    • flat: one websocket message per trigger signal (entry / exit)
  • model_version is always included at the top level to identify the active production model emitting the signal.
  • probability_ws.possibility_buffer subtracts a safety margin from model YES probabilities before publish, then clamps to [0,1]. Example: model 0.54 with buffer 0.02 publishes 0.52.
  • If you prefer not to store relay keys in JSON, set TWITTER_RELAY_KEY and use probability_ws.twitter_relay.key_env.
  • If payload_include_meta=true, the publisher appends a meta object with diagnostics.
  • Open position detection (Polygon RPC):
    • probability_ws.live_trading_mode=true is required to activate live on-chain checks.
    • probability_ws.open_position_detection.enabled=true turns on ERC-1155 balance polling for emitted entry tokens.
    • Configure RPC + wallet + contract via config or env fallback keys:
      • rpc_url or rpc_url_env (for example POLYGON_RPC_URL)
      • wallet_address or wallet_address_env
      • erc1155_contract_address or erc1155_contract_address_env
    • Runtime state includes per-token fields: entry_fill_confirmed, onchain_balance_raw, onchain_balance_units, and onchain_checked_at_utc.

Publisher outputs:

  • probability_ws_events.ndjson
  • probability_ws_signal_emits.ndjson (persisted trigger signals + metadata for dashboard/API)
  • probability_ws_comparison.ndjson (history snapshots for charts/table drill-down)
  • probability_ws_state.json

Ops dashboard + APIs (enabled in config by probability_ws.dashboard.enabled):

  • Dashboard UI: http://127.0.0.1:8891/
    • Expected-total chart: model vs market live implied expected tweet count.
    • Live table: model probability vs market live probability by range.
    • Click a range row to view historical model probability vs market Yes price.
    • Live paper trading is server-driven (no client-side heuristics):
      • strategy logic mirrors single_position_best_edge (best-edge candidate scoring, edge/time/tp/sl exits, cooldown, allocation controls)
      • default entry trigger mode is Tweet Count Change (entries only when tweet count updates)
      • dashboard renders backend paper_trading state, including trigger/condition/reason fields and live strategy config values
    • Event panel: shows current Polymarket event link and allows runtime URL update.
      • URL updates are validated against the current service window.
      • If event start/end time mismatches configured window, API returns a clear mismatch error.
  • GET /api/state
  • GET /api/event-url
  • POST /api/event-url with JSON body: { "event_url": "https://polymarket.com/event/<slug>" }
  • GET /api/events?limit=50
  • GET /api/signal-emits?limit=200 (persisted emitted trigger signals, model-filtered)
  • GET /api/comparison-history?limit=300
  • GET /api/comparison-latest
  • GET /api/latest-event
  • GET /api/probabilities
  • GET /healthz
  • GET /readyz
  • GET /metrics

Local service management:

chmod +x /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/probability_ws_service.sh
/Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/probability_ws_service.sh smoke
/Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/probability_ws_service.sh start
/Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/probability_ws_service.sh status
/Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/probability_ws_service.sh logs

Deployment wrapper (legacy script name, generic config path):

chmod +x /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/deploy_probability_ws_v1.sh
/Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/deploy_probability_ws_v1.sh check
/Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/deploy_probability_ws_v1.sh start

Deployment reference:

  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/deployment/probability_ws.service.example
  • /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/deployment/LOCAL_PROD_CHECKLIST.md

Remote GCP deploy/update helper:

  • Script: /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/remote_probability_ws_v1.sh
  • Defaults target: shuo_shan@35.223.123.14, remote repo dir /home/shuo_shan/prediction_market_arbitrage
  • First-time deploy (sync + validate + start):
chmod +x /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/remote_probability_ws_v1.sh
bash /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/remote_probability_ws_v1.sh deploy
  • Code update + service restart:
bash /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/remote_probability_ws_v1.sh update
  • Service status / logs:
bash /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/remote_probability_ws_v1.sh status
bash /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/scripts/remote_probability_ws_v1.sh logs

The helper rewrites path-bound config values into a remote config copy (configs/probability_ws.example.remote.json) and defaults dashboard host to 0.0.0.0 for external access on port 8891.

Scripts

  • elon_tweet_backtest.py

    • Supports two filter modes:
      • strict: keep only non-replies + replies to @elonmusk.
      • tracker_proxy: keep all non-replies, then include the highest-view replies until reaching a target count (optionally fetched from XTracker tracking stats).
    • Aligns to UTC and ET event window.
    • Supports service-latency modeling:
      • fixed, uniform, mixture (fast 2-5s with occasional slow spikes), or per-row latency column.
    • Supports XTracker-lag-aware execution constraints:
      • minimum latency advantage, pre-importedAt entry requirement, and importedAt-anchored exits.
    • Builds a Bayesian count model (Gamma-Poisson) for fair range probabilities.
    • Runs event-study metrics around each filtered tweet.
    • Simulates trading with configurable latency, edge threshold, and risk controls.
    • Entry-selection anti-bias controls (latency/legacy):
      • --candidate-score-mode EDGE|ROI|ZSCORE|NET_EDGE (NET_EDGE = edge minus approx round-trip cost)
      • --selection-mode max_edge|random_top_k
      • --selection-top-k, --selection-random-seed
      • --entry-edge-uncertainty-penalty
      • --min-entry-zscore
      • --min-edge-cost-ratio
    • Supports a research replication mode:
      • --strategy-mode single_position_best_edge
      • --expected-model improved|v1|latency_v1
      • optional seasonality/prior controls:
        • --use-hourly-seasonality-et
        • --use-weekday-seasonality-et (default OFF; current estimate is not leakage-free)
        • --prior-mean-rate-per-hour
        • --prior-strength-hours
        • --seasonality-factorized-json (used by latency_v1)
      • single-position controls:
        • --entry-edge-th, --exit-edge-th, --max-hold-seconds, --cooldown-seconds
        • --exit-eval-tick-seconds (evaluate exits on wall-clock ticks between tweets; fixes "tweets stopped so we never time-exited")
        • --flatten-seconds-before-end (optional forced flatten before --window-end-et)
        • --exit-edge-confirm-events (hysteresis edge exits)
        • --cooldown-scope, --cooldown-after-exit-mode
        • --core-top-k, --core-exit-rank-cutoff, --core-exit-edge-th, --core-disable-tp-sl, --core-enable-tp-sl
        • --position-fraction, --min-price, --max-price, --cost-tick
        • --tp-ret, --sl-ret
    • Supports an alternative latency trigger model:
      • --strategy-mode latency --expected-model latency (legacy) or latency_v1 (factorized seasonality)
      • entry: highest-edge bin before xTracker importedAt (with latency-advantage + pre-xtracker gating)
      • exit: sell on xtracker_update using --xtracker-exit-delay-seconds as the exit knob
      • defaults to single-position/high-frequency behavior (max_open_positions=1, max_new_trades_per_event=1)
      • v1 applies safer defaults for late sensitivity when those knobs are unset:
        • entry_edge_th=0.10, exit_edge_th=0.02, exit_edge_confirm_events=2
        • cooldown_scope=per_label, cooldown_after_exit_mode=losing_only
        • core_top_k=2, core_exit_rank_cutoff=3, core_disable_tp_sl=true
      • optional range-token remap from trigger logs:
        • --range-token-overrides-csv <path> (repeatable)
  • sweep_backtest_params.py

    • Runs grid sweeps across strategy parameters.
    • Saves ranked results so you can pick a best-performing configuration.
  • search_high_winrate_strategy.py

    • Focused grid search for robust overall performance.
    • Supports strategy controls:
      • yes-focus-bin-radius (e.g., +/- 2 bins around model mode for BUY_YES)
      • silence-driven BUY_NO entries on higher-count bins
      • long hold windows with stop-loss-pct and take-profit-pct
      • silence exit controls:
        • near-1.0 take profit (silence-take-profit-near-one-price, default 0.98)
        • market scope for silence entries (offset_range, all_above_mode, all_bins)
    • Sorts and exports configs by configurable objective:
      • pnl (raw total pnl)
      • pnl_drawdown (total pnl minus drawdown penalty)

Example Run

python3 /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/elon_tweet_backtest.py \
  --tweets /Users/arthurmeng/Downloads/elonmusk_tweets.csv \
  --trades /Users/arthurmeng/Downloads/elonmusk_market_trades.csv \
  --mapping /Users/arthurmeng/Downloads/elonmust_tweets_markets.csv \
  --output-dir /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/output_elon_backtest \
  --filter-mode tracker_proxy \
  --xtracker-tracking-id a9e9a6cb-a61a-425b-ab38-24d1576409f3 \
  --latency-mode uniform \
  --latency-min-seconds 2 \
  --latency-max-seconds 5

Example: Research Single-Position Repro Mode

python3 /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/elon_tweet_backtest.py \
  --tweets /Users/arthurmeng/Downloads/elonmusk_tweets.csv \
  --trades /Users/arthurmeng/Downloads/elonmusk_market_trades.csv \
  --mapping /Users/arthurmeng/Downloads/elonmust_tweets_markets.csv \
  --range-token-overrides-csv /Users/arthurmeng/Documents/winning_strategy_trade_triggers_conservative.csv \
  --range-token-overrides-csv /Users/arthurmeng/Documents/winning_strategy_trade_triggers_best_final_cash.csv \
  --output-dir /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/output_repro_research_conservative_from_csvs \
  --filter-mode tracker_proxy \
  --target-count 350 \
  --latency-mode fixed \
  --latency-seconds 2 \
  --strategy-mode single_position_best_edge \
  --expected-model v1 \
  --use-hourly-seasonality-et \
  --use-weekday-seasonality-et \
  --prior-mean-rate-per-hour 2.0 \
  --prior-strength-hours 24.0 \
  --entry-edge-th 0.15 \
  --exit-edge-th 0.10 \
  --max-hold-seconds 43200 \
  --cooldown-seconds 21600 \
  --position-fraction 0.25 \
  --tp-ret 0.3 \
  --sl-ret 0.3 \
  --min-price 0.02 \
  --max-price 0.98 \
  --cost-tick 0.001 \
  --total-funding 1000

Example: Latency-Advantage Setup (No Lookahead)

python3 /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/elon_tweet_backtest.py \
  --tweets /Users/arthurmeng/Downloads/xtracker_elonmusk_posts_2026-01-27_2026-02-03.csv \
  --trades /Users/arthurmeng/Downloads/elonmusk_market_trades.csv \
  --mapping /Users/arthurmeng/Downloads/elonmust_tweets_markets.csv \
  --output-dir /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/output_elon_backtest_xtracker_advantage_nolookahead_v2 \
  --latency-mode mixture \
  --latency-min-seconds 2 \
  --latency-max-seconds 5 \
  --latency-slow-seconds 30 \
  --latency-slow-prob 0.08 \
  --expected-xtracker-lag-seconds 160 \
  --min-latency-advantage-seconds 150 \
  --enforce-pre-xtracker-entry \
  --xtracker-entry-buffer-seconds 2 \
  --use-xtracker-exit \
  --xtracker-exit-delay-seconds 45

Example: Latency Model Exit-Knob Sweep

for d in 0 10 20 30 60; do
  python3 /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/elon_tweet_backtest.py \
    --tweets /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/verification/market_tweets_data_184874_20260213/event_184874/tweets_xtracker.csv \
    --trades /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/verification/market_tweets_data_184874_20260213/event_184874/market_trades.csv \
    --mapping /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/verification/market_tweets_data_184874_20260213/event_184874/market_mapping.csv \
    --output-dir /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/verification/latency_model_event184874_exit_sweep/delay_${d} \
    --filter-mode strict \
    --latency-mode fixed \
    --latency-seconds 2 \
    --strategy-mode latency \
    --expected-model latency \
    --entry-edge-th 0.03 \
    --min-latency-advantage-seconds 1 \
    --xtracker-entry-buffer-seconds 1 \
    --xtracker-exit-delay-seconds ${d} \
    --hold-seconds 600 \
    --capital-per-trade 100 \
    --total-funding 1000
done

Outputs

  • tweets_all_labeled.csv
  • tweets_filtered.csv
  • market_bins.csv
  • event_study.csv
  • backtest_trades.csv
  • summary.json
  • parameter_sweep.csv / parameter_sweep.json (from sweep script)

Robust Strategy Search Example

python3 /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/search_high_winrate_strategy.py \
  --tweets /Users/arthurmeng/Downloads/elonmusk_tweets.csv \
  --trades /Users/arthurmeng/Downloads/elonmusk_market_trades.csv \
  --mapping /Users/arthurmeng/Downloads/elonmust_tweets_markets.csv \
  --output-dir /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/output_strategy_search_overall \
  --filter-mode tracker_proxy \
  --target-count 350 \
  --edge-thresholds 0.08,0.12 \
  --hold-seconds-list 86400,172800 \
  --stop-loss-pct-list 0.12,0.2 \
  --take-profit-pct-list 0.2,0.3,0.4 \
  --yes-focus-bin-radius-list none \
  --objective pnl_drawdown \
  --drawdown-penalty 1.0

Canonical Repro Outputs

  • Conservative: /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/output_repro_research_conservative_from_csvs
  • Aggressive: /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/output_repro_research_aggressive_from_csvs
  • Best final cash: /Users/arthurmeng/Documents/smart_money_polymarket/prediciton_market_arbitrage/output_repro_research_best_final_cash_from_csvs

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages