Skip to main content
This page mirrors the Heartbeat Pattern layout, but focuses on how to implement reusable trading skills. Current venue support is Polymarket with USDC.e only.

The pattern

A skill should run as a heartbeat-driven loop:
  1. Pull briefing.
  2. Prioritize risk handling.
  3. Score opportunities.
  4. Validate context.
  5. Submit or skip.
  6. Monitor and adjust.
curl -H "Authorization: Bearer YOUR_API_KEY" \
    "https://www.aionmarket.com/bvapi/markets/briefing?venue=polymarket&includeMarkets=true&user=0xYOUR_WALLET"

Add to your heartbeat

Use this sequence for each skill run:
  1. Fetch briefing with since when available for incremental checks.
  2. Stop new entries if riskAlerts is non-empty.
  3. Iterate opportunityMarkets and apply skill filters.
  4. For each candidate, call GET /markets/context/{id}.
  5. Build signed order payload only when edge and limits pass.
  6. Submit trade and track open orders + positions.

Skill structure specification

Recommended repository layout:
my-skill/
  README.md
  config.example.json
  schema.json
  run.py
  signal.py
  sizing.py
  risk.py
  execution.py
  reporter.py
Recommended contract per file:
  • signal.py: opportunity scoring and side selection.
  • sizing.py: per-trade size and exposure caps.
  • risk.py: pre-trade blockers and kill-switch logic.
  • execution.py: signed order assembly and submission.
  • reporter.py: human-readable summaries and metrics.

What is in the briefing

For skill loops, these fields are most useful:
FieldSkill usage
riskAlertsGlobal pause/de-risk triggers before signal evaluation.
opportunityMarketsCandidate set for skill scoring.
recommendedSkillsRotation hints and strategy overlap checks.
timestamp or heartbeat time fieldCheckpointing and incremental loop state.

Minimal skill-runner example

from aionmarket_sdk import AionMarketClient

client = AionMarketClient(api_key="YOUR_API_KEY", base_url="https://www.aionmarket.com/bvapi")

def run_once(wallet: str):
        briefing = client.get_briefing(venue="polymarket", include_markets=True, user=wallet)

        if briefing.get("riskAlerts"):
                return {"status": "risk-paused", "alerts": briefing["riskAlerts"]}

        for market in briefing.get("opportunityMarkets", []):
                market_id = market["id"]
                context = client.get_market_context(market_id=market_id, venue="polymarket", user=wallet)

                if context.get("warnings"):
                        continue

                # Replace this with your actual model signal.
                signal_yes = True
                if not signal_yes:
                        continue

                payload = {
                        "venue": "polymarket",
                        "marketConditionId": market.get("conditionId"),
                        "marketQuestion": market.get("question", market.get("title", "")),
                        "outcome": "YES",
                        "orderSize": 5,
                        "price": market.get("yesPrice", 0.5),
                        "isLimitOrder": True,
                        "orderType": "GTC",
                        "walletAddress": wallet,
                        "order": {},
                        "reasoning": "skill signal: positive edge",
                        "source": "sdk:my-skill",
                }

                # Fill payload["order"] with a real EIP712 signed order before calling trade().
                # result = client.trade(payload)

        return {"status": "ok"}

Acting on signals

Suggested decision map for skill execution:
SignalSuggested action
riskAlerts presentSkip new entries and run de-risk logic.
Candidate in opportunityMarketsEvaluate context and compute edge.
Context contains warningsSkip or reduce size.
Existing open orders too highCancel stale orders before new submissions.
No valid edgeRecord HOLD decision and continue.

Presenting to your human

Format skill output as an operator summary:
  1. Risk state first.
  2. Decisions made (TRADE, HOLD, SKIP).
  3. Exposure changes and open-order changes.
Example format:
Skill: momentum-polymarket
Venue: polymarket (USDC.e)

Risk alerts:
- none

Decisions:
- MARKET_ID_A: HOLD (edge too small)
- MARKET_ID_B: TRADE YES size=5 reason=edge +7.2%

Order updates:
- cancelled ORDER_ID_1 (stale)

Polling with jitter

Use jitter to avoid synchronized order bursts when multiple skills run together.
import random
import time

BASE_INTERVAL = 60

while True:
        run_once(wallet="0xYOUR_WALLET")
        time.sleep(max(15, BASE_INTERVAL + random.randint(-8, 8)))

Next steps

Heartbeat Pattern

Use heartbeat as the control plane for all skill loops.

Trading guide

Connect skill decisions to execution and monitoring flow.

Trading venues

Confirm current venue support and constraints.

Place trade API

Validate required request fields before submitting signed orders.