#
Self-Match Detection
#
Purpose
Self-match detection in the Nekuti Matching Engine serves as a compliance and integrity safeguard. Its primary function is to prevent orders from accounts with the same beneficial owner from executing against each other in a way that could be interpreted as wash trading or used to simulate market activity.
#
Key Concepts
#
Pre-Match Evaluation
Self-match detection is performed during the matching process, prior to trade publication. If two orders are eligible to match and originate from accounts with shared beneficial ownership, the engine diverts the match into a distinct workflow. This evaluation considers:
- Beneficial ownership metadata attached to each account
- Order parameters and match eligibility
- Whether the execution should be marked as publishable to public market data
#
Transfer-Trade Workflow
When a self-match is detected:
- The engine executes a transfer-trade instead of a regular trade
- The transfer-trade is reported to the participant via standard execution report APIs
- The execution report includes metadata indicating the trade is non-publishable
- Consuming systems should filter these trades from public market data feeds based on the indicator
This workflow ensures that self-matches are handled transparently without contributing to public trade volume or price formation when consuming systems properly respect the non-publishable flag.
#
Market Integrity
Transfer-trades are designed to:
- Prevent the appearance of wash trading
- Avoid artificial volume inflation or tape painting
- Maintain complete audit trails for participants while excluding trades from public volume and price statistics
#
Integration Requirements
- Participants must configure and maintain accurate beneficial ownership metadata
- Consuming systems must detect and suppress transfer-trades based on execution report flags
- No additional configuration is required to enable this feature; it is active by default
- The following sections will provide execution report examples, metadata specifications, and implementation guidelines for consuming systems.
#
Setting Beneficial Ownership
The Control Gateway provides the /AccountAdmin/Owner endpoint to associate accounts with their beneficial owners. The owner is represented as a 64-bit signed integer identifier.
Note: Orders from the same account always implicitly share the same beneficial owner, even if no explicit owner is set via the API. Setting the owner field is only required when multiple accounts need to be associated with the same beneficial owner.
#
API Endpoint
POST http://[adminServer]:8181/AccountAdmin/Owner?account={accountNumber}&owner={ownerIdentifier}
#
Example: Configuring Accounts with Shared Ownership
Consider a scenario where a trading firm manages multiple accounts for the same client. Account 1001 and Account 1002 both belong to beneficial owner 500:
# Set owner for Account 1001
curl -X POST "http://[adminServer]:8181/AccountAdmin/Owner?account=1001&owner=500"
# Set owner for Account 1002
curl -X POST "http://[adminServer]:8181/AccountAdmin/Owner?account=1002&owner=500"
Once configured, any orders from accounts 1001 and 1002 that would match against each other will be routed through the transfer-trade workflow.
#
Transfer-Trade Detection Example
#
Scenario
- Account 1001 places a buy order for 100 BTCUSD @ 60000
- Account 1002 places a sell order for 100 BTCUSD @ 60000
- Both accounts share beneficial owner 500
- The orders are eligible to match
#
Normal Trade vs. Transfer-Trade
Without self-match detection, these orders would execute as a normal trade:
- Both execution reports would have
selfTradeLastQty: 0 - The trade would appear on public market data feeds
- The trade would contribute to volume statistics
With self-match detection enabled, the engine diverts to transfer-trade workflow:
- Both execution reports have a non-zero
selfTradeLastQtyvalue equal to the matched quantity - The trade is excluded from public market data feeds
- Account positions and balances are updated normally
- The trade is visible only to the participant via private execution APIs
#
Execution Report Structure
When monitoring executions via the WebSocket feed (ws://[adminServer]/realtime?executions), transfer-trades are identified by the selfTradeLastQty field:
{
"orderId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"clOrdId": "client-order-001",
"account": 1001,
"symbol": "BTCUSD",
"side": "Buy",
"execType": "Trade",
"execId": "exec-12345",
"lastQty": 100,
"lastPx": 60000.0,
"transactTime": "2025-10-28T10:15:30.123Z",
"selfTradeLastQty": 100,
...
}
A non-zero value in selfTradeLastQty signals that:
- This execution resulted from a self-match
- The trade should not be published to public feeds
- Consuming systems should exclude this from public volume calculations
- The trade remains valid for internal position tracking and settlement
- The
selfTradeLastQtyvalue indicates the quantity that matched against the same beneficial owner
#
Implementation Guidance
When consuming execution reports:
// Example: Filtering transfer-trades from public market data
function shouldPublishTrade(execution) {
// Transfer-trades have non-zero selfTradeLastQty
return !execution.selfTradeLastQty || execution.selfTradeLastQty === 0;
}
// Example: Processing executions with proper categorization
function processExecution(execution) {
if (execution.execType === "Trade") {
if (shouldPublishTrade(execution)) {
publishToMarketData(execution);
updateVolumeMetrics(execution);
} else {
// This is a transfer-trade (self-match)
logTransferTrade(execution, execution.selfTradeLastQty);
}
// Always update internal position tracking
updateAccountPosition(execution.account, execution);
}
}
#
Operational Considerations
- Auditability: Transfer-trades are fully auditable through private execution APIs
- Position Management: Transfer-trades affect positions identically to regular trades
- Fee Treatment: Commission and fee rules apply to transfer-trades as configured
- Reporting: Internal risk and compliance reporting should include transfer-trades
- Market Data: Public market data feeds should exclude transfer-trades to prevent artificial volume inflation
- Liquidation Price Feeds: Transfer-trades do not feed into the internal price feed used for liquidation checks on instruments whose mark price source is set to last-price