Live release feed
Sub-second macro releases for FX backtests
Point-in-time history
USD 25/month
무료 체험 시작

Implementation

How-To Guides

FX 거래 항목을 필터링하는 데 COT 데이터를 사용하는 방법

FXMacroData API에서 트레이더 포지셔닝 데이터를 뽑는 단계별 안내, 순 포지시셔닝 메트릭을 계산하고, 거래 항목을 기관 흐름과 조화시키는 방향 필터를 구축합니다.

다른 언어로도 제공 English
Share article X LinkedIn Email
FX 거래 항목을 필터링하는 데 COT 데이터를 사용하는 방법 image

COT 포지셔닝 데이터는 거래가 비상업 포지시팅의 방향 편향과 일치하면 높은 확률의 세트업과 정보 기관 흐름에 반대하는 거래를 분리하는 의미있는 필터를 추가합니다.

이 가이드는 전체 프로세스를 통해 걸습니다: FXMacroData API에서 COT 데이터를 뽑아내어, 키 파생 메트릭을 계산하고, 위치 필터를 구축하고, 입력 워크플로에 적용합니다.

당신 이 건축 할 것

  • A Python function that fetches weekly COT data for any of the eight supported currencies
  • 순위 위치 표준화 메트릭 (공개 이해의 순수 %)
  • 구성 가능한 임계값을 가진 다조건 위치 필터
  • 방향 신호를 돌려주는 트레이드 엔트리 게이트: long short, 또는 neutral
  • EUR/USD를 실무 예로 사용 한 실용적인 안내

필수 조건

  • FXMacroData API 키 이 사이트에서 이용하실 수 있습니다. / 가입COT 최종점은 모든 유료 계획에 포함되어 있습니다.
  • 파이썬 3.9+ 과 함께 requests 설치된 라이브러리 (pip install requests) 의 내용입니다.
  • COT 보고서 용어 (비상업 장기, 단기, 오픈 인테스) 에 대한 기본적인 친숙성. FX 트레이더를 위한 COT 보고서 가이드 기본 요소를 다루고 있습니다.
  • 선택적으로, pandas 데이터 조작 단계에 대해 (pip install pandas) 의 내용입니다.

Step 1 — Fetch COT Data from the API

FXMacroData COT 엔드포인트 (endpoint) 는 통화 선물에 대한 주간 비상업 및 상업적 포지셔닝을 반환합니다. 지원되는 통화는 AUD, CAD, CHF, EUR, GBP, JPY, NZD 및 USD입니다. 각 기록에는 비상공 및 상업 참여자의 긴, 짧은 및 순계 계약 수와 전체 오픈 이점이 포함되어 있습니다.

curl "https://fxmacrodata.com/api/v1/cot/eur?api_key=YOUR_API_KEY&start=2023-01-01"

JSON 응답은 다음과 같은 구조를 가지고 있습니다.

{
  "currency": "eur",
  "data": [
    {
      "date": "2025-03-25",
      "noncommercial_long": 198432,
      "noncommercial_short": 61840,
      "noncommercial_net": 136592,
      "commercial_long": 68230,
      "commercial_short": 201860,
      "open_interest": 591400
    },
    {
      "date": "2025-03-18",
      "noncommercial_long": 185710,
      "noncommercial_short": 66320,
      "noncommercial_net": 119390,
      "commercial_long": 72140,
      "commercial_short": 189430,
      "open_interest": 578200
    }
  ]
}

파이썬에서, 이 호출을 시간 순으로 정렬된 데이터 목록을 반환하는 보조에 포장합니다:

import requests
from datetime import date, timedelta

BASE_URL = "https://fxmacrodata.com/api/v1"
API_KEY  = "YOUR_API_KEY"


def fetch_cot(currency: str, lookback_days: int = 365) -> list[dict]:
    """Return COT weekly records for *currency* over the last *lookback_days* days."""
    start = (date.today() - timedelta(days=lookback_days)).isoformat()
    resp = requests.get(
        f"{BASE_URL}/cot/{currency.lower()}",
        params={"api_key": API_KEY, "start": start},
        timeout=15,
    )
    resp.raise_for_status()
    payload = resp.json()
    return sorted(payload["data"], key=lambda r: r["date"])


