Skip to main content

openclaw-polymarket-trading-bot

AI-powered prediction and automated trading bot for Polymarket's 5-minute Bitcoin Up/Down markets

Ir a la instalación

Datos de origen

Repositorio
reason-machines/hermes-skills
Última actividad en el origen
18 de junio de 2026 a las 13:42
Idioma detectado de SKILL.md
inglés
Estrellas
5
Forks
0

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
openclaw-polymarket-trading-bot
description
AI-powered prediction and automated trading bot for Polymarket's 5-minute Bitcoin Up/Down markets
triggers
["set up OpenClaw Polymarket trading bot","configure Polymarket AI trading bot with CLOB","run Polymarket prediction bot for BTC markets","deploy OpenClaw bot with whale flow analysis","integrate OpenAI with Polymarket trading strategy","build custom Polymarket trading indicators","debug Polymarket CLOB order execution","analyze whale activity on Polymarket BTC markets"]
# OpenClaw Polymarket Trading Bot > Skill by [ara.so](https://ara.so) — Hermes Skills collection. OpenClaw is a production-ready TypeScript bot that predicts whether Polymarket's 5-minute BTC Up/Down markets will move up (YES) or down (NO) and executes real orders via the Polymarket CLOB API. It combines momentum indicators, volatility analysis, whale flow tracking, and optional LLM scoring to generate trading signals. ## What It Does The bot runs a continuous loop that: 1. Identifies the active 5-minute BTC Up/Down market on Polymarket 2. Collects real-time price data and whale flow (large trades ≥ $200) 3. Computes indicators (momentum, volatility, whale bias) 4. Generates predictions using AI-enhanced scoring 5. Places market orders when edge threshold is exceeded 6. Optionally closes positions after a timed interval ## Installation ```bash git clone https://github.com/Golrypavium/openclaw-polymarket-trading-bot.git cd openclaw-polymarket-trading-bot npm install cp .env.example .env ``` Edit `.env` with your Polymarket CLOB credentials: ```bash # Required CLOB credentials PRIVATE_KEY=your_wallet_private_key_hex CLOB_API_KEY=your_clob_api_key CLOB_SECRET=your_clob_secret CLOB_PASS_PHRASE=your_clob_passphrase # Optional AI enhancement OPENAI_API_KEY=your_openai_key ``` ## Key Commands ```bash # Run bot in development mode npm run dev # Build for production npm run build # Run production build npm start # Start Signal Lab dashboard npm run serve ``` ## Configuration ### Environment Variables | Variable | Purpose | Default | |----------|---------|---------| | `PRIVATE_KEY` | Wallet private key (64 hex chars) | Required | | `CLOB_API_KEY` | Polymarket CLOB API key | Required | | `CLOB_SECRET` | CLOB secret | Required | | `CLOB_PASS_PHRASE` | CLOB passphrase | Required | | `LOOP_SECONDS` | Cycle interval | `15` | | `MAX_POSITION_USD` | Order size in USD | `100` | | `EDGE_THRESHOLD` | Minimum edge to trade | `0.03` | | `CLOSE_AFTER_SECONDS` | Auto-close timer (0=hold) | `0` | | `OPENAI_API_KEY` | Optional LLM enhancement | Empty | | `OPENAI_MODEL` | Model for predictions | `gpt-4o-mini` | ### Strategy Parameters The edge threshold determines when to trade: - `pUp5m > 0.5 + EDGE_THRESHOLD` → Open YES position - `pUp5m < 0.5 - EDGE_THRESHOLD` → Open NO position - Otherwise → Hold Example with `EDGE_THRESHOLD=0.03`: - Trade YES if pUp5m > 0.53 - Trade NO if pUp5m < 0.47 ## Core Architecture ### Data Flow ```typescript // core/entry.ts - Main bot loop import { opts } from './settings'; import { getMarketSnapshot } from './adapters/eventSource'; import { computeIndicators } from './strategy/indicators'; import { generateForecast } from './strategy/forecast'; import { decideAction } from './strategy/simulator'; import { submitBuy } from './adapters/orderBridge'; async function runCycle() { // 1. Get current market and price data const snapshot = await getMarketSnapshot(); // 2. Build indicators const indicators = computeIndicators(snapshot.ticks, snapshot.whale); // 3. Generate forecast const forecast = await generateForecast(indicators); // 4. Decide action const action = decideAction(forecast, snapshot.currentPrice); // 5. Execute if needed if (action.type === 'OPEN_YES') { await submitBuy('YES', action.size, snapshot.market); } } ``` ### Market Selection ```typescript // core/adapters/eventSource.ts import { opts } from '../settings'; export async function getCurrentMarket(): Promise<MarketInfo> { const gammaUrl = `${opts.polymarketRestBase}/markets`; const response = await fetch(gammaUrl); const markets = await response.json(); // Find active 5-min BTC market by time bucket const now = Date.now(); const btcMarket = markets.find(m => m.question.includes('BTC') && m.question.includes('5 minutes') && m.endDate > now && m.startDate <= now ); return { conditionId: btcMarket.conditionId, question: btcMarket.question, yesTokenId: btcMarket.tokens.YES, noTokenId: btcMarket.tokens.NO }; } ``` ### Indicator Calculation ```typescript // core/strategy/indicators.ts import { PricePoint, WhaleActivity, IndicatorSet } from '../schema/defs'; export function computeIndicators( ticks: PricePoint[], whale: WhaleActivity ): IndicatorSet { // Momentum: recent price changes const shortReturn = computeReturn(ticks, 2); // ~30s ago const medReturn = computeReturn(ticks, 8); // ~2min ago // Volatility: recent price range const recentPrices = ticks.slice(-8).map(t => t.price); const volatility = Math.max(...recentPrices) - Math.min(...recentPrices); // Whale bias: net YES vs NO from large trades const whaleBias = (whale.yesVolume - whale.noVolume) / (whale.yesVolume + whale.noVolume + 0.01); return { shortReturn, medReturn, volatility, whaleBias, whaleIntensity: whale.yesVolume + whale.noVolume }; } function computeReturn(ticks: PricePoint[], lookback: number): number { if (ticks.length < lookback + 1) return 0; const current = ticks[ticks.length - 1].price; const past = ticks[ticks.length - lookback - 1].price; return (current - past) / (past + 0.01); } ``` ### Forecast Generation ```typescript // core/strategy/forecast.ts import { IndicatorSet, Forecast } from '../schema/defs'; import { scoreLLM } from '../ai/remoteScorer'; import { opts } from '../settings'; export async function generateForecast( indicators: IndicatorSet ): Promise<Forecast> { // Base probability from momentum and whale bias let pUp5m = 0.5; // Momentum component (40% weight) const momentumSignal = (indicators.shortReturn * 0.6 + indicators.medReturn * 0.4); pUp5m += momentumSignal * 0.4; // Whale bias component (30% weight) pUp5m += indicators.whaleBias * 0.3; // Volatility dampening const volFactor = Math.min(indicators.volatility * 2, 0.1); pUp5m = 0.5 + (pUp5m - 0.5) * (1 - volFactor); // Optional LLM enhancement (30% weight) let llmBias = 0; if (opts.openaiApiKey) { llmBias = await scoreLLM(indicators); pUp5m += llmBias * 0.3; } // Clamp to [0.2, 0.8] pUp5m = Math.max(0.2, Math.min(0.8, pUp5m)); const confidence = Math.abs(pUp5m - 0.5) * 2; // [0, 1] return { pUp5m, confidence, llmBias }; } ``` ### LLM Integration ```typescript // core/ai/remoteScorer.ts import { IndicatorSet } from '../schema/defs'; import { opts } from '../settings'; export async function scoreLLM(indicators: IndicatorSet): Promise<number> { const prompt = `Predict Bitcoin 5-minute direction. Indicators: - Short momentum: ${indicators.shortReturn.toFixed(4)} - Medium momentum: ${indicators.medReturn.toFixed(4)} - Volatility: ${indicators.volatility.toFixed(4)} - Whale bias: ${indicators.whaleBias.toFixed(3)} Respond with a number from -1 (strong DOWN) to +1 (strong UP).`; const response = await fetch(`${opts.openaiBaseUrl}/chat/completions`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${opts.openaiApiKey}` }, body: JSON.stringify({ model: opts.openaiModel, messages: [{ role: 'user', content: prompt }], temperature: 0.3, max_tokens: 10 }) }); const data = await response.json(); const text = data.choices[0].message.content.trim(); const bias = parseFloat(text); return isNaN(bias) ? 0 : Math.max(-1, Math.min(1, bias)); } ``` ### Order Execution ```typescript // core/adapters/orderBridge.ts import { ClobClient } from '@polymarket/clob-client'; import { opts } from '../settings'; const clobClient = new ClobClient( opts.clobApiUrl, opts.clobChainId, opts.privateKey, { apiKey: opts.clobApiKey, secret: opts.clobSecret, passphrase: opts.clobPassPhrase } ); export async function submitBuy( side: 'YES' | 'NO', usdSize: number, market: MarketInfo ): Promise<string> { const tokenId = side === 'YES' ? market.yesTokenId : market.noTokenId; // Get current best price const book = await clobClient.getOrderBook(tokenId); const price = side === 'YES' ? parseFloat(book.asks[0]?.price || '0.5') : parseFloat(book.bids[0]?.price || '0.5'); const shares = usdSize / price; const order = await clobClient.createMarketBuyOrder({ tokenID: tokenId, amount: shares.toString(), feeRateBps: '0', nonce: Date.now() }); const result = await clobClient.postOrder(order); // Record position recordPosition({ orderId: result.orderID, side, entryPrice: price, shares, timestamp: Date.now(), marketId: market.conditionId }); return result.orderID; } ``` ### Position Management ```typescript // core/strategy/book.ts import fs from 'fs'; interface Position { orderId: string; side: 'YES' | 'NO'; entryPrice: number; shares: number; timestamp: number; marketId: string; } const POSITIONS_FILE = './positions.json'; export function recordPosition(pos: Position): void { const positions = loadPositions(); positions.push(pos); fs.writeFileSync(POSITIONS_FILE, JSON.stringify(positions, null, 2)); } export function getExpiredPositions(closeAfterSeconds: number): Position[] { const positions = loadPositions(); const now = Date.now(); return positions.filter(p => (now - p.timestamp) / 1000 > closeAfterSeconds ); } export function removePosition(orderId: string): void { const positions = loadPositions(); const filtered = positions.filter(p => p.orderId !== orderId); fs.writeFileSync(POSITIONS_FILE, JSON.stringify(filtered, null, 2)); } function loadPositions(): Position[] { if (!fs.existsSync(POSITIONS_FILE)) return []; return JSON.parse(fs.readFileSync(POSITIONS_FILE, 'utf-8')); } ``` ### Timed Position Closing ```typescript // In core/entry.ts cycle import { getExpiredPositions, removePosition } from './strategy/book'; import { submitSell } from './adapters/orderBridge'; async function closeExpiredPositions() { if (opts.closeAfterSeconds === 0) return; const expired = getExpiredPositions(opts.closeAfterSeconds); for (const pos of expired) { try { await submitSell(pos.side, pos.shares, pos.marketId); removePosition(pos.orderId); console.log(`Closed position ${pos.orderId} after timeout`); } catch (err) { console.error(`Failed to close ${pos.orderId}:`, err); } } } ``` ## Signal Lab Dashboard ### Starting the Dashboard ```bash npm run serve # Opens on http://localhost:8787 ``` ### Prediction API ```typescript // core/dashboard.ts import express from 'express'; import { getMarketSnapshot } from './adapters/eventSource'; import { computeIndicators } from './strategy/indicators'; import { generateForecast } from './strategy/forecast'; const app = express(); app.get('/api/prediction', async (req, res) => { try { const snapshot = await getMarketSnapshot(); const indicators = computeIndicators(snapshot.ticks, snapshot.whale); const forecast = await generateForecast(indicators); res.json({ market: snapshot.market.question, currentPrice: snapshot.currentPrice, prediction: forecast.pUp5m, confidence: forecast.confidence, recommendedSide: forecast.pUp5m > 0.5 ? 'YES' : 'NO', indicators: { momentum: indicators.shortReturn, volatility: indicators.volatility, whaleBias: indicators.whaleBias } }); } catch (error) {
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub