Receive Trade Capture (AE) Report on FIX Protocol


Trade Capture Report (AE) message is a post-trade message which is sent by the broker or exchange to report the trades for participant.

How to request Trade capture report?

A client may use Trade Capture Report Request (AD) to subscribe for trade capture reports based upon selection criteria provided on the trade capture report request.

The server will respond with a Trade Capture Report Request Ack (AR) to indicate, via the TradeRequestStatus (750) and TradeRequestResult (749) fields, whether the request is successful or not. Sometimes if the Trade Capture Report Request message is rejected due to some validations, a Reject message can be generated as the response.

Trade Capture Report Request (AD) Message Structure

TagField NameReqDescription
568 TradeRequestID Request unique identifier
569 TradeRequestType Y Type of request.
0: All Trades
1: Trades Matching Specified Criteria If none of the criteria below are specified, this will return all trades.
150ExecTypeNRequest for all trades of a specific execution type
<Instrument> blockNrequest for all trades for the list of instruments.
=>SymbolSymbol name
=> SecurityIdSecurity Id
=>……

You need to remember that these are standard fields for Trade Capture Report Request (AD) message, the list of supported fields may vary between various FIX formats. 

Always follow the Rules of engagement document provided by the broker before implementing this message type.

Trade Capture Report Request Ack (AC) Message

Itis acknowledge message to  Trade Capture Report Request

Tag FieldNameReqDescription
568 TradeRequestID Y Identifier of the request being acknowledged
569 TradeRequestType Y Identifier of the request being acknowledged
750 TradeRequestStatus Y Whether the request is accepted or rejected
0: Accepted
1: Rejected
749 TradeRequestResult Y Reason the request is rejected.
0: Successful
9: Not Authorized
100: Cannot Match Selection Criteria 200: Request Limit for Day Reached

Trade Capture Report

It is response message to TradeCapture Report Request (AD) which reports trades between counterparties.

Message Structure

TagField NameReqDescription
568 TradeRequestID YRequest unique identifier
571 TradeReportID YUnique Id of response message
17 ExecIdYIdentifier of the trade
48SecurityIdNInstrument Id
55SymbolNSymbol name
32LastQtyYTraded Quantity
31LastPxYTraded Price
75TradeDateYTraded date
60TransactTimeYTransaction time of a trade

Implementation

TradeCaptureReportRequest (AD)

TradeCaptureReportRequest request = new TradeCaptureReportRequest();

string requestId = DateTime.UtcNow.ToString("yyyyMMddHHmmssfff");//generate unique request ID
request.TradeRequestID = new TradeRequestID(requestId);
request.TradeRequestType = new TradeRequestType(TradeRequestType.MATCHED_TRADES_MATCHING_CRITERIA_PROVIDED_ON_REQUEST);

request.NoDates = new NoDates(2);
//Criteria to get trades between two dates var noDatesGroup = new TradeCaptureReportRequest.NoDatesGroup(); noDatesGroup.TransactTime = new TransactTime(start); request.AddGroup(noDatesGroup); noDatesGroup = new TradeCaptureReportRequest.NoDatesGroup(); noDatesGroup.TransactTime = new TransactTime(end); request.AddGroup(noDatesGroup);
Session.SendToTarget(request, sessionId);

TradeCaptureReportRequest Ack (AC)

public void OnMessage(TradeCaptureReportRequestAck ackReport, SessionID session)
{
	if (ackReport.TradeRequestStatus.getValue() == TradeRequestStatus.REJECTED)
	{
	  if (OnReject != null)
	   Console.WriteLine("TradeReportRequest Rejected");
	}
	else if (ackReport.TradeRequestStatus.getValue() == TradeRequestStatus.ACCEPTED)
	{
	   Console.WriteLine("TradeReportRequestStatus Accepted");
	}
	else if (ackReport.TradeRequestStatus.getValue() == TradeRequestStatus.COMPLETED)
	{
	  Console.WriteLine("TradeReportRequestStatus COMPLETED");
	}
}

TradeCaptureReport (AE)

public override void OnMessage(TradeCaptureReport ackReport, SessionID session)
{
        //Capturing data in DTO
	TradeReport tradeReport = new TradeReport
	{
	  Id = ackReport.ExecID.getValue(),
	  LastQty = ackReport.LastQty.getValue(),
	  TransactTime = ackReport.IsSetTransactTime() ? ackReport.TransactTime.getValue() : DateTime.UtcNow,
	  LastPrice = ackReport.LastPx.getValue(),
	  InstrumentId = Convert.ToInt32(ackReport.SecurityID.getValue())
	};

	NoSides noSides = ackReport.NoSides;
	tradeReport.Symbol = _symbolMap[tradeReport.InstrumentId];

	var group = new TradeCaptureReport.NoSidesGroup();
	group = (TradeCaptureReport.NoSidesGroup)ackReport.GetGroup(1, group);
	if (group.IsSetSide())
	{
		switch (group.Side.getValue())
		{
		 case Side.BUY:
		  tradeReport.Side = BuySellType.Buy;
		  break;
		  case Side.SELL:
		   tradeReport.Side = BuySellType.Sell;
		  break;
		}
	}
	tradeReport.OrderId = group.OrderID.getValue();
	tradeReport.ClientOrderId = group.ClOrdID.getValue();
}

You can download the code from Github.

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.