Slik fungerer replayen
- Meld deg på konkurransen via event-listen på AI Camp
- Hent token fra Min Side etter påmelding
- Les markedet med
GET /api/trading/market?competition=crypto-replay-arena - Legg inn ordre med
POST /api/trading/orders?competition=crypto-replay-arena - Ordren venter til neste candle åpner og fylles til neste candle-open-pris
- Følg porteføljen din i sanntid og justér strategien underveis
Replayen drives fremover av en autoritativ cron-jobb (POST /api/trading/admin/tick). Les-endepunkter muterer ingen tilstand.
Autentisering
Alle endepunkter krever et Bearer-token i Authorization-headeren:
Authorization: Bearer <din-token>
Hent tokenet ditt fra Min Side på aicamp.no etter påmelding. Token-et er unikt per konkurranse og skilt fra innloggingssession.
Rate limit (ordre): Maks 5 ordre per 10 sekunder per lag, og 20 per 10 sekunder per IP-adresse. For mange forespørsler gir 429 med Retry-After-header.
Kom i gang
Python (kun standardbibliotek)
import urllib.request, urllib.parse, json, os
TOKEN = os.environ["AICAMP_TOKEN"]
BASE = "https://aicamp.no"
COMPETITION = "crypto-replay-arena"
def api(method, path, body=None):
req = urllib.request.Request(
BASE + path,
method=method,
data=json.dumps(body).encode() if body else None,
headers={
"Authorization": f"Bearer {TOKEN}",
"Content-Type": "application/json",
}
)
with urllib.request.urlopen(req) as r:
return json.loads(r.read())
def qs(params):
return "?" + urllib.parse.urlencode(params)
# Hent markedsdata
market = api("GET", f"/api/trading/market{qs({'competition': COMPETITION})}")
candle = market["market"]["current_candle"]
print(f"BTC close: {candle['close']} USDT")
# Hent portefølje
portfolio = api("GET", f"/api/trading/portfolio{qs({'competition': COMPETITION})}")
print(f"Total verdi: {portfolio['portfolio']['total_value']} USDT")
print(f"Avkastning: {portfolio['portfolio']['return_pct']}%")
# Legg inn kjøpsordre
order = api("POST", f"/api/trading/orders{qs({'competition': COMPETITION})}",
{"side": "buy", "quantity": "0.01"})
print(f"Ordre {order['order']['id']}: {order['order']['status']}")
curl
export TOKEN="din-token-her"
COMP="crypto-replay-arena"
# Markedsdata
curl "https://aicamp.no/api/trading/market?competition=$COMP" \
-H "Authorization: Bearer $TOKEN"
# Portefølje
curl "https://aicamp.no/api/trading/portfolio?competition=$COMP" \
-H "Authorization: Bearer $TOKEN"
# Kjøp 0.01 BTC
curl -X POST "https://aicamp.no/api/trading/orders?competition=$COMP" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"side": "buy", "quantity": "0.01"}'
API-endepunkter
| Metode | Endepunkt | Beskrivelse |
|---|---|---|
| GET | /api/trading/competitions | Liste over aktive trading-konkurranser |
| GET | /api/trading/market?competition=crypto-replay-arena | Nåværende candle + historikk |
| GET | /api/trading/portfolio?competition=crypto-replay-arena | Portefølje, verdi og avkastning |
| GET | /api/trading/orders?competition=crypto-replay-arena | Ordrehistorikk |
| POST | /api/trading/orders?competition=crypto-replay-arena | Legg inn ny ordre |
| GET | /api/trading/leaderboard?competition=crypto-replay-arena | Leaderboard |
| GET | /api/trading/review?competition=crypto-replay-arena | Frossen sluttgjennomgang (etter konkurranseslutt) |
Markedsdata
curl "https://aicamp.no/api/trading/market?competition=crypto-replay-arena" \
-H "Authorization: Bearer $TOKEN"
{
"competition": {
"slug": "crypto-replay-arena",
"status": "live",
"starting_cash": "10000.00000",
"fee_rate": "0.001",
"replay": {
"current_step": 42,
"total_steps": 120,
"tick_seconds": 60,
"next_open_at": "2026-01-15T01:43:00.000Z",
"now": "2026-01-15T01:42:30.000Z"
}
},
"market": {
"symbol": "BTCUSDT",
"base_asset": "BTC",
"quote_asset": "USDT",
"interval": "1m",
"current_candle": {
"open_time": "2026-01-15T01:42:00.000Z",
"close_time": "2026-01-15T01:42:59.999Z",
"open": "97500.00000",
"high": "97800.00000",
"low": "97200.00000",
"close": "97650.00000",
"volume": "12.34500"
},
"next_candle": {
"open_time": "2026-01-15T01:43:00.000Z",
"open": "97700.00000"
},
"candles": [
{ "open_time": "...", "open": "...", "high": "...", "low": "...", "close": "...", "volume": "..." }
]
}
}
Nøkkelfelt å se etter:
competition.replay.current_step/total_steps— hvor langt i replayen du ercompetition.replay.next_open_at— tidspunktet neste candle åpner (og ordren din fylles)market.current_candle— nåværende prisdatamarket.next_candle— neste candle (åpningspris er det ordren fylles til)market.candles— historisk prisdata (maks 50 candles som standard, bruk?limit=Nfor å justere)
Portefølje
curl "https://aicamp.no/api/trading/portfolio?competition=crypto-replay-arena" \
-H "Authorization: Bearer $TOKEN"
{
"competition": { "slug": "crypto-replay-arena", "status": "live" },
"portfolio": {
"scope": "individual",
"cash_balance": "9500.00000",
"asset_balance": "0.05000",
"reserved_cash": "0.00000",
"reserved_asset": "0.00000",
"available_cash": "9500.00000",
"available_asset": "0.05000",
"asset_symbol": "BTC",
"quote_symbol": "USDT",
"mark_price": "97650.00000",
"asset_value": "4882.50000",
"total_value": "14382.50000",
"pnl": "4382.50000",
"return_pct": "43.82",
"fees_paid": "4.88500",
"frozen": false
},
"review": null
}
Nøkkelfelt:
available_cash— kontanter du faktisk kan handle for (cash minus reservert)available_asset— BTC du faktisk kan selge (asset minus reservert)total_value— samlet verdi av cash + BTC tilmark_pricereturn_pct— avkastning i prosent siden startreserved_cash/reserved_asset— holdt av til ventende ordrefrozen: truebetyr konkurransen er avsluttet og porteføljen er fryst
Ordrehistorikk
curl "https://aicamp.no/api/trading/orders?competition=crypto-replay-arena" \
-H "Authorization: Bearer $TOKEN"
{
"competition": { "slug": "crypto-replay-arena", "status": "live" },
"portfolio": { "..." },
"orders": [
{
"id": 42,
"side": "buy",
"type": "market",
"status": "filled",
"quantity": "0.05000",
"submitted_step": 40,
"target_step": 41,
"submitted_at": "2026-01-15T01:40:30.000Z",
"executed_at": "2026-01-15T01:41:00.000Z",
"executed_step": 41,
"fill_price": "97200.00000",
"gross_quote": "4860.00000",
"net_quote": "4908.60000",
"fee": "4.86000",
"asset_symbol": "BTC",
"quote_symbol": "USDT"
}
]
}
Ordrestatuser: pending (venter på neste candle), filled (utført), rejected (avvist).
Legg inn ordre
curl -X POST "https://aicamp.no/api/trading/orders?competition=crypto-replay-arena" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"side": "buy", "quantity": "0.05"}'
{
"code": null,
"competition": { "slug": "crypto-replay-arena", "status": "live" },
"order": {
"id": 43,
"side": "buy",
"type": "market",
"status": "pending",
"quantity": "0.05000",
"requested_price": "97650.00000",
"submitted_step": 42,
"target_step": 43,
"submitted_at": "2026-01-15T01:42:30.000Z",
"fill_price": null,
"fee": null,
"reserved_quote": "4931.36250",
"asset_symbol": "BTC",
"quote_symbol": "USDT"
}
}
Ordren har status: "pending" til neste candle åpner. Da settes fill_price til neste candle-open-pris og fee trekkes automatisk.
Request body:
| Felt | Type | Beskrivelse |
|---|---|---|
side | "buy" eller "sell" | Retning |
quantity | streng (desimaltall) | Mengde BTC, f.eks. "0.05" |
Avvist ordre
Hvis ordren avvises returneres HTTP 409 med en feilkode:
{
"error": "Ikke nok tilgjengelige kontanter i porteføljen",
"code": "overspend",
"competition": { "..." },
"order": { "..." }
}
| Kode | Beskrivelse |
|---|---|
overspend | Ikke nok kontanter til å kjøpe |
oversell | Ikke nok BTC å selge |
pre_open | Konkurransen har ikke startet ennå |
post_close | Konkurransen er avsluttet |
invalid_side | side må være buy eller sell |
invalid_quantity | Mengde må være større enn null |
Sluttgjennomgang
Etter at konkurransen er avsluttet fryses porteføljen automatisk. Bruk review-endepunktet for å se sluttresultatet:
curl "https://aicamp.no/api/trading/review?competition=crypto-replay-arena" \
-H "Authorization: Bearer $TOKEN"
{
"competition": { "slug": "crypto-replay-arena", "status": "completed" },
"portfolio": { "frozen": true, "settled_at": "2026-04-27T12:05:00.000Z" },
"review": {
"available": true,
"frozen": true,
"settled_at": "2026-04-27T12:05:00.000Z",
"final_mark_price": "102500.00000",
"final_total_value": "14250.00000",
"final_pnl": "4250.00000",
"final_return_pct": "42.50",
"order_count": 5,
"filled_order_count": 4,
"rejected_order_count": 1,
"turnover": "19500.00000",
"fees_paid": "19.50000"
}
}
Tokenet ditt er gyldig til read-only review i 30 dager etter konkurranseslutt.
Feilkoder
| Statuskode | Beskrivelse |
|---|---|
400 | Ugyldig forespørsel — sjekk side og quantity |
401 | Ugyldig eller manglende token |
404 | Konkurransen finnes ikke |
409 | Ordren ble avvist — se code-feltet for årsak |
429 | For mange ordre — se Retry-After-headeren |
500 | Serverfeil |
Alle feilsvar har formen {"error": "Forklaring...", "code": "kode"}.
Regler
- Startkapital: 10 000 USDT
- Marked: BTCUSDT (Binance historiske klines)
- Gebyr: 0.1% per kjøp og salg
- Ordretype: kun market-ordre
- Replay-motor: tick-basert cron-jobb (
POST /api/trading/admin/tick) - Slutt: etter siste candle fryses konkurransen automatisk
- Review-vindu: token er gyldig til read-only i 30 dager etter slutt
Tips
- Hent markedsdata og portefølje i én polling-loop for å holde oversikten
- Sjekk
available_cash(ikkecash_balance) før du plasserer en kjøpsordre - En
pending-ordre reserverer midler — legg ikke inn doble ordre - Følg
competition.replay.next_open_atfor å vite nøyaktig når ordren fylles - Bruk
competition.replay.current_step/total_stepsfor å vite når replayen slutter - Sett
?limit=200på market-endepunktet for å hente mer historikk til analyse - Automatiserte agenter som reagerer på prisendringer vil alltid slå manuell trading