Strasmore Research
Deep Dives · Matt ConnorBy Matt Connor ·

トレードのマークアウトとは?執行品質を解説

トレードのマークアウトとは何か、符号の定義と計測方法を平易に解説します。1秒から5分までの実測カーブで、執行後の市場の動きを確認できます。

トレードのマークアウトとは、約定が記録された時点を起点に、一定期間後までのミッド価格の変化を測ったものだ。取引後に市場が自分に有利な方向へ動けばプラスとなる。不利な方向へ動けばマイナスとなり、取引デスクではこれをアドバース・セレクションと呼ぶ。期間を一秒にするか五分にするかで、その数値が答える問いは変わる。

トレードのマークアウトとは

まずミッド価格を見る。これは最良買い気配と最良売り気配の中間値で、NBBOの中間点に当たる。マークアウトでは、約定後の指定した時点のミッド価格から基準価格を差し引き、取引サイドに応じて符号を付ける。

**期間hのマークアウト = side *(時点t+hのミッド価格 - 基準価格)**。sideは買いならプラス1、売りならマイナス1とする。

混乱しやすいのは符号の定義だ。買い約定の後にミッド価格が下落すれば、マークアウトはマイナスになる。自分が買った後に価格が下がり、相手方の売り手にとって有利な取引になったためだ。これはアドバース・セレクションを数値で表したものだ。売り約定の後にミッド価格が下落すれば、サイドによって符号が反転するためプラスになる。すべての約定には双方が存在し、一方のマークアウトは他方のマークアウトと符号が逆になる。

3つの基準価格

差し引く基準価格によって、マークアウトが測るものは変わる。

  • 約定価格。 マークアウトは損益になる。時点t+hにおけるポジションの価値を、支払った価格と比較する。支払った、または受け取ったスプレッドも含まれる。
  • 約定時点のミッド価格。 スプレッドを除外し、取引後に市場がどう動いたかを切り出す。アドバース・セレクションを最も明確に測れる。
  • 取引した側の気配値。 取った気配値、または提示した気配値と比較することで、約定価格を実際に利用可能だった価格と比べられる。

執行品質の分析では、アドバース・セレクションには2つ目の基準を、損益には1つ目の基準を使う。以下の最初のパネルでは、同じ約定群について両方を示している。

マークアウト曲線とその形状が示すもの

同じ統計を複数の期間で計算すると、曲線になる。その形状には、単一の数値を超える情報が含まれる。

  • 最初の一秒以内に急落し、その後も低い水準にとどまる曲線は、フローが先回りされたことを示す。約定直後に価格がほぼすぐ不利な方向へ動いている。
  • 数分にわたり下落し続ける曲線は、そのフローが価格の進行方向に関する実質的な情報を含んでいたことを示す。
  • ゼロ近辺で横ばいになる曲線は、穏当なフローを示す。五分後のミッド価格が約定時とほぼ変わらない。
  • マイナスで始まり、ゼロへ戻る曲線は、リベートを受け取るパッシブなマーケットメイカーが望む形だ。序盤の下落はスプレッドと即時の価格インパクトを示し、回復は市場が戻ったことを示す。

期間の選択自体が、何を測るかという判断になる。一秒未満では、マークアウトは主にレイテンシーとキュー・ポジションを示す。一分まで延ばすと、フローに含まれる短期的な情報を測る。五分を超えると、通常の市場の変動が約定そのものの影響を覆い始める。

実際のマークアウト曲線を約定ごとに見る

以下のパネルでは、2026年6月10日の通常取引時間中に記録されたINTCのすべてのプリントを対象とする。各プリントを、記録直前の一秒間における最後の気配値に基づき、買い主導または売り主導に分類した。そのうえで、符号付きマークアウトを5期間で平均している。同じ約定群について、約定時点のミッド価格を基準にした系列と、約定価格を基準にした系列の2つを示す。

クエリINTCのマークアウト曲線、2026年6月10日、2つの基準ベースから測定
各数値の背後にある正確なSQL
WITH
    mid_by_second AS
    (
        SELECT
            dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
            argMax((toFloat64(bid_price) + toFloat64(ask_price)) / 2, sip_timestamp)    AS mid
        FROM global_markets.cache_stocks_quotes
        WHERE ticker = 'INTC'
          AND sip_timestamp >= toDateTime('2026-06-10 13:30:00', 'UTC')
          AND sip_timestamp <  toDateTime('2026-06-10 20:00:00', 'UTC')
          AND bid_price > 0
          AND ask_price > bid_price
        GROUP BY sec
    ),
    signed_fills AS
    (
        SELECT
            t.sec        AS sec,
            t.fill_price AS fill_price,
            q.mid        AS ref_mid,
            if(t.fill_price > q.mid, 1, -1) AS side
        FROM
        (
            SELECT
                dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
                sec - 1          AS ref_sec,
                toFloat64(price) AS fill_price
            FROM global_markets.stocks_trades
            WHERE ticker = 'INTC'
              AND sip_timestamp >= toDateTime('2026-06-10 13:30:01', 'UTC')
              AND sip_timestamp <  toDateTime('2026-06-10 19:55:00', 'UTC')
              AND price > 0
              AND size > 0
        ) AS t
        INNER JOIN mid_by_second AS q ON q.sec = t.ref_sec
        WHERE t.fill_price != q.mid
    )
SELECT
    multiIf(f.horizon_s < 60,
            concat(toString(f.horizon_s), ' sec'),
            concat(toString(intDiv(f.horizon_s, 60)), ' min'))              AS horizon,
    round(avg(f.side * (fut.mid - f.ref_mid) / f.ref_mid) * 10000, 3)       AS mid_basis_bps,
    round(avg(f.side * (fut.mid - f.fill_price) / f.fill_price) * 10000, 3) AS fill_basis_bps,
    count()                                                                 AS fill_count
FROM
(
    SELECT
        sec,
        fill_price,
        ref_mid,
        side,
        horizon_s,
        sec + horizon_s AS future_sec
    FROM signed_fills
    ARRAY JOIN [1, 5, 15, 60, 300] AS horizon_s
) AS f
INNER JOIN mid_by_second AS fut ON fut.sec = f.future_sec
GROUP BY f.horizon_s
ORDER BY f.horizon_s
Run this yourself

分類された900593件の約定について、ミッド価格基準の系列は1 sec時点で3.068ベーシスポイント、5 min時点で2.977ベーシスポイントとなる。ベーシスポイントは価格の1%の100分の1に当たる。1件の約定では誤差の範囲でも、100万株になれば実際の損益に影響する。

約定価格基準の系列は、開始時点で-0.488ベーシスポイントとなる。最短期間における2系列の差は、実効ハーフスプレッドだ。プリントがミッド価格からどれだけ離れていたかを示す。テイカーはこれを支払い、マーケットメイカーは受け取る。最初の期間を超えた部分は、市場の変動である。

約定サイズと曲線の形状

アドバース・セレクションは、すべての約定に均等に生じるわけではない。同じ取引時間をプリントのサイズで分けると、小口約定と1,000株以上のブロック取引を同じ軸で比較できる。

クエリ同じ曲線を約定サイズ別に分割:小口約定とブロック約定
各数値の背後にある正確なSQL
WITH
    mid_by_second AS
    (
        SELECT
            dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
            argMax((toFloat64(bid_price) + toFloat64(ask_price)) / 2, sip_timestamp)    AS mid
        FROM global_markets.cache_stocks_quotes
        WHERE ticker = 'INTC'
          AND sip_timestamp >= toDateTime('2026-06-10 13:30:00', 'UTC')
          AND sip_timestamp <  toDateTime('2026-06-10 20:00:00', 'UTC')
          AND bid_price > 0
          AND ask_price > bid_price
        GROUP BY sec
    ),
    signed_fills AS
    (
        SELECT
            t.sec        AS sec,
            t.fill_size  AS fill_size,
            q.mid        AS ref_mid,
            if(t.fill_price > q.mid, 1, -1) AS side
        FROM
        (
            SELECT
                dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
                sec - 1          AS ref_sec,
                toFloat64(price) AS fill_price,
                size             AS fill_size
            FROM global_markets.stocks_trades
            WHERE ticker = 'INTC'
              AND sip_timestamp >= toDateTime('2026-06-10 13:30:01', 'UTC')
              AND sip_timestamp <  toDateTime('2026-06-10 19:55:00', 'UTC')
              AND price > 0
              AND size > 0
        ) AS t
        INNER JOIN mid_by_second AS q ON q.sec = t.ref_sec
        WHERE t.fill_price != q.mid
    )
SELECT
    multiIf(f.horizon_s < 60,
            concat(toString(f.horizon_s), ' sec'),
            concat(toString(intDiv(f.horizon_s, 60)), ' min'))                                   AS horizon,
    round(avgIf(f.side * (fut.mid - f.ref_mid) / f.ref_mid, f.fill_size < 1000) * 10000, 3)       AS small_fill_bps,
    round(avgIf(f.side * (fut.mid - f.ref_mid) / f.ref_mid, f.fill_size >= 1000) * 10000, 3)      AS block_fill_bps,
    countIf(f.fill_size >= 1000)                                                                 AS block_fill_count
FROM
(
    SELECT
        sec,
        fill_size,
        ref_mid,
        side,
        horizon_s,
        sec + horizon_s AS future_sec
    FROM signed_fills
    ARRAY JOIN [1, 5, 15, 60, 300] AS horizon_s
) AS f
INNER JOIN mid_by_second AS fut ON fut.sec = f.future_sec
GROUP BY f.horizon_s
HAVING countIf(f.fill_size < 1000) > 0
   AND countIf(f.fill_size >= 1000) > 0
ORDER BY f.horizon_s
Run this yourself

5 min時点では、1,000株未満のプリントの平均は2.983ベーシスポイントだった。一方、1,000株以上の11588件のプリントの平均は2.495だった。同じ総出来高をこの2つのグループに対して約定させても、取引終了時の結果は同じにならない。

マークアウトが執行レポートのスプレッド数値になる仕組み

マークアウトは、標準的なスプレッド分解における欠落項である。実効スプレッドは、テイカーが実際に支払った金額で、ミッド価格からプリントまでの符号付き距離の2倍に当たる。これを2つに分ける。一方は実現スプレッドで、市場が動いた後にマーケットメイカーが保持する金額だ。もう一方はアドバース・セレクションで、ミッド価格基準のマークアウトの2倍に当たる。関係式は完全に成立する。実効スプレッド = 実現スプレッド + アドバース・セレクションである。

クエリ実効スプレッドを実現スプレッドと逆選択に分解、30分ごと
各数値の背後にある正確なSQL
WITH
    mid_by_second AS
    (
        SELECT
            dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
            argMax((toFloat64(bid_price) + toFloat64(ask_price)) / 2, sip_timestamp)    AS mid
        FROM global_markets.cache_stocks_quotes
        WHERE ticker = 'INTC'
          AND sip_timestamp >= toDateTime('2026-06-10 13:30:00', 'UTC')
          AND sip_timestamp <  toDateTime('2026-06-10 20:00:00', 'UTC')
          AND bid_price > 0
          AND ask_price > bid_price
        GROUP BY sec
    ),
    signed_fills AS
    (
        SELECT
            t.sec + 60   AS future_sec,
            t.et_time    AS et_time,
            t.fill_price AS fill_price,
            q.mid        AS ref_mid,
            if(t.fill_price > q.mid, 1, -1) AS side
        FROM
        (
            SELECT
                dateDiff('second', toDateTime('2026-06-10 13:30:00', 'UTC'), sip_timestamp) AS sec,
                sec - 1          AS ref_sec,
                toFloat64(price) AS fill_price,
                formatDateTime(toStartOfInterval(toTimeZone(sip_timestamp, 'America/New_York'), toIntervalMinute(30)), '%H:%i') AS et_time
            FROM global_markets.stocks_trades
            WHERE ticker = 'INTC'
              AND sip_timestamp >= toDateTime('2026-06-10 13:30:01', 'UTC')
              AND sip_timestamp <  toDateTime('2026-06-10 19:55:00', 'UTC')
              AND price > 0
              AND size > 0
        ) AS t
        INNER JOIN mid_by_second AS q ON q.sec = t.ref_sec
        WHERE t.fill_price != q.mid
    )