records = fetch_cot("eur")
print(f"Loaded {len(records)} COT records for EUR")
print("Latest:", records[-1])

왜 12 개월 의 역사?

The filter thresholds in Step 3 are expressed as percentile ranks over the trailing year. One year is long enough to capture a full positioning cycle for most major pairs without including regime changes that are too old to be relevant. You can widen the window to 2–3 years for currencies with slower-moving positioning cycles like JPY or CHF.

단계 2 파생 위치 측정값을 계산

원료 계약 수치는 통화와 시간 간 비교하기가 어렵습니다. 80,000 계약의 순수 길이는 EUR 선물 (큰 유동 시장) 에 비해 CHF (소규모 오픈 인테스트) 에 매우 다른 것을 의미합니다. 두 가지 파생 메트릭이 이것을 해결합니다.

2a. 오픈 이의 비율로 순위

비상업 순위 지분을 전체 오픈 이자로 나누면 -1과 +1 사이의 정상화 비율이 생성됩니다. 이것은 측정법을 통화와 시간에 따라 직접 비교 할 수 있습니다.

def net_pct_oi(records: list[dict]) -> list[dict]:
    """Add 'net_pct' field = noncommercial_net / open_interest to each record."""
    enriched = []
    for r in records:
        oi = r.get("open_interest") or 1  # guard against zero
        enriched.append({**r, "net_pct": r["noncommercial_net"] / oi})
    return enriched


records = net_pct_oi(records)
latest  = records[-1]
print(f"EUR net % OI: {latest['net_pct']:.3f}  ({latest['date']})")

2b. 퍼센틸 순위 위치

현재 위치가 극단적인지 알기 위해서는 역사적 맥락이 필요합니다. net_pct 후기 창 안에 절대 숫자를 퍼센틸로 변환합니다 (0 = 가장 하락, 100 = 가장 상승). 75 이상의 퍼센티일은 밀집 된 긴 것을 나타냅니다. 25 이하는 밀집된 짧은 것을 나타낸다.

def percentile_rank(series: list[float], value: float) -> float:
    """Return the percentile rank of *value* within *series* (0–100)."""
    below = sum(1 for x in series if x < value)
    return below / len(series) * 100


net_series     = [r["net_pct"] for r in records]
current_net    = records[-1]["net_pct"]
pct_rank       = percentile_rank(net_series, current_net)

print(f"EUR positioning percentile: {pct_rank:.1f}th")

퍼센틸 순위 해석

  • 75~100 퍼센틸: 비상업적인 종목은 긴 종목으로 가득차 있습니다. 트렌드가 유지되는 동안 긴 종합을 선호합니다. 기본 변동이 발생할 경우 반전 위험을 추가합니다.
  • 25~75 퍼센틸: 중립 구역. 강한 위치 바람 또는 역풍 다른 신호가 이끌 수 없습니다.
  • 0~25 퍼센틸: 비상업가들은 코스가 많고, 추세가 유지되는 동안 코스를 선호하며, 상승한 놀라움에 대한 압박 위험을 추가합니다.

2c 위치 모멘텀

트렌드 방향은 현재 수준만큼이나 중요합니다. 성장하는 넷 롱은 평형화되거나 줄어들기 시작한 넷 론드와 다른 신호입니다. 모멘텀을 파악하기 위해 net_pct의 4 주 변화를 계산하십시오:

def positioning_momentum(records: list[dict], periods: int = 4) -> float:
    """Return the change in net_pct over the last *periods* weeks."""
    if len(records) < periods + 1:
        return 0.0
    return records[-1]["net_pct"] - records[-(periods + 1)]["net_pct"]


momentum = positioning_momentum(records)
print(f"EUR 4-week positioning change: {momentum:+.3f}")

단계 3 입력 필터를 구축

