blackmistcode's picture
Add files using upload-large-folder tool
71b8eb2 verified
|
Raw
History Blame Contribute Delete
4.79 kB

MARKETS.md — Módulo de mercados

Referencia para el frontend: contrato HTTP, mapping de datos de Polymarket, evento socket y errores.


Variables de entorno requeridas

DATABASE_URL=file:./backend/prisma/polysignal.db
PORT=7860

No se necesita clave de API para Polymarket Gamma (pública).


Endpoints

GET /api/v1/markets

Lista paginada de mercados activos sincronizados desde Polymarket. No requiere autenticación.

Query params

Param Tipo Default Descripción
limit int (1-100) 20 Máximo de resultados
offset int 0 Paginación por offset
category string Filtro: politics | crypto | economics | sports
status string active Filtro: active | closed | resolved

Respuesta 200

{
  "ok": true,
  "data": [
    {
      "id": "559677",
      "question": "Will Hillary Clinton win the 2028 Democratic presidential nomination?",
      "category": null,
      "countryCode": null,
      "yesPrice": 0.0075,
      "noPrice": 0.9925,
      "volumeEur": 38608906.44,
      "liquidityEur": 2301398.64,
      "status": "active",
      "closesAt": "2028-11-07T00:00:00.000Z",
      "lastSynced": "2026-05-16T09:38:30.204Z"
    }
  ],
  "meta": {
    "total": 100,
    "limit": 1,
    "offset": 0
  }
}

category y countryCode pueden ser null si Polymarket no los proporciona.


GET /api/v1/markets/:id

Detalle de un mercado por su ID de Polymarket. No requiere autenticación.

Params

Param Tipo Descripción
id string ID numérico de Polymarket (ej. 559677)

Respuesta 200

{
  "ok": true,
  "data": {
    "id": "559677",
    "question": "Will Hillary Clinton win the 2028 Democratic presidential nomination?",
    "category": null,
    "countryCode": null,
    "yesPrice": 0.0075,
    "noPrice": 0.9925,
    "volumeEur": 38608906.44,
    "liquidityEur": 2301398.64,
    "status": "active",
    "closesAt": "2028-11-07T00:00:00.000Z",
    "lastSynced": "2026-05-16T09:38:30.204Z"
  }
}

Respuesta 404

{
  "ok": false,
  "error": { "code": "NOT_FOUND", "message": "Market not found" }
}

GET /api/v1/markets/:id/signal

Señal AI más reciente para un mercado. Ver SIGNALS.md para el contrato completo.


Mapping Polymarket Gamma API → Market

URL de origen: https://gamma-api.polymarket.com/markets?active=true&closed=false&limit=100

Campo Gamma API Campo Market Transformación
id id String (ID numérico de Polymarket)
question question Directo
category category Minúsculas; null si Gamma no lo envía
countryCode null por defecto (no proporcionado por Gamma)
outcomePrices[0] yesPrice parseFloat; rango 0.0–1.0
outcomePrices[1] noPrice parseFloat; rango 0.0–1.0
volume volumeEur parseFloat(volume) * 0.93 (USD→EUR tasa fija)
liquidity liquidityEur Igual que volumeEur
active + closed + archived status active=true → "active", closed=true → "closed", archived=true → "resolved"
endDateIso closesAt new Date(endDateIso)
lastSynced new Date() en el momento del upsert

La sincronización usa prisma.market.upsert({ where: { id }, ... }) para evitar duplicados.


Socket — evento market_update

Emitido por src/socket/broadcaster.js cada 30 s (tras syncMarkets).

Nombre del evento: market_update

Payload

{
  "marketId": "0x1a2b...",
  "yesPrice": 0.63,
  "noPrice": 0.37,
  "volumeEur": 125000.00
}

Uso en el frontend (Socket.io client)

import { io } from 'socket.io-client';

const socket = io('http://localhost:7860');
socket.on('market_update', ({ marketId, yesPrice, noPrice }) => {
  // actualizar estado local del mercado
});

En producción (HF Spaces) el frontend y backend comparten origen → usar io() sin URL.


Ejemplos curl

# Listar mercados (primeros 5)
curl "http://localhost:7860/api/v1/markets?limit=5"

# Filtrar por estado
curl "http://localhost:7860/api/v1/markets?status=active&limit=10"

# Detalle de un mercado
curl "http://localhost:7860/api/v1/markets/559677"

# Señal AI del mercado
curl "http://localhost:7860/api/v1/markets/559677/signal"

Códigos de error relevantes

HTTP Código Cuándo
400 VALIDATION_ERROR Parámetro inválido (ej. limit > 100)
404 NOT_FOUND ID de mercado no existe en DB
500 INTERNAL Error inesperado del servidor

Los endpoints de markets no requieren autenticación — son datos públicos.