OrganizedMarket
Hard price data from TastyTrade. Prediction market odds from Polymarket and Kalshi. Sentiment from Twitter/X and financial news — all wired into a correlation engine running inside ClawBox's isolated Linux VM, orchestrated through OpenClaw. Surfaces arbitrage-adjacent signals across venues in real time.
The Core Idea
Prediction markets price real-world outcomes. Financial markets price risk. When they diverge — a Polymarket contract implying a Fed cut with probability X while /ZQ options price something different — there's signal. OrganizedMarket finds that gap continuously.
Explore the Guide
System Architecture
OrganizedMarket runs entirely inside ClawBox — a Tauri-wrapped macOS app that spins up an isolated Ubuntu 24.04 VM via Lima. OpenClaw runs inside that VM as the agent gateway. Your Mac stays clean; only explicitly uploaded files are shared with the VM.
ORGANIZEDMARKET — SYSTEM DIAGRAM
┌──────────────────────────────────────────────────────────────────┐
│ CLAWBOX (Tauri + React) │
│ Native macOS UI · one-click VM lifecycle │
├──────────────────────────────────────────────────────────────────┤
│ LIMA VM MANAGER │
│ Ubuntu 24.04 · isolated from host Mac │
├──────────────────────────────────────────────────────────────────┤
│ OPENCLAW GATEWAY :18789 │
│ │
│ ┌────────────────┐ ┌────────────────┐ ┌──────────────────┐ │
│ │ agent-signal │ │ agent-poly │ │ agent-kalshi │ │
│ │ TastyTrade API │ │ Polymarket CLOB│ │ Kalshi REST/WS │ │
│ │ DXLink stream │ │ yes/no markets │ │ event contracts │ │
│ │ options flow │ │ order books │ │ resolution data │ │
│ └───────┬────────┘ └───────┬────────┘ └────────┬─────────┘ │
│ │ │ │ │
│ └───────────────────┼─────────────────────┘ │
│ │ unified market state │
│ ┌───────────────────────────▼──────────────────────────────┐ │
│ │ agent-correlator │ │
│ │ cross-venue divergence · implied probability gap │ │
│ │ pearson correlation · time-lagged signal scoring │ │
│ └───────────────────────────┬──────────────────────────────┘ │
│ │ + sentiment stream │
│ ┌───────────────────────────┴──────────────────────────────┐ │
│ │ agent-sentiment │ │
│ │ Twitter/X v2 · financial news NLP · Claude Sonnet │ │
│ │ entity extraction · score: -1.0 → +1.0 │ │
│ └───────────────────────────┬──────────────────────────────┘ │
│ │ signal + context │
│ ┌───────────────────────────▼──────────────────────────────┐ │
│ │ agent-dispatcher │ │
│ │ Slack · Discord · webhook · ClawBox dashboard │ │
│ │ confidence gate · human review queue │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────────┘
│ │
▼ ▼
claws-mac-mini :11434 CF Pages dashboard
Claude Sonnet via OpenClaw organizedmarket.organizedai.vip
local inference (optional)
Why ClawBox as the Container
ClawBox's Lima-based VM isolation is ideal for a financial intelligence agent: API credentials never touch your host Mac, the VM can be snapshotted before experiments, and the OpenClaw gateway handles multi-agent orchestration without needing to wire up a separate orchestration layer. Everything is already there.
| Component | Technology | Role |
|---|---|---|
ClawBox GUI |
Tauri + React | Native macOS wrapper, one-click VM start/stop |
Lima VM |
Ubuntu 24.04 ARM | Isolated execution environment, no host filesystem access |
OpenClaw |
Node.js + Python | Agent gateway :18789, multi-agent orchestration, tool registry |
agent-signal |
Python + DXLink WS | TastyTrade streaming quotes, options flow, greeks ingestion |
agent-poly |
Python + REST/WS | Polymarket CLOB order book, market odds polling |
agent-kalshi |
Python + REST | Kalshi event contract prices, resolution tracking |
agent-sentiment |
Python + Claude Sonnet | Twitter/X entity scoring, financial news NLP |
agent-correlator |
Python + NumPy | Cross-venue divergence, Pearson + lag correlation matrix |
agent-dispatcher |
Python + webhooks | Confidence-gated alerts, Slack/Discord/ClawBox UI output |
ClawBox Setup
ClawBox ships as a native macOS app. It manages the entire Lima VM lifecycle — no CLI required.
Once installed, OpenClaw runs inside the Ubuntu 24.04 VM and exposes a gateway at
localhost:18789 through a port-forwarded bridge.
1. Install ClawBox
# Option A — Direct DMG download (recommended) # Visit: https://github.com/coderkk1992/clawbox/releases # Download ClawBox.dmg → drag to Applications # Option B — Build from source (for contributors) git clone https://github.com/coderkk1992/clawbox.git cd clawbox npm install npm run tauri dev # Homebrew dependency (required by Lima VM manager) brew install lima qemu
2. Launch VM & Install OpenClaw
# 1. Open ClawBox.app from Applications # 2. Click "Start VM" — provisions Ubuntu 24.04 via Lima (~2 min first run) # 3. ClawBox opens an embedded terminal into the VM # 4. Inside the VM terminal, install OpenClaw: curl -fsSL https://openclaw.ai/install.sh | bash # Verify OpenClaw is running openclaw status # → OpenClaw gateway running on :18789 # → 0 agents registered
3. Clone OrganizedMarket Into the VM
# Inside ClawBox VM terminal: git clone https://github.com/Organized-AI/organizedmarket.git cd organizedmarket # Install Python dependencies pip install -r requirements.txt # Install Node dependencies (for OpenClaw plugin registration) npm install
4. Wire Agent Config
# Copy and populate environment cp .env.example .env # .env contents — replace all placeholder values: TASTYTRADE_USERNAME=your_tastytrade_username TASTYTRADE_PASSWORD=your_tastytrade_password TASTYTRADE_ACCOUNT_NUMBER=your_account_number POLYMARKET_API_KEY=your_polymarket_api_key POLYMARKET_SECRET=your_polymarket_secret POLYMARKET_PASSPHRASE=your_polymarket_passphrase KALSHI_API_KEY_ID=your_kalshi_key_id KALSHI_PRIVATE_KEY_PATH=./keys/kalshi_private.pem TWITTER_BEARER_TOKEN=your_twitter_bearer_token NEWSAPI_KEY=your_newsapi_key # Claude routes through OpenClaw OAuth — no ANTHROPIC_API_KEY needed OPENCLAW_URL=http://localhost:18789 OPENCLAW_CODEX_TOKEN=codex_... # generated by: openclaw auth token SLACK_WEBHOOK_URL=https://hooks.slack.com/services/... # optional DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/... # optional
5. Register Agents with OpenClaw
# Register all 6 agents with the OpenClaw gateway python scripts/register_agents.py # Verify registration openclaw agents list # → agent-signal [registered] # → agent-poly [registered] # → agent-kalshi [registered] # → agent-sentiment [registered] # → agent-correlator [registered] # → agent-dispatcher [registered] # Start the full stack openclaw start --config openclaw.config.json # → All 6 agents initializing... # → TastyTrade session established # → Polymarket WebSocket connected # → Kalshi REST polling active # → Sentiment stream online # → Correlator ready # → Dispatcher armed
ClawBox Architecture Internals
┌──────────────────────────────────────────┐
│ ClawBox (Tauri + React) │
│ Native macOS UI │
├──────────────────────────────────────────┤
│ Lima VM Manager │
├──────────────────────────────────────────┤
│ Ubuntu 24.04 VM │
│ ┌──────────────────────────────────┐ │
│ │ OpenClaw Agent │ │
│ │ Browser · Terminal · File Sys │ │
│ └──────────────────────────────────┘ │
└──────────────────────────────────────────┘
▲
│ Your files stay on your Mac.
│ You share only what you upload.
└──────────────────────────────────
Data Sources
Three primary data sources feed OrganizedMarket: TastyTrade for live financial market data and options flow, Polymarket for binary prediction market odds, and Kalshi for regulated event contracts. Together they form a complete picture of market-implied probabilities versus hard derivative pricing.
TastyTrade API — Financial Market Data
TastyTrade provides a full open REST API with a WebSocket DXLink streamer for real-time quotes. The SDK supports equities, ETFs, options, futures, and futures options. OrganizedMarket uses it primarily for options chain data, implied volatility surfaces, and streaming quotes on macro-sensitive instruments (SPY, QQQ, /ES, /ZQ, TLT).
# agent-signal/tastytrade_client.py
import requests
import websockets
import json
from dataclasses import dataclass
BASE_URL = "https://api.tastytrade.com" # Production
# BASE_URL = "https://api.cert.tastyworks.com" # Sandbox
class TastyTradeClient:
def __init__(self, username: str, password: str):
self.session_token = None
self.dxlink_token = None
self._authenticate(username, password)
def _authenticate(self, username: str, password: str):
"""Create a session token. Valid for 24 hours."""
resp = requests.post(f"{BASE_URL}/sessions", json={
"login": username,
"password": password,
"remember-me": True
})
data = resp.json()["data"]
self.session_token = data["session-token"]
self.headers = {
"Authorization": self.session_token,
"Content-Type": "application/json"
}
def get_dxlink_token(self) -> str:
"""Get streaming token for DXLink WebSocket."""
resp = requests.get(
f"{BASE_URL}/api-quote-tokens",
headers=self.headers
)
token_data = resp.json()["data"]
self.dxlink_token = token_data["token"]
self.dxlink_streamer_url = token_data["streamer-url"]
return self.dxlink_token
def get_option_chain(self, symbol: str) -> dict:
"""Full option chain for correlation with prediction markets."""
resp = requests.get(
f"{BASE_URL}/option-chains/{symbol}/nested",
headers=self.headers
)
return resp.json()["data"]
def get_market_metrics(self, symbols: list[str]) -> dict:
"""IV rank, IV percentile, beta-weighted delta for a list of symbols."""
params = {"symbols[]": symbols}
resp = requests.get(
f"{BASE_URL}/market-metrics",
headers=self.headers,
params=params
)
return resp.json()["data"]["items"]
# DXLink WebSocket streaming — real-time quotes
async def stream_quotes(client: TastyTradeClient, symbols: list[str], callback):
token = client.get_dxlink_token()
uri = f"wss://tasty-openapi-ws.dxfeed.com/realtime?token={token}"
async with websockets.connect(uri) as ws:
# Authorize
await ws.send(json.dumps({
"type": "SETUP", "channel": 0,
"version": "0.1", "minVersion": "0.1"
}))
# Subscribe to quote events
await ws.send(json.dumps({
"type": "SUBSCRIBE", "channel": 1,
"add": [{"type": "Quote", "symbol": s} for s in symbols]
}))
async for msg in ws:
data = json.loads(msg)
if data.get("type") == "FEED_DATA":
await callback(data["data"]) # → agent-correlator
Polymarket — Prediction Market Odds
Polymarket uses a Central Limit Order Book (CLOB) model. OrganizedMarket pulls live order books and trades for politically and economically sensitive markets — Fed decisions, election outcomes, GDP prints, CPI surprises — and feeds the implied probabilities directly into the correlation engine for comparison against options-implied probabilities.
# agent-poly/polymarket_client.py
from py_clob_client.client import ClobClient
from py_clob_client.clob_types import ApiCreds
class PolymarketClient:
def __init__(self, api_key: str, secret: str, passphrase: str):
self.client = ClobClient(
host="https://clob.polymarket.com",
chain_id=137, # Polygon
creds=ApiCreds(
api_key=api_key,
api_secret=secret,
api_passphrase=passphrase
)
)
def get_market(self, condition_id: str) -> dict:
"""Get market metadata including question, resolution criteria."""
return self.client.get_market(condition_id)
def get_order_book(self, token_id: str) -> dict:
"""Live order book — bids/asks give implied yes probability."""
return self.client.get_order_book(token_id)
def search_markets(self, query: str, active_only: bool = True) -> list:
"""
Find prediction markets matching financial query terms.
e.g. query="Federal Reserve rate cut" → relevant contracts
"""
markets = self.client.get_markets()
results = []
for m in markets["data"]:
if query.lower() in m["question"].lower():
if not active_only or m["active"]:
results.append({
"condition_id": m["condition_id"],
"question": m["question"],
"yes_price": m.get("tokens", [{}])[0].get("price"),
"volume": m.get("volume"),
"end_date": m.get("end_date_iso")
})
return results
def get_implied_probability(self, condition_id: str) -> float:
"""
Mid-market yes price = implied probability.
Compare this to options-implied probability from TastyTrade.
"""
book = self.get_order_book(condition_id)
best_bid = float(book["bids"][0]["price"]) if book["bids"] else 0
best_ask = float(book["asks"][0]["price"]) if book["asks"] else 1
return (best_bid + best_ask) / 2
Kalshi — Regulated Event Contracts
Kalshi is CFTC-regulated, making it the cleanest source of prediction market data for US financial events. OrganizedMarket focuses on Kalshi's Fed rate, CPI, GDP, and jobs report markets — these map directly to instruments TastyTrade can stream.
# agent-kalshi/kalshi_client.py
import requests
import time
import jwt
from cryptography.hazmat.primitives import serialization
KALSHI_BASE = "https://trading-api.kalshi.com/trade-api/v2" # Production
# KALSHI_BASE = "https://demo-api.kalshi.co/trade-api/v2" # Demo
class KalshiClient:
def __init__(self, key_id: str, private_key_path: str):
self.key_id = key_id
with open(private_key_path, "rb") as f:
self.private_key = serialization.load_pem_private_key(f.read(), password=None)
def _headers(self, method: str, path: str) -> dict:
"""HMAC-signed headers required for all Kalshi API calls."""
ts = str(int(time.time() * 1000))
message = ts + method.upper() + path
sig = jwt.encode({"msg": message}, self.private_key, algorithm="RS256")
return {
"KALSHI-ACCESS-KEY": self.key_id,
"KALSHI-ACCESS-SIGNATURE": sig,
"KALSHI-ACCESS-TIMESTAMP": ts,
"Content-Type": "application/json"
}
def get_markets(self, category: str = "financials") -> list:
"""
Fetch open markets. category options:
financials · economic-indicators · monetary-policy
"""
path = f"/markets?category={category}&status=open"
resp = requests.get(
f"{KALSHI_BASE}{path}",
headers=self._headers("GET", path)
)
return resp.json()["markets"]
def get_market_orderbook(self, ticker: str) -> dict:
"""Order book for a specific market ticker."""
path = f"/markets/{ticker}/orderbook"
resp = requests.get(
f"{KALSHI_BASE}{path}",
headers=self._headers("GET", path)
)
return resp.json()
def get_yes_price(self, ticker: str) -> float:
"""Yes price (implied probability) for event resolution."""
book = self.get_market_orderbook(ticker)
yes_bids = book.get("orderbook", {}).get("yes", [])
return yes_bids[0][0] / 100 if yes_bids else None
Source Comparison
| Feature | TastyTrade | Polymarket | Kalshi |
|---|---|---|---|
| Data type | Options, equities, futures | Binary outcome markets | Regulated event contracts |
| Streaming | Yes — DXLink WS | Yes — CLOB WS | Polling (REST) |
| Regulation | FINRA/SEC | CFTC (prediction mkt) | CFTC regulated ✓ |
| Auth | Session token (24hr) | API key + L2 signing | RSA private key JWT |
| Free tier | Yes (account required) | Yes (read-only) | Yes (demo env) |
| Correlation use | Ground truth pricing | Implied probability | Regulated prob. signal |
The 6-Agent Pipeline
Each agent runs as an independent OpenClaw sub-process inside the ClawBox VM. They communicate via OpenClaw's internal message bus. The correlator consumes outputs from all data agents simultaneously and scores divergence signals. The dispatcher is the only agent that writes to external systems.
ORGANIZEDMARKET — AGENT DATA FLOW
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ agent-signal │ │ agent-poly │ │ agent-kalshi │
│ TastyTrade │ │ Polymarket │ │ Kalshi │
│ DXLink/REST │ │ CLOB API │ │ REST + JWT │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ quote_update │ odds_update │ contract_update
└─────────────────┼──────────────────┘
│
┌──────▼────────────────────────┐
│ agent-correlator │
│ cross-venue divergence calc │
│ Pearson · lag · Z-score │
└──────┬────────────────────────┘
│
┌────────────┴───────────────┐
│ agent-sentiment │
│ Twitter/X · news · Claude │
│ score: -1.0 → +1.0 │
└────────────┬───────────────┘
│ signal + context + confidence
┌──────▼────────────────────────┐
│ agent-dispatcher │
│ confidence gate (>0.75 alert) │
│ Slack · Discord · ClawBox UI │
└───────────────────────────────┘
Agent Definitions
Message Bus Schema
# Internal message format — all agents publish/subscribe this schema
{
"agent": "agent-signal",
"timestamp": "2025-04-16T14:30:00Z",
"type": "quote_update", # quote_update | odds_update | sentiment | signal
"payload": {
"symbol": "SPY",
"price": 528.42,
"iv_rank": 0.34, # 0.0–1.0 — low IV = market complacent
"options_implied_prob": 0.72, # from ATM options pricing for event date
"delta_1h": -0.015 # price delta last hour
}
}
# Correlator output to dispatcher
{
"agent": "agent-correlator",
"timestamp": "2025-04-16T14:31:05Z",
"type": "signal",
"payload": {
"signal_id": "SIG-20250416-001",
"tier": "HIGH",
"confidence": 0.81,
"divergence": {
"tastytrade_implied_prob": 0.72, # SPY options say 72% chance
"polymarket_yes_price": 0.54, # Polymarket says 54%
"kalshi_yes_price": 0.58, # Kalshi says 58%
"gap": 0.16 # 16pt divergence → signal
},
"sentiment_overlay": {
"entity": "Federal Reserve",
"score": -0.42, # bearish sentiment
"velocity": "rising_negative"
},
"summary": "Options market implies significantly higher probability of Fed hold than prediction markets. Bearish Twitter/X sentiment accelerating. Potential arb between /ZQ options and Kalshi FOMC market.",
"instruments": ["KXFED-25APR", "/ZQ", "TLT"],
"lag_correlation": 0.68 # sentiment leads price by ~45min
}
}
Intelligence Layer
The intelligence layer sits inside agent-correlator and agent-sentiment. It translates raw price feeds and social signals into structured, scored intelligence that a trader can act on.
Correlation Engine
The correlator maintains a rolling state of implied probabilities across all three venues. It computes Pearson correlation between TastyTrade options-implied probabilities and prediction market yes prices, then Z-scores the current divergence against its 30-day history.
# agent-correlator/engine.py
import numpy as np
from collections import deque
from dataclasses import dataclass, field
@dataclass
class MarketState:
tastytrade_prob: float # from options pricing
poly_yes: float # Polymarket mid-market
kalshi_yes: float # Kalshi best bid
sentiment_score: float # -1.0 to +1.0
timestamp: str
class CorrelationEngine:
def __init__(self, window_days: int = 30):
self.history: deque[MarketState] = deque(maxlen=window_days * 480) # ~5min bars
self.lag_window = 12 # 1 hour at 5min resolution
def add_state(self, state: MarketState):
self.history.append(state)
def compute_divergence(self, state: MarketState) -> dict:
"""
Primary signal: gap between options-implied probability
and prediction market consensus.
"""
tt_prob = state.tastytrade_prob
pm_consensus = (state.poly_yes + state.kalshi_yes) / 2
gap = tt_prob - pm_consensus
# Z-score vs historical gaps
if len(self.history) > 60:
hist_gaps = [s.tastytrade_prob - (s.poly_yes + s.kalshi_yes) / 2
for s in self.history]
z_score = (gap - np.mean(hist_gaps)) / (np.std(hist_gaps) + 1e-9)
else:
z_score = 0.0
return {
"gap": round(gap, 4),
"z_score": round(z_score, 3),
"tastytrade_implied": round(tt_prob, 4),
"pm_consensus": round(pm_consensus, 4),
"signal_strength": abs(z_score) / 3.0 # normalize 3σ = 1.0
}
def compute_sentiment_lag(self) -> float:
"""
Does sentiment precede price movement?
Returns correlation coefficient at optimal lag.
"""
if len(self.history) < self.lag_window * 2:
return 0.0
states = list(self.history)
sentiments = [s.sentiment_score for s in states]
prices = [s.tastytrade_prob for s in states]
# Test lag correlations: 0 to lag_window
best_r, best_lag = 0.0, 0
for lag in range(1, self.lag_window):
r = np.corrcoef(sentiments[:-lag], prices[lag:])[0, 1]
if abs(r) > abs(best_r):
best_r, best_lag = r, lag
return best_r # +/- indicates direction, magnitude indicates predictive power
def score_signal(self, divergence: dict, sentiment: dict) -> tuple[float, str]:
"""
Confidence score 0.0–1.0 + tier classification.
HIGH (>0.75): fire alert immediately
MED (0.45–0.75): queue for confirmation window
LOW (<0.45): log to flywheel only
"""
z = abs(divergence["z_score"])
gap = abs(divergence["gap"])
sent_magnitude = abs(sentiment.get("score", 0))
sent_alignment = 1.0 if (divergence["gap"] * sentiment.get("score", 0)) < 0 else 0.5
# Weighted confidence formula
confidence = (
min(z / 3.0, 1.0) * 0.45 + # statistical significance
min(gap / 0.20, 1.0) * 0.30 + # raw gap size (20pt = max)
sent_magnitude * sent_alignment * 0.25 # sentiment alignment
)
tier = "HIGH" if confidence > 0.75 else "MED" if confidence > 0.45 else "LOW"
return round(confidence, 3), tier
Twitter/X Sentiment Pipeline
The Twitter/X v2 filtered stream listens for tweets containing financial entities and watchlist ticker symbols. Claude Sonnet scores sentiment per entity and calculates velocity — the rate at which sentiment is shifting, which is often more predictive than absolute level.
# agent-sentiment/twitter_stream.py
import tweepy
import asyncio
from openclaw_client import claude_via_openclaw
STREAM_RULES = [
# Macro events
{"value": "Federal Reserve OR FOMC OR Jerome Powell -is:retweet lang:en"},
{"value": "CPI OR inflation OR \"jobs report\" -is:retweet lang:en"},
{"value": "recession OR \"rate cut\" OR \"rate hike\" -is:retweet lang:en"},
# Instruments (expand for your watchlist)
{"value": "SPY OR QQQ OR \"S&P 500\" -is:retweet lang:en"},
{"value": "Polymarket OR Kalshi OR \"prediction market\" -is:retweet lang:en"},
]
SENTIMENT_PROMPT = """
Analyze this tweet for financial market sentiment.
Tweet: {tweet_text}
Return JSON only:
{{
"entities": ["list of financial entities mentioned"],
"primary_entity": "main subject (Fed, SPY, inflation, etc.)",
"sentiment": -1.0 to 1.0 (-1=very bearish, 0=neutral, +1=very bullish),
"event_signal": true/false (does this reference a specific upcoming event?),
"event_date": "YYYY-MM-DD or null",
"confidence": 0.0 to 1.0
}}
No commentary. JSON only.
"""
class SentimentStream(tweepy.StreamingClient):
def __init__(self, bearer_token: str, message_bus, openclaw_url: str):
super().__init__(bearer_token)
self.bus = message_bus
self.openclaw_url = openclaw_url
self.entity_buffer = {} # accumulate before velocity calc
def on_tweet(self, tweet):
asyncio.create_task(self._process(tweet.text))
async def _process(self, text: str):
response = await claude_via_openclaw(
self.openclaw_url,
prompt=SENTIMENT_PROMPT.format(tweet_text=text[:500]),
max_tokens=200
)
try:
sentiment_data = json.loads(response)
entity = sentiment_data["primary_entity"]
score = float(sentiment_data["sentiment"])
# Update entity buffer and calculate velocity
if entity not in self.entity_buffer:
self.entity_buffer[entity] = deque(maxlen=20)
self.entity_buffer[entity].append(score)
# Velocity = delta in rolling mean over last 5 vs previous 5
buf = list(self.entity_buffer[entity])
velocity = np.mean(buf[-5:]) - np.mean(buf[-10:-5]) if len(buf) >= 10 else 0
await self.bus.publish({
"type": "sentiment",
"entity": entity,
"sentiment_score": score,
"velocity": round(velocity, 4),
"event_signal": sentiment_data.get("event_signal", False),
"event_date": sentiment_data.get("event_date"),
})
except (json.JSONDecodeError, KeyError):
pass # malformed response — skip
Signal Summary Generation
Before dispatching any alert, Claude generates a plain-English summary that includes data provenance, confidence rationale, and relevant context. The goal is a summary that could be handed to a trader who has no context and they immediately understand the opportunity.
SIGNAL_SUMMARY_PROMPT = """
You are a market intelligence analyst. Summarize this trading signal for a professional trader.
Signal data:
- TastyTrade options-implied probability: {tt_prob:.0%}
- Polymarket yes price: {poly_yes:.0%}
- Kalshi yes price: {kalshi_yes:.0%}
- Divergence gap: {gap:.1%} ({z_score:.1f} standard deviations from 30-day mean)
- Sentiment on {entity}: {sentiment_score:+.2f} (velocity: {velocity:+.3f})
- Instruments: {instruments}
- Confidence score: {confidence:.0%} ({tier})
Write 3-4 sentences:
1. What the signal is and where the divergence lies
2. What the sentiment context suggests
3. What instruments are relevant and how
4. What a trader should do to investigate further (NO trading advice — information only)
Be direct. Use financial terminology. No hedging language.
"""
Intelligence Data Flow
SENTIMENT + PRICE → SIGNAL LIFECYCLE
Twitter/X stream ──┐
NewsAPI polling ───┼──→ agent-sentiment ──→ score (-1 to +1)
│ (Claude NLP) velocity calc
│
TastyTrade DXLink ─┼──→ options-implied prob
│ IV rank + delta
│
Polymarket CLOB ───┼──→ yes price (mid)
│ order flow delta
│
Kalshi REST ───────┘──→ yes price
resolution timeline
All streams ──→ agent-correlator
· Pearson correlation matrix
· Z-score vs 30-day history
· Lag analysis (sentiment → price)
· Confidence + tier scoring
│
HIGH (>0.75) ───→ immediate alert + Claude summary
MED (0.45–0.75) → 15-min confirmation window
LOW (<0.45) ────→ flywheel log only
Stack & Conventions
Python-first, OpenClaw-native agent architecture. All agents are independent Python processes
registered with the OpenClaw gateway. Shared types and utilities live in
packages/. Same monorepo conventions as the broader Organized AI codebase.
Runtime
Key Dependencies
| Package | Purpose |
|---|---|
tastytrade | Official Python SDK — sessions, option chains, DXLink streamer |
py-clob-client | Polymarket CLOB API — order books, markets, trades |
tweepy | Twitter/X v2 filtered stream client |
websockets | DXLink WebSocket streaming for TastyTrade real-time quotes |
numpy | Pearson correlation, rolling statistics, Z-score calculation |
cryptography / pyjwt | Kalshi RSA signature auth |
newsapi-python | Financial news sources — Reuters, Bloomberg, WSJ aggregation |
sqlalchemy | Signal log persistence — all signals stored for flywheel replay |
pydantic | Message bus schema validation across all agents |
anthropic | Claude Sonnet — sentiment NLP + signal summary (via OpenClaw OAuth) |
Monorepo Layout
organizedmarket/
agents/
agent-signal/ # TastyTrade ingestion
tastytrade_client.py
dxlink_stream.py
options_analyzer.py
agent-poly/ # Polymarket CLOB
polymarket_client.py
order_book_tracker.py
agent-kalshi/ # Kalshi event markets
kalshi_client.py
contract_tracker.py
agent-sentiment/ # Twitter/X + news NLP
twitter_stream.py
news_poller.py
sentiment_scorer.py
agent-correlator/ # Cross-venue intelligence
engine.py
lag_analyzer.py
signal_scorer.py
agent-dispatcher/ # Alert routing
dispatcher.py
formatters.py
packages/
message_bus/ # Internal pub/sub (asyncio queues)
schemas/ # Pydantic models for all message types
openclaw_client/ # OpenClaw gateway HTTP client
db/ # SQLite signal log helpers
scripts/
register_agents.py # Register all 6 agents with OpenClaw
setup_keys.sh # Generate and store all API keys
backfill.py # Historical signal replay for correlation testing
dashboard/ # CF Pages — signal feed + correlation viewer
index.html
assets/
openclaw.config.json # Agent registry + message bus config
.env.example
requirements.txt
CLAUDE.md # Agent conventions for Claude Code
Conventions
# All agents follow this contract:
# 1. Register with OpenClaw on startup
# 2. Subscribe to relevant message-bus topics
# 3. Publish typed, validated messages only (Pydantic schemas)
# 4. Never write to external systems (dispatcher only)
# 5. Log all errors to OpenClaw structured log
# 6. Store raw data in SQLite for flywheel replay
# openclaw.config.json — agent registry
{
"gateway_port": 18789,
"agents": [
{ "name": "agent-signal", "entry": "agents/agent-signal/main.py", "restart": "always" },
{ "name": "agent-poly", "entry": "agents/agent-poly/main.py", "restart": "always" },
{ "name": "agent-kalshi", "entry": "agents/agent-kalshi/main.py", "restart": "on-failure" },
{ "name": "agent-sentiment", "entry": "agents/agent-sentiment/main.py", "restart": "always" },
{ "name": "agent-correlator", "entry": "agents/agent-correlator/main.py", "restart": "always" },
{ "name": "agent-dispatcher", "entry": "agents/agent-dispatcher/main.py", "restart": "on-failure" }
],
"message_bus": { "type": "asyncio", "max_queue": 10000 },
"claude_model": "claude-sonnet-4-6"
}
Deploy & Run
Two deploy targets: the ClawBox agent stack (runs locally inside the VM) and the CF Pages dashboard (public-facing signal feed + docs, deployed via Wrangler CLI). No CI/CD required — run from your Mac.
1. Configure API Keys
cp .env.example .env # Fill all placeholder values — see Sources section for how to obtain each key # DO NOT commit .env to git # Verify .env is in .gitignore echo ".env" >> .gitignore echo "keys/" >> .gitignore
2. TastyTrade Sandbox (Recommended First)
# Use TastyTrade's certification environment before connecting live account # .env: switch BASE_URL to sandbox BASE_URL=https://api.cert.tastyworks.com # Sandbox # BASE_URL=https://api.tastytrade.com # Production (uncomment when ready) # Create a sandbox account at: https://developer.tastytrade.com # Sandbox has all API features including DXLink streaming # Kalshi demo environment KALSHI_BASE=https://demo-api.kalshi.co/trade-api/v2 # Demo # KALSHI_BASE=https://trading-api.kalshi.com/trade-api/v2 # Production
3. Start OrganizedMarket (ClawBox VM)
# Inside ClawBox VM terminal: cd ~/organizedmarket # Register agents and start the full stack python scripts/register_agents.py openclaw start --config openclaw.config.json # Watch agent status openclaw agents status # → agent-signal [running] pid:1234 uptime:00:02:14 # → agent-poly [running] pid:1235 uptime:00:02:13 # → agent-kalshi [running] pid:1236 uptime:00:02:13 # → agent-sentiment [running] pid:1237 uptime:00:02:12 # → agent-correlator [running] pid:1238 uptime:00:02:11 # → agent-dispatcher [running] pid:1239 uptime:00:02:11 # View live signal feed openclaw logs agent-dispatcher --follow # View correlation engine output openclaw logs agent-correlator --follow
4. Deploy Dashboard to CF Pages
# From your Mac (outside ClawBox VM): cd organizedmarket/dashboard # First deploy — create CF Pages project wrangler pages project create organizedmarket-arch \ --production-branch=main # Deploy docs/dashboard wrangler pages deploy . \ --project-name=organizedmarket-arch \ --branch=main \ --commit-dirty=true # → Published: https://organizedmarket-arch.pages.dev # Custom domain (optional) wrangler pages domain add organizedmarket.organizedai.vip \ --project-name=organizedmarket-arch
5. Push Wrangler Secrets (Dashboard Workers)
# If running a CF Worker alongside the dashboard for live signal relay: echo $OPENCLAW_URL | wrangler secret put OPENCLAW_URL --name organizedmarket-relay echo $OPENCLAW_CODEX_TOKEN | wrangler secret put OPENCLAW_CODEX_TOKEN --name organizedmarket-relay # Account metadata CLOUDFLARE_ACCOUNT_ID=YOUR_ACCOUNT_ID \ wrangler deploy --name organizedmarket-relay \ --config workers/relay/wrangler.toml
Deploying These Docs
# The exact pattern used to deploy this guide: wrangler pages project create organizedmarket-arch --production-branch=main wrangler pages deploy /path/to/organizedmarket/dashboard \ --project-name=organizedmarket-arch \ --branch=main \ --commit-dirty=true
Architecture Options
| A — Cloud only | B — Local only | C — ClawBox ✓ | D — ExoClaw bridge | |
|---|---|---|---|---|
| Claude cost | High ($20+/mo) | Free (local model) | Low ($4–8/mo) | Free |
| Signal quality | Best | Good | Best | Good |
| Setup complexity | Low | Medium | Low | High |
| Reliability | Best | Mac-dependent | Good | Mac-dependent |
| Isolation | Full | None | Full (Lima VM) | Partial |
Operational Checklist
Quick Links
| Resource | URL |
|---|---|
| GitHub | github.com/Organized-AI/organizedmarket — agents, scripts, dashboard |
| TastyTrade API | developer.tastytrade.com — REST docs + DXLink WS |
| Polymarket Docs | docs.polymarket.com — CLOB API reference |
| Kalshi API | kalshi.com/docs/api — REST + auth guide |
| ClawBox Repo | github.com/coderkk1992/clawbox — source + releases |
| OpenClaw | github.com/openclaw/openclaw — gateway + agent registry |