Skip to content

onlycastle/taco

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 

Repository files navigation

Taco

Iran / war / oil prediction agent + Polymarket auto-trading orchestration

Overview

Taco is a pipeline that collects and analyzes geopolitical and market signals to produce positions (BUY_YES / BUY_NO / HOLD) on Polymarket prediction markets and executes orders via a NestJS trading server.

Challenge Taco approach
Manually combining news, satellite, oil, etc. LangGraph agent: collect → aggregate → LLM analyze → position calculation
Manual Polymarket orders 12 traders (trader01–trader12) mapped to markets; batch send via execute-order
Slow reaction to market moves Trigger on reference values (brent, polymarket prob); re-run agent and refresh orders
Stop-loss / take-profit net_pct-based stop/take lines; auto-send opposite position (close) when hit

Architecture

┌─────────────────────────────────────────────────────────────────────────────┐
│                         predict-win-rate (Python)                           │
│  ┌─────────────┐   ┌─────────────┐   ┌─────────────┐   ┌─────────────────┐ │
│  │ News/Sat/   │   │  Aggregate   │   │ LLM         │   │ notify          │ │
│  │ Oil/Geo     │ → │ WarRiskScore│ → │ (GPT-4o)    │ → │ market_predict  │ │
│  │ collect     │   │             │   │ JSON pos’n  │   │ + send_orders   │ │
│  └─────────────┘   └─────────────┘   └─────────────┘   └────────┬────────┘ │
│         ↑                  ↑                  ↑                    │         │
│   RSS, Sentinel,      aggregator.py      analyze_node          webhook.py   │
│   oil_signals,        country_strike    (Claude-style         TRADER_MARKET│
│   market_signals      oil_predictor     prompt)                 _MAP       │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    │ POST /polymarket/execute-order
                                    │ { traderId, recommendation }
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                     polymarket-trader-main (NestJS)                          │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │ PolymarketService.executeOrder(traderId, recommendation)              │  │
│  │ • CONSTANTS.POLYMARKET_MARKET[traderId] → slug, tokenIdYes/No         │  │
│  │ • BUY_YES: close NO, then buy YES at market (FAK)                     │  │
│  │ • BUY_NO:  close YES, then buy NO at market (FAK)                      │  │
│  │ • HOLD:    close all positions                                         │  │
│  └───────────────────────────────────────────────────────────────────────┘  │
│  CLOB Client (Polygon), MongoDB (trade history), Swagger /docs               │
└─────────────────────────────────────────────────────────────────────────────┘

Core concepts

predict-win-rate (agent & signal pipeline)

  • Workspace: All signal collection, analysis, and position calculation runs here.
  • Agent cycle: Each run collects news (RSS), satellite (Sentinel), oil (WTI/COT/EIA), geo/military (ADS-B, vessels, quakes), Polymarket prices in parallel, then aggregate → LLM → per-question positions → trading server and dashboard.
  • Config: Single “Iran / war / oil” setup: config/settings, TRADER_MARKET_MAP.
  • Persistence: Order state lives in polymarket-trader MongoDB and trade-pnl API; predict-win-rate talks via order_url (execute-order) and trade-pnl (net_pct for stop/take).
  • Convoy: One cycle’s 12 market recommendations = market_predictions; each trader gets one recommendation per cycle.

polymarket-trader-main (order execution server)

  • Role: APIs for market data, balance, order execution, trade history, PnL on Polymarket CLOB.
  • Traders (trader01–trader12): Each has its own wallet (EOA or Safe) and one Polymarket market (POLYMARKET_MARKET in constants.ts).
  • execute-order: POST /polymarket/execute-order with { traderId, recommendation } runs BUY_YES/BUY_NO/HOLD logic (FAK market orders) for that trader’s market.
  • trade-pnl: GET /polymarket/trade-pnl/:traderId returns PnL time series; predict-win-rate uses it for net_pct and sends opposite position on stop/take.

Interaction summary

predict-win-rate polymarket-trader-main
order_urlPOST .../execute-order executeOrder(dto) → CLOB order execution
send_orders(market_predictions) Receives per-trader recommendation
TRADER_MARKET_MAP (trader → market_predictions path) POLYMARKET_MARKET (trader → slug, tokenIdYes/No)
Fetches net_pct from trade-pnl URL → sends opposite position on stop/take Serves trade-pnl API

How the model works (agent pipeline)

The agent is a LangGraph state graph; one cycle runs in this order.

1. Collect (parallel)

  • News: RSS multi-source → topic and severity labels.
  • Satellite: Sentinel Hub → Iran nuclear/military site change scores.
  • Oil: WTI, COT, EIA, OPEC schedule, etc.
  • Geo/military: ADS-B/OpenSky military flights, Hormuz vessels, quakes, GDELT.
  • Market: Yahoo Finance (brent, gold, VIX), Polymarket Iran war probability (polymarket_prob).

2. Aggregate

  • WarEscalationScore = 0.35×military + 0.25×naval + 0.20×satellite + 0.20×news, with momentum adjustment.
  • Country strike probabilities (country_strike): news and geo bonuses.
  • Diplomatic score: used for ceasefire/negotiation-related positions.

3. Analyze

  • LLM (GPT-4o) gets aggregated summary, headlines, geo, oil; returns fixed JSON:
    • war_probability, trend, hotspots, recommendation (BUY_YES/BUY_NO/HOLD)
    • Per-question market_predictions (us_enter_iran_march14, us_enter_iran_march31, …).

