본문으로 건너뛰기
SDK 레퍼런스

TypeScript SDK

@spectre-trade/terminal 패키지의 클라이언트, 스트림, 터미널 탐색, 오류.

설치

npm install @spectre-trade/terminal

Terminal

실행 중인 터미널 하나의 클라이언트입니다.

토큰으로 생성하거나, Terminal.discover가 포트와 토큰을 찾고 API 버전을 확인하도록 합니다. 모든 메서드는 async이며, 2xx가 아닌 응답에는 ApiError를, 응답이 없으면 TerminalUnreachableError를 던집니다.

필드타입설명
hoststring
portnumber
timeoutMsnumber
baseUrlstringhttp://127.0.0.1:48180/v1/ — 토큰은 여기에 포함되지 않습니다.

Terminal()

new Terminal(options: TerminalOptions)

discover()

static discover(options: DiscoverOptions = {}): Promise<Terminal>

터미널을 찾아 확인합니다: 토큰은 options.token 또는 SPECTRE_LOCAL_API_TOKEN에서(없으면 TokenMissingError), 포트는 options.port 또는 instance.json에서(없으면 48180; 파일에 API가 꺼져 있다고 적혀 있으면 LocalApiDisabledError) 가져온 뒤, GET /v1/meta를 한 번 호출합니다. api_version이 "1"이 아니면 IncompatibleTerminalError이고, unauthorized 응답은 토큰이 오래되었거나 API가 꺼졌을 수 있다는 메시지를 담은 ApiError입니다.

옵션타입설명
token선택stringSPECTRE_LOCAL_API_TOKEN보다 우선합니다.
port선택numberinstance.json보다 우선합니다.
host선택string
timeoutMs선택number
instancePath선택stringOS별 instance.json 경로 대신 이 파일을 읽습니다(테스트용).

meta()

meta(): Promise<Meta>

GET /v1/meta: API 버전, 빌드, 토큰 권한, 제한, 스트림 토픽입니다.

HTTP 작업: GET /v1/meta

health()

health(): Promise<Health>

GET /v1/health.

HTTP 작업: GET /v1/health

connections()

connections(): Promise<List<Connection>>

GET /v1/connections (connections:read).

HTTP 작업: GET /v1/connections

connection()

connection(id: number): Promise<Connection>

GET /v1/connections/{id} (connections:read); 알 수 없는 id는 not_found입니다.

HTTP 작업: GET /v1/connections/{id}

instruments()

instruments(options: InstrumentsOptions): Promise<InstrumentsPage>

GET /v1/instruments (market:read): 거래소와 마켓의 카탈로그 한 페이지이며, connectionId 또는 exchange + market으로 지정합니다. next_cursor를 직접 따라가거나 iterInstruments를 사용합니다.

HTTP 작업: GET /v1/instruments

옵션타입설명
connectionId선택number
exchange선택string
market선택string
q선택string심볼 또는 기준 코인의 부분 문자열이며, 대소문자를 구분하지 않습니다.
limit선택number1–2000, 기본값은 500입니다.
cursor선택string이전 페이지의 next_cursor입니다.

iterInstruments()

iterInstruments(options: InstrumentsOptions): AsyncGenerator<Instrument, void, undefined>

옵션에 맞는 모든 종목을 페이지 단위로 차례로 반환합니다.

옵션타입설명
connectionId선택number
exchange선택string
market선택string
q선택string심볼 또는 기준 코인의 부분 문자열이며, 대소문자를 구분하지 않습니다.
limit선택number1–2000, 기본값은 500입니다.
cursor선택string이전 페이지의 next_cursor입니다.

intervals()

intervals(): Promise<Intervals>

GET /v1/market/intervals (market:read): 캔들과 클러스터의 인터벌입니다.

HTTP 작업: GET /v1/market/intervals

candles()

candles(instrument: InstrumentAddress, options: CandlesOptions): Promise<Candles>

GET /v1/market/candles (market:read): 캔들 히스토리이며, 오래된 것부터 나열됩니다.

HTTP 작업: GET /v1/market/candles