세 가지 메트릭스를 가지고, 어떤 통화에 대한 방향 신호를 반환하는 필터 함수를 만들 수 있습니다. 논리는 현재 수준, 퍼센틸 컨텍스트, 그리고 모멘텀 방향을 하나의 게이트로 결합합니다.

def cot_entry_filter(
    currency: str,
    lookback_days: int = 365,
    long_pct_threshold: float = 55.0,
    short_pct_threshold: float = 45.0,
    momentum_min: float = 0.005,
) -> dict:
    """
    Return a COT positioning signal for *currency*.

    Parameters
    ----------
    currency            : ISO currency code (AUD, CAD, CHF, EUR, GBP, JPY, NZD, USD)
    lookback_days       : history window for percentile calculation
    long_pct_threshold  : minimum percentile to confirm a long bias
    short_pct_threshold : maximum percentile to confirm a short bias
    momentum_min        : minimum absolute 4-week change to confirm momentum

    Returns
    -------
    dict with keys: currency, signal, net_pct, percentile, momentum, date
    """
    records  = fetch_cot(currency, lookback_days)
    records  = net_pct_oi(records)
    latest   = records[-1]

    net_series = [r["net_pct"] for r in records]
    pct_rank   = percentile_rank(net_series, latest["net_pct"])
    momentum   = positioning_momentum(records)

    if pct_rank >= long_pct_threshold and momentum >= momentum_min:
        signal = "long"
    elif pct_rank <= short_pct_threshold and momentum <= -momentum_min:
        signal = "short"
    else:
        signal = "neutral"

    return {
        "currency"   : currency.upper(),
        "signal"     : signal,
        "net_pct"    : round(latest["net_pct"], 4),
        "percentile" : round(pct_rank, 1),
        "momentum"   : round(momentum, 4),
        "date"       : latest["date"],
    }


result = cot_entry_filter("eur")
print(result)

EUR 비상업이 붐비는 경우 샘플 출력

{
  "currency"  : "EUR",
  "signal"    : "long",
  "net_pct"   : 0.231,
  "percentile": 82.4,
  "momentum"  : 0.018,
  "date"      : "2025-03-25"
}

단계 4 거래 항목에 필터를 적용

필터 함수는 세 개의 신호 중 하나를 반환합니다. long short, 또는 neutral- 의도된 사용은 주요 입력 신호 앞의 게이트입니다: COT 필터가 long (또는 neutral 만약 당신이 더 공격적이면), 그리고 COT 필터가 short- 그래요

def should_enter_trade(
    currency: str,
    proposed_direction: str,
    allow_neutral: bool = False,
) -> bool:
    """
    Return True if COT positioning supports *proposed_direction* for *currency*.

    Parameters
    ----------
    currency           : ISO currency code
    proposed_direction : 'long' or 'short'
    allow_neutral      : if True, a 'neutral' COT signal does not block entry
    """
    cot = cot_entry_filter(currency)
    if cot["signal"] == proposed_direction:
        return True
    if allow_neutral and cot["signal"] == "neutral":
        return True
    return False


# Example: checking whether to enter a EUR/USD long
currency = "eur"   # base currency of the pair
direction = "long"

if should_enter_trade(currency, direction):
    print(f"COT confirms {direction} bias for {currency.upper()} — proceed to entry check")
else:
    print(f"COT filter blocked {direction} entry for {currency.upper()}")

실행 참고: COT는 주간 신호입니다.

COT 데이터는 전날 화요일부터 포지션에 대해 매주 금요일 공개됩니다. 이는 주간 또는 일일 편향을 필터링하는 데 적합 한 낮은 주파수 신호가됩니다. 금요일 오후 3:30 ET 출시 후 일주일에 한 번 필터를 다시 실행하고 결과를 캐시하고 다음 주에 모든 항목에 대한 정적 편향 게이트로 사용합니다. COT 최종점 문서 발매 시기를 확인하기 위해서요.

단계 5 다화 대시보드로 확장

Running the filter across all eight supported currencies at once gives you a weekly positioning dashboard. This is useful for identifying which FX pairs have the clearest speculator-driven tailwinds and which to avoid because positioning is working against your direction.

CURRENCIES = ["aud", "cad", "chf", "eur", "gbp", "jpy", "nzd", "usd"]

def cot_dashboard() -> list[dict]:
    """Return COT positioning signals for all supported currencies."""
    results = []
    for ccy in CURRENCIES:
        try:
            result = cot_entry_filter(ccy)
            results.append(result)
        except Exception as exc:
            print(f"Warning: could not load {ccy.upper()} COT data — {exc}")
    return results


dashboard = cot_dashboard()
for row in dashboard:
    bar = "▲" if row["signal"] == "long" else ("▼" if row["signal"] == "short" else "–")
    print(f"{row['currency']:4s}  {bar} {row['signal']:8s}  pct={row['percentile']:5.1f}  mom={row['momentum']:+.3f}")

샘플 주간 출력:

AUD   ▲ long      pct= 71.2  mom=+0.012
CAD   – neutral   pct= 53.8  mom=-0.004
CHF   ▲ long      pct= 68.4  mom=+0.008
EUR   ▲ long      pct= 82.4  mom=+0.018
GBP   – neutral   pct= 48.1  mom=-0.002
JPY   ▼ short     pct= 19.6  mom=-0.022
NZD   ▲ long      pct= 63.0  mom=+0.007
USD   ▼ short     pct= 22.1  mom=-0.015

이 스냅샷을 읽음: 비상업 거래는 EUR, AUD, CHF 및 NZD 선물; JPY 및 USD의 짧은 포지션이며 CAD 및 GBP에 중립적입니다. EUR/JPY 장기 거래를 고려하는 거래자는 두 다리를 투기자의 흐름에 의해 확인되는 것을 발견합니다. USD/CAD 장기 거래를 검토하는 거래자가 USD에 대한 COT 역풍과 CAD에 대한 중립적인 배경에 직면 할 것입니다. 포지셔닝 관점에서 약한 설정.

단계 6 COT를 매크로 확인 계층과 결합

가장 강력한 설정은 같은 방향성 요점을 뒷받침하는 적어도 하나의 거시적 기본과 COT 위치화를 결합합니다. 금리 차이는 자연스러운 보완입니다. 투기자들이 EUR를 길게하고 ECB-Fed 금리차가 EUR의 이익을 위해 넓어지면 위치와 기본 사례가 일치합니다.

을 사용하세요 정책금리 최종점 각 통화의 가장 최근의 환율을 뽑아내고 이차를 계산하기 위해:

def fetch_latest_rate(currency: str) -> float | None:
    """Return the most recent policy rate for *currency* as a float."""
    resp = requests.get(
        f"{BASE_URL}/announcements/{currency.lower()}/policy_rate",
        params={"api_key": API_KEY, "limit": 1},
        timeout=15,
    )
    if resp.status_code != 200:
        return None
    data = resp.json().get("data", [])
    return data[0]["val"] if data else None


def rate_differential(base_ccy: str, quote_ccy: str) -> float | None:
    """Return base_rate − quote_rate, or None if either rate is unavailable."""
    base_rate  = fetch_latest_rate(base_ccy)
    quote_rate = fetch_latest_rate(quote_ccy)
    if base_rate is None or quote_rate is None:
        return None
    return base_rate - quote_rate


