Transaction Cost Analysis (TCA) API Reference
Overview
The Ediphy TCA API provides comprehensive post-trade analytics, enabling traders and portfolio managers to measure execution quality, quantify transaction costs, and benchmark performance against market activity. Whether you're analyzing a single trade or reviewing an entire portfolio's execution history, TCA delivers actionable insights into how your trades performed relative to the market.
Product Coverage: Fixed Income Bonds (Corporate Credit, Government, Emerging Markets)
Why Ediphy TCA?
- Multi-Source Benchmarking — Compare executions against MiFID post-trade data, TRACE, Consolidated Tape (CT), and evaluated pricing sources
- Flexible Pricing References — Incorporate bank mid prices, fair value marks, or custom pricing feeds based on your data subscriptions
- Intelligent Cost Attribution — Measure costs in basis points (yield spread), dollar terms, and percentage of trade value
- Peer Universe Analysis — See how your execution compares to similar trades by instrument type, maturity, sector, and rating
- Statistical Rigor — Spline interpolation and clustering algorithms derive expected costs from sparse market data
- Seamless Integration — Analyze trades from your OMS, link to EMS executions, or enter trades manually
1. Key Concepts
1.1 Trade Input Methods
TCA accepts trades from multiple sources to accommodate different workflows:
Direct Entry: - Submit trade details directly via API (ISIN, side, quantity, price, timestamp) - Ideal for manual analysis or trades executed outside Ediphy
EMS Linkage: - Reference executed trades by ticket ID from the Ediphy EMS - Automatically pulls execution details including partial fills and average prices
Batch Import: - Upload multiple trades for portfolio-level analysis - CSV/JSON format for OMS integration
For trades executed via Ediphy EMS, use ticket linkage to ensure fill-level accuracy. Direct entry is best for analyzing external executions or hypothetical scenarios.
1.2 Cost Measurement Framework
TCA measures transaction costs across three dimensions:
Spread Cost (Basis Points)
The distance between your execution price and a reference price, expressed in yield terms:
spread_cost_bps = (execution_yield - reference_yield) × direction_multiplier
Where direction_multiplier is +1 for buys (paying more is a cost) and -1 for sells (receiving less is a cost).
Dollar Cost
The absolute dollar impact of the spread, scaled by trade size and duration:
dollar_cost = spread_cost_bps × duration × notional / 10000
For a 5MM trade with 5-year duration and 10bps spread cost:
dollar_cost = 10 × 5 × 5,000,000 / 10000 = $25,000
Percentage Cost
The cost as a proportion of trade value:
pct_cost = dollar_cost / (notional × clean_price / 100)
Dollar cost calculation uses modified duration to translate yield spread into price impact. For instruments without duration data, a duration-neutral price spread is used instead.
1.3 Reference Price Hierarchy
TCA computes costs against multiple reference prices, providing a multi-dimensional view of execution quality:
| Reference | Description | Availability |
|---|---|---|
arrival_mid |
Mid-price at trade arrival time | Real-time pricing subscriptions |
execution_mid |
Mid-price at exact execution time | Real-time pricing subscriptions |
vwap |
Volume-weighted average price over benchmark window | MiFID/TRACE/CT data |
twap |
Time-weighted average price over benchmark window | MiFID/TRACE/CT data |
close |
End-of-day settlement or mark price | Evaluated pricing |
fair_value |
Ediphy's proprietary fair value estimate | Standard |
bank_mid |
Custom bank pricing feed | Client subscription |
curve_implied |
Yield implied by fitted curve | Curve data subscription |
Reference Selection:
By default, TCA computes costs against all available references. You can specify a primary reference for headline metrics:
JSON{ "primary_reference": "arrival_mid", "include_all_references": true }
1.4 Benchmark Data Sources
TCA aggregates market activity from multiple regulatory and commercial sources:
1.4.1 MiFID Post-Trade Data (European Markets)
Trade reports from the MiFID II transparency regime covering European fixed income markets:
| Field | Description |
|---|---|
mifid_volume |
Total traded volume in the benchmark window |
mifid_count |
Number of reported trades |
mifid_vwap |
Volume-weighted average price |
mifid_high / mifid_low |
Price range |
mifid_median_yield |
Median traded yield |
MiFID data is available T+1 for most instruments, with some deferred reporting for large-in-scale trades.
1.4.2 TRACE Data (US Corporate & Agency)
FINRA's Trade Reporting and Compliance Engine provides US corporate bond transparency:
| Field | Description |
|---|---|
trace_volume |
Total reported volume |
trace_count |
Number of trades |
trace_vwap |
Volume-weighted average price |
trace_high / trace_low |
Price range |
trace_median_spread |
Median spread to benchmark |
TRACE data is subject to dissemination caps (5MM+ trades may be reported as "5MM+"). TCA applies statistical adjustments when computing benchmarks from capped data.
1.4.3 Consolidated Tape (CT)
Where available, consolidated tape data provides a unified view across trading venues:
| Field | Description |
|---|---|
ct_volume |
Consolidated traded volume |
ct_count |
Trade count across venues |
ct_vwap |
Consolidated VWAP |
1.4.4 Evaluated Pricing Sources
Client data subscriptions enable additional pricing references:
| Source | Description | Subscription Required |
|---|---|---|
| Ediphy Fair Value | Proprietary end-of-day marks | Standard |
| Bank Runs | Executable/indicative prices from dealers | Per-bank subscription |
| Pricing Services | Third-party evaluated prices (e.g., ICE, Bloomberg) | Per-provider subscription |
| Custom Feeds | Client-provided pricing data | Custom integration |
1.5 Peer Universe Construction
TCA contextualizes your execution by comparing it to a peer universe of similar trades. The peer universe is constructed by filtering market activity across multiple dimensions:
Instrument Characteristics:
| Dimension | Buckets |
|---|---|
| Asset Class | Government, Investment Grade Credit, High Yield, Emerging Markets |
| Maturity | Short (0-3Y), Medium (3-7Y), Long (7-15Y), Ultra-Long (15Y+) |
| Sector | Financials, Industrials, Utilities, Consumer, Technology, etc. |
| Rating | AAA/AA, A, BBB, BB, B, CCC and below |
| Currency | USD, EUR, GBP, etc. |
Trade Characteristics:
| Dimension | Buckets |
|---|---|
| Trade Size | Small (<1MM), Medium (1-5MM), Large (5-25MM), Block (25MM+) |
| Direction | Buy, Sell |
Benchmark Window:
| Window | Description |
|---|---|
| Same-day | Trades on the same calendar day |
| T-1 to T+1 | Three-day window centered on execution |
| Rolling 5-day | Five trading days ending on execution date |
| Rolling 20-day | Twenty trading days ending on execution date |
The response includes `peer_count` indicating how many comparable trades were found. Sparse peer universes (< 10 trades) may produce less reliable percentile rankings.
1.6 Statistical Methods
TCA employs statistical techniques to derive meaningful benchmarks from sparse fixed income data:
1.6.1 Spline Interpolation
For instruments with limited direct trading activity, TCA constructs synthetic benchmarks using spline interpolation across the issuer's curve:
- Fit a smooth yield curve to the issuer's traded bonds
- Interpolate/extrapolate to the target maturity
- Estimate fair value spread based on curve position
This is particularly valuable for off-the-run bonds where direct comparables are scarce.
1.6.2 Clustering Analysis
TCA groups instruments into clusters based on similarity across multiple features:
- Credit risk profile (rating, sector, issuer characteristics)
- Duration and convexity
- Liquidity characteristics
- Historical trading patterns
Execution costs are then compared within the cluster to identify outliers and establish expected cost ranges.
1.6.3 Confidence Intervals
Rather than a single "expected cost" point estimate, TCA provides confidence bands:
| Metric | Description |
|---|---|
expected_cost_low |
25th percentile of expected cost |
expected_cost_mid |
Median expected cost |
expected_cost_high |
75th percentile of expected cost |
percentile_rank |
Where your execution falls in the distribution |
A trade in the 90th percentile cost a lot more than most comparable trades; 10th percentile indicates exceptional execution.
2. Authentication & Authorization
2.1 Authentication
The API uses Bearer token authentication. Include your API key in the Authorization header:
Authorization: Bearer <api_key>
API keys are managed through the Ediphy client portal. See the EMS Client API documentation for details on key management and rotation.
2.2 Required Permissions
| Permission | Description |
|---|---|
external.tca.analyze |
Submit trades for TCA analysis |
external.tca.batch |
Batch upload trades |
external.tca.reports |
Retrieve historical TCA reports |
external.tca.team |
View TCA reports for team members |
2.3 Data Entitlements
Access to benchmark data sources depends on your subscription:
| Entitlement | Data Access |
|---|---|
data.mifid |
MiFID post-trade data |
data.trace |
TRACE data |
data.ct |
Consolidated tape |
data.pricing.<provider> |
Evaluated pricing from specific provider |
data.bank.<bank_id> |
Bank pricing feed |
TCA analysis uses all data sources you're entitled to. The response indicates which sources contributed to each benchmark.
3. API Design
3.1 Base URL Structure
Production: https://api.ediphymarkets.com/tca/v1
Sandbox: https://api.sandbox.ediphymarkets.com/tca/v1
3.2 Common Headers
Request:
Content-Type: application/json
Authorization: Bearer <api_key>
Response:
Content-Type: application/json
X-Ediphy-Request-Id: <uuid>
3.3 Error Response Format
JSON{ "error": { "code": "VALIDATION_ERROR", "message": "Invalid ISIN format", "field": "inst_id", "request_id": "req_abc123" } }
Error Codes:
| Code | Description |
|---|---|
AUTHENTICATION_FAILED |
Invalid or missing credentials |
PERMISSION_DENIED |
Not authorized for action or data source |
VALIDATION_ERROR |
Invalid request parameters |
INVALID_ISIN |
ISIN format invalid or unrecognized |
INVALID_SIDE |
Side must be buy or sell |
INVALID_QUANTITY |
Quantity must be a positive number |
INVALID_PRICE |
Price must be a positive number |
INVALID_TIMESTAMP |
Timestamp format invalid or in future |
TICKET_NOT_FOUND |
EMS ticket does not exist or not accessible |
INSUFFICIENT_DATA |
Not enough market data to compute benchmarks |
REPORT_NOT_FOUND |
TCA report does not exist |
RATE_LIMIT_EXCEEDED |
Too many requests |
INTERNAL_ERROR |
Server-side issue |
3.4 HTTP Status Codes
| Status Code | Meaning | When Used |
|---|---|---|
200 OK |
Success | Analysis complete, results returned |
202 Accepted |
Processing | Batch analysis accepted, poll for results |
400 Bad Request |
Malformed request | Invalid JSON, missing required fields |
401 Unauthorized |
Authentication failed | Invalid/missing credentials |
403 Forbidden |
Permission denied | Valid auth but not authorized for action |
404 Not Found |
Resource not found | Unknown report_id or ticket_id |
422 Unprocessable |
Cannot analyze | Valid request but insufficient data |
429 Too Many Requests |
Rate limit exceeded | See rate limiting section |
500 Internal Server Error |
Server error | Unexpected failure |
4. Trade Analysis Endpoints
4.1 Analyze Single Trade
Submits a single trade for TCA analysis and returns comprehensive cost metrics.
Request Body (Direct Entry)
JSON{ "trade": { "inst_id": "US912828ZT77", "side": "buy", "quantity": 5000000, "price": 99.50, "yield": 4.25, "executed_at": "2025-01-15T14:30:00.000Z" }, "options": { "primary_reference": "arrival_mid", "benchmark_windows": ["same_day", "5_day"], "peer_dimensions": ["asset_class", "maturity", "rating"], "include_curve_analysis": true } }
Request Body (EMS Ticket Linkage)
JSON{ "ticket_id": "TICKET_abc123def456", "options": { "primary_reference": "arrival_mid", "benchmark_windows": ["same_day", "5_day"] } }
Trade Field Definitions
| Field | Required | Type | Description |
|---|---|---|---|
inst_id |
Yes | string | ISIN of the bond (12 characters) |
side |
Yes | string | Trade direction: "buy" or "sell" |
quantity |
Yes | integer | Notional amount in base currency units (e.g., 5000000 for 5MM) |
price |
Yes* | number | Clean execution price |
yield |
Yes* | number | Execution yield. Either price or yield must be provided; system converts using instrument terms. |
executed_at |
Yes | string | ISO8601 timestamp of execution |
arrival_at |
No | string | ISO8601 timestamp when order was first submitted. Defaults to executed_at if not provided. |
venue |
No | string | Execution venue identifier |
counterparty |
No | string | Counterparty identifier (for bilateral trades) |
client_trade_id |
No | string | Your internal trade reference |
*Either price or yield must be provided.
Options Field Definitions
| Field | Required | Default | Description |
|---|---|---|---|
primary_reference |
No | "fair_value" |
Primary reference for headline cost metrics. Options: "arrival_mid", "execution_mid", "vwap", "twap", "close", "fair_value", "bank_mid", "curve_implied" |
benchmark_windows |
No | ["same_day"] |
Time windows for peer comparison. Options: "same_day", "t1" (T-1 to T+1), "5_day", "20_day" |
peer_dimensions |
No | ["asset_class", "maturity", "size"] |
Dimensions for peer universe construction. Options: "asset_class", "maturity", "sector", "rating", "currency", "size" |
include_curve_analysis |
No | true |
Include spline-based curve analysis |
include_all_references |
No | true |
Compute costs against all available references |
custom_reference_price |
No | - | Client-provided reference price for comparison |
custom_reference_yield |
No | - | Client-provided reference yield for comparison |
bank_ids |
No | - | Specific bank pricing feeds to include (requires subscription) |
Response (Success - 200 OK)
JSON{ "report_id": "TCA_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "trade": { "inst_id": "US912828ZT77", "short_name": "T 2.5 05/15/30", "legal_name": "US TREASURY N/B", "side": "buy", "quantity": 5000000, "quantity_mm": 5.0, "price": 99.50, "yield": 4.25, "executed_at": "2025-01-15T14:30:00.000Z", "arrival_at": "2025-01-15T14:28:30.000Z" }, "instrument": { "asset_class": "Government", "sector": "Sovereign", "rating": "AAA", "currency": "USD", "maturity": "2030-05-15", "maturity_bucket": "Medium", "duration": 4.85, "coupon": 2.5 }, "cost_summary": { "primary_reference": "arrival_mid", "spread_cost_bps": 3.2, "dollar_cost": 7760, "pct_cost": 0.0156, "direction_label": "Paid up", "quality_rating": "Good" }, "reference_prices": { "arrival_mid": { "price": 99.532, "yield": 4.218, "source": "live_pricing", "spread_cost_bps": 3.2, "dollar_cost": 7760 }, "execution_mid": { "price": 99.525, "yield": 4.222, "source": "live_pricing", "spread_cost_bps": 2.8, "dollar_cost": 6790 }, "vwap": { "price": 99.48, "yield": 4.250, "source": "trace", "spread_cost_bps": -2.0, "dollar_cost": -4850, "volume": 125000000, "trade_count": 47 }, "fair_value": { "price": 99.51, "yield": 4.237, "source": "ediphy", "as_of": "2025-01-15T00:00:00Z", "spread_cost_bps": 1.3, "dollar_cost": 3153 }, "curve_implied": { "price": 99.495, "yield": 4.244, "source": "spline_fit", "curve_residual_bps": 0.6, "spread_cost_bps": 0.6, "dollar_cost": 1455 } }, "peer_analysis": { "window": "same_day", "peer_count": 47, "peer_volume": 125000000, "peer_dimensions": { "asset_class": "Government", "maturity_bucket": "Medium", "size_bucket": "Medium" }, "cost_distribution": { "p10": -2.5, "p25": -0.8, "p50": 1.2, "p75": 3.5, "p90": 6.8, "mean": 1.8, "std_dev": 3.2 }, "your_percentile": 62, "expected_cost": { "low": -0.8, "mid": 1.2, "high": 3.5 } }, "curve_analysis": { "curve_date": "2025-01-15", "issuer_curve_bonds": 12, "curve_fit_quality": "Good", "curve_r_squared": 0.987, "target_curve_yield": 4.244, "curve_spread_bps": 0.6, "richness_cheapness": "Slightly Cheap", "z_score": 0.45 }, "market_context": { "benchmark_window": "same_day", "sources": ["trace", "mifid"], "trace": { "volume": 125000000, "trade_count": 47, "vwap_price": 99.48, "vwap_yield": 4.250, "high_price": 99.72, "low_price": 99.31, "median_spread_bps": 1.5 }, "mifid": { "volume": 45000000, "trade_count": 18, "vwap_price": 99.52, "vwap_yield": 4.231 }, "liquidity_indicator": "High", "market_direction": "Slightly Weaker" }, "data_quality": { "overall_confidence": "High", "reference_data_available": ["arrival_mid", "execution_mid", "vwap", "twap", "fair_value", "curve_implied"], "reference_data_unavailable": ["bank_mid"], "peer_universe_depth": "Adequate", "curve_data_quality": "Good", "warnings": [] }, "metadata": { "analyzed_at": "2025-01-15T14:35:12.456Z", "api_version": "1.0", "data_subscriptions_used": ["trace", "mifid", "ediphy_pricing"] } }
4.2 Batch Analysis
Submits multiple trades for analysis. Returns immediately with a batch ID; poll for results.
Request Body
JSON{ "trades": [ { "inst_id": "US912828ZT77", "side": "buy", "quantity": 5000000, "price": 99.50, "executed_at": "2025-01-15T14:30:00.000Z", "client_trade_id": "TRADE-001" }, { "inst_id": "US037833EK23", "side": "sell", "quantity": 10000000, "yield": 5.125, "executed_at": "2025-01-15T15:45:00.000Z", "client_trade_id": "TRADE-002" } ], "options": { "primary_reference": "fair_value", "benchmark_windows": ["same_day", "5_day"], "include_curve_analysis": true } }
Response (Accepted - 202)
JSON{ "batch_id": "BATCH_abc123def456", "status": "processing", "trades_submitted": 2, "estimated_completion": "2025-01-15T14:36:00.000Z", "links": { "status": "/analyze/batch/BATCH_abc123def456", "results": "/analyze/batch/BATCH_abc123def456/results" } }
4.3 Get Batch Status
Check the status of a batch analysis request.
Response (Success - 200 OK)
JSON{ "batch_id": "BATCH_abc123def456", "status": "completed", "trades_submitted": 2, "trades_analyzed": 2, "trades_failed": 0, "started_at": "2025-01-15T14:35:00.000Z", "completed_at": "2025-01-15T14:35:45.000Z", "links": { "results": "/analyze/batch/BATCH_abc123def456/results" } }
Batch Status Values:
| Status | Description |
|---|---|
processing |
Analysis in progress |
completed |
All trades analyzed successfully |
completed_with_errors |
Some trades failed analysis |
failed |
Batch processing failed |
4.4 Get Batch Results
Retrieve results for a completed batch analysis.
Query Parameters
| Parameter | Description |
|---|---|
limit |
Max results per page (default 50, max 200) |
cursor |
Pagination cursor |
client_trade_id |
Filter by your trade reference |
Response (Success - 200 OK)
JSON{ "batch_id": "BATCH_abc123def456", "results": [ { "report_id": "TCA_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "client_trade_id": "TRADE-001", "status": "success", "trade": { /* ... */ }, "cost_summary": { /* ... */ }, "reference_prices": { /* ... */ }, "peer_analysis": { /* ... */ } }, { "report_id": "TCA_def456ghi789", "client_trade_id": "TRADE-002", "status": "success", "trade": { /* ... */ }, "cost_summary": { /* ... */ }, "reference_prices": { /* ... */ }, "peer_analysis": { /* ... */ } } ], "summary": { "total_trades": 2, "total_notional": 15000000, "aggregate_spread_cost_bps": 2.1, "aggregate_dollar_cost": 15750, "weighted_percentile": 58 }, "pagination": { "total": 2, "limit": 50, "has_more": false } }
4.5 Get Report
Retrieve a previously generated TCA report by ID.
Response (Success - 200 OK)
Returns the full report structure as shown in Section 4.1.
4.6 List Reports
List TCA reports for the authenticated user.
Query Parameters
| Parameter | Description |
|---|---|
from |
Start date (ISO8601) |
to |
End date (ISO8601) |
inst_id |
Filter by ISIN |
side |
Filter by side: buy, sell |
client_trade_id |
Filter by your trade reference |
limit |
Max results (default 50, max 200) |
cursor |
Pagination cursor |
Response (Success - 200 OK)
JSON{ "reports": [ { "report_id": "TCA_7f3a9b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c", "inst_id": "US912828ZT77", "short_name": "T 2.5 05/15/30", "side": "buy", "quantity_mm": 5.0, "executed_at": "2025-01-15T14:30:00.000Z", "spread_cost_bps": 3.2, "percentile": 62, "quality_rating": "Good", "analyzed_at": "2025-01-15T14:35:12.456Z" } ], "pagination": { "total": 127, "limit": 50, "has_more": true, "next_cursor": "eyJpZCI6InRjYV8xMjM0In0=" } }
5. Cost Metrics Detail
5.1 Spread Metrics
Yield Spread (Primary)
The difference between your execution yield and the reference yield:
| Metric | Calculation | Interpretation |
|---|---|---|
spread_cost_bps |
(exec_yield - ref_yield) × direction |
Positive = cost, Negative = saving |
For buys: Paying a higher yield (lower price) is a cost. For sells: Receiving a lower yield (lower price) is a cost.
Price Spread (Secondary)
For instruments where yield isn't meaningful (e.g., floaters), price spread is provided:
| Metric | Calculation | Interpretation |
|---|---|---|
price_spread_bps |
(ref_price - exec_price) / ref_price × 10000 × direction |
Positive = cost |
5.2 Dollar Cost
Translates yield spread into dollar impact using duration:
dollar_cost = spread_cost_bps × modified_duration × notional / 10000
| Field | Description |
|---|---|
dollar_cost |
Absolute dollar cost of execution |
dollar_cost_per_mm |
Cost per million notional |
Modified duration is sourced from reference data. For bonds without duration data, an estimated duration based on maturity is used, flagged in `data_quality.warnings`.
5.3 Implementation Shortfall
Measures the total cost of implementing a trade decision from arrival to completion:
| Metric | Description |
|---|---|
implementation_shortfall_bps |
Total cost from arrival to execution |
delay_cost_bps |
Cost attributed to time between arrival and execution |
execution_cost_bps |
Cost attributed to actual execution vs execution-time mid |
implementation_shortfall = delay_cost + execution_cost
High delay cost suggests market moved against you while waiting. High execution cost suggests poor execution relative to available prices at execution time.
5.4 Market Impact
For larger trades, TCA estimates the market impact of your execution:
| Metric | Description |
|---|---|
estimated_impact_bps |
Estimated market impact based on trade size and liquidity |
realized_impact_bps |
Observed price movement during/after execution |
permanent_impact_bps |
Price change that persists after execution |
temporary_impact_bps |
Price change that reverts after execution |
Market impact metrics require sufficient post-trade data and are only populated for trades where post-execution prices are observable.
6. Benchmark Data Detail
6.1 MiFID Data Fields
| Field | Type | Description |
|---|---|---|
mifid_volume |
number | Total reported volume (EUR equivalent) |
mifid_count |
integer | Number of reported trades |
mifid_vwap_price |
number | Volume-weighted average price |
mifid_vwap_yield |
number | Volume-weighted average yield |
mifid_twap_price |
number | Time-weighted average price |
mifid_high_price |
number | Highest reported price |
mifid_low_price |
number | Lowest reported price |
mifid_median_yield |
number | Median traded yield |
mifid_coverage |
string | Data completeness: "full", "partial", "deferred" |
6.2 TRACE Data Fields
| Field | Type | Description |
|---|---|---|
trace_volume |
number | Total reported volume (USD) |
trace_count |
integer | Number of reported trades |
trace_vwap_price |
number | Volume-weighted average price |
trace_vwap_yield |
number | Volume-weighted average yield |
trace_high_price |
number | Highest reported price |
trace_low_price |
number | Lowest reported price |
trace_median_spread |
number | Median spread to benchmark (bps) |
trace_capped_trades |
integer | Number of trades with capped volume |
6.3 Consolidated Tape Fields
| Field | Type | Description |
|---|---|---|
ct_volume |
number | Consolidated volume |
ct_count |
integer | Consolidated trade count |
ct_vwap_price |
number | Consolidated VWAP |
ct_sources |
array | Contributing data sources |
6.4 Evaluated Pricing Fields
| Field | Type | Description |
|---|---|---|
fair_value_price |
number | Ediphy fair value price |
fair_value_yield |
number | Ediphy fair value yield |
fair_value_as_of |
string | Timestamp of fair value calculation |
bank_mid_price |
number | Bank composite mid price (if subscribed) |
bank_mid_yield |
number | Bank composite mid yield |
bank_contributors |
array | Banks contributing to composite |
curve_implied_yield |
number | Yield implied by curve fit |
curve_spread |
number | Spread to fitted curve (bps) |
7. Statistical Analysis Detail
7.1 Spline Interpolation
The curve_analysis section provides detail on curve-based valuation:
| Field | Type | Description |
|---|---|---|
curve_date |
string | Date of curve snapshot |
issuer_curve_bonds |
integer | Number of issuer bonds used in fit |
curve_fit_quality |
string | Quality indicator: "Excellent", "Good", "Fair", "Poor" |
curve_r_squared |
number | R-squared of curve fit (0-1) |
target_curve_yield |
number | Interpolated yield at target maturity |
curve_spread_bps |
number | Your execution vs curve-implied fair value |
richness_cheapness |
string | Relative value: "Rich", "Slightly Rich", "Fair", "Slightly Cheap", "Cheap" |
z_score |
number | Standard deviations from curve fair value |
Curve Fit Quality Criteria:
| Quality | R-Squared | Bonds in Curve | Description |
|---|---|---|---|
| Excellent | > 0.99 | 10+ | High confidence in curve-based valuation |
| Good | 0.95-0.99 | 5-10 | Reliable curve estimate |
| Fair | 0.90-0.95 | 3-5 | Use with caution |
| Poor | < 0.90 | < 3 | Curve estimate may be unreliable |
7.2 Clustering Analysis
The cluster_analysis section (when available) provides peer grouping detail:
| Field | Type | Description |
|---|---|---|
cluster_id |
string | Assigned cluster identifier |
cluster_description |
string | Human-readable cluster description |
cluster_size |
integer | Number of instruments in cluster |
cluster_avg_spread |
number | Average execution spread in cluster |
cluster_std_dev |
number | Standard deviation of spreads |
similarity_score |
number | How similar target instrument is to cluster center (0-1) |
7.3 Percentile Calculations
Percentile rank contextualizes your execution against the peer universe:
| Field | Type | Description |
|---|---|---|
your_percentile |
integer | Your cost percentile (0-100) |
percentile_interpretation |
string | Human-readable interpretation |
Interpretation Guide:
| Percentile Range | Interpretation |
|---|---|
| 0-20 | Excellent execution — significantly better than peers |
| 20-40 | Good execution — better than most peers |
| 40-60 | Average execution — in line with market |
| 60-80 | Below average — paid more than most peers |
| 80-100 | Poor execution — significantly worse than peers |
8. Quality Ratings
TCA provides a summary quality rating for each trade:
| Rating | Criteria | Description |
|---|---|---|
Excellent |
Percentile < 20 | Significantly outperformed peers |
Good |
Percentile 20-40 | Beat most comparable trades |
Average |
Percentile 40-60 | In line with market |
Below Average |
Percentile 60-80 | Underperformed most peers |
Poor |
Percentile > 80 | Significantly underperformed |
The rating considers: - Primary reference spread cost - Peer universe percentile - Data quality and confidence level
Quality ratings are relative to the peer universe. A "Good" rating on an illiquid bond may represent excellent execution given difficult market conditions.
9. Data Quality & Confidence
9.1 Confidence Levels
Each TCA report includes a data quality assessment:
| Field | Description |
|---|---|
overall_confidence |
Aggregate confidence: "High", "Medium", "Low" |
reference_data_available |
List of available reference prices |
reference_data_unavailable |
List of unavailable references |
peer_universe_depth |
Quality of peer comparison: "Deep", "Adequate", "Sparse" |
curve_data_quality |
Quality of curve analysis: "Excellent", "Good", "Fair", "Poor", "Unavailable" |
warnings |
Array of data quality warnings |
Confidence Criteria:
| Level | Criteria |
|---|---|
| High | 3+ reference prices available, 20+ peer trades, good curve fit |
| Medium | 2+ reference prices, 10-20 peer trades OR fair curve fit |
| Low | Limited references, < 10 peers, poor/no curve data |
9.2 Common Warnings
| Warning Code | Description |
|---|---|
SPARSE_PEER_UNIVERSE |
Fewer than 10 comparable trades found |
STALE_REFERENCE_PRICE |
Reference price is more than T+1 |
ESTIMATED_DURATION |
Duration estimated from maturity, not from terms |
CAPPED_TRADE_DATA |
TRACE data includes capped volumes |
PARTIAL_MIFID_COVERAGE |
Some MiFID data may be deferred |
THIN_CURVE |
Curve fitted with fewer than 5 bonds |
EXTRAPOLATED_CURVE |
Target maturity outside curve range |
10. Client Integration Patterns
10.1 Post-Trade Analysis
Analyze a trade immediately after execution:
PYTHONimport requests API_BASE = "https://api.ediphymarkets.com/tca/v1" API_KEY = "ak_live_..." headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } def analyze_trade(isin, side, quantity, price, executed_at): payload = { "trade": { "inst_id": isin, "side": side, "quantity": quantity, "price": price, "executed_at": executed_at }, "options": { "primary_reference": "arrival_mid", "benchmark_windows": ["same_day", "5_day"] } } response = requests.post( f"{API_BASE}/analyze", json=payload, headers=headers ) response.raise_for_status() return response.json() # Analyze a trade result = analyze_trade( isin="US912828ZT77", side="buy", quantity=5000000, price=99.50, executed_at="2025-01-15T14:30:00.000Z" ) print(f"Spread cost: {result['cost_summary']['spread_cost_bps']} bps") print(f"Dollar cost: ${result['cost_summary']['dollar_cost']:,.0f}") print(f"Percentile: {result['peer_analysis']['your_percentile']}th") print(f"Rating: {result['cost_summary']['quality_rating']}")
10.2 Batch Portfolio Analysis
Analyze an entire day's trading activity:
PYTHONimport requests import time API_BASE = "https://api.ediphymarkets.com/tca/v1" API_KEY = "ak_live_..." headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } def analyze_portfolio(trades): # Submit batch payload = { "trades": trades, "options": { "primary_reference": "fair_value", "benchmark_windows": ["same_day"] } } response = requests.post( f"{API_BASE}/analyze/batch", json=payload, headers=headers ) response.raise_for_status() batch = response.json() batch_id = batch["batch_id"] # Poll for completion while True: status_response = requests.get( f"{API_BASE}/analyze/batch/{batch_id}", headers=headers ) status = status_response.json() if status["status"] in ["completed", "completed_with_errors"]: break time.sleep(2) # Retrieve results results_response = requests.get( f"{API_BASE}/analyze/batch/{batch_id}/results", headers=headers ) return results_response.json() # Example portfolio trades = [ { "inst_id": "US912828ZT77", "side": "buy", "quantity": 5000000, "price": 99.50, "executed_at": "2025-01-15T14:30:00.000Z", "client_trade_id": "TRADE-001" }, { "inst_id": "US037833EK23", "side": "sell", "quantity": 10000000, "price": 101.25, "executed_at": "2025-01-15T15:45:00.000Z", "client_trade_id": "TRADE-002" } ] results = analyze_portfolio(trades) print(f"Total trades: {results['summary']['total_trades']}") print(f"Total notional: ${results['summary']['total_notional']:,.0f}") print(f"Aggregate cost: {results['summary']['aggregate_spread_cost_bps']:.1f} bps") print(f"Aggregate dollar cost: ${results['summary']['aggregate_dollar_cost']:,.0f}")
10.3 EMS Integration
Analyze trades executed via Ediphy EMS:
PYTHONimport requests API_BASE = "https://api.ediphymarkets.com/tca/v1" API_KEY = "ak_live_..." headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } def analyze_ems_trade(ticket_id): payload = { "ticket_id": ticket_id, "options": { "primary_reference": "arrival_mid", "include_curve_analysis": True } } response = requests.post( f"{API_BASE}/analyze", json=payload, headers=headers ) response.raise_for_status() return response.json() # Analyze EMS execution result = analyze_ems_trade("TICKET_abc123def456") # Check implementation shortfall if "implementation_shortfall_bps" in result["cost_summary"]: is_bps = result["cost_summary"]["implementation_shortfall_bps"] delay = result["cost_summary"]["delay_cost_bps"] exec_cost = result["cost_summary"]["execution_cost_bps"] print(f"Implementation shortfall: {is_bps:.1f} bps") print(f" - Delay cost: {delay:.1f} bps") print(f" - Execution cost: {exec_cost:.1f} bps")
10.4 Periodic Reporting
Generate weekly TCA summary reports:
PYTHONimport requests from datetime import datetime, timedelta API_BASE = "https://api.ediphymarkets.com/tca/v1" API_KEY = "ak_live_..." headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json", } def weekly_tca_summary(): # Get last week's reports end_date = datetime.now() start_date = end_date - timedelta(days=7) response = requests.get( f"{API_BASE}/reports", params={ "from": start_date.isoformat() + "Z", "to": end_date.isoformat() + "Z", "limit": 200 }, headers=headers ) response.raise_for_status() data = response.json() # Aggregate statistics total_trades = len(data["reports"]) total_cost_bps = sum(r["spread_cost_bps"] for r in data["reports"]) avg_cost_bps = total_cost_bps / total_trades if total_trades > 0 else 0 ratings = {} for r in data["reports"]: rating = r["quality_rating"] ratings[rating] = ratings.get(rating, 0) + 1 print(f"Weekly TCA Summary ({start_date.date()} to {end_date.date()})") print(f"Total trades analyzed: {total_trades}") print(f"Average spread cost: {avg_cost_bps:.1f} bps") print(f"Rating distribution: {ratings}") weekly_tca_summary()
11. Rate Limiting
11.1 Default Limits
| Endpoint | Rate Limit |
|---|---|
POST /analyze |
20/second |
POST /analyze/batch |
2/second |
GET /analyze/batch/{id} |
20/second |
GET /analyze/batch/{id}/results |
10/second |
GET /reports |
20/second |
GET /reports/{id} |
50/second |
11.2 Response Headers
X-Ediphy-RateLimit-Limit: 20
X-Ediphy-RateLimit-Remaining: 18
X-Ediphy-RateLimit-Reset: 2025-01-15T14:31:00Z
11.3 Rate Limit Exceeded (429)
JSON{ "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Too many requests", "retry_after": 5 } }
12. Security Considerations
12.1 Transport Security
- TLS 1.3 required for all connections
- Certificate pinning recommended for production integrations
12.2 Data Access
- TCA reports are private to the authenticated user
- Team-level access requires explicit permission
- Data source access controlled by subscription entitlements
12.3 Audit Trail
All TCA requests are logged with: - Timestamp - User identity - Request parameters - Data sources used - Results summary
Audit reports available upon request for compliance purposes.
13. Endpoint Summary
| Method | Endpoint | Description |
|---|---|---|
POST |
/analyze |
Analyze single trade |
POST |
/analyze/batch |
Submit batch for analysis |
GET |
/analyze/batch/{id} |
Get batch status |
GET |
/analyze/batch/{id}/results |
Get batch results |
GET |
/reports |
List TCA reports |
GET |
/reports/{id} |
Get specific report |
14. Appendix: Field Reference
14.1 Trade Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
inst_id |
string | Yes | ISIN (12 characters) |
side |
string | Yes | "buy" or "sell" |
quantity |
integer | Yes | Notional in base currency units |
price |
number | Yes* | Clean execution price |
yield |
number | Yes* | Execution yield |
executed_at |
string | Yes | ISO8601 execution timestamp |
arrival_at |
string | No | ISO8601 order arrival timestamp |
venue |
string | No | Execution venue |
counterparty |
string | No | Counterparty identifier |
client_trade_id |
string | No | Your internal trade reference |
*Either price or yield required.
14.2 Options Fields
| Field | Type | Default | Description |
|---|---|---|---|
primary_reference |
string | "fair_value" |
Primary reference for headline metrics |
benchmark_windows |
array | ["same_day"] |
Time windows for peer analysis |
peer_dimensions |
array | ["asset_class", "maturity", "size"] |
Peer universe dimensions |
include_curve_analysis |
boolean | true |
Include spline curve analysis |
include_all_references |
boolean | true |
Compute all available references |
custom_reference_price |
number | - | Custom reference price |
custom_reference_yield |
number | - | Custom reference yield |
bank_ids |
array | - | Specific bank feeds to include |
14.3 Cost Summary Fields
| Field | Type | Description |
|---|---|---|
primary_reference |
string | Reference used for headline metrics |
spread_cost_bps |
number | Spread cost in basis points |
dollar_cost |
number | Dollar cost of execution |
pct_cost |
number | Cost as percentage of trade value |
direction_label |
string | "Paid up", "Given away", "At mid" |
quality_rating |
string | "Excellent", "Good", "Average", "Below Average", "Poor" |
implementation_shortfall_bps |
number | Total implementation shortfall (if arrival provided) |
delay_cost_bps |
number | Cost from delay (if arrival provided) |
execution_cost_bps |
number | Cost from execution (if arrival provided) |
14.4 Reference Price Fields
| Field | Type | Description |
|---|---|---|
price |
number | Reference price |
yield |
number | Reference yield |
source |
string | Data source identifier |
as_of |
string | Timestamp of reference |
spread_cost_bps |
number | Spread to this reference |
dollar_cost |
number | Dollar cost vs this reference |
volume |
number | Volume for market-based references |
trade_count |
integer | Trade count for market-based references |
14.5 Peer Analysis Fields
| Field | Type | Description |
|---|---|---|
window |
string | Benchmark window used |
peer_count |
integer | Number of comparable trades |
peer_volume |
number | Total volume in peer universe |
peer_dimensions |
object | Dimensions used for peer matching |
cost_distribution.p10 |
number | 10th percentile cost |
cost_distribution.p25 |
number | 25th percentile cost |
cost_distribution.p50 |
number | 50th percentile (median) cost |
cost_distribution.p75 |
number | 75th percentile cost |
cost_distribution.p90 |
number | 90th percentile cost |
cost_distribution.mean |
number | Mean cost |
cost_distribution.std_dev |
number | Standard deviation |
your_percentile |
integer | Your cost percentile (0-100) |
expected_cost.low |
number | 25th percentile expected cost |
expected_cost.mid |
number | Median expected cost |
expected_cost.high |
number | 75th percentile expected cost |
14.6 Curve Analysis Fields
| Field | Type | Description |
|---|---|---|
curve_date |
string | Date of curve snapshot |
issuer_curve_bonds |
integer | Bonds used in curve fit |
curve_fit_quality |
string | Quality: "Excellent", "Good", "Fair", "Poor" |
curve_r_squared |
number | R-squared of fit (0-1) |
target_curve_yield |
number | Interpolated yield at target maturity |
curve_spread_bps |
number | Execution vs curve-implied value |
richness_cheapness |
string | Relative value assessment |
z_score |
number | Standard deviations from curve fair value |
14.7 Market Context Fields
| Field | Type | Description |
|---|---|---|
benchmark_window |
string | Window used for market data |
sources |
array | Data sources used |
trace.* |
object | TRACE market data (see Section 6.2) |
mifid.* |
object | MiFID market data (see Section 6.1) |
ct.* |
object | Consolidated tape data (see Section 6.3) |
liquidity_indicator |
string | "High", "Medium", "Low" |
market_direction |
string | "Stronger", "Weaker", "Unchanged" |
14.8 Data Quality Fields
| Field | Type | Description |
|---|---|---|
overall_confidence |
string | "High", "Medium", "Low" |
reference_data_available |
array | Available reference types |
reference_data_unavailable |
array | Unavailable reference types |
peer_universe_depth |
string | "Deep", "Adequate", "Sparse" |
curve_data_quality |
string | Curve analysis quality |
warnings |
array | Data quality warning codes |
15. Glossary
| Term | Definition |
|---|---|
| Arrival Price | The market price at the time a trade decision is made or order is submitted |
| Basis Point (bp) | One hundredth of one percent (0.01%); 100 bps = 1% |
| Implementation Shortfall | Total cost of implementing a trade decision, from arrival to completion |
| Market Impact | The effect of a trade on the market price |
| Modified Duration | Measure of bond price sensitivity to yield changes |
| Percentile Rank | Position in a distribution; 50th percentile = median |
| Peer Universe | Set of comparable trades used for benchmarking |
| Spline Interpolation | Mathematical technique to construct smooth curves through data points |
| TRACE | Trade Reporting and Compliance Engine (FINRA) |
| TWAP | Time-Weighted Average Price |
| VWAP | Volume-Weighted Average Price |