Tutorial boți Polymarket · Capitolul 24 din 32

Polymarket Perps are un API public complet, cu SDK-uri oficiale pentru TypeScript și Python. În acest capitol construim un bot pe interfața reală: autentificare cu o cheie proxy de tranzacționare, date de piață prin REST și WebSocket, ordine cu take-profit și stop-loss, plus controalele de risc care împiedică un bot cu efect de levier să golească contul.

Build your own theme park, free in your browserAd Advertise here
Înainte să construiești. Plasarea ordinelor Perps nu este permisă din Statele Unite, Canada, Cuba, Iran, Coreea de Nord, Siria, Crimeea, Donețk sau Luhansk, iar polymarket.com blochează și alte țări. Un bot sau un server din altă țară nu schimbă acest lucru. Cu efect de levier, un bug pierde bani repede, așa că testează la dimensiunea minimă. Ești nou în Perps? Începe cu ghidul Polymarket Perps.

Ce acoperă acest capitol

  • Cifrele cheie pentru cei care construiesc boți
  • Cum este construit API-ul Perps
  • Pasul 1: instalează SDK-ul și deschide o sesiune
  • Pasul 2: citește datele de piață prin REST și WebSocket
  • Pasul 3: plasează ordine cu take-profit și stop-loss
  • Pasul 4: un schelet de bot cu controale de risc în cod
  • Erori, mecanismul dead man's switch, reguli pentru boți și găzduire

Fiecare metodă SDK și fiecare endpoint de aici provine din documentația Perps a Polymarket (docs.polymarket.com/perps, consultată pe 6 noiembrie 2026). Logica noastră proprie este marcată în comentarii, iar funcția de strategie este un placeholder etichetat ca atare.

Cifrele cheie pentru cei care construiesc boți (noiembrie 2026)

