Tutorial de bots para Polymarket · Capítulo 24 de 32

Polymarket Perps tiene una API pública completa con SDK oficiales para TypeScript y Python. En este capítulo construimos un bot sobre la interfaz real: autenticación con una clave de trading proxy, datos de mercado por REST y WebSocket, órdenes con take-profit y stop-loss, y los controles de riesgo que evitan que un bot con apalancamiento vacíe la cuenta.

Build your own theme park, free in your browserAnuncio Anúnciate aquí
Antes de empezar. No se permite colocar órdenes de Perps desde Estados Unidos, Canadá, Cuba, Irán, Corea del Norte, Siria, Crimea, Donetsk ni Luhansk, y polymarket.com bloquea otros países más. Un bot o un servidor en el extranjero no cambia esto. Con apalancamiento, un bug pierde dinero rápido, así que haz pruebas con el tamaño mínimo. ¿Eres nuevo en Perps? Empieza por la guía de Polymarket Perps.

Qué cubre este capítulo

  • Cifras clave para quienes construyen bots
  • Cómo está construida la API de Perps
  • Paso 1: instala el SDK y abre una sesión
  • Paso 2: lee datos de mercado por REST y WebSocket
  • Paso 3: coloca órdenes con take-profit y stop-loss
  • Paso 4: un esqueleto de bot con controles de riesgo en el código
  • Errores, el interruptor de hombre muerto (dead man's switch), reglas para bots y alojamiento

Cada método del SDK y cada endpoint de este capítulo provienen de la documentación de Perps de Polymarket (docs.polymarket.com/perps, consultada el 6 de noviembre de 2026). Nuestra propia lógica está marcada en los comentarios, y la función de estrategia es un marcador de posición señalado como tal.

Cifras clave para quienes construyen bots (a noviembre de 2026)

ElementoValor
URL base de RESThttps://api.perpetuals.polymarket.com
WebSocketwss://ws.perpetuals.polymarket.com/v1/ws
SDK de TypeScript@polymarket/client (con viem para firmar)
SDK de Pythonpolymarket-client (asíncrono)
Datos públicos/v1/info/*, sin autenticación
Lecturas privadas/v1/account/* con los encabezados polymarket-proxy y polymarket-secret
Escrituras firmadas/v1/trade/*, firma EIP-712 de la clave proxy, válida durante 5 minutos
Credenciales de sesiónCaducan tras una semana por defecto
Orden mínima$10 de valor nocional; depósito mínimo de 10 pUSD
Orden a mercado más grande$1M en los mercados de 50x y 20x, $500K en la mayoría de los demás, $50K en las monedas de 3x y 5x
Formato de precio y tamañoCadenas decimales, sin superar los decimales del mercado ni 5 cifras significativas
Apalancamiento máximo50x (BTC, ETH, USA500, US100); en los demás, 20x, 10x, 5x o 3x según el mercado, menos para posiciones grandes
Comisiones (nivel base)Taker 0,040%, maker 0,0125%; ANT a mitad de precio
Financiación (funding)Cada hora, con un tope de +/-4% por hora
Activadores de TP/SLPrecio de marca, no la última operación
Keepalive del WebSocketPing cada 25 segundos aprox.; considera la conexión obsoleta tras unos 65 segundos de silencio
Actualidad del tickerHasta 10 segundos de antigüedad

Cómo está construida la API de Perps

Perps es un exchange híbrido: el emparejamiento de órdenes ocurre offchain, y la custodia y la compensación están en Polygon. Solo los depósitos y retiros son onchain, así que no hay gas por orden. La API tiene tres capas:

  • Datos públicos (/v1/info/): instrumentos, tickers, libro de órdenes, velas, operaciones, financiación, comisiones. No hace falta clave y no hay bloqueo geográfico.
  • Lecturas privadas (/v1/account/): cartera, saldos, órdenes, ejecuciones, configuración.
  • Escrituras firmadas (/v1/trade/): órdenes, cancelaciones, apalancamiento, margen aislado, cancelación automática. Cada escritura se codifica en MessagePack, se le aplica el hash keccak256 y la clave proxy la firma como datos tipados EIP-712.

Los SDK se encargan de la firma por ti. También hay una especificación OpenAPI (/api-spec/perps-openapi.json en el sitio de la documentación) y una especificación AsyncAPI para el WebSocket.

Los símbolos difieren de los ejemplos de la documentación. La documentación muestra BTC-PERP. La API en vivo devuelve BTC-USD, SP500-USD (USA500), NAS100-USD (US100), ANT-USD, etc. Obtén la lista de instrumentos, busca el symbol en vivo y guarda el id numérico. No copies los ID de los ejemplos: en vivo, BTC es 6 y SP500 es 1.

Paso 1: instala el SDK y abre una sesión

Instala con pip install polymarket-client o npm install @polymarket/client@latest viem. El bot necesita la dirección de tu billetera de Polymarket y la clave privada del firmante dueño de la cuenta de Perps (la cuenta está vinculada a la EOA firmante, no a la Safe). Al abrir una sesión se firma una sola vez para autorizar una nueva clave de trading proxy, que a partir de entonces firma cada orden, así tu clave de fondos nunca opera. Guarda session.credentials cifrado para reanudar más adelante.

import asyncio
import os
from datetime import timedelta

from polymarket import AsyncSecureClient


async def main():
    client = await AsyncSecureClient.create(
        private_key=os.environ["PRIVATE_KEY"],
        wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
    )
    # One signature creates a proxy trading key. Orders are signed by the proxy,
    # not by your wallet key. Credentials expire after one week by default.
    session = await client.open_perps_session(
        expires_in=timedelta(days=1),
        label="perps-bot",
    )
    stored = session.credentials.model_dump(mode="json")  # keep it encrypted

    instruments = await client.fetch_perps_instruments()
    btc = next(i for i in instruments if i.symbol == "BTC-USD")
    print(btc.id, btc.max_leverage, btc.min_notional, btc.price_decimals)


asyncio.run(main())
import { createSecureClient } from "@polymarket/client";
import { privateKey } from "@polymarket/client/viem";

const client = await createSecureClient({
  wallet: process.env.POLYMARKET_WALLET_ADDRESS!,
  signer: privateKey(process.env.PRIVATE_KEY!),
});

// One signature creates a proxy trading key. Orders are signed by the proxy,
// not by your wallet key. Credentials expire after one week by default.
const session = await client.openPerpsSession({
  expiresIn: 24 * 60 * 60 * 1000,
  label: "perps-bot",
});
const stored = session.credentials; // keep it encrypted

const instruments = await client.fetchPerpsInstruments();
const btc = instruments.find((i) => i.symbol === "BTC-USD");
if (!btc) throw new Error("BTC-USD not listed");
console.log(btc.id, btc.maxLeverage, btc.minNotional, btc.priceDecimals);

Depositar desde el código (deposit_to_perps / depositToPerps) también requiere una clave de API de Relayer, que se obtiene en polymarket.com, Settings, API Keys. Lo más simple y seguro: fondea la cuenta en la aplicación web y mantén el bot alejado del movimiento de dinero. Desde el 5 de noviembre de 2026, las cuentas con libreta de direcciones de retiro solo pueden retirar a direcciones guardadas. Para paneles de control, usa una clave de solo lectura (un proxy con la etiqueta read-only:, que rechaza escrituras firmadas), nunca la clave de trading. El almacenamiento de claves se explica en nuestro capítulo de billeteras y autenticación.

Paso 2: lee datos de mercado por REST y WebSocket

El ticker tiene tres precios: índice (valor justo a partir de fuentes como Pyth, Chainlink Data Streams e Hyperliquid), marca (usado para PnL, margen, liquidación y TP/SL) y último (solo ejecución), además de la tasa de financiación y la hora de la próxima financiación. Basa tus señales en el precio de marca o en el índice.

# Inside your async main(), after Step 1 (btc is the BTC-USD instrument)
from polymarket import AsyncPublicClient
from polymarket.streams import PerpsBboSpec

client = AsyncPublicClient()

ticker = await client.fetch_perps_ticker(instrument_id=btc.id)
print(ticker.mark_price, ticker.index_price, ticker.funding_rate)

stream = await client.subscribe(PerpsBboSpec(instrument_id=btc.id))
async for event in stream:
    print(event.payload.bid_price, event.payload.ask_price)
// After Step 1 (btc is the BTC-USD instrument)
import { createPublicClient } from "@polymarket/client";

const client = createPublicClient();

const ticker = await client.fetchPerpsTicker({ instrumentId: btc.id });
console.log(ticker.markPrice, ticker.indexPrice, ticker.fundingRate);

const stream = await client.subscribe([{ topic: "perps.bbo", instrumentId: btc.id }]);
for await (const event of stream) {
  console.log(event.payload.bidPrice, event.payload.askPrice);
}

Sin el SDK, suscríbete en el WebSocket directo con {"id": 1, "req": "sub", "chs": ["bbo::6"]}. Los canales incluyen bbo::<id>, book::<id>, trades::<id>, tickers::<id> y klines::<id>::1m. Cada actualización tiene un número de secuencia sq: tras un salto o una reconexión, vuelve a leer el estado por REST. Para backtests, list_perps_candles / listPerpsCandles pagina el historial (el endpoint REST devuelve hasta 1.000 velas por llamada).

Paso 3: coloca órdenes con take-profit y stop-loss

Una orden tiene un side (BUY o SELL), una quantity en unidades del activo base, un price opcional en pUSD y una vigencia (gtc, ioc o fok). Post-only requiere GTC; reduce-only solo puede reducir una posición. No hay un indicador de largo o corto: sin posición, BUY abre un largo y SELL abre un corto.

Una orden bracket adjunta un take-profit y un stop-loss a la entrada. Permanecen inactivos hasta que la entrada se ejecuta por completo, y se cancelan si la entrada se cancela o solo se ejecuta en parte. Los precios de abajo son hipotéticos.

# Inside your async main(), after Step 1 (btc is the BTC-USD instrument)
from polymarket import PerpsTpSlTrigger

result = await session.place_order(
    instrument_id=btc.id,
    side="BUY",
    price="100000",
    quantity="0.01",
    time_in_force="gtc",
    take_profit=PerpsTpSlTrigger(trigger_price="104000"),
    stop_loss=PerpsTpSlTrigger(trigger_price="98000"),
)
print(result.order.id, result.order.status)
// After Step 1 (btc is the BTC-USD instrument)
import { OrderSide, PerpsTimeInForce } from "@polymarket/client";

const result = await session.placeOrder({
  instrumentId: btc.id,
  side: OrderSide.BUY,
  price: "100000",
  quantity: "0.01",
  timeInForce: PerpsTimeInForce.GTC,
  takeProfit: { triggerPrice: "104000" },
  stopLoss: { triggerPrice: "98000" },
});
console.log(result.order.id, result.tpSl.stopLoss?.orderId);

Para una posición abierta, place_position_tp_sl / placePositionTpSl añade activadores que cierran toda la posición. Reglas:

  • Los activadores vigilan el precio de marca y envían una orden reduce-only. El TP/SL de posición sale a mercado, así que espera deslizamiento (slippage) en libros poco profundos.
  • Un take-profit y un stop-loss de posición por mercado. Mover un stop implica cancelar y luego crear, lo cual no es atómico.
  • Se rechaza un activador que el precio de marca ya haya cruzado, y también los precios límite demasiado alejados del precio de marca.

Para probar el flujo de órdenes a mano antes de automatizarlo, abre el mercado de BTC en Polymarket Perps y coloca la orden más pequeña permitida. Ver las ejecuciones, las comisiones y el panel de posición hace que las respuestas de la API sean más fáciles de leer.

Paso 4: un esqueleto de bot con controles de riesgo en el código

El esqueleto en Python de abajo usa solo llamadas documentadas del SDK; la lógica de riesgo es nuestra. Tres capas de protección:

  1. Tope de apalancamiento. El apalancamiento se fija en 3x o en el máximo del mercado, el que sea menor, con margen aislado, y se rechazan los tamaños que caen en un nivel de riesgo con un tope más bajo.
  2. Interruptores de emergencia (kill switches). Un archivo HALT, un límite de pérdida diaria del 5% y una salida en caso de liquidación. El interruptor cierra las posiciones con órdenes IOC reduce-only, cancela las órdenes restantes y luego comprueba que ambas hayan desaparecido.
  3. Un stop en cada posición. Las entradas fill-or-kill evitan ejecuciones parciales sin protección. Tras cada ejecución se colocan un stop y un take-profit de posición; si se rechazan, la posición se cierra de inmediato.
import asyncio
import logging
import os
from datetime import timedelta
from decimal import Decimal, ROUND_DOWN

from polymarket import AsyncSecureClient, PerpsPositionTpSlTrigger

SYMBOL = "BTC-USD"                   # live API symbol; docs examples say "BTC-PERP"
LEVERAGE_CAP = 3                     # our cap, far below the 50x BTC allows
RISK_PER_TRADE = Decimal("20")       # pUSD we accept losing if the stop fills
STOP_PCT = Decimal("0.02")           # stop 2% from entry
TAKE_PCT = Decimal("0.04")           # take profit 4% from entry
MAX_NOTIONAL = Decimal("2000")       # hard cap per position, in pUSD
MAX_SLIPPAGE = Decimal("0.002")      # worst entry price: ask + 0.2%
MAX_FUNDING = Decimal("0.0005")      # skip longs if funding > 0.05% per hour
DAILY_LOSS_LIMIT = Decimal("0.05")   # kill switch at -5% of start equity
HALT_FILE = "/opt/perps-bot/HALT"    # touch this file to stop the bot


def fit(value: Decimal, decimals: int, sig: int = 5) -> str:
    """Round down to the market's decimals and to 5 significant figures."""
    v = value.quantize(Decimal(1).scaleb(-decimals), rounding=ROUND_DOWN)
    if v != 0:
        step = Decimal(1).scaleb(v.adjusted() - sig + 1)
        if step > Decimal(1).scaleb(-decimals):
            v = v.quantize(step, rounding=ROUND_DOWN)
    return format(v, "f")


def tier_cap(inst, notional: Decimal) -> int:
    """Max leverage allowed for this notional by the market's risk tiers."""
    cap = inst.max_leverage
    for tier in inst.risk_tiers:
        if notional >= Decimal(tier.lower_bound):
            cap = tier.max_leverage
    return cap


async def close_all(session):
    """Close every position with reduce-only IOC orders, then cancel the rest."""
    portfolio = await session.fetch_portfolio()
    for pos in portfolio.positions:
        if pos.size != 0:
            await session.place_order(
                instrument_id=pos.instrument_id,
                side="SELL" if pos.size > 0 else "BUY",
                quantity=abs(pos.size),
                time_in_force="ioc",
                reduce_only=True,
            )
    await session.cancel_all_orders()


async def kill_switch(session, reason: str):
    logging.error("KILL SWITCH: %s", reason)
    for attempt in range(3):
        await close_all(session)
        portfolio = await session.fetch_portfolio()
        open_orders = await session.fetch_open_orders()
        if not open_orders and all(p.size == 0 for p in portfolio.positions):
            return
        await asyncio.sleep(2)
    logging.critical("Positions still open after kill switch: act manually")


async def open_long(client, session, inst):
    ticker = await client.fetch_perps_ticker(instrument_id=inst.id)
    if Decimal(ticker.funding_rate) > MAX_FUNDING:
        return                                     # longs would pay too much
    book = await client.fetch_perps_book(instrument_id=inst.id, depth=10)
    if not book.asks:
        return
    ask = Decimal(book.asks[0].price)
    stop = ask * (1 - STOP_PCT)
    qty = RISK_PER_TRADE / (ask - stop)            # size from the stop, not leverage
    qty = min(qty, MAX_NOTIONAL / ask)
    notional = qty * ask
    if notional < Decimal(inst.min_notional):
        return
    if tier_cap(inst, notional) < LEVERAGE_CAP:
        return                                     # size would break our cap

    entry = await session.place_order(
        instrument_id=inst.id,
        side="BUY",
        price=fit(ask * (1 + MAX_SLIPPAGE), inst.price_decimals),
        quantity=fit(qty, inst.quantity_decimals),
        time_in_force="fok",                       # all or nothing
    )
    if entry.order.status != "filled":
        return

    try:                                           # stop on the whole position
        await session.place_position_tp_sl(
            instrument_id=inst.id,
            take_profit=PerpsPositionTpSlTrigger(
                trigger_price=fit(ask * (1 + TAKE_PCT), inst.price_decimals)),
            stop_loss=PerpsPositionTpSlTrigger(
                trigger_price=fit(stop, inst.price_decimals)),
        )
    except Exception:
        logging.exception("TP/SL rejected: closing the unprotected position")
        await close_all(session)


async def my_signal(client, inst) -> bool:
    """PLACEHOLDER: your strategy goes here. Not part of the SDK."""
    return False


async def main():
    logging.basicConfig(level=logging.INFO)
    client = await AsyncSecureClient.create(
        private_key=os.environ["PRIVATE_KEY"],
        wallet=os.environ["POLYMARKET_WALLET_ADDRESS"],
    )
    session = await client.open_perps_session(
        expires_in=timedelta(days=1), label="perps-bot")
    inst = next(i for i in await client.fetch_perps_instruments()
                if i.symbol == SYMBOL)

    # Control 1: leverage cap and isolated margin, set before any order
    await session.update_leverage(
        instrument_id=inst.id,
        leverage=min(LEVERAGE_CAP, inst.max_leverage),
        cross_margin=False,
    )

    # Field names below follow the documented portfolio JSON
    # (margin.total_account_value, in_liquidation). Check them in your SDK.
    start_equity = Decimal((await session.fetch_portfolio()).margin.total_account_value)

    while True:
        portfolio = await session.fetch_portfolio()
        equity = Decimal(portfolio.margin.total_account_value)

        # Control 2: kill switches
        if os.path.exists(HALT_FILE):
            await kill_switch(session, "HALT file found")
            break
        if equity < start_equity * (1 - DAILY_LOSS_LIMIT):
            await kill_switch(session, f"daily loss limit hit: {equity}")
            break
        if portfolio.in_liquidation:
            await kill_switch(session, "account in liquidation")
            break

        in_position = any(p.instrument_id == inst.id and p.size != 0
                          for p in portfolio.positions)
        if not in_position and await my_signal(client, inst):
            await open_long(client, session, inst)   # Control 3 lives here

        await asyncio.sleep(5)


asyncio.run(main())

El cálculo del tamaño. El tamaño se calcula a partir de la distancia al stop, no del apalancamiento. Con una oferta de venta hipotética de BTC de 100.000 pUSD y un stop del 2%, el stop queda en 98.000. El riesgo por unidad es de 2.000, así que la cantidad es 20 / 2.000 = 0,01 BTC, un valor nocional de 1.000 pUSD. A 3x eso requiere unos 333 pUSD de margen. La tasa de margen de mantenimiento de BTC es del 1% (0,5 / 50x), así que el precio de liquidación del largo es 100.000 x (1 - 1/3) / (1 - 0,01) = unos 67.340, una caída del 32,7%. El stop en -2% se activa mucho antes. Si el stop se ejecuta en su precio de activación, la pérdida es de 20 pUSD más comisiones: 0,40 al abrir y unos 0,39 al cerrar con la tasa taker del 0,040%, es decir, unos 20,79 pUSD antes del deslizamiento. El apalancamiento solo decide cuánto margen queda inmovilizado. No cambia la pérdida en el stop.

Antes de pasar a producción, añade un límite diario de operaciones, alertas sobre ejecuciones e interruptores de emergencia, y una conciliación al arrancar (fetch_portfolio, fetch_open_orders, fetch_orders, list_fills). Consulta nuestros capítulos de código de riesgo y de trading simulado, la guía de apalancamiento y liquidación de Perps y la guía de tasas de financiación de Perps.

Errores, reintentos y el interruptor de hombre muerto

  • 503 service_unavailable no demuestra que la solicitud haya fallado. Reintenta las lecturas y los cambios de apalancamiento con backoff y respeta Retry-After. Para cambios de saldo firmados (margen, retiros), reenvía solo la solicitud firmada original exacta; una firma nueva es un segundo ajuste.
  • signature expired: tiene más de 5 minutos. Mantén el reloj sincronizado.
  • insufficient_margin / invalid_leverage: las comprobaciones usan tu posición más todas las órdenes en espera.
  • message_rate_limited: se agotó el presupuesto del WebSocket. Las claves de solo lectura tienen 1.000 mensajes por minuto por IP (ráfaga de 50) y cuatro conexiones por cuenta por gateway; consulta la página Rate Limits de la documentación para el resto.
  • Errores de formato: demasiados decimales o más de 5 cifras significativas. De ahí fit().

La cancelación automática cancela todas las órdenes abiertas si tu bot deja de rearmarla. El plazo debe estar al menos 5 segundos en el futuro, y las activaciones por día UTC son limitadas, así que desármala al apagar el bot de forma limpia.

// For quoting bots: cancel all resting orders if this process dies
await session.armAutoCancel({ cancelAt: Date.now() + 60_000 });
const rearm = setInterval(() => {
  // A missed re-arm is fail-safe: the armed switch still fires.
  session.armAutoCancel({ cancelAt: Date.now() + 60_000 }).catch(console.error);
}, 20_000);

// On a clean shutdown
clearInterval(rearm);
await session.disarmAutoCancel();
Cancelación automática y stops. La documentación incluye la cancelación automática como una de las formas en que se cancela una orden TP/SL, así que una caída del bot puede eliminar el stop de una posición abierta. La cancelación automática es adecuada para bots que cotizan, como los market makers. Nuestro esqueleto no tiene entradas en espera, así que deja la cancelación automática desactivada para mantener vivos sus stops. En cualquier caso, lo que evita que un bot caído sea liquidado es un apalancamiento bajo.

Competiciones, builder codes y las reglas para bots

La documentación incluye «bots de trading que reaccionan a señales del mercado» y market makers entre los usos de la API. Se aplican dos conjuntos de reglas.

  • Competiciones. Están prohibidos las operaciones ficticias (wash trading), el self-trading, las cuentas múltiples, operar principalmente para generar volumen y los «bots, scripts o medios automatizados destinados a manipular el Programa». Un bot que opera de verdad está bien; uno que genera volumen artificial puede ser descalificado.
  • Builder codes. Una aplicación que opera para otros usuarios puede añadir una comisión de hasta 10 puntos básicos con la aprobación de cada trader. Debe verificar la ubicación de cada usuario y bloquear las órdenes de jurisdicciones restringidas, no solo advertir.

Las recompensas de liquidez para makers y las competiciones se explican en la guía de Polymarket Perps.

Alojamiento del bot

Un bot con apalancamiento no debería correr en una laptop. Tiene que mantener vivo su WebSocket, reaccionar a las ejecuciones en segundos y sobrevivir a un corte de internet doméstico. Ejecútalo en un VPS bajo systemd con reinicio automático, guarda la clave en un archivo de entorno que solo pueda leer el usuario del bot y sincroniza el reloj. No se permite colocar órdenes desde ubicaciones restringidas, así que no lo alojes en Estados Unidos ni en Canadá, y nunca uses un VPS para eludir un bloqueo que se aplique a ti. Nosotros ejecutamos nuestros propios bots en TradingVPS (enlace de afiliado: ganamos una pequeña comisión y el precio que pagas es el mismo). Nuestro capítulo de alojamiento en VPS lo compara con otros proveedores en latencia, precio y regiones.

Después del trading simulado, fondea la cuenta con una cantidad pequeña desde la página de Polymarket Perps y opera con el tamaño mínimo durante una semana antes de escalar.

Puntos clave

  • Usa los SDK oficiales, @polymarket/client o polymarket-client. Tu billetera firma una vez; una clave proxy firma las órdenes.
  • Identifica los mercados por el símbolo en vivo (BTC-USD, no BTC-PERP) y guarda el ID numérico.
  • Calcula el tamaño a partir de la distancia al stop, limita el apalancamiento en el código, usa margen aislado y pon un stop a cada posición justo después de la ejecución.
  • El TP/SL se activa con el precio de marca y sale a mercado. La cancelación automática puede eliminar los stops.
  • Los bots están permitidos; manipular las competiciones, no. Nunca operes desde un país restringido.

Preguntas frecuentes

¿Polymarket Perps tiene una API para bots de trading?
Sí. Hay una API REST en api.perpetuals.polymarket.com, un WebSocket en ws.perpetuals.polymarket.com y SDK oficiales: @polymarket/client para TypeScript y polymarket-client para Python. La documentación de Polymarket incluye los bots de trading y los sistemas de market making entre los usos admitidos.
¿Debo usar el SDK de TypeScript o el de Python?
Cualquiera de los dos. Ambos cubren el mismo flujo: crear un cliente seguro, abrir una sesión de Perps, obtener los instrumentos, colocar órdenes con TP/SL y recibir eventos en streaming. El SDK de TypeScript usa viem para firmar. El SDK de Python es asíncrono. Elige el lenguaje en el que ya está escrito tu bot.
¿Mi bot necesita la clave privada de mi billetera principal?
Solo para abrir una sesión. Esa única firma autoriza una clave de trading proxy, y a partir de ahí el proxy firma las órdenes. Las credenciales de sesión caducan tras una semana por defecto. Guárdalas cifradas y usa claves de solo lectura para los paneles de control.
¿Cómo configuro un stop-loss con la API de Perps?
Adjunta los activadores takeProfit y stopLoss a la orden de entrada como bracket, o llama a placePositionTpSl (place_position_tp_sl en Python) sobre una posición abierta. Los activadores vigilan el precio de marca y salen con una orden reduce-only. El TP/SL de posición cierra toda la posición a mercado.
¿Cuál es el tamaño mínimo de orden en Polymarket Perps?
$10 de valor nocional por orden, y el depósito mínimo es de 10 pUSD (a noviembre de 2026). Los precios y tamaños también deben ajustarse a los decimales de cada mercado y a un máximo de 5 cifras significativas; de lo contrario, la orden se rechaza.
¿Hay un interruptor de emergencia o un interruptor de hombre muerto?
Sí. La cancelación automática cancela todas las órdenes abiertas si tu bot deja de rearmarla, y cancelAllOrders elimina las órdenes cuando lo pidas. La documentación incluye la cancelación automática como una de las formas en que se puede cancelar una orden TP/SL, así que una caída del bot también puede eliminar tus stops. Programa también tu propio interruptor de emergencia.
¿Puedo ejecutar un bot de Polymarket Perps desde Estados Unidos o Canadá?
No. No se permite colocar órdenes de Perps desde Estados Unidos, Canadá, Cuba, Irán, Corea del Norte, Siria, Crimea, Donetsk ni Luhansk. No alojes un bot allí, y no uses un VPS ni una VPN para eludir un bloqueo que se aplique a ti.
¿Se permiten bots en las competiciones de trading de Polymarket Perps?
Operar con un bot está permitido. Las reglas de la competición prohíben las operaciones ficticias (wash trading), el self-trading, las cuentas múltiples, operar principalmente para generar volumen y los bots o scripts destinados a manipular el programa. Incumplirlas puede llevar a la descalificación.