예측시장 트레이딩 신호: 예상 변동폭의 변화 측정하기

시장 확률을 입력으로 쓰려면 정책금리 경로를 일정에 따라 읽고, 나중의 예상 변동폭에서 이전의 예상 변동폭을 뺍니다. Narwhal은 회의별 expected_change_bps를 실시간과 일별 기록으로 제공합니다.

정책금리 경로 폴링하기

여기서 신호는 시장이 반영한 중앙은행 정책금리의 변동입니다. 정책금리 경로는 앞으로 열릴 회의마다 이를 반환합니다. 이 요청은 연방준비제도를 조회하고 첫 번째 회의만 남깁니다.

curl, 현재 정책금리 경로
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/predictions/policy-paths/federal-reserve"
응답, 요약
{
  "as_of": "2026-11-03T02:28:00Z",
  "meetings": [
    {
      "event_id": "usa-fed-2026-12",
      "p_cut": "0.0097",
      "p_hold": "0.2534",
      "p_hike": "0.7369",
      "expected_change_bps": "18.6",
      "cumulative_change_bps": "18.6",
      "resolves_at": "2026-12-09T19:00:00Z"
    }
  ]
}

expected_change_bps는 해당 회의에서 정책금리의 변화를 확률로 가중한 값이며 단위는 베이시스포인트입니다. 이것은 변화량이지 현재 금리가 아닙니다. cumulative_change_bps는 목록의 회의를 순서대로 더한 값입니다. p_cut, p_hold, p_hike는 그 바탕이 되는 확률이고 as_of는 호가 시각입니다. 이 엔드포인트를 폴링해 조회할 때마다 as_of와 함께 회의당 한 행으로 저장하고, 네 가지 확률 및 변동 필드는 Decimal 값으로 유지하세요.

과거 날짜의 같은 경로 읽기

기록 엔드포인트는 하루에 하나의 스냅샷을 반환합니다. start와 end는 모두 필수이며 날짜-시간 값이므로 2026-10-26만 쓰면 거부되고 2026-10-26T00:00:00Z는 허용됩니다. 기간은 최대 366일입니다. 이 요청은 2026년 10월 26일부터 11월 2일까지를 조회하며, 아래 응답은 이틀치와 각 날의 첫 번째 회의만 남긴 것입니다.

curl, 정책금리 경로 일별 기록
curl -s -H "Authorization: Bearer $NARWHAL_API_KEY" \
  "https://api.narwhalapi.com/v1/predictions/policy-paths/federal-reserve/history?start=2026-10-26T00:00:00Z&end=2026-11-03T00:00:00Z"
응답, 요약
{
  "meeting_dates": [
    {
      "event_id": "usa-fed-2026-10",
      "resolves_at": "2026-10-28T18:00:00Z"
    },
    {
      "event_id": "usa-fed-2026-12",
      "resolves_at": "2026-12-09T19:00:00Z"
    }
  ],
  "days": [
    {
      "date": "2026-11-01",
      "meetings": [
        {
          "event_id": "usa-fed-2026-12",
          "p_cut": "0.0093",
          "p_hold": "0.2766",
          "p_hike": "0.7141",
          "expected_change_bps": "17.9",
          "cumulative_change_bps": "17.9"
        }
      ]
    },
    {
      "date": "2026-11-02",
      "meetings": [
        {
          "event_id": "usa-fed-2026-12",
          "p_cut": "0.0098",
          "p_hold": "0.2535",
          "p_hike": "0.7367",
          "expected_change_bps": "18.5",
          "cumulative_change_bps": "18.5"
        }
      ]
    }
  ]
}

days에는 날짜마다 하나의 항목이 있고, 각 항목에는 그날 아직 열리지 않았던 회의가 실시간 경로와 같은 확률 필드와 함께 들어 있습니다. meeting_dates는 각 회의의 resolves_at을 한 번씩 보여 줍니다.

두 조회 사이의 변화 계산하기

예상 변동폭의 변화는 같은 회의에 대해 나중의 expected_change_bps에서 이전 값을 뺀 것입니다. 조회값은 위치가 아니라 event_id로 맞추세요. 2026년 10월 26일의 첫 행은 10월 회의 usa-fed-2026-10이지만, 2026년 11월 2일에는 그 회의가 이미 결정되어 첫 행이 12월 회의가 됩니다. 스크립트는 Decimal로 뺄셈을 하고, 이어서 두 번의 실시간 폴링 사이에서도 같은 계산을 반복합니다.

Python, 예상 변동폭의 변화
import json
import os
import time
import urllib.request
from decimal import Decimal

def get(path):
    req = urllib.request.Request(
        "https://api.narwhalapi.com" + path,
        headers={"Authorization": "Bearer " + os.environ["NARWHAL_API_KEY"]},
    )
    with urllib.request.urlopen(req, timeout=30) as r:
        return json.load(r)

