1+ package com .alignmentsystems .matching ;
2+ import java .nio .BufferUnderflowException ;
3+ import java .nio .ByteBuffer ;
4+ import java .time .DateTimeException ;
5+ import java .time .Instant ;
6+ import java .time .OffsetDateTime ;
7+ import java .util .UUID ;
8+
9+ import com .alignmentsystems .fix44 .ExecutionReport ;
10+ import com .alignmentsystems .fix44 .field .AvgPx ;
11+ import com .alignmentsystems .fix44 .field .CumQty ;
12+ import com .alignmentsystems .fix44 .field .ExecID ;
13+ import com .alignmentsystems .fix44 .field .ExecType ;
14+ import com .alignmentsystems .fix44 .field .LastPx ;
15+ import com .alignmentsystems .fix44 .field .LastQty ;
16+ import com .alignmentsystems .fix44 .field .LeavesQty ;
17+ import com .alignmentsystems .fix44 .field .OrdStatus ;
18+ import com .alignmentsystems .fix44 .field .OrderID ;
19+ import com .alignmentsystems .fix44 .field .SenderCompID ;
20+ import com .alignmentsystems .fix44 .field .Side ;
21+ import com .alignmentsystems .fix44 .field .TargetCompID ;
22+ import com .alignmentsystems .fix44 .field .TimeInForce ;
23+ /******************************************************************************
24+ *
25+ * Author : John Greenan
26+ * Contact : sales@alignment-systems.com
27+ * Date : 13th September 2023
28+ * Copyright : Alignment Systems Ltd 2023
29+ * Project : Alignment Matching Toy
30+ * Artefact : BinaryToCanonicalRepresentationProcessor
31+ * Description :
32+ *****************************************************************************/
33+ import com .alignmentsystems .library .AlignmentOrder ;
34+ import com .alignmentsystems .library .DataMapper ;
35+ import com .alignmentsystems .library .constants .Constants ;
36+ import com .alignmentsystems .library .enumerations .Encodings ;
37+ import com .alignmentsystems .library .enumerations .OrderBookSide ;
38+ import com .alignmentsystems .library .interfaces .InterfaceExecutionReport ;
39+ import com .alignmentsystems .library .interfaces .InterfaceOrder ;
40+
41+ public class BinaryFromToCanonical {
42+ final static Encodings encoding = Encodings .FIXSBELITTLEENDIAN ;
43+
44+ public BinaryFromToCanonical () {
45+ }
46+
47+
48+
49+ protected byte [] getBufferFromExecutionReport (InterfaceExecutionReport er ) {
50+ byte [] returnValue = null ;
51+ ByteBuffer buf = null ;
52+ final Encodings encoding = Encodings .FIXSBELITTLEENDIAN ;
53+
54+ final Short msgType = DataMapper .EXCHANGEMESSAGETYPEMAPPEDFROMEXECUTIONREPORT ;
55+
56+ try {
57+ final int bufferLength =
58+ Short .BYTES //messageType
59+ +
60+ Long .BYTES * 2 //ExecID
61+ +
62+ Long .BYTES * 2 //ClOrdID
63+ +
64+ Long .BYTES * 2 //OrderID
65+ +
66+ Short .BYTES //ExecType
67+ +
68+ Short .BYTES //Side
69+ +
70+ Long .BYTES //LeavesQty
71+ +
72+ Long .BYTES //CumQty
73+ +
74+ Long .BYTES //AvgPx
75+ +
76+ Long .BYTES //ExecPrice
77+ +
78+ Long .BYTES //ExecQty
79+ +
80+ Long .BYTES //this.ts getEpochSecond
81+ +
82+ Integer .BYTES // this.ts getNano()
83+
84+ ;
85+ buf = ByteBuffer .allocate (bufferLength ).order (encoding .getByteOrder ());
86+
87+ buf .putShort (msgType );
88+ buf .putLong (er .getExecID ().getLeastSignificantBits ());
89+ buf .putLong (er .getExecID ().getMostSignificantBits ());
90+ buf .putLong (er .getClOrdID ().getLeastSignificantBits ());
91+ buf .putLong (er .getClOrdID ().getMostSignificantBits ());
92+ buf .putLong (er .getOrderID ().getLeastSignificantBits ());
93+ buf .putLong (er .getOrderID ().getMostSignificantBits ());
94+ buf .putShort (er .getExecType ());
95+ buf .putShort (er .getOrdStatus ());
96+ buf .putShort (er .getSideCode ());
97+ buf .putLong (er .getLeavesQuantity ());
98+ buf .putLong (er .getCumQuantity ());
99+ buf .putLong (er .getAveragePrice ());
100+ buf .putLong (er .getExecutionPrice ());
101+ buf .putLong (er .getExecutionQuantity ());
102+ buf .putLong (er .getTimestamp ().toInstant ().getEpochSecond ());
103+ buf .putInt (er .getTimestamp ().toInstant ().getNano ());
104+
105+
106+ buf .flip ();
107+ } catch (Exception e ) {
108+ //this.log.error(e.getMessage() , e);
109+ throw e ;
110+ }
111+
112+ return returnValue ;
113+ }
114+
115+
116+ protected Sender getBufferFromAlignmentOrder (InterfaceOrder inSeq ) {
117+
118+ ByteBuffer buf = null ;
119+ String receivedSymbol = null ;
120+ String orderId = null ;
121+
122+ try {
123+ receivedSymbol = inSeq .getSymbol ();
124+ orderId = inSeq .getOrderId ().toString ();
125+
126+ final short messageType = inSeq .getAlignmentType ();
127+ final String receivedSender = inSeq .getSender ();
128+ final String receivedTarget = inSeq .getTarget ();
129+ final char receivedSide = inSeq .getOrderBookSide ().sideCharValue ;
130+ final char receivedTimeInForce = inSeq .getTimeInForce ();
131+ //get mappings...
132+ final Long exchangeIdMappedFromSenderCompID = DataMapper .getExchangeIdMappedFromSenderCompID (receivedSender );
133+ final Long exchangeIdMappedFromTargetCompID = DataMapper .getExchangeIdMappedFromTargetCompID (receivedTarget );
134+ final Long exchangeInstrumentIdMappedFromSymbol = DataMapper .getExchangeIdMappedFromInstrumentId (receivedSymbol );
135+ final Short exchangeSideCodeMappedFromSideCode = DataMapper .getExchangeSideCodeMappedFromMemberSideCode (receivedSide );
136+ final Short exchangeTimeInForceMappedFromTimeInForce = DataMapper .getMemberTimeInForceMappedToExchangeTimeInForce (receivedTimeInForce );
137+
138+ final Encodings encoding = Encodings .FIXSBELITTLEENDIAN ;
139+
140+
141+ final int bufferLength =
142+ Short .BYTES //messageType
143+ +
144+ Long .BYTES * 2 //ClOrdId
145+ +
146+ Long .BYTES * 2 //OrderId
147+ +
148+ Long .BYTES //exchangeIdMappedFromSenderCompID.BYTES
149+ +
150+ Long .BYTES //exchangeIdMappedFromTargetCompID.BYTES
151+ +
152+ Long .BYTES //this.orderQty
153+ +
154+ Long .BYTES //this.limitPrice
155+ +
156+ Long .BYTES //exchangeInstrumentIdMappedFromSymbol.BYTES
157+ +
158+ Long .BYTES //this.ts getEpochSecond
159+ +
160+ Integer .BYTES // this.ts getNano()
161+ +
162+ Short .BYTES //this.SideCode
163+ +
164+ Short .BYTES //inSeq.getTimeInForce()
165+ ;
166+
167+ buf = ByteBuffer .allocate (bufferLength ).order (encoding .getByteOrder ());
168+ buf .putShort (messageType );
169+ buf .putLong (inSeq .getClOrdID ().getLeastSignificantBits ());
170+ buf .putLong (inSeq .getClOrdID ().getMostSignificantBits ());
171+ buf .putLong (inSeq .getOrderId ().getLeastSignificantBits ());
172+ buf .putLong (inSeq .getOrderId ().getMostSignificantBits ());
173+ buf .putLong (exchangeIdMappedFromSenderCompID );
174+ buf .putLong (exchangeIdMappedFromTargetCompID );
175+ buf .putLong (inSeq .getOrderQty ());
176+ buf .putLong (inSeq .getLimitPrice ());
177+ buf .putLong (exchangeInstrumentIdMappedFromSymbol );
178+ buf .putLong (inSeq .getTimestamp ().toInstant ().getEpochSecond ());
179+ buf .putInt (inSeq .getTimestamp ().toInstant ().getNano ());
180+ buf .putLong (exchangeSideCodeMappedFromSideCode );
181+ buf .putShort (exchangeTimeInForceMappedFromTimeInForce );
182+
183+ buf .flip ();
184+ } catch (Exception e ) {
185+ //this.log.error(e.getMessage() , e);
186+ throw e ;
187+ }
188+
189+
190+ Sender sender = new Sender (buf .array (), receivedSymbol , orderId );
191+
192+ return sender ;
193+ }
194+
195+
196+
197+
198+
199+
200+ public final static AlignmentOrder getAlignmentOrderFromBuffer (byte [] message , short msgType ) {
201+ // ByteBuffer buf = ByteBuffer.allocate(bufferLength).order(encoding.getByteOrder());
202+ // buf.putShort(messageType);
203+ // buf.putLong(inSeq.getClOrdID().getLeastSignificantBits());
204+ // buf.putLong(inSeq.getClOrdID().getMostSignificantBits());
205+ // buf.putLong(inSeq.getOrderId().getLeastSignificantBits());
206+ // buf.putLong(inSeq.getOrderId().getMostSignificantBits());
207+ // buf.putLong(exchangeIdMappedFromSenderCompID);
208+ // buf.putLong(exchangeIdMappedFromTargetCompID);
209+ // buf.putLong(inSeq.getOrderQty());
210+ // buf.putLong(inSeq.getLimitPrice());
211+ // buf.putLong(exchangeInstrumentIdMappedFromSymbol);
212+ // buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond());
213+ // buf.putInt(inSeq.getTimestamp().toInstant().getNano());
214+ // buf.putLong(exchangeSideCodeMappedFromSideCode);
215+ // buf.putShort(exchangeTimeInForceMappedFromTimeInForce);
216+
217+ // buf.flip();
218+
219+ try {
220+
221+ ByteBuffer bb = ByteBuffer .wrap (message ).order (encoding .getByteOrder ());
222+ //final short msgType = bb.getShort(); // buf.putShort(messageType);
223+ final Long clOrdIdLeast = bb .getLong ();// buf.putLong(inSeq.getClOrdID().getLeastSignificantBits());
224+ final Long clOrdIdMost = bb .getLong ();// buf.putLong(inSeq.getClOrdID().getMostSignificantBits());
225+ final Long orderIdLeast = bb .getLong ();// buf.putLong(inSeq.getOrderId().getLeastSignificantBits());
226+ final Long orderIdMost = bb .getLong ();// buf.putLong(inSeq.getOrderId().getMostSignificantBits());
227+ final Long senderId = bb .getLong ();// buf.putLong(exchangeIdMappedFromSenderCompID);
228+ final Long targetId = bb .getLong ();// buf.putLong(exchangeIdMappedFromTargetCompID);
229+ final Long orderQty = bb .getLong ();// buf.putLong(inSeq.getOrderQty());
230+ final Long limitPrice = bb .getLong ();// buf.putLong(inSeq.getLimitPrice());
231+ final Long instrumentId = bb .getLong ();// buf.putLong(exchangeInstrumentIdMappedFromSymbol);
232+ final Long timeStampEpochSeconds = bb .getLong ();// buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond());
233+ final int timeStampNanoseconds = bb .getInt ();// buf.putInt(inSeq.getTimestamp().toInstant().getNano());
234+ final Short sideCode = bb .getShort ();// buf.putLong(exchangeSideCodeMappedFromSideCode);
235+ final short msgTimeInForce = bb .getShort ();// buf.putShort(exchangeTimeInForceMappedFromTimeInForce);
236+ final UUID clOrdId = new UUID (clOrdIdMost , clOrdIdLeast );
237+ final UUID orderId = new UUID (orderIdMost , orderIdLeast );
238+
239+ final String senderCompId = DataMapper .getMemberFIXSenderCompIdMappedFromExchangeId (senderId );
240+ final String targetCompId = DataMapper .getMemberFIXTargetCompIdMappedFromExchangeId (targetId );
241+ final String instrument = DataMapper .getMemberInstrumentIdMappedFromExchangeInstrumentId (instrumentId );
242+ final char sideCodeFIX = DataMapper .getMemberSideCodeMappedFromExchangeSideCode (sideCode );
243+ final Instant instant = Instant .ofEpochSecond (timeStampEpochSeconds ).plusNanos (timeStampNanoseconds );
244+ final OffsetDateTime ts = OffsetDateTime .ofInstant (instant , Constants .HERE );
245+ final OrderBookSide obs = OrderBookSide .getEnumForID (sideCodeFIX );
246+ final char tif = DataMapper .getExchangeTimeInForceMappedToMemberTimeInForce (msgTimeInForce );
247+
248+ AlignmentOrder ao = new AlignmentOrder ();
249+ ao .reCreateOrder (instrument , tif , obs , orderQty , limitPrice , ts , senderCompId , targetCompId , orderId , clOrdId );
250+ return ao ;
251+ } catch (BufferUnderflowException | DateTimeException e ) {
252+ throw e ;
253+ }
254+ }
255+
256+
257+
258+ public final static AlignmentOrder getAlignmentOrderFromBuffer (byte [] message ) {
259+ ByteBuffer bb = ByteBuffer .wrap (message ).order (encoding .getByteOrder ());
260+ final short msgType = bb .getShort (); // buf.putShort(messageType
261+ return getAlignmentOrderFromBuffer (bb .array (), msgType );
262+ }
263+
264+
265+
266+ public static ExecutionReport getExecutionReportFromBuffer (ByteBuffer bb , short msgType ) {
267+
268+ ExecutionReport er = null ;
269+ try {
270+ final Long execIdLeast = bb .getLong (); //buf.putLong(er.getExecID().getLeastSignificantBits());
271+ final Long execIdMost = bb .getLong (); //buf.putLong(er.getExecID().getMostSignificantBits());
272+ final Long clOrdIdLeast = bb .getLong (); //buf.putLong(er.getClOrdID().getLeastSignificantBits());
273+ final Long clOrdIdMost = bb .getLong (); //buf.putLong(er.getClOrdID().getMostSignificantBits());
274+ final Long orderIdLeast = bb .getLong (); //buf.putLong(er.getOrderID().getLeastSignificantBits());
275+ final Long orderIdMost = bb .getLong (); //buf.putLong(er.getOrderID().getMostSignificantBits());
276+ final Short execType = bb .getShort (); //.putShort(er.getExecType());
277+ final Short ordStatus = bb .getShort (); //buf.putShort(er.getOrdStatus());
278+ final Short sideCode = bb .getShort (); //buf.putShort(er.getSideCode());
279+ final Long leavesQty = bb .getLong (); //buf.putLong(er.getLeavesQuantity());
280+ final Long cumQty = bb .getLong (); //buf.putLong(er.getCumQuantity());
281+ final Long avgPx = bb .getLong (); //buf.putLong(er.getAveragePrice());
282+ final Long execPrice = bb .getLong (); //buf.putLong(er.getExecutionPrice());
283+ final Long execQty = bb .getLong (); //buf.putLong(er.getExecutionQuantity());
284+ final Long timeStampEpochSeconds = bb .getLong ();// buf.putLong(er.getTimestamp().toInstant().getEpochSecond());
285+ final int timeStampNanoseconds = bb .getInt ();// buf.putInt(er.getTimestamp().toInstant().getNano());
286+
287+ final Instant instant = Instant .ofEpochSecond (timeStampEpochSeconds ).plusNanos (timeStampNanoseconds );
288+ final OffsetDateTime ts = OffsetDateTime .ofInstant (instant , Constants .HERE );
289+
290+ final UUID execId = new UUID (execIdMost , execIdLeast );
291+
292+ final UUID clOrdId = new UUID (clOrdIdMost , clOrdIdLeast );
293+ final UUID orderId = new UUID (orderIdMost , orderIdLeast );
294+ final char execTypeFIX = DataMapper .getMemberExecTypeMappedFromExchangeExecType (execType );
295+ final char orderStatusFIX = DataMapper .getMemberOrdStatusMappedToExchangeOrdStatus (ordStatus );
296+ final char sideFIX = DataMapper .getMemberSideCodeMappedFromExchangeSideCode (sideCode );
297+ er = new ExecutionReport (
298+ new OrderID (orderId .toString ())
299+ , new ExecID (execId .toString ())
300+ , new ExecType (execTypeFIX )
301+ , new OrdStatus (orderStatusFIX )
302+ , new Side (sideFIX )
303+ , new LeavesQty (leavesQty )
304+ , new CumQty (cumQty )
305+ , new AvgPx (avgPx )
306+ );
307+ er .setField (new OrderID (clOrdId .toString ()));
308+ er .setField (new LastPx (execPrice ));
309+ er .setField (new LastQty (execQty ));
310+
311+ } catch (BufferUnderflowException | DateTimeException e ) {
312+ throw e ;
313+ }
314+ return er ;
315+
316+ }
317+
318+ protected static ExecutionReport getExecutionReportAckFromBuffer (ByteBuffer bb , short msgType ) {
319+
320+ AlignmentOrder ao = getAlignmentOrderFromBuffer (bb .array (), msgType );
321+ final Double leaves = 0d ;
322+ final Double cum = 0d ;
323+ final Double avg = 0d ;
324+ final OrderID orderId = new OrderID (ao .getOrderId ().toString ());
325+ final ExecID execID = new ExecID (UUID .randomUUID ().toString ());
326+ final ExecType execType = new ExecType (ExecType .NEW );
327+ final OrdStatus ordStatus = new OrdStatus (OrdStatus .NEW );
328+ final Side side = new Side (ao .getOrderBookSide ().sideCharValue );
329+ final TimeInForce tif = new TimeInForce (ao .getTimeInForce ());
330+ final LeavesQty leavesQty = new LeavesQty (leaves );
331+ final CumQty cumQty = new CumQty (cum );
332+ final AvgPx avgPx = new AvgPx (avg );
333+ final String sender = ao .getSender ();
334+ final String target = ao .getTarget ();
335+ final SenderCompID senderCompID = new SenderCompID (sender );
336+ final TargetCompID targetCompID = new TargetCompID (target );
337+
338+ ExecutionReport er = new ExecutionReport (orderId , execID , execType , ordStatus , side , leavesQty , cumQty , avgPx );
339+ er .set (tif );
340+ er .getHeader ().setField (senderCompID );
341+ er .getHeader ().setField (targetCompID );
342+
343+ return er ;
344+ }
345+
346+
347+
348+ }
0 commit comments