옵션타입설명
intervalstring/v1/market/intervals의 코드입니다: 1m, 5m, …
limit선택number최대 2000, 기본값은 500입니다.
end선택numberUTC 밀리초로 나타낸 오른쪽 경계이며, 기본값은 현재 시각입니다.
connectionId선택number

trades()

trades(instrument: InstrumentAddress, options: TradesOptions = {}): Promise<Trades>

GET /v1/market/trades (market:read): 페어의 최근 체결이며, 오래된 것부터 최신 순입니다. 구독이 없는 페어는 요청 시 열리므로 호출에 최대 3초가 걸릴 수 있습니다.

HTTP 작업: GET /v1/market/trades

옵션타입설명
limit선택number최근 1–1000건, 기본값은 100입니다.
sinceTs선택number이 수신 시각 이후만 해당하며, UTC 밀리초입니다.
connectionId선택number

snapshot()

snapshot(instrument: InstrumentAddress, options: ConnectionOptions = {}): Promise<Snapshot>

GET /v1/market/snapshot (market:read): 최우선 매수/매도 호가, 마지막 체결, 마크 가격, 티커입니다.

HTTP 작업: GET /v1/market/snapshot

옵션타입설명
connectionId선택number

orderbook()

orderbook(instrument: InstrumentAddress, options: OrderbookOptions = {}): Promise<Orderbook>

GET /v1/market/orderbook (market:read); 3초 안에 전체 호가창이 없으면 unavailable입니다.

HTTP 작업: GET /v1/market/orderbook

옵션타입설명
depth선택number1–200, 기본값은 50입니다.
connectionId선택number

clusters()

clusters(instrument: InstrumentAddress, options: ConnectionOptions = {}): Promise<Clusters>

GET /v1/market/clusters (market:read): 터미널에서 선택된 인터벌의 버킷 최대 10개입니다. 창에 열려 있지 않은 종목에 대한 첫 호출은 not_active(409)로 응답할 수 있으며, 몇 초 뒤 다시 시도하면 클러스터를 찾습니다.

HTTP 작업: GET /v1/market/clusters

옵션타입설명
connectionId선택number

accountOrders()

accountOrders(connectionId: number): Promise<AccountOrders>

GET /v1/account/orders (account:read): 한 연결의 미체결 주문과 트리거 주문이며, 터미널 창에 보이는 것과 같은 상태입니다. 알 수 없는 연결은 not_found입니다.

HTTP 작업: GET /v1/account/orders

accountPositions()

accountPositions(connectionId: number): Promise<AccountPositions>

GET /v1/account/positions (account:read): 한 연결의 열린 포지션입니다.

HTTP 작업: GET /v1/account/positions

accountBalances()

accountBalances(connectionId: number): Promise<AccountBalances>

GET /v1/account/balances (account:read): 통화별로, API를 켠 뒤 거래소가 보낸 최신 값입니다. 그 뒤로 변동이 없는 통화는 포함되지 않습니다.

HTTP 작업: GET /v1/account/balances

accountFills()

accountFills(connectionId: number, options: AccountFillsOptions = {}): Promise<AccountFills>

GET /v1/account/fills (account:read): API를 켠 뒤 연결의 체결 내역 (최근 1000건)이며, 오래된 것부터 최신 순입니다.

HTTP 작업: GET /v1/account/fills

옵션타입설명
limit선택number최근 1–1000건, 기본값은 100입니다.
sinceTs선택number이 거래소 시각 이후만 해당하며, UTC 밀리초입니다.

placeOrder()

placeOrder(options: PlaceOrderOptions): Promise<Accepted>

POST /v1/orders (trading:write): 창이 쓰는 것과 같은 명령으로 지정가 또는 시장가 주문을 넣습니다. 응답은 거래소가 아니라 터미널이 접수했다는 뜻입니다: 스트림의 account.orders나 accountOrders에서 key로 주문을 지켜봅니다. 비활성화되었거나 읽기 전용이거나 자격 증명이 없는 연결은 not_tradable(409), 다른 거래소나 마켓의 종목이거나 수량 또는 가격이 거부되면 invalid_request(400), limits.commands_per_second를 넘으면 rate_limited(429)입니다.

HTTP 작업: POST /v1/orders

옵션타입설명
connectionIdnumber거래 연결이며, 기본값은 없습니다.
instrumentInstrumentAddress
sideSide
typeOrderTypelimit에는 price가 필요하고, market은 받지 않습니다.
price선택Decimal
size선택Decimal기준 코인 단위의 수량이며, size와 notional 중 정확히 하나만 전달합니다.
notional선택Decimal호가 통화 금액이며, size와 notional 중 정확히 하나만 전달합니다.
reduceOnly선택boolean기본값은 false입니다.
postOnly선택boolean기본값은 false입니다.
timeInForce선택TimeInForce없으면 거래소의 기본값입니다.
clientKey선택string멱등성 키입니다: 같은 키로 반복하면 이전 응답을 반환하고 주문을 중복해서 넣지 않습니다(터미널은 최근 1000개를 기억합니다).

cancelOrder()

cancelOrder(options: CancelOrderOptions): Promise<Accepted>

DELETE /v1/orders/{id} (trading:write): 터미널 키(t-…) 또는 거래소의 id로 주문 하나를 취소합니다. 취소는 거래소로 직접 전달되며, 확인은 스트림으로 도착합니다.

HTTP 작업: DELETE /v1/orders/{id}

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress
orderIdstring터미널 키(t-…) 또는 거래소의 주문 id입니다.

cancelAll()

cancelAll(options: InstrumentCommandOptions): Promise<Accepted>

POST /v1/orders/cancel-all (trading:write): 스페이스 바를 누른 것처럼 종목의 모든 주문을 취소합니다.

HTTP 작업: POST /v1/orders/cancel-all

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress

closePosition()

closePosition(options: InstrumentCommandOptions): Promise<Accepted>

POST /v1/positions/close (trading:write): 창이 하는 방식 그대로 종목의 포지션을 청산합니다 — 선물에서는 포지션 크기만큼의 시장가 주문, 현물에서는 "모두 취소하고 청산"을 하나의 원자적 명령으로 처리합니다. 열린 포지션이 없으면 invalid_request입니다.

HTTP 작업: POST /v1/positions/close

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress

placeTrigger()

placeTrigger(options: PlaceTriggerOptions): Promise<Accepted>

POST /v1/orders/trigger (trading:write): 창이 쓰는 것과 같은 서비스로 넣는 스톱로스, 테이크프로핏 또는 스톱입니다. stop_loss와 take_profit은 열린 포지션에 걸립니다(방향, 수량, 규칙을 포지션에서 가져오며, 포지션이 없으면 invalid_request). stop에는 side와 notional이 필요합니다. 응답의 key는 트리거의 키(sl_…, tp_…, stop_…)이며, accountOrders에서 트리거의 client_id로 나타납니다. 취소와 수정에는 그곳의 숫자 id를 사용합니다. 터미널에 트리거 주문이 없는 거래소에서는 unsupported(501)입니다.

HTTP 작업: POST /v1/orders/trigger

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress
kindTriggerTypestop_loss와 take_profit은 열린 포지션에 걸리며, stop은 자체 주문입니다.
triggerPriceDecimal
side선택Sidestop 전용입니다.
notional선택Decimalstop 전용입니다: 호가 통화 금액입니다.
rule선택TriggerRulestop 전용입니다. 없으면 매수는 시장 가격 위, 매도는 시장 가격 아래를 뜻합니다.
clientKey선택string멱등성 키이며, Terminal.placeOrder에서와 같습니다.

cancelTrigger()

cancelTrigger(options: CancelTriggerOptions): Promise<Accepted>

DELETE /v1/orders/trigger/{id} (trading:write): 숫자 id로 트리거 하나를 취소합니다.

HTTP 작업: DELETE /v1/orders/trigger/{id}

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress
triggerIdstring | numberaccountOrders().triggers에 있는 트리거의 숫자 id입니다.

cancelAllTriggers()

cancelAllTriggers(options: InstrumentCommandOptions): Promise<Accepted>

POST /v1/orders/trigger/cancel-all (trading:write): 종목의 모든 트리거를 취소합니다. 일반 주문은 그대로 남습니다.

HTTP 작업: POST /v1/orders/trigger/cancel-all

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress

amendTrigger()

amendTrigger(options: AmendTriggerOptions): Promise<Accepted>

PATCH /v1/orders/trigger/{id} (trading:write): 트리거를 새 가격으로 옮깁니다 — 창과 같은 순차 교체로, 취소한 뒤 다시 넣습니다. kind는 필수이며, stop에는 side도 필요합니다. key는 null입니다.

HTTP 작업: PATCH /v1/orders/trigger/{id}

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress
triggerIdstring | numberaccountOrders().triggers에 있는 트리거의 숫자 id입니다.
kindTriggerType
triggerPriceDecimal
side선택Sidestop 전용입니다.
rule선택TriggerRulestop 전용입니다.

leverage()

leverage(options: InstrumentCommandOptions): Promise<Leverage>

GET /v1/account/leverage (account:read): 선물 종목의 레버리지와 마진 모드이며, 터미널의 캐시에서 가져옵니다. 터미널이 아직 다루지 않은 종목은 not_active(409)입니다: 창에서 종목을 열거나 setLeverage를 호출하면 캐시에 들어갑니다.

HTTP 작업: GET /v1/account/leverage

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress

setLeverage()

setLeverage(options: SetLeverageOptions): Promise<Accepted>

POST /v1/account/leverage (trading:write): 창이 하는 방식 그대로 레버리지를 설정합니다 — leverage(1 이상의 정수)와 mode(max, smart) 중 정확히 하나만 전달합니다. 적용된 값은 거래소가 응답한 뒤 leverage에 나타납니다.

HTTP 작업: POST /v1/account/leverage

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress
leverage선택number1 이상의 정수입니다.
mode선택"max" | "smart"

setMarginMode()

setMarginMode(options: SetMarginModeOptions): Promise<Accepted>

POST /v1/account/margin-mode (trading:write): cross 또는 isolated입니다. 포지션이 열려 있는 동안의 변경은 창에서와 같이 거래소가 거부하며, accepted 응답에는 아직 이것이 나타나지 않습니다.

HTTP 작업: POST /v1/account/margin-mode

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress
marginModeMarginMode

workspace()

workspace(): Promise<Workspace>

GET /v1/workspace (workspace:read): 모든 창과 그 탭, 스택, 차트이며, 창이 구조가 바뀔 때마다 게시하는 스냅샷에서 가져옵니다. id는 터미널의 이번 실행에서만 쓰이는 내부 번호입니다.

HTTP 작업: GET /v1/workspace

workspaceWindow()

workspaceWindow(options: WindowOptions): Promise<WorkspaceWindow>

GET /v1/workspace/windows/{id} (workspace:read): 창 하나이며, 알 수 없는 id는 not_found입니다.

HTTP 작업: GET /v1/workspace/windows/{id}

옵션타입설명
windowIdnumber

openStack()