4. Position calculation (inside notify)

  • build_all_market_predictions: Combines LLM output, country_strike, oil targets (WTI $100/$110/$120/$150, $80 LOW), ceasefire question → position / probability / confidence / reasoning for every Polymarket question.
  • EV filter (weatherbot-style): When polymarket_prob (market YES price) is present, applies min edge and entry thresholds; otherwise flips to HOLD.

5. Send (notify)

  • send_orders(market_predictions): For trader01–trader12, reads the corresponding market_predictions entry from TRADER_MARKET_MAP and POSTs to order_url (execute-order) only when the position changed.
  • Stop/take: Fetches each trader’s net_pct from trade-pnl; when past the configured lines, sends opposite position once (close) and applies cooldown.
  • Dashboard: If dashboard_url is set, POSTs the same payload as signal.
  • Trading server: If trading_server_url is set, POSTs payload only when overall recommendation or probability meaningfully changed (avoids HOLD spam).

Schedule and triggers

  • Scheduled run: Every SCHEDULER_INTERVAL_MINUTES (default 1; recommend 15 for production), one agent cycle → 12 recommendations → execute-order.
  • Reference trigger: Every RECOMMENDATION_TRIGGER_INTERVAL_MINUTES (default 1), only brent and polymarket_prob are fetched. If change vs previous exceeds RECOMMENDATION_TRIGGER_CHANGE_PCT (default 2%), run the agent again and send new recommendations to execute-order. Cooldown after trigger prevents repeated runs.

See predict-win-rate/docs/agent-schedule-and-trigger.md for details.

Trader–market mapping

traderId predict-win-rate (TRADER_MARKET_MAP) polymarket-trader (POLYMARKET_MARKET slug)
trader01 us_forces_enter_iran_march31 us-forces-enter-iran-by-march-31
trader02 us_forces_enter_iran_dec31 us-forces-enter-iran-by-december-31-...
trader03 us_iran_ceasefire_march31 us-x-iran-ceasefire-by-march-31
trader04 country_strike_by_march31 → uae will-uae-strike-iran-by-march-31
trader05 country_strike_by_march31 → saudi_arabia will-saudi-arabia-strike-iran-by-march-31
trader06 another_country_strike_iran_march31 will-another-country-strike-iran-by-march-31-833
trader07–10 wti_reach_100/110/120/150_march31 Will Crude Oil (CL) hit (HIGH) $100/$110/$120/$150 by end of March
trader11 wti_low_80_march31 Will Crude Oil (CL) hit (LOW) $80 by end of March
trader12 us_invade_iran_march31 will-the-us-invade-iran-by-march-31

When changing mapping, update both predict-win-rate signals/market_predictions.py (TRADER_MARKET_MAP) and polymarket-trader-main src/common/config/constants.ts (POLYMARKET_MARKET).

Install and run

Prerequisites

  • predict-win-rate: Python 3.10+, OpenAI API key, Sentinel Hub credentials; optional: RapidAPI, OpenSky, etc.
  • polymarket-trader-main: Node 18+, MongoDB, Polymarket Builder API and wallet keys, Polygon RPC.

predict-win-rate

cd predict-win-rate
pip install -r requirements.txt   # or install from pyproject.toml
cp .env.example .env              # set OpenAI, Sentinel, ORDER_URL, etc.
python main.py                    # start scheduler and triggers
  • ORDER_URL: Full execute-order URL of polymarket-trader (e.g. http://localhost:8080/polymarket/execute-order).
  • TRADING_SERVER_URL: Optional server for aggregate signals.
  • DASHBOARD_URL: Optional dashboard signal URL.

polymarket-trader-main

cd polymarket-trader-main
npm install
cp .env.example .env              # MONGODB_*, POLYMARKET_*, POLYGON_RPC, TRADER01_KEY, etc.
npm run start:dev                # default port 8080
  • API docs: After starting, open http://localhost:8080/docs (Swagger).
  • execute-order: POST /polymarket/execute-order with body { "traderId": "trader01", "recommendation": "BUY_YES" }.

Run order

  1. Start polymarket-trader-main so execute-order and trade-pnl are available.
  2. Set ORDER_URL in predict-win-rate .env, then run python main.py.

Main settings (predict-win-rate)

Setting Default Description
SCHEDULER_INTERVAL_MINUTES 1 Agent run interval (minutes). Recommend 15 for production.
RECOMMENDATION_TRIGGER_INTERVAL_MINUTES 1 Reference (brent, polymarket) check interval (minutes). 0 = disabled.
RECOMMENDATION_TRIGGER_CHANGE_PCT 2.0 Trigger when brent (%) or polymarket (%p) change exceeds this.
ORDER_URL (none) Full execute-order URL.
ORDER_ENABLED true Set false to disable order sending.
siege_stop_loss_pct / siege_take_profit_pct 10 Per-trader net_pct stop/take (%); then send opposite position.
confidence_threshold 0.40 BUY_YES/BUY_NO only when confidence ≥ this; else HOLD.
polymarket_min_edge, polymarket_entry_max_yes, etc. (see settings) EV filter and entry thresholds.

Troubleshooting

  • Orders not sent: Check ORDER_URL, that polymarket-trader is running, and ORDER_ENABLED=true. Look for “주문 전송” / “주문 전송 실패” in logs.
  • Trader–market mismatch: Ensure TRADER_MARKET_MAP and POLYMARKET_MARKET slugs/questions refer to the same markets.
  • Stop/take not firing: Verify trade-pnl URL is derived from order_url (.../execute-order.../trade-pnl) and that the endpoint returns 200 with PnL data.
  • Agent runs but orders skipped: send_orders only sends when the recommendation changed for that trader. Repeated HOLD is skipped; log shows “주문 스킵 (변화 없음)”.

License

See each subproject (polymarket-trader-main, predict-win-rate) for its license.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors