Live release feed
Release-timestamped macro data for FX backtests
Point-in-time history

Implementation

How-To Guides

取引記録をフィルタリングするためにCOTデータをどのように使用するか

FXMacroData APIからトレーダーの位置付けデータを引き出すためのステップバイステップガイド,ネット位置付けメトリックの計算,および取引エントリと機関流の調整を図る方向フィルターを構築する.

他言語版 English
Share article X LinkedIn Email
取引記録をフィルタリングするためにCOTデータをどのように使用するか image

COTのポジショニングデータは,通貨先物市場の最大の投機的な参加者が毎週,解釈なしに,実際のお金で何をしているか教えてくれます. あなたが非商業ポジショনিংの方向性バイアスと取引エントリを調整すると,情報機関流量に対して泳いでいる取引から高い確率設定を分離する有意義なフィルターを追加します.

このガイドでは,COTデータをFXMacroData APIから抽出し,キー派生メトリックを計算し,ポジショニングフィルターを構築し,入力ワークフローに適用する.終了時までに,任意のFX戦略にスロットできる動作するPythonベースのフィルターを用意します.

あなた が 築く もの

  • A Python function that fetches weekly COT data for any of the eight supported currencies
  • 純定位標準化指標 (公開利息の%として)
  • 設定可能な値を持つ多条件位置位置フィルター
  • 方向信号を返した取引エントリゲート: longほら shortほら neutral
  • EUR/USD を実例として使った実践的な説明

条件

  • FXMacroData API キーを サイトで入手できます / サブスクリプト付与プランには,COTエンドポイントが含まれています.
  • Python 3.9+ ほら ほろ requests インストールされたライブラリ (pip install requests) について
  • 基礎的なCOTレポート用語 (非商業的なロング,ショート,オープン・インテレスト) を熟知している. 外国為替取引者向けCOTレポートガイド 基本をカバーしています
  • 選択的に pandas データ操作のステップ (pip install pandas) について

Step 1 — Fetch COT Data from the API

FXMacroData COTエンドポイントは,通貨先物に対する週間の非商業および商業的ポジショニングを返します.サポートされる通貨は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
    }
  ]
}

Pythonでは,この呼び出しを時間順に並べたデータリストを返します.

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 導致位置測定値を計算する

Raw contract counts are hard to compare across currencies and across time. A net long of 80,000 contracts means something very different in EUR futures (large, liquid market) versus CHF (smaller open interest). Two derived metrics resolve this.

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 入力フィルターを構築する

With the three metrics in hand, you can construct a filter function that returns a directional signal for any currency. The logic combines current level, percentile context, and momentum direction into a single gate.

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 取引エントリにフィルターを適用する

The filter function returns one of three signals — longほら shortほら neutral目的の使用は,あなたの主要な入力信号の前でゲートとして: COTフィルタが言うときだけ長いセットアップを取ります long (あるいは) neutral 短時間設定をする場合のみです. 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 data is released every Friday for positions as of the prior Tuesday. That makes it a low-frequency signal — appropriate for filtering weekly or daily bias, not intraday entries. Re-run the filter once per week after Friday's 3:30 pm ET release, cache the result, and use it as a static bias gate for all entries in the following week. Use the 試験終了点のドキュメント リリースタイミングを検証する

ステップ 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とマクロ確認層を組み合わせる

The most robust setups combine COT positioning with at least one macro fundamental that supports the same directional thesis. Rate differentials are the natural complement: if speculators are long EUR and the ECB-to-Fed rate differential is widening in EUR's favour, the positioning and fundamental case are aligned.

やってみろ 政策金利の最終点 各通貨の最新レートを抽出し,差を計算する

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フィルタだけでは不十分です. 中央銀行の政策金利の歴史 位置を移動させるため 近づいて見ろ

概要

You now have a complete COT-based entry filter built on live FXMacroData API data. The workflow consists of six steps:

  1. 取引中の通貨または通貨の毎週COT記録を取得します.
  2. 通貨間正常化のために,オープン利息の割合として純資産を計算する.
  3. Rank current positioning within the trailing year to identify extreme or neutral conditions.
  4. 4週間の動向を計算して ポジションが有利なのか確認します
  5. フィルター信号にゲートする取引エントリ COTのアライナメントがあなたの方向に一致するときにのみ実行します.
  6. 選択的に,二要素確認のために,レート差のチェックと組み合わせます.

投資家の資金がどこに位置しているかについて毎週スナップショットを表示します. そのため,取引は,それに対してではなく,機関的な流れに合わせて行われます. 次のステップとして,COTフィルターを インフレ ほら 雇用 endpoints to build a macro-scoring model that weights all three signals together — positioning, rate differentials, and growth/inflation momentum — for a more complete regime picture.

Blogroll

AI Answer-Ready

Key Facts

Page
How To COT Data FX Trade Filter
Section
Articles
Canonical URL
https://fxmacrodata.com/ja/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.