def reading(meetings):
    return {m["event_id"]: (Decimal(m["expected_change_bps"]), Decimal(m["cumulative_change_bps"]))
            for m in meetings}

def change(before, after):
    # Match meetings by event_id: the first row is a different meeting once a decision has passed.
    return {e: (after[e][0] - before[e][0], after[e][1] - before[e][1])
            for e in before if e in after}

path = "/v1/predictions/policy-paths/federal-reserve/history"
days = get(path + "?start=2026-10-26T00:00:00Z&end=2026-11-03T00:00:00Z")["days"]
first, last = days[0], days[-1]
print(first["date"], "->", last["date"])
for event_id, (move, cumulative) in list(change(reading(first["meetings"]),
                                                reading(last["meetings"])).items())[:4]:
    print(event_id, f"{move:+} bps at the meeting, {cumulative:+} bps cumulative")

# Polling: take a reading, wait, take another and run the same comparison.
def poll():
    return reading(get("/v1/predictions/policy-paths/federal-reserve")["meetings"])

previous = poll()
time.sleep(120)
for event_id, (move, _) in list(change(previous, poll()).items())[:2]:
    print(event_id, f"{move:+} bps since the last poll")
회의2026년 10월 26일2026년 11월 2일예상 변동폭의 변화
usa-fed-2026-1219.5 bps18.5 bps-1.0 bps
usa-fed-2027-017.3 bps6.1 bps-1.2 bps

2분 간격으로 한 두 번의 실시간 폴링은 두 회의 모두 +0.0 bps를 출력했습니다. 변화가 0인 것도 유효한 조회 결과입니다. 이 필드가 가진 소수 첫째 자리에서는 호가가 움직이지 않았다는 뜻입니다. 변화가 음수이면 예상 변동이 인하 쪽으로, 양수이면 인상 쪽으로 이동했다는 뜻입니다. 필드 값 자체가 0보다 작으면 시장이 해당 회의에서 인하를 예상한다는 뜻입니다.

수치를 쓰기 전에 확인할 것

  • 회의별 값끼리 비교하세요. 12월 회의의 10월 26일부터 11월 2일까지 누적 변화는 -2.7 bps이지만 회의별 변화는 -1.0 bps입니다. 그 사이에 10월 회의가 결정되어 그 1.7 bps가 누적 합계에서 빠졌기 때문입니다.
  • expected_change_bps는 소수 첫째 자리까지 가지므로 0.1 bps보다 작은 변화는 나타날 수 없습니다.
  • 각 조회의 as_of를 확인하세요. as_of가 같은 두 조회는 같은 거래소 확인에서 나온 것입니다.
  • 가격이 형성된 회의가 없는 중앙은행은 빈 meetings 목록을 반환합니다.
  • 이 수치는 시장 호가입니다. Narwhal은 그 변화가 무언가를 예측하는지 말하지 않으며, 이 페이지도 그렇다고 주장하지 않습니다.

폴링 대신 알림을 받을 수 있나요?

네. 예측 확률이 움직일 때 알림 받기 가이드에서 이 옵션을 설명합니다. 위와 같이 이미 일정에 따라 실행되는 스크립트에는 폴링이 맞고, 알려 받고 싶은 임계값이 있다면 알림이 맞습니다.

과거 조회 기록으로 저장소를 채우려면 어떻게 하나요?

기록 엔드포인트를 최대 366일 단위로 호출해 days의 각 항목을 date 날짜의 조회값으로 적재하세요. 그런 다음 정책금리 경로의 실시간 폴링을 추가합니다. 두 소스는 같은 확률 및 변동 필드를 가지므로 이어 붙인 지점을 가로질러 비교할 수 있습니다. 일별 스냅샷은 날짜당 하나이므로 두 스냅샷 사이에 한 폴링에는 비교할 기록 행이 없습니다.

이틀 사이에 첫 번째 회의가 바뀐 이유는 무엇인가요?

경로에는 아직 열리지 않은 회의가 나열됩니다. 연방준비제도가 2026년 10월 28일에 결정을 내리자 10월 회의는 목록에서 빠지고 12월 회의가 첫 행으로 올라왔습니다. 기록 응답에서 10월 28일 항목은 여전히 10월 회의가 맨 앞에 있고, 10월 29일 항목은 12월 회의로 시작합니다.

이 경로는 어떤 중앙은행을 다루나요?

이 경로는 federal-reserve에 응답하며, 같은 엔드포인트가 european-central-bank, bank-of-japan, bank-of-canada, reserve-bank-of-australia에도 응답합니다. 한 회의를 자세히 읽는 방법은 중앙은행 금리 결정 확률을 참고하세요.

에 게시되었습니다.

다음 단계