ElementValoare
URL de bază RESThttps://api.perpetuals.polymarket.com
WebSocketwss://ws.perpetuals.polymarket.com/v1/ws
SDK TypeScript@polymarket/client (cu viem pentru semnare)
SDK Pythonpolymarket-client (async)
Date publice/v1/info/*, fără autentificare
Citiri private/v1/account/* cu antetele polymarket-proxy și polymarket-secret
Scrieri semnate/v1/trade/*, semnătură EIP-712 cu cheia proxy, valabilă 5 minute
Credențialele sesiuniiExpiră implicit după o săptămână
Ordin minim$10 valoare nominală; depunere minimă 10 pUSD
Cel mai mare ordin la piață$1M pe piețele cu 50x și 20x, $500K pe majoritatea celorlalte, $50K pe monedele cu 3x și 5x
Formatul prețului și al cantitățiiȘiruri zecimale, cel mult numărul de zecimale al pieței și 5 cifre semnificative
Efect de levier maxim50x (BTC, ETH, USA500, US100), altfel 20x, 10x, 5x sau 3x în funcție de piață, mai mic pentru pozițiile mari
Comisioane (nivelul de bază)Taker 0,040%, maker 0,0125%; ANT la jumătate de preț
FinanțareOrară, plafonată la +/-4% pe oră
Declanșatoare TP/SLPrețul de marcare, nu ultima tranzacție
Keepalive WebSocketPing cam la fiecare 25 de secunde; consideră conexiunea moartă după aproximativ 65 de secunde de tăcere
Prospețimea ticker-uluiPână la 10 secunde vechime

Cum este construit API-ul Perps

Perps este un exchange hibrid: potrivirea ordinelor are loc offchain, iar custodia și decontarea pe Polygon. Doar depunerile și retragerile sunt onchain, deci nu plătești gas pentru fiecare ordin. API-ul are trei niveluri:

  • Date publice (/v1/info/): instrumente, tickere, registrul de ordine, lumânări, tranzacții, finanțare, comisioane. Nu ai nevoie de cheie și nu există blocare geografică.
  • Citiri private (/v1/account/): portofoliu, solduri, ordine, execuții, configurație.
  • Scrieri semnate (/v1/trade/): ordine, anulări, efect de levier, marjă izolată, anulare automată. Fiecare scriere este codificată MessagePack, hash-uită cu keccak256 și semnată ca date tipizate EIP-712 de cheia proxy.

SDK-urile se ocupă de semnare în locul tău. Există și o specificație OpenAPI (/api-spec/perps-openapi.json pe site-ul documentației) și o specificație AsyncAPI pentru WebSocket.

Simbolurile diferă de exemplele din documentație. Documentația afișează BTC-PERP. API-ul live returnează BTC-USD, SP500-USD (USA500), NAS100-USD (US100), ANT-USD și așa mai departe. Preia lista de instrumente, potrivește symbol live și salvează id numeric. Nu copia ID-urile din exemple: live, BTC are 6, iar SP500 are 1.

Pasul 1: instalează SDK-ul și deschide o sesiune

Instalează cu pip install polymarket-client sau npm install @polymarket/client@latest viem. Botul are nevoie de adresa portofelului tău Polymarket și de cheia privată a semnatarului care deține contul Perps (contul este legat de EOA-ul semnatar, nu de Safe). Deschiderea unei sesiuni semnează o singură dată pentru a autoriza o cheie proxy de tranzacționare nouă, care semnează apoi fiecare ordin, așa că cheia ta de finanțare nu tranzacționează niciodată. Salvează session.credentials criptat, ca să poți relua sesiunea mai târziu.

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);

Depunerea din cod (deposit_to_perps / depositToPerps) necesită și o cheie Relayer API din polymarket.com, Settings, API Keys. Mai simplu și mai sigur: alimentează contul din aplicația web și ține botul departe de mișcările de bani. Din 5 noiembrie 2026, conturile care folosesc agenda de adrese pentru retrageri pot retrage doar către adresele salvate. Pentru dashboard-uri folosește o cheie read-only (un proxy etichetat read-only:, care refuză scrierile semnate), niciodată cheia de tranzacționare. Păstrarea cheilor este explicată în capitolul despre portofele și autentificare.

Pasul 2: citește datele de piață prin REST și WebSocket

Ticker-ul are trei prețuri: index (valoarea justă din surse precum Pyth, Chainlink Data Streams și Hyperliquid), mark (prețul de marcare, folosit pentru PnL, marjă, lichidare și TP/SL) și last (doar pentru execuție), plus rata de finanțare și momentul următoarei finanțări. Bazează-ți semnalele pe prețul de marcare sau pe index.

# 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);
}

Fără SDK, abonează-te direct pe WebSocket cu {"id": 1, "req": "sub", "chs": ["bbo::6"]}. Canalele includ bbo::<id>, book::<id>, trades::<id>, tickers::<id> și klines::<id>::1m. Fiecare actualizare are un număr de secvență sq: după un gol sau o reconectare, recitește starea prin REST. Pentru backtesting, list_perps_candles / listPerpsCandles paginează istoricul (endpoint-ul REST returnează până la 1.000 de lumânări per apel).

Pasul 3: plasează ordine cu take-profit și stop-loss

Un ordin are un side (BUY sau SELL), o quantity în unități ale activului de bază, un price opțional în pUSD și o durată de valabilitate (gtc, ioc sau fok). Post-only necesită GTC; reduce-only poate doar să micșoreze o poziție. Nu există un indicator long sau short: fără poziție deschisă, BUY deschide un long, iar SELL deschide un short.

Un ordin bracket atașează intrării un take-profit și un stop-loss. Acestea rămân inactive până când intrarea este executată integral și sunt anulate dacă intrarea este anulată sau executată doar parțial. Prețurile de mai jos sunt ipotetice.

# 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);

Pentru o poziție deschisă, place_position_tp_sl / placePositionTpSl adaugă declanșatoare care închid întreaga poziție. Reguli:

  • Declanșatoarele urmăresc prețul de marcare și trimit un ordin reduce-only. TP/SL pe poziție iese la piață, așa că te poți aștepta la slippage în registrele de ordine cu lichiditate redusă.
  • Un singur take-profit și un singur stop-loss pe poziție pentru fiecare piață. Mutarea unui stop înseamnă anulare și apoi creare, operație care nu este atomică.
  • Un declanșator pe care prețul de marcare l-a depășit deja este respins, iar prețurile limită prea îndepărtate de prețul de marcare sunt refuzate.

Ca să încerci manual fluxul ordinelor înainte să-l automatizezi, deschide piața BTC pe Polymarket Perps și plasează cel mai mic ordin permis. Când vezi execuțiile, comisioanele și panoul poziției, răspunsurile API devin mai ușor de citit.

Pasul 4: un schelet de bot cu controale de risc în cod

Scheletul Python de mai jos folosește doar apeluri SDK documentate; logica de risc este a noastră. Trei niveluri de protecție:

  1. Plafon pentru efectul de levier. Efectul de levier este setat la 3x sau la maximul pieței, oricare este mai mic, cu marjă izolată, iar dimensiunile care intră într-un nivel de risc cu plafon mai mic sunt refuzate.
  2. Kill switch-uri. Un fișier HALT, o limită de pierdere zilnică de 5% și ieșire în caz de lichidare. Kill switch-ul închide pozițiile cu ordine IOC reduce-only, anulează ordinele rămase, apoi verifică dacă au dispărut ambele.
  3. Un stop pe fiecare poziție. Intrările fill-or-kill înseamnă că nu există execuții parțiale neprotejate. După fiecare execuție urmează un stop și un take-profit pe poziție; dacă sunt respinse, poziția este închisă imediat.
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())

Calculul dimensiunii. Dimensiunea rezultă din distanța până la stop, nu din efectul de levier. Cu un preț ask ipotetic pentru BTC de 100.000 pUSD și un stop de 2%, stopul este la 98.000. Riscul pe unitate este 2.000, deci cantitatea este 20 / 2.000 = 0,01 BTC, adică o valoare nominală de 1.000 pUSD. La 3x, asta necesită aproximativ 333 pUSD marjă. Rata marjei de menținere pentru BTC este 1% (0,5 / 50x), deci prețul de lichidare al poziției long este 100.000 x (1 - 1/3) / (1 - 0,01) = aproximativ 67.340, o scădere de 32,7%. Stopul de la -2% se declanșează cu mult înainte. Dacă stopul este executat la prețul de declanșare, pierderea este 20 pUSD plus comisioane: 0,40 la deschidere și aproximativ 0,39 la închidere, la rata taker de 0,040%, deci cam 20,79 pUSD înainte de slippage. Efectul de levier decide doar câtă marjă este blocată. Nu schimbă pierderea la stop.

Înainte să treci live, adaugă o limită zilnică de tranzacții, alerte pentru execuții și kill switch-uri, plus o reconciliere la pornire (fetch_portfolio, fetch_open_orders, fetch_orders, list_fills). Vezi capitolele noastre despre codul de risc și tranzacționarea demo, ghidul Perps despre efectul de levier și lichidare și ghidul Perps despre ratele de finanțare.

Erori, reîncercări și dead man's switch

  • 503 service_unavailable nu dovedește că cererea a eșuat. Reîncearcă citirile și modificările efectului de levier cu backoff și respectă Retry-After. Pentru modificările de sold semnate (marjă, retrageri), retrimite doar cererea semnată originală, exact așa cum era; o semnătură nouă înseamnă o a doua ajustare.
  • signature expired: semnătura e mai veche de 5 minute. Ține ceasul sincronizat.
  • insufficient_margin / invalid_leverage: verificările iau în calcul poziția ta plus toate ordinele în așteptare.
  • message_rate_limited: bugetul WebSocket s-a epuizat. Cheile read-only primesc 1.000 de mesaje pe minut per IP (rafală de 50) și patru conexiuni per cont per gateway; pentru restul, vezi pagina Rate Limits din documentație.
  • Erori de format: prea multe zecimale sau mai mult de 5 cifre semnificative. De aici fit().

Anularea automată anulează toate ordinele deschise dacă botul tău nu o mai reactivează. Termenul limită trebuie să fie cu cel puțin 5 secunde în viitor, iar numărul de declanșări pe zi UTC este limitat, așa că dezactiveaz-o la o oprire curată.

// 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();
Anularea automată și stopurile. Documentația enumeră anularea automată printre modurile în care un ordin TP/SL poate fi anulat, deci un crash poate elimina stopul unei poziții deschise. Anularea automată se potrivește boților care cotează prețuri, cum ar fi market makerii. Scheletul nostru nu are intrări în așteptare, așa că lasă anularea automată dezactivată ca să-și păstreze stopurile. Oricum ar fi, un efect de levier mic este cel care ferește de lichidare un bot căzut.

Competiții, coduri de builder și regulile pentru boți

Documentația enumeră „boții de tranzacționare care reacționează la semnalele pieței” și market makerii printre utilizările API-ului. Se aplică două seturi de reguli.

  • Competiții. Sunt interzise tranzacțiile fictive (wash trading), tranzacționarea cu tine însuți (self-trading), conturile multiple, tranzacționarea în principal pentru volum și „boții, scripturile sau mijloacele automate destinate manipulării Programului”. Un bot care tranzacționează cu adevărat este în regulă; unul care generează volum artificial poate fi descalificat.
  • Coduri de builder. O aplicație care tranzacționează pentru alți utilizatori poate adăuga un comision de până la 10 puncte de bază, cu aprobarea fiecărui trader. Ea trebuie să verifice locația fiecărui utilizator și să blocheze ordinele din jurisdicțiile restricționate, nu doar să avertizeze.

Recompensele pentru lichiditatea maker și competițiile sunt explicate în ghidul Polymarket Perps.

Găzduirea botului

Un bot cu efect de levier nu ar trebui să ruleze pe un laptop. Trebuie să-și țină WebSocket-ul activ, să reacționeze la execuții în câteva secunde și să supraviețuiască unei căderi a internetului de acasă. Rulează-l pe un VPS sub systemd cu repornire automată, păstrează cheia într-un fișier de mediu pe care doar utilizatorul botului îl poate citi și sincronizează ceasul. Plasarea ordinelor nu este permisă din locațiile restricționate, deci nu găzdui botul în SUA sau Canada și nu folosi niciodată un VPS ca să ocolești o blocare care ți se aplică. Noi ne rulăm boții pe TradingVPS (link de afiliere: primim un mic comision, iar prețul pe care îl plătești rămâne același). Capitolul nostru despre găzduirea pe VPS îl compară cu alți furnizori după latență, preț și regiuni.

După tranzacționarea demo, alimentează contul cu o sumă mică de pe pagina Polymarket Perps și rulează la dimensiunea minimă timp de o săptămână înainte să crești.

Concluzii cheie

  • Folosește SDK-urile oficiale, @polymarket/client sau polymarket-client. Portofelul tău semnează o singură dată; o cheie proxy semnează ordinele.
  • Identifică piețele după simbolul live (BTC-USD, nu BTC-PERP) și salvează ID-ul numeric.
  • Calculează dimensiunea din distanța până la stop, plafonează efectul de levier în cod, folosește marjă izolată și pune un stop pe fiecare poziție imediat după execuție.
  • TP/SL se declanșează pe prețul de marcare și iese la piață. Anularea automată poate elimina stopurile.
  • Boții sunt permiși, manipularea competițiilor nu. Nu tranzacționa niciodată dintr-o țară restricționată.

Întrebări frecvente

Are Polymarket Perps un API pentru boți de tranzacționare?
Da. Există un API REST la api.perpetuals.polymarket.com, un WebSocket la ws.perpetuals.polymarket.com și SDK-uri oficiale: @polymarket/client pentru TypeScript și polymarket-client pentru Python. Documentația Polymarket enumeră boții de tranzacționare și sistemele de market making printre utilizările acceptate.
Ar trebui să folosesc SDK-ul TypeScript sau pe cel Python?
Oricare. Ambele acoperă același flux: creezi un client securizat, deschizi o sesiune Perps, preiei instrumentele, plasezi ordine cu TP/SL și primești evenimente în flux. SDK-ul TypeScript folosește viem pentru semnare. SDK-ul Python este async. Alege limbajul în care este deja scris botul tău.
Are nevoie botul meu de cheia privată a portofelului principal?
Doar pentru a deschide o sesiune. Acea unică semnătură autorizează o cheie proxy de tranzacționare, iar de atunci încolo proxy-ul semnează ordinele. Credențialele sesiunii expiră implicit după o săptămână. Păstrează-le criptate și folosește chei read-only pentru dashboard-uri.
Cum setez un stop loss prin API-ul Perps?
Atașează declanșatoarele takeProfit și stopLoss la ordinul de intrare, ca bracket, sau apelează placePositionTpSl (place_position_tp_sl în Python) pe o poziție deschisă. Declanșatoarele urmăresc prețul de marcare și ies cu un ordin reduce-only. TP/SL pe poziție închide întreaga poziție la piață.
Care este dimensiunea minimă a unui ordin pe Polymarket Perps?
10 USD valoare nominală per ordin, iar depunerea minimă este de 10 pUSD (în noiembrie 2026). Prețurile și cantitățile trebuie să respecte și numărul de zecimale al fiecărei piețe și să aibă cel mult 5 cifre semnificative, altfel ordinul este respins.
Există un kill switch sau un dead man's switch?
Da. Anularea automată anulează toate ordinele deschise dacă botul tău nu o mai reactivează, iar cancelAllOrders șterge ordinele la cerere. Documentația enumeră anularea automată printre modurile în care un ordin TP/SL poate fi anulat, deci un crash îți poate elimina și stopurile. Scrie-ți și propriul kill switch în cod.
Pot rula un bot Polymarket Perps din SUA sau Canada?
Nu. Plasarea ordinelor Perps nu este permisă din Statele Unite, Canada, Cuba, Iran, Coreea de Nord, Siria, Crimeea, Donețk sau Luhansk. Nu găzdui un bot acolo și nu folosi un VPS sau un VPN ca să ocolești o blocare care ți se aplică.
Sunt permiși boții în competițiile de tranzacționare Polymarket Perps?
Tranzacționarea cu un bot este permisă. Regulile competiției interzic tranzacțiile fictive (wash trading), tranzacționarea cu tine însuți, conturile multiple, tranzacționarea în principal pentru a genera volum și boții sau scripturile destinate manipulării programului. Încălcarea lor poate duce la descalificare.