def combined_filter(base_ccy: str, quote_ccy: str, direction: str) -> dict:
    """
    Return a combined COT + rate-differential signal for a currency pair.

    direction : 'long' (buy base) or 'short' (sell base)
    """
    cot_base   = cot_entry_filter(base_ccy)
    cot_quote  = cot_entry_filter(quote_ccy)
    diff       = rate_differential(base_ccy, quote_ccy)

    # For a long (buy base): we want long bias on base AND short/neutral on quote
    if direction == "long":
        cot_ok   = cot_base["signal"] == "long" and cot_quote["signal"] != "long"
        macro_ok = diff is not None and diff > 0
    else:
        cot_ok   = cot_base["signal"] == "short" and cot_quote["signal"] != "short"
        macro_ok = diff is not None and diff < 0

    return {
        "pair"       : f"{base_ccy.upper()}/{quote_ccy.upper()}",
        "direction"  : direction,
        "cot_ok"     : cot_ok,
        "macro_ok"   : macro_ok,
        "confirmed"  : cot_ok and macro_ok,
        "cot_base"   : cot_base,
        "cot_quote"  : cot_quote,
        "rate_diff"  : round(diff, 4) if diff is not None else None,
    }


signal = combined_filter("eur", "jpy", "long")
print("Confirmed:", signal["confirmed"])
print("COT base :", signal["cot_base"]["signal"], "| COT quote:", signal["cot_quote"]["signal"])
print("Rate diff :", signal["rate_diff"])

COT와 매크로가 동의하지 않을 때

포지셔닝이 한쪽에서 매우 밀집되어 있지만 거시적 기본이 반대 방향으로 변할 때 (예를 들어, JPY 선물의 큰 단축이지만 일본 은행은 강화되기 시작합니다), 체제는 전환이 될 수 있습니다. 이것들은 가장 빠르고 가장 큰 움직임을 일으키는 설정입니다. 종종 단축 또는 긴 청산을 강요하는 방향으로. 그러한 경우 COT 필터 만으로는 충분하지 않습니다. 중앙은행 정책금리 역사 위치 풀기를 유발할 수 있는 모든 이동을 위해 가까이

요약

이제 당신은 라이브 FXMacroData API 데이터에 구축 된 완전한 COT 기반 입력 필터를 가지고 있습니다. 작업 흐름은 여섯 단계로 구성됩니다:

  1. 주간 COT 기록을 가져오기 위해 통화 또는 통화 당신은 거래.
  2. 순위 지분은 외환에 따라 정상화되도록 개방된 금리의 비율로 계산합니다.
  3. 극한 또는 중립적인 조건을 식별하기 위해 후기 일 년 내에 현재 위치를 순위 지정하십시오.
  4. 4주간의 동력을 계산해 보시면, 포지셔닝이 여러분의 편에 있는지 확인해 보실 수 있습니다.
  5. 필터 신호에 대한 거래 항목을 게이트 COT 정렬이 방향과 일치 할 때만 진행하십시오.
  6. 선택적으로 두 가지 요인 확인을 위해 비율 차이 확인과 결합합니다.

전체 다화 대시보드는 주간 스펙레이터 돈의 위치를 파악할 수 있도록 해줍니다. 따라서 당신은 기관 흐름에 대한 거래가 아니라 기관 흐름과 함께 거래를 합니다. 다음 단계로, COT 필터를 인플레이션 아니면 고용 마크로 점수 모델을 구축하기 위한 최종 지점으로 세 가지 신호를 모두 함께 위치, 금리 차수, 성장/인플레이션 동력을 더 완전한 체제 그림을 위해 가중합니다.

Blogroll

AI Answer-Ready

Key Facts

Page
How To COT Data FX Trade Filter
Section
Articles
Canonical URL
https://fxmacrodata.com/ko/articles/how-to-cot-data-fx-trade-filter
Source
FXMacroData editorial and official publisher references
Last Updated
2026-06-15 11:06 UTC

Provenance And Trust

Cite the canonical URL and source field above. Where available, this page maps to official publisher releases and timestamped updates.

Quick Q&A

What is this page about? This page explains How To COT Data FX Trade Filter with directly usable context for trading, research, and API workflows.

What source should be cited? Use the canonical URL and the listed source field; cite official publisher references when available.

How fresh is this content? The last updated value above reflects the page metadata or latest available data timestamp.

Can this be used in AI assistants? Yes. This section is intentionally structured for retrieval and citation in chat assistants.

Prompt Packs

Use these in ChatGPT, Claude, Gemini, Mistral, Perplexity, or Grok for consistent source-aware outputs.