Multi-symbol scanner: one strategy watches many symbols (up to 200) on the same exchange — per-symbol positions, orders and state, separated automatically.
Ordering on two exchanges from one strategy (legs — cross-exchange arbitrage/hedging): backtests (incl. jobs), paper AND live real orders are supported. Per-leg wallets, fees and an interlocked kill-switch; live requires API keys for every leg before it starts (no half-executed hedge, no silent downgrade). P&L of legs in different currencies is never aggregated (an approximate USD figure is shown for reference only).
Aux-symbol reference: use another symbol/exchange's price as a signal (ctx.ref slots — e.g. watch Binance BTC while trading on Upbit). Works in backtests, paper and live.
Multiple exchanges at once: you can also launch one run per exchange — a single agent holds keys for several exchanges and runs them all in parallel (strategy A on Upbit + strategy B on Binance futures).
Multi-agent cluster: scanner symbols are distributed across several agents automatically and run in parallel (Elite plan + onboarding required).
Data: candles (1m–1d), volume, orderbook, funding rates, open interest/liquidations, macro series (dollar index, US 10y yield, Nasdaq-100, gold — ctx.macro), real FX rates (USD/KRW — ctx.fx; premium math is yours) and external signals (webhooks). Unknown values are null — never faked as 0.
Safety: order caps (guardrails), fee-aware loss kill-switch, dry-run.
Validation: backtests up to 100k bars, walk-forward via fixed end dates, plus a per-tick decision-time estimate in the studio and a live tick monitor (see on the run card whether your server keeps up).
Not supported yet (we don't pretend otherwise):
Splitting legs across different agents — today one agent holds the keys for every leg and executes them all. The compute-central/execute-edge architecture is in development.
Automatic cluster rebalancing — distribution is static. If an agent drops, its symbols wait and the UI says so honestly (they are not silently moved).
Stock (KIS) deploys/live trading — stock candle data and backtests only for now.
Rules
Pure function — no network, no imports, no async. Only the ctx below.
qty is always an amount of coin (not cash).
Indicators return null without enough data — always null-check.
Keep your variables in ctx.state; they persist across calls.
ctx.ref slots use logical names ('hedge' etc.) — real symbols are bound at deploy time.
Order objects
Market: { side: 'buy'|'sell', qty } — walks the book (slippage, partial fills, taker fee).
Limit: { side, qty, type: 'limit', price } — fills at your price with maker fee when touched. postOnly: true rejects a limit that would fill immediately.
Smart (work order): { side, qty, type: 'smart', chase?, slices?, trigger?, hardStopMs? } — executed over time: chasing (peg the book → cross at deadline), slicing, stop/trailing triggers, and a hard time budget, in live and paper runs. Backtests approximate it as a market order — validate with a live paper run.
Cancel all: { cancel: 'all' } — cancels resting limits AND all work orders (chasing can't be stopped by canceling a single order).
The table below is the entire ctx (generated from the same source as the editor autocompletion). To get strategy code from an AI, use Create an AI Strategy or paste the whole AI reference.
ctx
Tato tabulka je generována ze zdrojů, jako je automatické doplňování v editoru a AI dokumentace (/llms.txt) – funkce, které zde nejsou uvedeny, neexistují.
상태
ctx.candle현재 봉 { t, o, h, l, c, v } — t 는 실데이터면 실제 봉 시각(epoch ms), 합성 시세만 봉 번호. ★라이브·페이퍼도 실제 봉 시작 시각(에이전트 1.66.0+ — 그 이전 라이브는 링버퍼 인덱스(499)로 굳어 있었다: 요일·시간대 로직을 쓰면 반드시 1.66.0 이상에서 확인할 것). 시각을 모르는 경로는 null(인덱스를 시각인 척 주지 않는다)
ctx.price현재가(종가)
ctx.closes현재 봉까지의 종가 배열(미래 없음)
ctx.i현재 봉 번호
ctx.position보유 수량(코인). 선물(usdm)에선 부호 수량 — +롱/−숏
ctx.entryPx(선물) 평균 진입가 — 포지션 없으면/spot 이면 null
ctx.liqPx(선물) 격리 청산가(해석해) — 포지션 없으면/spot 이면 null
ctx.uPnl(선물) 미실현손익(quote) — spot 이면 null
ctx.leverage(선물) 현재 레버리지 — spot 이면 null
ctx.funding(선물) 직전 적용 펀딩 rate — 아직 없으면/spot 이면 null
ctx.macd(fast=12, slow=26, sig=9)MACD → {macd, signal, hist} | null. 구간이 모자라면 signal·hist 만 null(macd 는 준다)
ctx.atr(n=14)ATR(평균 진폭) → number | null. 변동성 기반 손절폭·포지션 크기에 쓴다. 구간이 모자라거나 라이브에서 고가·저가를 못 얻으면 null
ctx.stoch(n=14, d=3)스토캐스틱 → {k, d} | null. %K=(종가−최저)/(최고−최저)×100, %D=%K의 SMA(d). 구간이 완전 횡보면 k=50(중립). d 구간이 모자라면 d만 null
오더북
ctx.book()호가 전체 { bids, asks } (좋은 가격 순)
ctx.bid()최우선 매수호가
ctx.ask()최우선 매도호가
ctx.mid()중간가
ctx.spread()호가 차이(절대값)
ctx.spreadPct()호가 차이(중간가 대비 %)
ctx.fillPrice(side, qty)시장가 예상 체결 { avgPx, filled }. filled<qty면 유동성 부족
ctx.depth(side, px)px 까지 쌓인 누적 물량
주문
ctx.openOrders()대기 중인 지정가 목록(읽기 전용, 행에 ex — 작업주문은 workOrders 로)
ctx.workOrders()활성 작업주문(스마트 — 체이싱·분할·트리거 대기) 목록. 백테스트는 트리거 대기분만(체이싱은 봉 해상도에 개념 없음)
스캐너(여러 종목)
ctx.sym이번 호출의 종목(예: "BTC")
ctx.ex이번 틱 종목이 속한 거래소(예: 'upbit'). legs 백테스트·라이브에선 실값, 호출부가 거래소를 안 알려준 단일 백테스트는 null
ctx.wallets()거래소(다리)별 지갑 맵 { upbit: { quote, cash, reserved? }, … } — 단일 실행도 한 다리짜리 맵(거래소를 모르면 'default' 키). 통화가 달라 합산값은 없다 — 환산은 ctx.fx 로 직접
ctx.marketType시장 종류 'spot'|'usdm' — usdm 이면 position 이 부호 수량(+롱/−숏), entryPx·liqPx·uPnl·leverage·funding 필드 추가
ctx.syms시세를 받은 종목 이름 목록
ctx.markets()전 종목 요약 [{ sym, ex, price, ch1, ch5, ch60 }] — ch 는 퍼센트(2 = +2%. change()의 소수 단위와 다름!). 봉이 모자라면 null. 단일 종목 실행에선 그 한 종목만 담긴 배열(빈 배열 아님). ex 는 legs 면 그 다리 거래소, 모르면 null
ctx.market(sym)한 종목 요약 (없으면 null)
ctx.pos(sym, ex?)그 종목 보유 수량(이번 틱 다리 기준). 2번째 인자로 다른 다리(거래소) 지정 조회 — 모르는 다리는 null(0 은 "없음"을 단정하는 거짓)
ctx.positions종목별 보유 수량 스냅샷 { SYM: qty } — 이미 든 종목을 피할 때
ctx.symState현재 종목 전용 저장소(자동 분리) — 종목별 손절가·보유 플래그는 여기에. state.__sym[sym] 과 같은 객체
거래량
ctx.vol현재 봉 거래량 (모르면 null)
ctx.volumes봉별 거래량 배열 (모르면 null)
ctx.avgVol(n)최근 n봉 평균 거래량 (봉이 모자라거나 모르면 null)
멀티에셋·환율
ctx.ref(slot)보조 종목 현재가. 슬롯명은 논리명(예: 'hedge')
ctx.refs사용 가능한 슬롯명 목록
ctx.fx(quote)1 USD 당 해당 통화 값(예: ctx.fx('KRW')). USD 환산은 직접
ctx.fxQuotes사용 가능한 통화 목록
파생 심리(OI·청산)
ctx.binanceOi()(라이브·페이퍼) 현재 종목 최신 미결제약정 { ts, oi, oiUsd } — 바이낸스 USDT-M 5분 집계. 백테스트·수집 전·모르면 null
ctx.binanceLiqs(n)(라이브·페이퍼) 최근 n분(기본 5·최대 60) 강제청산 합계 { longUsd, shortUsd, cnt } — longUsd=롱 청산(하방 압력의 해소). 백테스트·모르면 null. ★행이 없는 분은 "청산 0" 과 "수집 공백" 을 구분할 수 없음
거시 지표(달러·금리·주가·금)
ctx.macro('dxy')거시 지표 { value, day, chg1d, chg7d, chg30d(%) } — 계열: dxy(달러지수)·ust10y(미국채 10년 금리)·ndx(나스닥100)·gold(금). ★전일(완결된 날) 값 — 당일 값은 마감 전 미존재 정보라 주지 않음. 데이터 없거나 14일 이상 낡으면 null. dxy 는 ICE 공식(고정 가중치 동일)을 현물 UTC 종가로 재구성한 값 — 원본 지수 호가와 스냅샷 시각·현물/선물 차이로 ±0.1~0.3 정도 다를 수 있음(추세·변화율 무영향). ust10y 는 공표 지연으로 보통 1~2영업일 늦음(구조적 — chg1d 는 마지막 두 공표일 비교). ★chg 는 **달력일 as-of**: chgNd = (현재값 − '기준일−N일 이하의 가장 최근 관측값')/그 값 — 배열의 N행 전이 아니다(주말·휴장이 있으므로 7행 전 ≠ 7일 전). 외부에서 재현할 땐 이 정의로. 데이터가 첨부한 격자는 **관측일 그대로**(공개 API 기본과 동일 — GET /api/market/macro 는 grid:'raw', ?ffill=1 은 표시용 채움)
ctx.macroSeries사용 가능한 거시 계열 이름 배열(데이터가 실제로 첨부된 것만)
외부 신호(웹훅)
ctx.signal(slot)외부 신호(TradingView 웹훅 등) 조회 { payload, at, age } — payload 는 보낸 JSON 그대로(파싱·해석 안 함), at 은 신호 시각(epoch ms), age 는 경과 초(내림). 백테스트는 현재 봉 시각 이하의 가장 최근 신호(as-of — 미래 신호는 안 보인다), 라이브·페이퍼는 60초 캐시 스냅샷. 신호가 아직 없거나 모르는 slot 이면 null(0·빈객체로 지어내지 않음 — 반드시 null 검사)
로그
ctx.log(...)디버그. 라이브는 분당 20건 서버 전송 제한 — 초과분은 VPS 로컬 파일(runstate/run-<id>.log)에 전량 보존. 백테스트는 500건 상한
ctx.warn(...)중요. 라이브에서 스로틀 없이 항상 서버 전송 + 직전 로그 맥락 동봉 — 촘촘한 검증·이상 신호는 log 대신 이걸 쓰세요
ctx.alert(msg)조건 근접 알림 — 전략이 "진입 조건에 근접했다"고 스스로 판정해 유저에게 알림을 보낸다. msg 는 문자열로 강제(200자 컷)·반환값 없음. 라이브·페이퍼는 run 당 60초 쿨다운으로 발송(60초 내 재호출은 무시 — 로그에 남음), 백테스트는 발송 없이 로그에 [알림] 으로만 기록(상한 50개, 초과는 개수만 alertsDropped)
Klíč objednávky
side'buy' | 'sell'
qty수량(코인). 현금이 아니다
type'limit'=지정가, 'smart'=작업 주문(시간에 걸쳐 집행 — 체이싱·분할·트리거). 기본은 시장가. smart 는 라이브·페이퍼에서 집행되고 백테스트는 시장가로 근사
price지정가일 때의 가격
postOnlytrue 면 즉시 체결될 지정가는 거부(메이커만)
chasesmart: 호가 추격 { escalateMs?=20000, deadlineMs?=45000, bandTicks?, minRepegMs? } — 호가 조인(메이커)→1틱 전진→마감 시 크로스(테이커). 기본 켜짐, false 면 끔
slicessmart: 분할 { n, everyMs } — 수량을 n조각으로 everyMs 간격 집행
triggersmart: 조건 대기 { type:'stop'|'trail', px?, offset? } — 조건이 닿기 전엔 주문이 안 나간다. 실데이터 백테스트도 봉 h/l 로 발동 판정(2026-08, 체결 라벨 stop/trail)