openStack(options: OpenStackOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/stacks (workspace:write): 종목의 스택을 새 탭 또는 새 창에 열며, chart가 설정되어 있으면 그 위에 차트를 함께 엽니다. 응답은 창, 탭, 새 위젯을 알려 줍니다. 터미널의 카탈로그에 없는 종목은 invalid_request입니다.

HTTP 작업: POST /v1/workspace/stacks

옵션타입설명
instrumentInstrumentAddress
connectionId선택number생략하면 공통 규칙에 따라 선택됩니다.
chart선택boolean스택 위에 여는 같은 종목의 차트입니다.
target선택OpenTargetnew_tab(기본값) 또는 new_window입니다.
windowId선택number새 탭을 열 창이며, 생략하면 포커스된 창입니다.
activate선택booleanfalse는 탭을 백그라운드에서 엽니다. 새 창은 항상 포커스를 가져갑니다.

openTab()

openTab(options: OpenTabOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/tabs (workspace:write): 항목마다 열 하나 — 스택과, chart가 있으면 그 위의 차트 — 를 배치한 탭을 새 탭 또는 새 창에 엽니다. name을 생략하면 유일한 종목, 또는 첫 종목에 개수를 붙인 이름이 됩니다. 거부 시에는 해당 항목(items[1]: …)을 알려 주며, 창에는 아무것도 전달되지 않습니다.

HTTP 작업: POST /v1/workspace/tabs

옵션타입설명
itemsArray<TabItemOptions | InstrumentAddress>순서대로 나열한 열이며, 1개에서 50개까지입니다. 주소만 쓰면 차트 없는 스택입니다.
name선택string최대 64자이며, 생략하면 터미널이 종목 이름을 따라 탭 이름을 짓습니다.
target선택OpenTargetnew_tab(기본값) 또는 new_window입니다.
windowId선택number새 탭을 열 창이며, 생략하면 포커스된 창입니다.
activate선택booleanfalse는 탭을 백그라운드에서 엽니다. 새 창은 항상 포커스를 가져갑니다.

addStacks()

addStacks(options: AddStacksOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/windows/{id}/tabs/{tab}/stacks (workspace:write): 같은 열을 탭의 마지막 열 뒤에 추가합니다. 탭의 이름과 열 너비는 그대로 유지됩니다. 응답에는 추가된 위젯만 나열됩니다.

HTTP 작업: POST /v1/workspace/windows/{id}/tabs/{tab}/stacks

옵션타입설명
windowIdnumber
tabIdnumber
itemsArray<TabItemOptions | InstrumentAddress>순서대로 나열한 열이며, 1개에서 50개까지입니다. 주소만 쓰면 차트 없는 스택입니다.

openMultiview()

openMultiview(options: OpenMultiviewOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/multiview (workspace:write): «거래소 배치»의 모든 거래소에 코인을 열며, 창의 멀티뷰 버튼과 같은 계획을 따릅니다. 코인에 해당하는 셀이 없으면 not_found입니다.

HTTP 작업: POST /v1/workspace/multiview

옵션타입설명
basestring코인(BTC) 또는 페어(BTC/USDT)입니다.
target선택OpenTarget생략하면 멀티뷰의 «열기» 설정이 결정합니다.
windowId선택number
activate선택boolean

setStackInstrument()

setStackInstrument(options: StackInstrumentOptions): Promise<WorkspaceOutcome>

PATCH /v1/workspace/stacks/{widget_id} (workspace:write): 스택과 그 차트의 종목을 다른 종목으로 바꿉니다.

HTTP 작업: PATCH /v1/workspace/stacks/{widget_id}

옵션타입설명
widgetIdnumber
instrumentInstrumentAddress
connectionId선택number

closeStack()

closeStack(options: StackOptions): Promise<WorkspaceOutcome>

DELETE /v1/workspace/stacks/{widget_id} (workspace:write): 스택의 닫기 버튼처럼 스택 하나를 닫습니다.

HTTP 작업: DELETE /v1/workspace/stacks/{widget_id}

옵션타입설명
widgetIdnumber

closeTab()

closeTab(options: TabOptions): Promise<WorkspaceOutcome>

DELETE /v1/workspace/windows/{id}/tabs/{tab} (workspace:write): 창의 유일한 탭은 invalid_request입니다.

HTTP 작업: DELETE /v1/workspace/windows/{id}/tabs/{tab}

옵션타입설명
windowIdnumber
tabIdnumber

activateTab()

activateTab(options: TabOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/windows/{id}/tabs/{tab}/activate (workspace:write): 탭을 선택합니다. 창의 포커스는 바뀌지 않습니다.

HTTP 작업: POST /v1/workspace/windows/{id}/tabs/{tab}/activate

옵션타입설명
windowIdnumber
tabIdnumber

closeWindow()

closeWindow(options: WindowOptions): Promise<WorkspaceOutcome>

DELETE /v1/workspace/windows/{id} (workspace:write): 메인 창은 invalid_request입니다.

HTTP 작업: DELETE /v1/workspace/windows/{id}

옵션타입설명
windowIdnumber

activateWindow()

activateWindow(options: WindowOptions): Promise<WorkspaceOutcome>

POST /v1/workspace/windows/{id}/activate (workspace:write): 최소화되어 있으면 복원하고 맨 앞으로 가져옵니다.

HTTP 작업: POST /v1/workspace/windows/{id}/activate

옵션타입설명
windowIdnumber

settings()

settings(options: SettingsOptions = {}): Promise<Settings>

GET /v1/settings (settings:read): 저장된 그대로의 행이며, 기본값 단계는 채우지 않습니다. 옵션이 없으면 연결이 없는 전역 행입니다. 각 행은 updateSettings로 쓸 수 있는지를 writable로 알려 줍니다.

HTTP 작업: GET /v1/settings

옵션타입설명
scope선택"global" | "order_book"global(기본값) 또는 order_book입니다.
category선택string
key선택string
connectionId선택number연결의 행이며, 없으면 연결이 없는 행입니다.
instrument선택InstrumentAddress페어의 행입니다(scope order_book).

orderbookSettings()

orderbookSettings(options: InstrumentCommandOptions): Promise<OrderbookSettings>

GET /v1/settings/orderbook (settings:read): 연결의 스택이 보는 그대로의 종목 스택 설정 — 페어의 행, 연결의 기본값, 연결이 없는 페어의 행, 전역 기본값 — 이며, 모든 키에 resolved_from이 붙습니다.

HTTP 작업: GET /v1/settings/orderbook

옵션타입설명
connectionIdnumber
instrumentInstrumentAddress

updateSettings()

updateSettings(changes: SettingChange[]): Promise<SettingsApplied>

PATCH /v1/settings (settings:write): Settings App이 하는 방식 그대로 설정을 씁니다. 모든 변경은 먼저 터미널의 카탈로그와 대조됩니다(changes[i]를 알려 주는 invalid_request, 아무것도 쓰지 않음; 레버리지는 여기서 unsupported이므로 setLeverage를 사용합니다). 그 뒤 순서대로 적용됩니다: Settings App과 같은 행, 창 이벤트, 서비스 캐시입니다. 처음 실패한 변경이 호출을 거부하며, 그 앞의 변경은 적용된 채로 남습니다.

HTTP 작업: PATCH /v1/settings

stream()

stream(options: StreamOptions = {}): Promise<Stream>

/v1/stream을 엽니다. Node 전용입니다: 토큰은 핸드셰이크 헤더로 보냅니다.

옵션타입설명
timeoutMs선택number핸드셰이크 타임아웃이며, 기본값은 클라이언트의 timeoutMs입니다.

StreamProtocol

스트림 프로토콜에서 소켓과 무관한 절반입니다: 요청 id를 발급하고, 응답을 기다리는 요청을 보관하며, subscribed / unsubscribed / error 프레임으로 요청을 완료하고, 그 밖의 모든 것을 소비자가 순회하는 프레임으로 바꿉니다. 순수하므로 서버 없이 단위 테스트할 수 있습니다.

nextRequestId()

nextRequestId(): string

이 스트림 안에서 고유한 새 request_id입니다.

expect()

expect(requestId: string): Promise<ReplyFrame>

요청을 등록하고, 그 응답으로 완료될 프로미스를 받습니다.

pendingCount

pendingCount: number

아직 응답을 기다리는 요청입니다.

route()

route(raw: unknown): StreamFrame | undefined

디코딩된 프레임을 분류합니다. 우리 요청에 대한 응답은 해당 프로미스를 완료하고 undefined를 반환합니다. event, gap, 구독 오류는 소비자에게 반환됩니다. 알 수 없거나 형식이 잘못된 것은 버려집니다.

abortAll()

abortAll(error: Error): void

기다리는 모든 요청을 거부합니다. 예를 들어 소켓이 닫힐 때입니다.

Stream

class Stream extends AsyncIterable<StreamFrame>

살아 있는 /v1/stream 연결입니다.

terminal.stream()으로 얻습니다. subscribe로 구독한 뒤 순회합니다: for await (const frame of stream)은 이벤트, gap, 구독 오류를 도착 순서대로 내보내며, 소비자가 바쁜 동안 제한 없이 버퍼링합니다(서버는 스스로를 보호합니다: 5초 넘게 뒤처진 클라이언트는 4008로 닫힙니다). 한 번에 한 소비자만 순회하며, 동시에 호출된 두 번째 next()는 자기 차례를 기다립니다.

서버가 연결을 닫으면 순회가 끝납니다. 1001, 4008, 4029와 끊어진 연결(1006)의 경우 StreamClosedError를 던지며 끝납니다. closeCode와 closeReason은 어느 경우든 설정됩니다. 클라이언트 쪽에서 닫으면(close, 또는 루프에서 break) 순회가 정상적으로 끝납니다.

connect()

static connect(options: StreamConnectOptions): Promise<Stream>

WebSocket을 열고 핸드셰이크를 완료합니다. 터미널이 받아 주지 않으면 TerminalUnreachableError로 거부됩니다: Node의 WebSocket은 거부된 핸드셰이크(터미널 꺼짐, API 꺼짐, 토큰 거부)를 하나의 일반 실패로 보고하므로 세 경우를 구분할 수 없습니다.

옵션타입설명
urlstringws://127.0.0.1:48180/v1/stream.
tokenstring
timeoutMs선택number핸드셰이크 타임아웃이며, 기본값은 10 000입니다.

url

url: string

스트림 URL입니다(토큰은 절대 포함되지 않습니다).

closed

closed: boolean

소켓이 닫히면 누가 닫았든 true입니다.

closeCode

closeCode: number | undefined

닫힌 뒤의 WebSocket 종료 코드입니다.

closeReason

closeReason: string | undefined

닫힌 뒤의 WebSocket 종료 사유입니다.

subscribe()

subscribe(options: SubscribeOptions): Promise<Subscribed>

종목의 토픽 또는 연결의 계정 토픽을 구독합니다. 서버의 subscribed 프레임(요청한 topic과, 시장 토픽의 경우 instrument를 더한 것)으로 완료되고, 서버의 error 응답에는 StreamRequestError로 거부됩니다. 그동안 다른 구독의 이벤트는 계속 흐릅니다. 초당 신규 거래소 구독 수에 대한 터미널의 제한(/v1/meta)에 유의합니다. 계정 토픽은 거래소를 건드리지 않으며 스냅샷 프레임을 보내지 않으므로, 현재 상태는 먼저 /v1/account/* 작업으로 읽습니다.

옵션타입설명
topicTopic
instrument선택InstrumentAddress시장 토픽에는 필수이며, account.*에서는 무시됩니다.
connectionId선택numberaccount.*에는 필수이며, 시장 토픽에서는 생략하면 공통 규칙에 따라 선택됩니다.
params선택BookTopParamsbook.top만 읽습니다. 와이어 이름(depth, interval_ms)을 씁니다.

unsubscribe()

unsubscribe(subscription: Subscribed | SubscribedFrame | string): Promise<void>

구독을 즉시 제거합니다. subscribe가 완료하며 반환한 값 또는 sub id만 받습니다. 서버의 unsubscribed로 완료됩니다.

close()

close(code: number = CLOSE_NORMAL, reason?: string): Promise<void>

스트림을 닫습니다. 서버는 클라이언트의 코드로 종료 핸드셰이크를 완료하며, 프로미스는 그때 완료되거나, 서버가 끝내 완료하지 않으면 짧은 유예 시간 뒤에 완료됩니다. 여러 번 호출해도 안전합니다.

터미널 탐색

상수값설명
DEFAULT_PORT48180SPECTRE_LOCAL_API_PORT로 바꾸지 않는 한 터미널이 수신하는 포트입니다.
TOKEN_ENV"SPECTRE_LOCAL_API_TOKEN"토큰을 읽어 오는 환경 변수입니다.

instancePath()

function instancePath(options: DiscoveryEnvironment = {}): string

OS별 터미널 instance.json의 경로입니다:

  • Linux: $XDG_DATA_HOME/spectre-terminal/instance.json, 없으면 ~/.local/share/spectre-terminal/instance.json;
  • macOS: ~/Library/Application Support/spectre-terminal/instance.json;
  • Windows: %LOCALAPPDATA%\spectre-terminal\instance.json, 없으면 %USERPROFILE%\AppData\Local\....

터미널 자체의 데이터 디렉터리(dirs::data_local_dir)와 같습니다.

readPort()

function readPort(options: ReadPortOptions = {}): Promise<number | undefined>

instance.json에 게시된 Local API 포트입니다.

파일이 없거나 읽을 수 없으면(실행 중인 터미널이 없거나, 이 필드를 게시하지 않는 터미널) undefined로 완료되며, 호출자는 DEFAULT_PORT로 대체합니다. 파일은 있지만 local_api_port가 null이거나 없으면 LocalApiDisabledError를 던집니다 — 터미널은 실행 중이고 API는 꺼져 있는 것입니다. 이 필드 하나만 읽습니다.

tokenFromEnv()

function tokenFromEnv(env: Record<string, string | undefined> = process.env): string | undefined

SPECTRE_LOCAL_API_TOKEN의 토큰이며, 설정되지 않았거나 비어 있으면 undefined입니다.

오류

SpectreTerminalError

class SpectreTerminalError extends Error

이 패키지가 던지는 모든 오류의 기본 클래스입니다.

ApiError

class ApiError extends SpectreTerminalError

터미널이 2xx가 아닌 상태로 응답했습니다.

code는 계약의 오류 엔벨로프에 있는 안정적인 코드(unauthorized, not_found, rate_limited, …)이고, status는 HTTP 상태입니다. 엔벨로프가 아닌 2xx 외 본문은 코드 "unknown"이 됩니다.

필드타입설명
codestring계약의 안정적인 오류 코드 또는 "unknown"입니다.
statusnumber응답의 HTTP 상태입니다.
detailstring서버가 보낸, 접두사 없는 사람이 읽기 위한 메시지입니다.

TerminalUnreachableError

class TerminalUnreachableError extends SpectreTerminalError

HTTP 응답이 전혀 없습니다: 연결 거부, 요청 타임아웃, 예상치 못한 리디렉션, 또는 완료되지 않은 WebSocket 핸드셰이크입니다. 원래의 실패는 cause에 있습니다.

LocalApiDisabledError

class LocalApiDisabledError extends SpectreTerminalError

instance.json은 있지만 Local API 포트가 게시되어 있지 않습니다: 터미널이 API를 끈 채 실행 중이거나, 정상 종료되지 않은 터미널이 파일을 남긴 것입니다. 어느 경우든 Settings App(일반 → Local API)에서 API를 켤 때까지 연결할 포트가 없습니다.

TokenMissingError

class TokenMissingError extends SpectreTerminalError

token 옵션도 SPECTRE_LOCAL_API_TOKEN도 토큰을 제공하지 않았습니다.

IncompatibleTerminalError

class IncompatibleTerminalError extends SpectreTerminalError

/v1/meta가 이 클라이언트가 사용하지 않는 API 버전을 보고했습니다.

필드타입설명
apiVersionstring터미널이 보고한 api_version입니다.
appVersionstring터미널이 보고한 app_version입니다.

StreamRequestError

class StreamRequestError extends SpectreTerminalError

스트림이 subscribe 또는 unsubscribe 요청에 error 프레임으로 응답했습니다. code는 계약의 오류 코드(not_found, rate_limited, invalid_request, …)입니다. 다른 구독은 계속 흐릅니다.

필드타입설명
codestring계약의 안정적인 오류 코드입니다.
detailstring서버가 보낸, 접두사 없는 사람이 읽기 위한 메시지입니다.

StreamClosedError

class StreamClosedError extends SpectreTerminalError

소비자가 대응해야 하는 이유로 서버가 스트림을 닫았습니다: 1001 — API가 꺼졌거나 토큰이 재발급됨; 4008 — 이 클라이언트가 너무 느리게 읽음; 4029 — 토큰당 연결 수 제한. 연결이 close 프레임 없이 끊어진 1006과, 이미 닫힌 스트림에서의 subscribe / unsubscribe에서도 발생합니다.

필드타입설명
codenumberWebSocket 종료 코드입니다.
reasonstring서버가 보낸 종료 사유이며, 비어 있을 수 있습니다.

@spectre-trade/terminal 코드의 커밋 2d1c324에서 생성되었습니다.

이 페이지의 내용