SELECT
    f.et_time                                                                  AS et_time,
    round(avg(2 * f.side * (f.fill_price - f.ref_mid) / f.ref_mid) * 10000, 3) AS effective_spread_bps,
    round(avg(2 * f.side * (f.fill_price - fut.mid) / f.ref_mid) * 10000, 3)   AS realized_spread_bps,
    round(avg(2 * f.side * (fut.mid - f.ref_mid) / f.ref_mid) * 10000, 3)      AS adverse_selection_bps,
    count()                                                                    AS fill_count
FROM signed_fills AS f
INNER JOIN mid_by_second AS fut ON fut.sec = f.future_sec
GROUP BY f.et_time
ORDER BY f.et_time
Run this yourself

米東部時間09:30から始まる30分間では、実効スプレッドは平均10.651ベーシスポイントだった。このうち、60秒時点のアドバース・セレクションが8.313、マーケットメイカーが保持する部分が2.338だった。パネルは13個の30分区間を対象としている。

これらの構成要素は、Rule 605および606の執行レポートで市場施設ごとに集計される数値だ。また、サブペニー・ルールと価格改善に基づく価格改善の主張の算術的な根拠でもある。リベートは1株当たりの固定的なクレジットだ。アドバース・セレクションは、実際に気配値が約定した場合に生じる1株当たりの変動コストである。見出しの料率表ではなく、測定した曲線に沿って両者を比較することが、マーケットメイカー向け手数料とリベートを検証する方法になる。これはマーケットメイカーが損失を出す理由の仕組みとも並ぶ。

これらの数値の計算方法

すべてのパネルは、2026年6月10日の通常取引時間、米東部時間09:30から16:00までのINTCの気配値とプリントを読み込んでいる。気配値は1秒ごとに1つのミッド価格へ集約し、その秒の中で最後に記録された気配値を使う。プリントが直前の一秒のミッド価格を上回っていれば買い主導、下回っていれば売り主導に分類する。これは標準的な気配値ルールだ。ミッド価格と完全に一致するプリントは推測で分類せず除外したため、ミッド価格での約定はサンプルに含まれない。直前の一秒のミッド価格を基準にすることで、将来の情報を参照しない。期間はプリントが記録された秒から数えた整数秒とし、対象秒に気配値が存在する場合だけ、その約定を該当期間に含める。

FAQ

取引におけるマークアウトとは

マークアウトとは、約定後の一定期間におけるミッド価格の変化を、符号付きで示したものだ。約定後に市場が取引方向へ動けばプラスとなる。逆方向へ動けばマイナスで、これがアドバース・セレクションの定義である。

マイナスのマークアウトは常に悪い約定か

そうとは限らない。市場性注文の一秒時点のマークアウトがマイナスでも、その大部分は注文を即時に約定させるために支払ったスプレッドである。より重要なのは、長い期間でも曲線が下落し続けるか、それとも横ばいになるかだ。

マークアウトとスリッページの違いは何か

スリッページは、約定価格を意思決定価格や到着価格と比較する。そのため、注文全体の執行経路を評価する。マークアウトは、約定価格を約定後の特定時点のミッド価格と比較する。そのため、約定後に何が起きたかを評価する。一方は親注文を評価し、もう一方は個々の約定を評価する。

マークアウトにはどの期間を使うべきか

約定の目的によって異なる。一秒未満の期間はレイテンシーに敏感な執行を評価する。流動性の高い銘柄でアドバース・セレクションを測る場合、一分が一般的なデフォルトだ。数値の横に期間を示して初めて、2つのマークアウトを比較できる。

マークアウトは実効スプレッドとどう関係するか

実効スプレッドは、実現スプレッドとアドバース・セレクションに分解できる。アドバース・セレクションは、ミッド価格基準のマークアウトの2倍だ。期間を変えると、両者の分解も変わる。そのため、期間を付記しないスプレッド統計は不完全である。


ここで示したすべてのパネルには、作成に使ったSQLが付属している。いずれかを開いてティッカーや日付を変更すれば、Strasmore terminal上で同じマークアウト曲線を最初から再構築できる。