メインコンテンツまでスキップ

Copy execution transparency (フェーズ3)

per-copy実行事実 — レイテンシ、現実的スリッページ、fill vs failure — すべてのコピー試行でキャプチャされ、per-profile透明性レポートとして表面化。デフォルトオフ; App:Copy:TransparencyEnabled=trueで有効化。オフのとき、コピーエンジンは字节identical: hostはno-op sinkに放出、変更なし。

動作原理​

CopyEngineHost ──Record(fact)──▶ ICopyEventSink
│
(transparency off) NullCopyEventSink → 破棄(デフォルト;ゼロホットパスコスト)
(transparency on) ChannelCopyEventSink → バウンドメモリチャネル(DropOldest)
│
▼
CopyExecutionDrainer (BackgroundService)
│ App drain間隔でバッチ処理
▼
CopyExecution append-onlyテーブル ◀── GET /api/copy/profiles/{id}/transparency
  • ホットパスはI/Oから解放。 HostはICopyEventSink.Record(...)を呼び出し — ノンブロッキング、決してスローしないエンキュー。決してawaitせず、データベースに触れず、注文実行をブロックしない。
  • バックプレッシャーより損失が優先。 チャネルはバウンド(CopyExecutionChannelCapacity)でDropOldest: DBドレイナーが停止している場合、最古の透明性行がドロップされ代わりにコピーが遅延。透明性 = ベストエフォートテレメトリ、トレーディング依存ではなく。
  • アウトオブバンド永続化。 CopyExecutionDrainerはチャネルをバッチ(CopyExecutionDrainBatchSize)でCopyExecutionDrainIntervalにドレーし、スコープDataContext経由でCopyExecution行を書き込みます。シャットダウン時の最終フラッシュ。
  • 事実而非コマンド。 CopyExecution = append-onlyログ(InstanceLog/AuditLogと同様)、而非アグリゲート。読み取りモデルは直接クエリ(CQRS-lite)、メモリ内アグリゲート。

何が記録されるか​

1つのCopyExecutionRecordは1つの宛先での1つのコピー試行ごと:

Kindいつ運ぶもの
Openedコピー注文が配置されたシンボル、サイド、wire volume、マスター価格 реализованный slippage(ポイント)、レイテンシ(ms)
Failedコピーオープンがスロー/拒否されたシンボル、サイド、マスターvolume/price、レイテンシ、失敗理由(例外タイプ)

(Closed/Skipped/Reconciledは将来拡張のためにenumに存在。)

レポート​

GET /api/copy/profiles/{id}/transparency(owner-scoped)は最新の500事実 대해以下を返します:

  • 概要 — 合計、opened、failed、fill rate、平均レイテンシ(ms)、平均スリッページ(ポイント)。
  • 最近 — 生の最近事実(宛先、ソースポジション、シンボル、サイド、volume、マスター価格、スリッページ、レイテンシ、理由、タイムスタンプ)。

設定(App:Copy)​

設定デフォルト効果
TransparencyEnabledfalseこのノードのper-copy事実キャプチャ+ドレイナー有效化。

チャネル容量、ドレインバッチサイズ、ドレイン間隔 = CopyDefaults定数(CopyExecutionChannelCapacity / CopyExecutionDrainBatchSize / CopyExecutionDrainInterval)。

テスト​

  • ユニット(CopyTransparencyTests) — 正常なオープンは正しいシンボル/サイド/ volume/レイテンシでOpened事実を放出;拒否されたオープンは理由と共にFailed事実を放出。キャプチャリングsink介して駆動。
  • 統合(CopyExecutionDrainerTests、real Postgres) — ドレイナーはバッファされた事実をCopyExecutionログに永続化;空sinkは書き込みなし。
  • DST — hostはno-opデフォルトsinkでfire-and-forgetを発するため、決定論的コピーストレススイートは緑のままであり(23/23)。