diff --git a/administrator/version.properties b/administrator/version.properties index ca0b613..cbb6934 100644 --- a/administrator/version.properties +++ b/administrator/version.properties @@ -1,2 +1,2 @@ -#Mon Sep 18 00:46:07 AEST 2023 -VERSION_BUILD=664 +#Mon Sep 18 18:10:51 AEST 2023 +VERSION_BUILD=703 diff --git a/exchange/.classpath b/exchange/.classpath index 8988b92..59ced19 100644 --- a/exchange/.classpath +++ b/exchange/.classpath @@ -19,5 +19,6 @@ + diff --git a/exchange/src/main/java/com/alignmentsystems/matching/BinaryFromToCanonical.java b/exchange/src/main/java/com/alignmentsystems/matching/BinaryFromToCanonical.java new file mode 100644 index 0000000..47e0cc1 --- /dev/null +++ b/exchange/src/main/java/com/alignmentsystems/matching/BinaryFromToCanonical.java @@ -0,0 +1,348 @@ +package com.alignmentsystems.matching; +import java.nio.BufferUnderflowException; +import java.nio.ByteBuffer; +import java.time.DateTimeException; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.util.UUID; + +import com.alignmentsystems.fix44.ExecutionReport; +import com.alignmentsystems.fix44.field.AvgPx; +import com.alignmentsystems.fix44.field.CumQty; +import com.alignmentsystems.fix44.field.ExecID; +import com.alignmentsystems.fix44.field.ExecType; +import com.alignmentsystems.fix44.field.LastPx; +import com.alignmentsystems.fix44.field.LastQty; +import com.alignmentsystems.fix44.field.LeavesQty; +import com.alignmentsystems.fix44.field.OrdStatus; +import com.alignmentsystems.fix44.field.OrderID; +import com.alignmentsystems.fix44.field.SenderCompID; +import com.alignmentsystems.fix44.field.Side; +import com.alignmentsystems.fix44.field.TargetCompID; +import com.alignmentsystems.fix44.field.TimeInForce; +/****************************************************************************** + * + * Author : John Greenan + * Contact : sales@alignment-systems.com + * Date : 13th September 2023 + * Copyright : Alignment Systems Ltd 2023 + * Project : Alignment Matching Toy + * Artefact : BinaryToCanonicalRepresentationProcessor + * Description : + *****************************************************************************/ +import com.alignmentsystems.library.AlignmentOrder; +import com.alignmentsystems.library.DataMapper; +import com.alignmentsystems.library.constants.Constants; +import com.alignmentsystems.library.enumerations.Encodings; +import com.alignmentsystems.library.enumerations.OrderBookSide; +import com.alignmentsystems.library.interfaces.InterfaceExecutionReport; +import com.alignmentsystems.library.interfaces.InterfaceOrder; + +public class BinaryFromToCanonical { + final static Encodings encoding = Encodings.FIXSBELITTLEENDIAN; + + public BinaryFromToCanonical() { + } + + + + protected byte[] getBufferFromExecutionReport(InterfaceExecutionReport er) { + byte[] returnValue = null; + ByteBuffer buf = null; + final Encodings encoding = Encodings.FIXSBELITTLEENDIAN; + + final Short msgType = DataMapper.EXCHANGEMESSAGETYPEMAPPEDFROMEXECUTIONREPORT; + + try { + final int bufferLength = + Short.BYTES //messageType + + + Long.BYTES * 2//ExecID + + + Long.BYTES * 2//ClOrdID + + + Long.BYTES * 2//OrderID + + + Short.BYTES //ExecType + + + Short.BYTES//Side + + + Long.BYTES //LeavesQty + + + Long.BYTES //CumQty + + + Long.BYTES //AvgPx + + + Long.BYTES //ExecPrice + + + Long.BYTES //ExecQty + + + Long.BYTES //this.ts getEpochSecond + + + Integer.BYTES // this.ts getNano() + + ; + buf = ByteBuffer.allocate(bufferLength).order(encoding.getByteOrder()); + + buf.putShort(msgType); + buf.putLong(er.getExecID().getLeastSignificantBits()); + buf.putLong(er.getExecID().getMostSignificantBits()); + buf.putLong(er.getClOrdID().getLeastSignificantBits()); + buf.putLong(er.getClOrdID().getMostSignificantBits()); + buf.putLong(er.getOrderID().getLeastSignificantBits()); + buf.putLong(er.getOrderID().getMostSignificantBits()); + buf.putShort(er.getExecType()); + buf.putShort(er.getOrdStatus()); + buf.putShort(er.getSideCode()); + buf.putLong(er.getLeavesQuantity()); + buf.putLong(er.getCumQuantity()); + buf.putLong(er.getAveragePrice()); + buf.putLong(er.getExecutionPrice()); + buf.putLong(er.getExecutionQuantity()); + buf.putLong(er.getTimestamp().toInstant().getEpochSecond()); + buf.putInt(er.getTimestamp().toInstant().getNano()); + + + buf.flip(); + } catch (Exception e) { + //this.log.error(e.getMessage() , e); + throw e; + } + + return returnValue; + } + + + protected Sender getBufferFromAlignmentOrder(InterfaceOrder inSeq) { + + ByteBuffer buf = null; + String receivedSymbol = null; + String orderId = null; + + try { + receivedSymbol = inSeq.getSymbol(); + orderId = inSeq.getOrderId().toString(); + + final short messageType = inSeq.getAlignmentType(); + final String receivedSender = inSeq.getSender(); + final String receivedTarget = inSeq.getTarget(); + final char receivedSide = inSeq.getOrderBookSide().sideCharValue; + final char receivedTimeInForce = inSeq.getTimeInForce(); + //get mappings... + final Long exchangeIdMappedFromSenderCompID = DataMapper.getExchangeIdMappedFromSenderCompID(receivedSender); + final Long exchangeIdMappedFromTargetCompID = DataMapper.getExchangeIdMappedFromTargetCompID(receivedTarget); + final Long exchangeInstrumentIdMappedFromSymbol = DataMapper.getExchangeIdMappedFromInstrumentId(receivedSymbol); + final Short exchangeSideCodeMappedFromSideCode = DataMapper.getExchangeSideCodeMappedFromMemberSideCode(receivedSide); + final Short exchangeTimeInForceMappedFromTimeInForce = DataMapper.getMemberTimeInForceMappedToExchangeTimeInForce(receivedTimeInForce); + + final Encodings encoding = Encodings.FIXSBELITTLEENDIAN; + + + final int bufferLength = + Short.BYTES //messageType + + + Long.BYTES * 2 //ClOrdId + + + Long.BYTES * 2 //OrderId + + + Long.BYTES //exchangeIdMappedFromSenderCompID.BYTES + + + Long.BYTES //exchangeIdMappedFromTargetCompID.BYTES + + + Long.BYTES //this.orderQty + + + Long.BYTES //this.limitPrice + + + Long.BYTES //exchangeInstrumentIdMappedFromSymbol.BYTES + + + Long.BYTES //this.ts getEpochSecond + + + Integer.BYTES // this.ts getNano() + + + Short.BYTES //this.SideCode + + + Short.BYTES //inSeq.getTimeInForce() + ; + + buf = ByteBuffer.allocate(bufferLength).order(encoding.getByteOrder()); + buf.putShort(messageType); + buf.putLong(inSeq.getClOrdID().getLeastSignificantBits()); + buf.putLong(inSeq.getClOrdID().getMostSignificantBits()); + buf.putLong(inSeq.getOrderId().getLeastSignificantBits()); + buf.putLong(inSeq.getOrderId().getMostSignificantBits()); + buf.putLong(exchangeIdMappedFromSenderCompID); + buf.putLong(exchangeIdMappedFromTargetCompID); + buf.putLong(inSeq.getOrderQty()); + buf.putLong(inSeq.getLimitPrice()); + buf.putLong(exchangeInstrumentIdMappedFromSymbol); + buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond()); + buf.putInt(inSeq.getTimestamp().toInstant().getNano()); + buf.putLong(exchangeSideCodeMappedFromSideCode); + buf.putShort(exchangeTimeInForceMappedFromTimeInForce); + + buf.flip(); + } catch (Exception e) { + //this.log.error(e.getMessage() , e); + throw e; + } + + + Sender sender = new Sender(buf.array(), receivedSymbol, orderId); + + return sender; + } + + + + + + + public final static AlignmentOrder getAlignmentOrderFromBuffer(byte[] message, short msgType) { + // ByteBuffer buf = ByteBuffer.allocate(bufferLength).order(encoding.getByteOrder()); + // buf.putShort(messageType); + // buf.putLong(inSeq.getClOrdID().getLeastSignificantBits()); + // buf.putLong(inSeq.getClOrdID().getMostSignificantBits()); + // buf.putLong(inSeq.getOrderId().getLeastSignificantBits()); + // buf.putLong(inSeq.getOrderId().getMostSignificantBits()); + // buf.putLong(exchangeIdMappedFromSenderCompID); + // buf.putLong(exchangeIdMappedFromTargetCompID); + // buf.putLong(inSeq.getOrderQty()); + // buf.putLong(inSeq.getLimitPrice()); + // buf.putLong(exchangeInstrumentIdMappedFromSymbol); + // buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond()); + // buf.putInt(inSeq.getTimestamp().toInstant().getNano()); + // buf.putLong(exchangeSideCodeMappedFromSideCode); + // buf.putShort(exchangeTimeInForceMappedFromTimeInForce); + + // buf.flip(); + + try { + + ByteBuffer bb = ByteBuffer.wrap(message).order(encoding.getByteOrder()); + //final short msgType = bb.getShort(); // buf.putShort(messageType); + final Long clOrdIdLeast = bb.getLong();// buf.putLong(inSeq.getClOrdID().getLeastSignificantBits()); + final Long clOrdIdMost = bb.getLong();// buf.putLong(inSeq.getClOrdID().getMostSignificantBits()); + final Long orderIdLeast = bb.getLong();// buf.putLong(inSeq.getOrderId().getLeastSignificantBits()); + final Long orderIdMost = bb.getLong();// buf.putLong(inSeq.getOrderId().getMostSignificantBits()); + final Long senderId = bb.getLong();// buf.putLong(exchangeIdMappedFromSenderCompID); + final Long targetId = bb.getLong();// buf.putLong(exchangeIdMappedFromTargetCompID); + final Long orderQty = bb.getLong();// buf.putLong(inSeq.getOrderQty()); + final Long limitPrice = bb.getLong();// buf.putLong(inSeq.getLimitPrice()); + final Long instrumentId = bb.getLong();// buf.putLong(exchangeInstrumentIdMappedFromSymbol); + final Long timeStampEpochSeconds = bb.getLong();// buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond()); + final int timeStampNanoseconds = bb.getInt();// buf.putInt(inSeq.getTimestamp().toInstant().getNano()); + final Short sideCode = bb.getShort();// buf.putLong(exchangeSideCodeMappedFromSideCode); + final short msgTimeInForce = bb.getShort();// buf.putShort(exchangeTimeInForceMappedFromTimeInForce); + final UUID clOrdId = new UUID(clOrdIdMost, clOrdIdLeast); + final UUID orderId = new UUID(orderIdMost, orderIdLeast); + + final String senderCompId = DataMapper.getMemberFIXSenderCompIdMappedFromExchangeId(senderId); + final String targetCompId = DataMapper.getMemberFIXTargetCompIdMappedFromExchangeId(targetId); + final String instrument = DataMapper.getMemberInstrumentIdMappedFromExchangeInstrumentId(instrumentId); + final char sideCodeFIX = DataMapper.getMemberSideCodeMappedFromExchangeSideCode(sideCode); + final Instant instant = Instant.ofEpochSecond(timeStampEpochSeconds).plusNanos(timeStampNanoseconds); + final OffsetDateTime ts = OffsetDateTime.ofInstant(instant, Constants.HERE); + final OrderBookSide obs = OrderBookSide.getEnumForID(sideCodeFIX); + final char tif = DataMapper.getExchangeTimeInForceMappedToMemberTimeInForce(msgTimeInForce); + + AlignmentOrder ao = new AlignmentOrder(); + ao.reCreateOrder(instrument , tif, obs , orderQty , limitPrice , ts , senderCompId , targetCompId , orderId , clOrdId); + return ao; + } catch(BufferUnderflowException | DateTimeException e) { + throw e; + } + } + + + + public final static AlignmentOrder getAlignmentOrderFromBuffer(byte[] message) { + ByteBuffer bb = ByteBuffer.wrap(message).order(encoding.getByteOrder()); + final short msgType = bb.getShort(); // buf.putShort(messageType + return getAlignmentOrderFromBuffer(bb.array(), msgType); + } + + + + public static ExecutionReport getExecutionReportFromBuffer(ByteBuffer bb , short msgType) { + + ExecutionReport er = null; + try { + final Long execIdLeast = bb.getLong(); //buf.putLong(er.getExecID().getLeastSignificantBits()); + final Long execIdMost = bb.getLong(); //buf.putLong(er.getExecID().getMostSignificantBits()); + final Long clOrdIdLeast = bb.getLong(); //buf.putLong(er.getClOrdID().getLeastSignificantBits()); + final Long clOrdIdMost = bb.getLong(); //buf.putLong(er.getClOrdID().getMostSignificantBits()); + final Long orderIdLeast = bb.getLong(); //buf.putLong(er.getOrderID().getLeastSignificantBits()); + final Long orderIdMost = bb.getLong(); //buf.putLong(er.getOrderID().getMostSignificantBits()); + final Short execType = bb.getShort(); //.putShort(er.getExecType()); + final Short ordStatus = bb.getShort(); //buf.putShort(er.getOrdStatus()); + final Short sideCode = bb.getShort(); //buf.putShort(er.getSideCode()); + final Long leavesQty = bb.getLong(); //buf.putLong(er.getLeavesQuantity()); + final Long cumQty = bb.getLong(); //buf.putLong(er.getCumQuantity()); + final Long avgPx = bb.getLong(); //buf.putLong(er.getAveragePrice()); + final Long execPrice = bb.getLong(); //buf.putLong(er.getExecutionPrice()); + final Long execQty = bb.getLong(); //buf.putLong(er.getExecutionQuantity()); + final Long timeStampEpochSeconds = bb.getLong();// buf.putLong(er.getTimestamp().toInstant().getEpochSecond()); + final int timeStampNanoseconds = bb.getInt();// buf.putInt(er.getTimestamp().toInstant().getNano()); + + final Instant instant = Instant.ofEpochSecond(timeStampEpochSeconds).plusNanos(timeStampNanoseconds); + final OffsetDateTime ts = OffsetDateTime.ofInstant(instant, Constants.HERE); + + final UUID execId = new UUID(execIdMost, execIdLeast); + + final UUID clOrdId = new UUID(clOrdIdMost, clOrdIdLeast); + final UUID orderId = new UUID(orderIdMost, orderIdLeast); + final char execTypeFIX = DataMapper.getMemberExecTypeMappedFromExchangeExecType(execType); + final char orderStatusFIX = DataMapper.getMemberOrdStatusMappedToExchangeOrdStatus(ordStatus); + final char sideFIX = DataMapper.getMemberSideCodeMappedFromExchangeSideCode(sideCode); + er = new ExecutionReport( + new OrderID(orderId.toString()) + , new ExecID(execId.toString()) + , new ExecType(execTypeFIX) + , new OrdStatus(orderStatusFIX) + , new Side(sideFIX) + , new LeavesQty(leavesQty) + , new CumQty(cumQty) + , new AvgPx(avgPx) + ); + er.setField(new OrderID(clOrdId.toString())); + er.setField(new LastPx(execPrice)); + er.setField(new LastQty(execQty)); + + } catch(BufferUnderflowException | DateTimeException e) { + throw e; + } + return er; + + } + + protected static ExecutionReport getExecutionReportAckFromBuffer(ByteBuffer bb, short msgType) { + + AlignmentOrder ao = getAlignmentOrderFromBuffer(bb.array(), msgType); + final Double leaves = 0d; + final Double cum = 0d; + final Double avg = 0d; + final OrderID orderId = new OrderID(ao.getOrderId().toString()); + final ExecID execID = new ExecID(UUID.randomUUID().toString()); + final ExecType execType = new ExecType(ExecType.NEW); + final OrdStatus ordStatus = new OrdStatus(OrdStatus.NEW); + final Side side = new Side(ao.getOrderBookSide().sideCharValue); + final TimeInForce tif = new TimeInForce(ao.getTimeInForce()); + final LeavesQty leavesQty = new LeavesQty(leaves); + final CumQty cumQty = new CumQty(cum); + final AvgPx avgPx = new AvgPx(avg); + final String sender = ao.getSender(); + final String target = ao.getTarget(); + final SenderCompID senderCompID = new SenderCompID(sender); + final TargetCompID targetCompID = new TargetCompID(target); + + ExecutionReport er = new ExecutionReport(orderId, execID, execType, ordStatus, side, leavesQty, cumQty, avgPx); + er.set(tif); + er.getHeader().setField(senderCompID); + er.getHeader().setField(targetCompID); + + return er; + } + + + +} \ No newline at end of file diff --git a/exchange/src/main/java/com/alignmentsystems/matching/BinaryToCanonicalRepresentationProcessor.java b/exchange/src/main/java/com/alignmentsystems/matching/BinaryToCanonicalRepresentationProcessor.java deleted file mode 100644 index 8302f72..0000000 --- a/exchange/src/main/java/com/alignmentsystems/matching/BinaryToCanonicalRepresentationProcessor.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.alignmentsystems.matching; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.time.DateTimeException; -import java.time.Instant; -import java.time.OffsetDateTime; -import java.util.UUID; - -/****************************************************************************** - * - * Author : John Greenan - * Contact : sales@alignment-systems.com - * Date : 13th September 2023 - * Copyright : Alignment Systems Ltd 2023 - * Project : Alignment Matching Toy - * Artefact : BinaryToCanonicalRepresentationProcessor - * Description : - *****************************************************************************/ -import com.alignmentsystems.library.AlignmentOrder; -import com.alignmentsystems.library.constants.Constants; -import com.alignmentsystems.library.enumerations.Encodings; -import com.alignmentsystems.library.enumerations.OrderBookSide; - -public class BinaryToCanonicalRepresentationProcessor { - final static Encodings encoding = Encodings.FIXSBELITTLEENDIAN; - - public BinaryToCanonicalRepresentationProcessor() { - } - - - - - - public static AlignmentOrder getAlignmentOrder(byte[] message) { - - - try { - // ByteBuffer buf = ByteBuffer.allocate(bufferLength).order(encoding.getByteOrder()); - // buf.putShort(messageType); - // buf.putLong(inSeq.getClOrdID().getLeastSignificantBits()); - // buf.putLong(inSeq.getClOrdID().getMostSignificantBits()); - // buf.putLong(inSeq.getOrderId().getLeastSignificantBits()); - // buf.putLong(inSeq.getOrderId().getMostSignificantBits()); - // buf.putLong(exchangeIdMappedFromSenderCompID); - // buf.putLong(exchangeIdMappedFromTargetCompID); - // buf.putLong(inSeq.getOrderQty()); - // buf.putLong(inSeq.getLimitPrice()); - // buf.putLong(exchangeInstrumentIdMappedFromSymbol); - // buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond()); - // buf.putInt(inSeq.getTimestamp().toInstant().getNano()); - // buf.putLong(exchangeSideCodeMappedFromSideCode); - // buf.putShort(exchangeTimeInForceMappedFromTimeInForce); - - // buf.flip(); - - - ByteBuffer bb = ByteBuffer.wrap(message).order(encoding.getByteOrder()); - final short msgType = bb.getShort(); // buf.putShort(messageType); - final Long clOrdIdLeast = bb.getLong();// buf.putLong(inSeq.getClOrdID().getLeastSignificantBits()); - final Long clOrdIdMost = bb.getLong();// buf.putLong(inSeq.getClOrdID().getMostSignificantBits()); - final Long orderIdLeast = bb.getLong();// buf.putLong(inSeq.getOrderId().getLeastSignificantBits()); - final Long orderIdMost = bb.getLong();// buf.putLong(inSeq.getOrderId().getMostSignificantBits()); - final Long senderId = bb.getLong();// buf.putLong(exchangeIdMappedFromSenderCompID); - final Long targetId = bb.getLong();// buf.putLong(exchangeIdMappedFromTargetCompID); - final Long orderQty = bb.getLong();// buf.putLong(inSeq.getOrderQty()); - final Long limitPrice = bb.getLong();// buf.putLong(inSeq.getLimitPrice()); - final Long instrumentId = bb.getLong();// buf.putLong(exchangeInstrumentIdMappedFromSymbol); - final Long timeStampEpochSeconds = bb.getLong();// buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond()); - final int timeStampNanoseconds = bb.getInt();// buf.putInt(inSeq.getTimestamp().toInstant().getNano()); - final Long sideCode = bb.getLong();// buf.putLong(exchangeSideCodeMappedFromSideCode); - final short msgTimeInForce = bb.getShort();// buf.putShort(exchangeTimeInForceMappedFromTimeInForce); - final UUID clOrdId = new UUID(clOrdIdMost, clOrdIdLeast); - final UUID orderId = new UUID(orderIdMost, orderIdLeast); - - final String senderCompId = DataMapper.getMemberFIXSenderCompIdMappedFromExchangeId(senderId); - final String targetCompId = DataMapper.getMemberFIXTargetCompIdMappedFromExchangeId(targetId); - final String instrument = DataMapper.getMemberInstrumentIdMappedFromExchangeInstrumentId(instrumentId); - final String sideCodeFIX = DataMapper.getMemberSideCodeMappedFromExchangeSideCode(sideCode); - final Instant instant = Instant.ofEpochSecond(timeStampEpochSeconds).plusNanos(timeStampNanoseconds); - final OffsetDateTime ts = OffsetDateTime.ofInstant(instant, Constants.HERE); - final OrderBookSide obs = OrderBookSide.getEnumForString(sideCodeFIX); - final char tif = DataMapper.getExchangeTimeInForceMappedToMemberTimeInForce(msgTimeInForce); - - AlignmentOrder ao = new AlignmentOrder(); - ao.reCreateOrder(instrument , tif, obs , orderQty , limitPrice , ts , senderCompId , targetCompId , orderId , clOrdId); - return ao; - } catch(BufferUnderflowException | DateTimeException e) { - throw e; - } - } -} \ No newline at end of file diff --git a/exchange/src/main/java/com/alignmentsystems/matching/BinaryToFIXProcessor.java b/exchange/src/main/java/com/alignmentsystems/matching/BinaryToFIXProcessor.java deleted file mode 100644 index 6b435df..0000000 --- a/exchange/src/main/java/com/alignmentsystems/matching/BinaryToFIXProcessor.java +++ /dev/null @@ -1,107 +0,0 @@ -package com.alignmentsystems.matching; -import java.nio.BufferUnderflowException; -import java.nio.ByteBuffer; -import java.time.DateTimeException; -import java.time.Instant; -import java.time.OffsetDateTime; -import java.util.UUID; - -import com.alignmentsystems.fix44.ExecutionReport; -/****************************************************************************** - * - * Author : John Greenan - * Contact : sales@alignment-systems.com - * Date : 13th September 2023 - * Copyright : Alignment Systems Ltd 2023 - * Project : Alignment Matching Toy - * Artefact : BinaryToCanonicalRepresentationProcessor - * Description : - *****************************************************************************/ -import com.alignmentsystems.library.AlignmentOrder; -import com.alignmentsystems.library.annotations.NotYetImplemented; -import com.alignmentsystems.library.constants.Constants; -import com.alignmentsystems.library.enumerations.Encodings; -import com.alignmentsystems.library.enumerations.OrderBookSide; - -public class BinaryToFIXProcessor { - final static Encodings encoding = Encodings.FIXSBELITTLEENDIAN; - - public BinaryToFIXProcessor() { - } - - - @NotYetImplemented - public static ExecutionReport getExecutionReport(byte[] message) { - ExecutionReport er = new ExecutionReport(); - - try { - ByteBuffer bb = ByteBuffer.wrap(message).order(encoding.getByteOrder()); - final short msgType = bb.getShort(); // buf.putShort(messageType); - } catch(BufferUnderflowException | DateTimeException e) { - throw e; - } - return er; - - } - - - - - public static AlignmentOrder getAlignmentOrder(byte[] message) { - - - try { - // ByteBuffer buf = ByteBuffer.allocate(bufferLength).order(encoding.getByteOrder()); - // buf.putShort(messageType); - // buf.putLong(inSeq.getClOrdID().getLeastSignificantBits()); - // buf.putLong(inSeq.getClOrdID().getMostSignificantBits()); - // buf.putLong(inSeq.getOrderId().getLeastSignificantBits()); - // buf.putLong(inSeq.getOrderId().getMostSignificantBits()); - // buf.putLong(exchangeIdMappedFromSenderCompID); - // buf.putLong(exchangeIdMappedFromTargetCompID); - // buf.putLong(inSeq.getOrderQty()); - // buf.putLong(inSeq.getLimitPrice()); - // buf.putLong(exchangeInstrumentIdMappedFromSymbol); - // buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond()); - // buf.putInt(inSeq.getTimestamp().toInstant().getNano()); - // buf.putLong(exchangeSideCodeMappedFromSideCode); - // buf.putShort(exchangeTimeInForceMappedFromTimeInForce); - - // buf.flip(); - - - ByteBuffer bb = ByteBuffer.wrap(message).order(encoding.getByteOrder()); - final short msgType = bb.getShort(); // buf.putShort(messageType); - final Long clOrdIdLeast = bb.getLong();// buf.putLong(inSeq.getClOrdID().getLeastSignificantBits()); - final Long clOrdIdMost = bb.getLong();// buf.putLong(inSeq.getClOrdID().getMostSignificantBits()); - final Long orderIdLeast = bb.getLong();// buf.putLong(inSeq.getOrderId().getLeastSignificantBits()); - final Long orderIdMost = bb.getLong();// buf.putLong(inSeq.getOrderId().getMostSignificantBits()); - final Long senderId = bb.getLong();// buf.putLong(exchangeIdMappedFromSenderCompID); - final Long targetId = bb.getLong();// buf.putLong(exchangeIdMappedFromTargetCompID); - final Long orderQty = bb.getLong();// buf.putLong(inSeq.getOrderQty()); - final Long limitPrice = bb.getLong();// buf.putLong(inSeq.getLimitPrice()); - final Long instrumentId = bb.getLong();// buf.putLong(exchangeInstrumentIdMappedFromSymbol); - final Long timeStampEpochSeconds = bb.getLong();// buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond()); - final int timeStampNanoseconds = bb.getInt();// buf.putInt(inSeq.getTimestamp().toInstant().getNano()); - final Long sideCode = bb.getLong();// buf.putLong(exchangeSideCodeMappedFromSideCode); - final short msgTimeInForce = bb.getShort();// buf.putShort(exchangeTimeInForceMappedFromTimeInForce); - final UUID clOrdId = new UUID(clOrdIdMost, clOrdIdLeast); - final UUID orderId = new UUID(orderIdMost, orderIdLeast); - - final String senderCompId = DataMapper.getMemberFIXSenderCompIdMappedFromExchangeId(senderId); - final String targetCompId = DataMapper.getMemberFIXTargetCompIdMappedFromExchangeId(targetId); - final String instrument = DataMapper.getMemberInstrumentIdMappedFromExchangeInstrumentId(instrumentId); - final String sideCodeFIX = DataMapper.getMemberSideCodeMappedFromExchangeSideCode(sideCode); - final Instant instant = Instant.ofEpochSecond(timeStampEpochSeconds).plusNanos(timeStampNanoseconds); - final OffsetDateTime ts = OffsetDateTime.ofInstant(instant, Constants.HERE); - final OrderBookSide obs = OrderBookSide.getEnumForString(sideCodeFIX); - final char tif = DataMapper.getExchangeTimeInForceMappedToMemberTimeInForce(msgTimeInForce); - - AlignmentOrder ao = new AlignmentOrder(); - ao.reCreateOrder(instrument , tif, obs , orderQty , limitPrice , ts , senderCompId , targetCompId , orderId , clOrdId); - return ao; - } catch(BufferUnderflowException | DateTimeException e) { - throw e; - } - } -} \ No newline at end of file diff --git a/exchange/src/main/java/com/alignmentsystems/matching/FIXEngineExchange.java b/exchange/src/main/java/com/alignmentsystems/matching/FIXEngineExchange.java index f7bd851..274f879 100644 --- a/exchange/src/main/java/com/alignmentsystems/matching/FIXEngineExchange.java +++ b/exchange/src/main/java/com/alignmentsystems/matching/FIXEngineExchange.java @@ -18,25 +18,15 @@ import org.apache.kafka.clients.consumer.ConsumerRecord; import com.alignmentsystems.fix44.ExecutionReport; -import com.alignmentsystems.fix44.field.AvgPx; -import com.alignmentsystems.fix44.field.ClOrdID; -import com.alignmentsystems.fix44.field.CumQty; -import com.alignmentsystems.fix44.field.ExecID; -import com.alignmentsystems.fix44.field.ExecType; -import com.alignmentsystems.fix44.field.LeavesQty; -import com.alignmentsystems.fix44.field.OrdStatus; -import com.alignmentsystems.fix44.field.OrderID; -import com.alignmentsystems.fix44.field.Side; import com.alignmentsystems.library.AlignmentOrder; +import com.alignmentsystems.library.DataMapper; import com.alignmentsystems.library.LibraryOrders; import com.alignmentsystems.library.LogEncapsulation; import com.alignmentsystems.library.constants.Constants; import com.alignmentsystems.library.enumerations.Encodings; import com.alignmentsystems.library.enumerations.InstanceType; import com.alignmentsystems.library.enumerations.MessageDirection; -import com.alignmentsystems.library.enumerations.OperationEventType; import com.alignmentsystems.library.enumerations.OrderBookSide; -import com.alignmentsystems.library.interfaces.InterfaceMatch; import com.alignmentsystems.library.interfaces.InterfaceQueueNonSequenced; import quickfix.DoNotSend; @@ -48,7 +38,6 @@ import quickfix.RejectLogon; import quickfix.Session; import quickfix.SessionID; -import quickfix.SessionNotFound; import quickfix.UnsupportedMessageType; /** @@ -61,7 +50,7 @@ public class FIXEngineExchange extends MessageCracker implements quickfix.Applic private final static Encodings encoding = Encodings.FIXSBELITTLEENDIAN; private LogEncapsulation log = null; private InstanceType instanceType = null; - + private static BinaryFromToCanonical binaryFromToCanonical = new BinaryFromToCanonical(); @@ -308,102 +297,21 @@ public void processMessage(String topicName, ConsumerRecord mess log.info(CLASSNAME + " received " + topicName); //topicName - - + ByteBuffer bb = ByteBuffer.wrap(message.value()).order(encoding.getByteOrder()); final short msgType = bb.getShort(); // buf.putShort(messageType); //When we get to here we know the message type that was used - - - - } - - private void sendExecutionReportsForMatch(InterfaceMatch match) { - final String methodName ="matchHappened"; - - log.infoMatchingEvent(OperationEventType.MATCHEVENT, match); - Long executionQuantity = match.getMatchQuantity(); - - - OrderID b_orderId = new OrderID(match.getBuyOrderId().toString()); - ClOrdID b_ClOrdId = new ClOrdID(match.getBuyClOrdId().toString()); - ExecID b_execID = new ExecID(UUID.randomUUID().toString()); - CumQty b_cumQty = new CumQty(match.getMatchQuantity()); - AvgPx b_avgPx = new AvgPx(match.getMatchPrice()); - Side b_side = new Side(Side.BUY); - - ExecType b_execType = null; - OrdStatus b_ordStatus = null; - Long b_orderQty = match.getBuyOrderQty(); - LeavesQty b_leavesQty = new LeavesQty( match.getBuyOrderQty()-match.getBuyCumQty()); - - //int java.lang.Double.compareTo(Double anotherDouble) - //the value 0 if anotherDouble is numerically equal to this Double; - //a value less than 0 if this Double is numerically less than anotherDouble; - //and a value greater than 0 if this Double is numerically greater than anotherDouble. - //Therefore, if this is equal to zero then the execution quantity is equal to the order quantity - - if (executionQuantity.compareTo(b_orderQty)==0) { - b_execType = new ExecType(ExecType.FILL); - b_ordStatus = new OrdStatus(OrdStatus.FILLED); - } - - ExecutionReport buyExecRpt = new ExecutionReport( - b_orderId - , b_execID - , b_execType - , b_ordStatus - , b_side - , b_leavesQty - , b_cumQty - , b_avgPx) - ; - buyExecRpt.set(b_ClOrdId); - - + //if its an Order then we need to send acknowledgement + //if it's an er, we need to send it to the counterparty... + ExecutionReport er = null; + String sender = null; + String target = null; - //TODO - clean up the above - //Repeat the same code with s_ instead of b_ - OrderID s_orderId = new OrderID(match.getSellOrderId().toString()); - ClOrdID s_ClOrdId = new ClOrdID(match.getBuyClOrdId().toString()); - ExecID s_execID = new ExecID(UUID.randomUUID().toString()); - CumQty s_cumQty = new CumQty(match.getMatchQuantity()); - AvgPx s_avgPx = new AvgPx(match.getMatchPrice()); - Side s_side = new Side(Side.SELL); - - ExecType s_execType = null; - OrdStatus s_ordStatus = null; - Long s_orderQty = match.getSellOrderQty(); - LeavesQty s_leavesQty = new LeavesQty(match.getSellOrderQty() - match.getSellCumQty() ); - - //int java.lang.Double.compareTo(Double anotherDouble) - //the value 0 if anotherDouble is numerically equal to this Double; - //a value less than 0 if this Double is numerically less than anotherDouble; - //and a value greater than 0 if this Double is numerically greater than anotherDouble. - //Therefore, if this is equal to zero then the execution quantity is equal to the order quantity - - if (executionQuantity == s_orderQty) { - s_execType = new ExecType(ExecType.FILL); - s_ordStatus = new OrdStatus(OrdStatus.FILLED); - } - - ExecutionReport sellExecRpt = new ExecutionReport( - s_orderId - , s_execID - , s_execType - , s_ordStatus - , s_side - , s_leavesQty - , s_cumQty - , s_avgPx) - ; - buyExecRpt.set(s_ClOrdId); - - try { - Session.sendToTarget(sellExecRpt, match.getSellSenderId(), match.getSellTargetId()); - Session.sendToTarget(buyExecRpt, match.getBuySenderId() , match.getBuyTargetId()); - } catch (SessionNotFound e) { - log.error(e.getMessage(), e); - }; + if (msgType==DataMapper.EXCHANGEMESSAGETYPEMAPPEDFROMEXECUTIONREPORT) { + //it's an execution report. + //rehydrate into a POJO and then send + er = BinaryFromToCanonical.getExecutionReportAckFromBuffer(bb, msgType); + Session.sendToTarget(er); + } } } \ No newline at end of file diff --git a/exchange/src/main/java/com/alignmentsystems/matching/FIXToBinaryProcessor.java b/exchange/src/main/java/com/alignmentsystems/matching/FIXToBinaryProcessor.java index 829d876..91b3752 100644 --- a/exchange/src/main/java/com/alignmentsystems/matching/FIXToBinaryProcessor.java +++ b/exchange/src/main/java/com/alignmentsystems/matching/FIXToBinaryProcessor.java @@ -1,19 +1,6 @@ package com.alignmentsystems.matching; import java.io.FileNotFoundException; - -/****************************************************************************** - * - * Author : John Greenan - * Contact : sales@alignment-systems.com - * Date : 12th September 2023 - * Copyright : Alignment Systems Ltd 2023 - * Project : Alignment Matching Toy - * Artefact : FIXToBinaryProcessor - * Description : - *****************************************************************************/ - -import java.nio.ByteBuffer; import java.util.Properties; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicBoolean; @@ -24,7 +11,6 @@ import com.alignmentsystems.library.LibraryFunctions; import com.alignmentsystems.library.LogEncapsulation; import com.alignmentsystems.library.constants.Constants; -import com.alignmentsystems.library.enumerations.Encodings; import com.alignmentsystems.library.enumerations.InstanceType; import com.alignmentsystems.library.interfaces.InterfaceFIXToBinaryProcessor; import com.alignmentsystems.library.interfaces.InterfaceOrder; @@ -42,7 +28,8 @@ public class FIXToBinaryProcessor implements Runnable, InterfaceFIXToBinaryProce private KafkaProducer kafkaProducerB = null; private AtomicBoolean running = new AtomicBoolean(false); private final static int MILLISLEEP = 200; - + private static BinaryFromToCanonical binaryFromToCanonical = new BinaryFromToCanonical(); + public FIXToBinaryProcessor() { // TODO Auto-generated constructor stub } @@ -65,84 +52,6 @@ public boolean initialise(ConcurrentLinkedQueue inQueue, LogEnca return true; } - private Sender getBufferFromOrder(InterfaceOrder inSeq) { - - ByteBuffer buf = null; - String receivedSymbol = null; - String orderId = null; - - try { - receivedSymbol = inSeq.getSymbol(); - orderId = inSeq.getOrderId().toString(); - - final short messageType = inSeq.getAlignmentType(); - final String receivedSender = inSeq.getSender(); - final String receivedTarget = inSeq.getTarget(); - final String receivedSide = inSeq.getOrderBookSide().getSideFIXStringValue(); - final char receivedTimeInForce = inSeq.getTimeInForce(); - //get mappings... - final Long exchangeIdMappedFromSenderCompID = DataMapper.getExchangeIdMappedFromSenderCompID(receivedSender); - final Long exchangeIdMappedFromTargetCompID = DataMapper.getExchangeIdMappedFromTargetCompID(receivedTarget); - final Long exchangeInstrumentIdMappedFromSymbol = DataMapper.getExchangeIdMappedFromInstrumentId(receivedSymbol); - final Long exchangeSideCodeMappedFromSideCode = DataMapper.getExchangeSideCodeMappedFromMemberSideCode(receivedSide); - final Short exchangeTimeInForceMappedFromTimeInForce = DataMapper.getMemberTimeInForceMappedToExchangeTimeInForce(receivedTimeInForce); - - final Encodings encoding = Encodings.FIXSBELITTLEENDIAN; - - - final int bufferLength = - Short.BYTES //messageType - + - Long.BYTES * 2 //ClOrdId - + - Long.BYTES * 2 //OrderId - + - Long.BYTES //exchangeIdMappedFromSenderCompID.BYTES - + - Long.BYTES //exchangeIdMappedFromTargetCompID.BYTES - + - Long.BYTES //this.orderQty - + - Long.BYTES //this.limitPrice - + - Long.BYTES //exchangeInstrumentIdMappedFromSymbol.BYTES - + - Long.BYTES //this.ts getEpochSecond - + - Integer.BYTES // this.ts getNano() - + - Long.BYTES //this.SideCode - + - Short.BYTES //inSeq.getTimeInForce() - ; - - buf = ByteBuffer.allocate(bufferLength).order(encoding.getByteOrder()); - buf.putShort(messageType); - buf.putLong(inSeq.getClOrdID().getLeastSignificantBits()); - buf.putLong(inSeq.getClOrdID().getMostSignificantBits()); - buf.putLong(inSeq.getOrderId().getLeastSignificantBits()); - buf.putLong(inSeq.getOrderId().getMostSignificantBits()); - buf.putLong(exchangeIdMappedFromSenderCompID); - buf.putLong(exchangeIdMappedFromTargetCompID); - buf.putLong(inSeq.getOrderQty()); - buf.putLong(inSeq.getLimitPrice()); - buf.putLong(exchangeInstrumentIdMappedFromSymbol); - buf.putLong(inSeq.getTimestamp().toInstant().getEpochSecond()); - buf.putInt(inSeq.getTimestamp().toInstant().getNano()); - buf.putLong(exchangeSideCodeMappedFromSideCode); - buf.putShort(exchangeTimeInForceMappedFromTimeInForce); - - buf.flip(); - } catch (Exception e) { - this.log.error(e.getMessage() , e); - throw e; - } - - - Sender sender = new Sender(buf.array(), receivedSymbol, orderId); - - return sender; - } @@ -156,7 +65,7 @@ public void run() { InterfaceOrder inSeq = inQueue.poll(); if (inSeq != null) { - Sender sender = getBufferFromOrder(inSeq); + Sender sender = binaryFromToCanonical.getBufferFromAlignmentOrder(inSeq); this.send(sender.getSymbol(), sender.getOrderId(), sender.getBinaryMessage()); } try { @@ -174,9 +83,7 @@ public void run() { System.err.println(new StringBuilder().append(CLASSNAME).append(Constants.SPACE).append(e.getMessage()) .toString()); } - } - } protected void send(String topicName, String key, byte[] binaryMessage) { @@ -193,5 +100,4 @@ protected void send(String topicName, String key, byte[] binaryMessage) { // KafkaProducer this.kafkaProducerB.send(producerRecord); } - } \ No newline at end of file diff --git a/exchange/src/main/java/com/alignmentsystems/matching/OrderBook.java b/exchange/src/main/java/com/alignmentsystems/matching/OrderBook.java index 887e248..5915b4b 100644 --- a/exchange/src/main/java/com/alignmentsystems/matching/OrderBook.java +++ b/exchange/src/main/java/com/alignmentsystems/matching/OrderBook.java @@ -20,22 +20,26 @@ import org.apache.kafka.clients.consumer.ConsumerRecord; -import com.alignmentsystems.fix44.field.Side; +import com.alignmentsystems.library.AlignmentExecutionReport; +import com.alignmentsystems.library.AlignmentMatch; import com.alignmentsystems.library.AlignmentOrderComparatorBuy; import com.alignmentsystems.library.AlignmentOrderComparatorSell; +import com.alignmentsystems.library.DataMapper; import com.alignmentsystems.library.LibraryFunctions; import com.alignmentsystems.library.LogEncapsulation; -import com.alignmentsystems.library.Match; import com.alignmentsystems.library.PersistenceToFileClient; import com.alignmentsystems.library.annotations.NotYetImplemented; import com.alignmentsystems.library.constants.Constants; import com.alignmentsystems.library.enumerations.OrderBookSide; import com.alignmentsystems.library.interfaces.InterfaceAddedOrderToOrderBook; +import com.alignmentsystems.library.interfaces.InterfaceExecutionReport; import com.alignmentsystems.library.interfaces.InterfaceMatch; import com.alignmentsystems.library.interfaces.InterfaceMatchEvent; import com.alignmentsystems.library.interfaces.InterfaceOrder; import com.alignmentsystems.library.interfaces.InterfaceOrderBook; +import quickfix.FieldNotFound; + /** * @author John Greenan * buy = snapShotOrderBookBySide(OrderBookSide.BUY); List sell = snapShotOrderBookBySide(OrderBookSide.SELL); - log.infoOrderBookStatus(buy, sell); + this.log.infoOrderBookStatus(buy, sell); } /** @@ -203,7 +208,7 @@ private void runMatch() { final UUID sellOrderID = topOfSellBook.getOrderId(); final boolean isEligibleForMarketData = true; - Match match = new Match( + AlignmentMatch match = new AlignmentMatch( tradedQuantity , tradedPrice , aggressor @@ -218,11 +223,18 @@ private void runMatch() { , topOfSellBook.getOrderQty() //Long sellOrderQty , topOfBuyBook.getAvgPx()//Long buyAvgPx , topOfSellBook.getAvgPx()//Long sellAvgPx + , topOfBuyBook.getLeavesQty() + , topOfSellBook.getLeavesQty() , topOfBuyBook.getSender() //String buySenderId , topOfBuyBook.getTarget() //String buyTargetId , topOfSellBook.getSender() // String sellSenderId , topOfSellBook.getTarget() //String sellTargetId - , isEligibleForMarketData); + , DataMapper.EXCHANGEORDSTATUSFILLED //buyOrderStatus + , DataMapper.EXCHANGEEXECTYPETRADE //buyExecType + , DataMapper.EXCHANGEORDSTATUSFILLED //sellOrderStatus + , DataMapper.EXCHANGEEXECTYPETRADE //sellExecType + , isEligibleForMarketData + ); //tradedQuantity, tradedPrice, aggressor, executionTimestamp, buyClOrdID, sellClOrdID, buyOrderID, sellOrderID, isEligibleForMarketData buy.remove(topOfBuyBook); @@ -256,11 +268,14 @@ public void addMatchEventListener(InterfaceMatchEvent toAdd) { } @Override - public void addedOrderToOrderBook(InterfaceOrder nos) { + public void addedOrderToOrderBook(InterfaceExecutionReport toAdd) { for (InterfaceAddedOrderToOrderBook hl : listenersAddedOrderToOrderBook) - hl.addedOrderToOrderBook(nos); + hl.addedOrderToOrderBook(toAdd); } + + + @Override public void addAddedOrderToOrderBookListener(InterfaceAddedOrderToOrderBook toAdd) { listenersAddedOrderToOrderBook.add(toAdd); @@ -325,15 +340,19 @@ public void matchHappened(InterfaceMatch match) { @Override public void processMessage(String topicName, ConsumerRecord message) throws Exception { // TODO Auto-generated method stub - InterfaceOrder io = BinaryToCanonicalRepresentationProcessor.getAlignmentOrder(message.value()); + InterfaceOrder io = BinaryFromToCanonical.getAlignmentOrderFromBuffer(message.value()); if (io.getOrderBookSide()==OrderBookSide.SELL) { this.sell.add(io); }else { this.buy.add(io); } - addedOrderToOrderBook(io); + //get ExecutionReport from the Order... + InterfaceExecutionReport er = getExecutionReportAcknowledgementForOrder(io); + this.addedOrderToOrderBook(er); //raise the event out to the listeners... + + this.orderBookLastUpdateTime = OffsetDateTime.now(Constants.HERE); // this.snapShotOrderBook(); this.runMatch(); @@ -341,14 +360,50 @@ public void processMessage(String topicName, ConsumerRecord mess } + private static InterfaceExecutionReport getExecutionReportAcknowledgementForOrder(InterfaceOrder nos) throws FieldNotFound { +// UUID execID +// , UUID clOrdID +// , UUID orderID +// , String buySenderId +// , String buyTargetId +// , String sellSenderId +// , String sellTargetId +// , OffsetDateTime timestamp +// , Long executionQuantity +// , Long executionPrice +// , Long leavesQuantity +// , Long cumQuantity +// , Long averagePrice +// , Short ordStatus +// , Short execType +// , Short sideCode + + InterfaceExecutionReport er2 = new AlignmentExecutionReport(); + er2.setExecutionReport( + null + , nos.getClOrdID() + , nos.getOrderId() + , nos.getSender() + , nos.getTarget() + , null + , null + , nos.getTimestamp() + , 0L + , 0L + , 0L + , 0L + , 0L + , DataMapper.EXCHANGEORDSTATUSNEW + , DataMapper.EXCHANGEEXECTYPENEW + , DataMapper.getExchangeSideCodeMappedFromMemberSideCode(nos.getOrderBookSide().sideCharValue) + ); + return er2; + } + @Override public void run() { - // TODO Auto-generated method stub running.set(true); - InterfaceOrder inSeq = null; - StringBuilder sb = new StringBuilder(); - try { Thread.currentThread(); Thread.sleep(milliSleep); diff --git a/exchange/src/main/java/com/alignmentsystems/matching/OrderBookKafkaProducer.java b/exchange/src/main/java/com/alignmentsystems/matching/OrderBookKafkaProducer.java index 8185a50..95af1be 100644 --- a/exchange/src/main/java/com/alignmentsystems/matching/OrderBookKafkaProducer.java +++ b/exchange/src/main/java/com/alignmentsystems/matching/OrderBookKafkaProducer.java @@ -12,50 +12,37 @@ import java.io.FileNotFoundException; import java.util.Properties; -import java.util.UUID; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.atomic.AtomicBoolean; import org.apache.kafka.clients.producer.KafkaProducer; import org.apache.kafka.clients.producer.ProducerRecord; -import com.alignmentsystems.fix44.ExecutionReport; -import com.alignmentsystems.fix44.NewOrderSingle; -import com.alignmentsystems.fix44.field.AvgPx; -import com.alignmentsystems.fix44.field.ClOrdID; -import com.alignmentsystems.fix44.field.CumQty; -import com.alignmentsystems.fix44.field.ExecID; -import com.alignmentsystems.fix44.field.ExecType; -import com.alignmentsystems.fix44.field.LeavesQty; -import com.alignmentsystems.fix44.field.OrdStatus; -import com.alignmentsystems.fix44.field.OrderID; -import com.alignmentsystems.fix44.field.Side; -import com.alignmentsystems.fix44.field.TimeInForce; +import com.alignmentsystems.library.AlignmentExecutionReport; import com.alignmentsystems.library.LibraryFunctions; import com.alignmentsystems.library.LogEncapsulation; import com.alignmentsystems.library.enumerations.InstanceType; import com.alignmentsystems.library.enumerations.OperationEventType; import com.alignmentsystems.library.interfaces.InterfaceAddedOrderToOrderBook; +import com.alignmentsystems.library.interfaces.InterfaceExecutionReport; import com.alignmentsystems.library.interfaces.InterfaceMatch; import com.alignmentsystems.library.interfaces.InterfaceMatchEvent; -import com.alignmentsystems.library.interfaces.InterfaceOrder; - -import quickfix.FieldNotFound; -import quickfix.Session; -import quickfix.SessionID; -import quickfix.SessionNotFound; public class OrderBookKafkaProducer implements InterfaceMatchEvent, InterfaceAddedOrderToOrderBook, Runnable { private KafkaProducer kafkaProducerB = null; private LogEncapsulation log = null; + private static BinaryFromToCanonical binaryFromToCanonical = new BinaryFromToCanonical(); + + + + public OrderBookKafkaProducer() { // TODO Auto-generated constructor stub } - - + + public boolean initialise(LogEncapsulation log) throws Exception{ - + this.log = log; if (this.kafkaProducerB == null) { @@ -70,9 +57,9 @@ public boolean initialise(LogEncapsulation log) throws Exception{ } return true; } - - - + + + protected void send(String topicName, String key, byte[] binaryMessage) { // create the ProducerRecord object which will represent the message to the @@ -89,70 +76,47 @@ protected void send(String topicName, String key, byte[] binaryMessage) { } - @Override - public void addedOrderToOrderBook(InterfaceOrder nos) { - sendExecutionReportAcknowledgementForReceivedOrder(nos); - } - - private void sendExecutionReportAcknowledgementForReceivedOrder(InterfaceOrder nos) { - final String methodName = "sendExecutionReportAcknowledgementForReceivedOrder"; - - ExecutionReport er = getExecutionReportAcknowledgementForOrder(nos); - final Boolean connectionToFIXEngineWorking = Boolean.FALSE; - - if(connectionToFIXEngineWorking) { + @Override + public void run() { + AtomicBoolean run = new AtomicBoolean(true); + while (run.get()) { try { - Session.sendToTarget(er, nos.getSender(), nos.getTarget()); - //Session.sendToTarget(er, sessionID); - } catch (SessionNotFound e) { - log.error(e.getMessage(), e); + wait(2000); + } catch (InterruptedException e) { + log.error(e.getMessage() , e ); } } } - private static ExecutionReport getExecutionReportAcknowledgementForOrder(InterfaceOrder nos) { - final OrderID orderId = new OrderID(nos.getOrderId().toString()); - final ExecID execID = new ExecID(UUID.randomUUID().toString()); - final ExecType execType = new ExecType(ExecType.NEW); - final OrdStatus ordStatus = new OrdStatus(OrdStatus.NEW); - final Side side = new Side(nos.getOrderBookSide().sideCharValue); - final TimeInForce tif = new TimeInForce(nos.getTimeInForce()); - final LeavesQty leavesQty = new LeavesQty(0d); - final CumQty cumQty = new CumQty(0d); - final AvgPx avgPx = new AvgPx(0d); - - ExecutionReport er = new ExecutionReport(orderId, execID, execType, ordStatus, side, leavesQty, cumQty, avgPx); - er.set(tif); - //Convert er to Binary and send to Kafka - - - return er; - } - - - - - @Override public void matchHappened(InterfaceMatch match) { - //sendExecutionReportsForMatch(match); - ////Convert match to Binary and send to Kafka - } + @SuppressWarnings("unused") + final String methodName = "matchHappened"; + final String TOPIC = "FILL"; + + log.infoMatchingEvent(OperationEventType.MATCHEVENT, match); + AlignmentExecutionReport buyRpt = match.getBuyReport(); + AlignmentExecutionReport sellRpt = match.getSellReport(); + final byte[] buy = binaryFromToCanonical.getBufferFromExecutionReport(buyRpt); + final byte[] sell = binaryFromToCanonical.getBufferFromExecutionReport(sellRpt); + + this.send(TOPIC , match.getSellOrderId().toString(), buy); + this.send(TOPIC , match.getBuyOrderId().toString(), sell); + } @Override - public void run() { - AtomicBoolean run = new AtomicBoolean(true); - while (run.get()) { - try { - wait(2000); - } catch (InterruptedException e) { - log.error(e.getMessage() , e ); - } - } + public void addedOrderToOrderBook(InterfaceExecutionReport er) { + @SuppressWarnings("unused") + final String methodName = "addedOrderToOrderBook"; + final String TOPIC = "ACK"; + //log.infoMatchingEvent(OperationEventType.NEWORDEREVENT, er); + + byte[] ack = binaryFromToCanonical.getBufferFromExecutionReport(er); + this.send(TOPIC, er.getExecID().toString(), ack); } } diff --git a/exchange/version.properties b/exchange/version.properties index fc0faa9..884d706 100644 --- a/exchange/version.properties +++ b/exchange/version.properties @@ -1,2 +1,2 @@ -#Mon Sep 18 00:46:07 AEST 2023 -VERSION_BUILD=662 +#Mon Sep 18 18:10:51 AEST 2023 +VERSION_BUILD=701 diff --git a/fixclient/version.properties b/fixclient/version.properties index ca0b613..cbb6934 100644 --- a/fixclient/version.properties +++ b/fixclient/version.properties @@ -1,2 +1,2 @@ -#Mon Sep 18 00:46:07 AEST 2023 -VERSION_BUILD=664 +#Mon Sep 18 18:10:51 AEST 2023 +VERSION_BUILD=703 diff --git a/sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentExecutionReport.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentExecutionReport.java new file mode 100644 index 0000000..d7e928d --- /dev/null +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentExecutionReport.java @@ -0,0 +1,155 @@ +package com.alignmentsystems.library; +/****************************************************************************** + * + * Author : John Greenan + * Contact : sales@alignment-systems.com + * Date : 18th September 2023 + * Copyright : Alignment Systems Ltd 2023 + * Project : Alignment Matching Toy + * Artefact : AlignmentExecutionReport + * Description : + *****************************************************************************/ + +import java.time.OffsetDateTime; +import java.util.UUID; + +import com.alignmentsystems.library.interfaces.InterfaceExecutionReport; + +public class AlignmentExecutionReport implements InterfaceExecutionReport { + public final static Short EXCHANGEMESSAGETYPE = DataMapper.EXCHANGEMESSAGETYPEMAPPEDFROMEXECUTIONREPORT; + + private UUID execID = null; + private String buySenderId = null; + private String buyTargetId = null; + private String sellSenderId = null; + private String sellTargetId = null; + private OffsetDateTime timestamp = null; + private Long executionQuantity = null; + private Long executionPrice = null; + private Long leavesQuantity = null; + private Long cumQuantity = null; + private Long averagePrice = null; + private UUID clOrdID = null; + private UUID orderID = null; + private Short ordStatus = null; + private Short execType = null; + private Short sideCode = null; + + + @Override + public void setExecutionReport( + UUID execID + , UUID clOrdID + , UUID orderID + , String buySenderId + , String buyTargetId + , String sellSenderId + , String sellTargetId + , OffsetDateTime timestamp + , Long executionQuantity + , Long executionPrice + , Long leavesQuantity + , Long cumQuantity + , Long averagePrice + , Short ordStatus + , Short execType + , Short sideCode + ) { + this.execID = execID; + this.clOrdID = clOrdID; + this.orderID = orderID; + this.buySenderId = buySenderId; + this.buyTargetId = buyTargetId; + this.sellSenderId = sellSenderId; + this.sellTargetId = sellTargetId; + this.timestamp = timestamp; + this.executionQuantity = executionQuantity; + this.executionPrice = executionPrice; + this.leavesQuantity = leavesQuantity; + this.cumQuantity = cumQuantity; + this.averagePrice = averagePrice; + this.ordStatus = ordStatus; + this.execType = execType; + this.sideCode = sideCode; + } + + @Override + public UUID getExecID() { + return this.execID; + } + + @Override + public String getBuySenderId() { + return this.buySenderId; + } + + @Override + public String getBuyTargetId() { + return this.buyTargetId; + } + + @Override + public String getSellSenderId() { + return this.sellSenderId; + } + + @Override + public String getSellTargetId() { + return this.sellTargetId; + } + + @Override + public OffsetDateTime getTimestamp() { + return this.timestamp; + } + + @Override + public Long getExecutionQuantity() { + return this.executionQuantity; + } + + @Override + public Long getExecutionPrice() { + return this.executionPrice; + } + + @Override + public Long getLeavesQuantity() { + return this.leavesQuantity; + } + + @Override + public Long getCumQuantity() { + return this.cumQuantity; + } + + @Override + public Long getAveragePrice() { + return this.averagePrice; + } + + @Override + public UUID getClOrdID() { + return this.clOrdID; + } + + @Override + public UUID getOrderID() { + return this.orderID; + } + + @Override + public Short getOrdStatus() { + return this.ordStatus; + } + + @Override + public Short getExecType() { + return this.execType; + } + + @Override + public Short getSideCode() { + return this.sideCode; + } +} \ No newline at end of file diff --git a/sharedlibrary/src/main/java/com/alignmentsystems/library/Match.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentMatch.java similarity index 69% rename from sharedlibrary/src/main/java/com/alignmentsystems/library/Match.java rename to sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentMatch.java index 9d08017..4a56378 100644 --- a/sharedlibrary/src/main/java/com/alignmentsystems/library/Match.java +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentMatch.java @@ -20,7 +20,7 @@ * @author John Greenan * */ -public class Match implements InterfaceMatch { +public class AlignmentMatch implements InterfaceMatch { private Long matchQuantity = 0L; private Long matchPrice = 0L; private OrderBookSide aggressorSide = null; @@ -35,17 +35,29 @@ public class Match implements InterfaceMatch { private Long sellOrderQty = null; private Long buyAvgPx = null; private Long sellAvgPx = null; + private Long buyLeavesQty = null; + private Long sellLeavesQty = null; + private String buySenderId = null; private String buyTargetId = null; private String sellSenderId = null; private String sellTargetId = null; + private UUID buyExecId = null; + private UUID sellExecId = null; + private Short buyOrdStatus = null; + private Short buyExecType = null; + private Short sellOrdStatus = null; + private Short sellExecType = null; + + + private UUID matchId = null; private Boolean isEligibleForMarketData = Boolean.FALSE; - public Match( + public AlignmentMatch( Long matchQuantity , Long matchPrice , OrderBookSide aggressorSide @@ -60,10 +72,19 @@ public Match( , Long sellOrderQty , Long buyAvgPx , Long sellAvgPx + , Long buyLeavesQty + , Long sellLeavesQty + , String buySenderId , String buyTargetId , String sellSenderId , String sellTargetId + + , Short buyOrdStatus + , Short buyExecType + + , Short sellOrdStatus + , Short sellExecType , Boolean getIsEligibleForMarketData ) { @@ -82,13 +103,27 @@ public Match( this.sellOrderQty = sellOrderQty; this.buyAvgPx = buyAvgPx; this.sellAvgPx = sellAvgPx; + this.buyLeavesQty = buyLeavesQty ; + this.sellLeavesQty = sellLeavesQty ; this.buySenderId = buySenderId; this.buyTargetId = buyTargetId; this.sellSenderId = sellSenderId; this.sellTargetId = sellTargetId; + this.buyOrdStatus = buyOrdStatus; + this.buyExecType = buyExecType; + + this.sellOrdStatus = sellOrdStatus; + this.sellExecType = sellExecType; + + this.isEligibleForMarketData = getIsEligibleForMarketData; + + this.buyExecId = UUID.randomUUID(); + this.sellExecId = UUID.randomUUID(); + + this.matchId = UUID.randomUUID(); } @@ -250,4 +285,77 @@ public String getSellSenderId() { public String getSellTargetId() { return this.sellTargetId; } + + + + + + @Override + public AlignmentExecutionReport getBuyReport() { + AlignmentExecutionReport buy = new AlignmentExecutionReport(); + buy.setExecutionReport( + this.buyExecId + , this.buyClOrdId + , this.buyOrderId + , this.buySenderId + , this.buyTargetId + , this.sellSenderId + , this.sellTargetId + , this.timestamp + , this.matchQuantity + , this.matchPrice + , this.buyLeavesQty + , this.buyCumQty + , this.buyAvgPx + , this.buyOrdStatus + , this.buyExecType + , DataMapper.EXCHANGESIDEBUY + ); + return buy; + } + + + @Override + public AlignmentExecutionReport getSellReport() { + AlignmentExecutionReport sell = new AlignmentExecutionReport(); + sell.setExecutionReport( + this.buyExecId + , this.sellClOrdId + , this.sellOrderId + , this.sellSenderId + , this.sellTargetId + , this.sellSenderId + , this.sellTargetId + , this.timestamp + , this.matchQuantity + , this.matchPrice + , this.sellLeavesQty + , this.sellCumQty + , this.sellAvgPx + , this.sellOrdStatus + , this.sellExecType + , DataMapper.EXCHANGESIDESELL + ); + return sell; + } + + @Override + public Short getBuyOrdStatus() { + return this.buyOrdStatus; + } + + @Override + public Short getBuyExecType() { + return this.buyExecType; + } + + @Override + public Short getSellOrdStatus() { + return this.sellOrdStatus; + } + + @Override + public Short getSellExecType() { + return this.sellExecType; + } } \ No newline at end of file diff --git a/sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentOrder.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentOrder.java index e0063c8..53832b8 100644 --- a/sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentOrder.java +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/AlignmentOrder.java @@ -48,6 +48,7 @@ public class AlignmentOrder implements InterfaceOrder{ private short alignmentType = 0; private Long cumQty = null; private Long avgPx = null; + private Long leavesQty = null; @Override public String toString() { @@ -108,7 +109,7 @@ public void setNewOrderSingle( this.orderQty = (long) nos.getOrderQty().getValue(); this.limitPrice = (long) nos.getPrice().getValue(); this.symbol = nos.getSymbol().getValue(); - this.timeInForce = nos.getTimeInForce().getValue(); + this.timeInForce = nos.getTimeInForce().getValue(); } catch (FieldNotFound e) { throw e; } @@ -248,5 +249,10 @@ public long getCumQty() { @Override public long getAvgPx() { return this.avgPx; + } + + @Override + public Long getLeavesQty() { + return this.leavesQty; } } \ No newline at end of file diff --git a/exchange/src/main/java/com/alignmentsystems/matching/DataMapper.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/DataMapper.java similarity index 69% rename from exchange/src/main/java/com/alignmentsystems/matching/DataMapper.java rename to sharedlibrary/src/main/java/com/alignmentsystems/library/DataMapper.java index b6efee2..c20611e 100644 --- a/exchange/src/main/java/com/alignmentsystems/matching/DataMapper.java +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/DataMapper.java @@ -1,4 +1,4 @@ -package com.alignmentsystems.matching; +package com.alignmentsystems.library; /****************************************************************************** * * Author : John Greenan @@ -20,43 +20,66 @@ public class DataMapper { private static HashMap memberFIXSenderCompIdToExchangeIdMap = new HashMap(); private static HashMap memberFIXTargetCompIdToExchangeIdMap = new HashMap(); private static HashMap memberInstrumentIdToExchangeInstrumentIdMap = new HashMap(); - private static HashMap memberSideCodeToExchangeSideCodeMap = new HashMap(); - + private static HashMap memberSideCodeToExchangeSideCodeMap = new HashMap(); private static HashMap memberMessageTypeToExchangeMessageTypeMap = new HashMap(); - private static HashMap memberTimeInForceToExchangeTimeInForceMap = new HashMap(); + private static HashMap memberExecTypeToExchangeExecTypeMap = new HashMap(); + private static HashMap memberOrdStatusToExchangeOrdStatusMap = new HashMap(); private static HashMap exchangeIdToMemberFIXSenderCompIdMap = new HashMap(); private static HashMap exchangeIdToMemberFIXTargetCompIdMap = new HashMap(); private static HashMap exchangeInstrumentIdToMemberInstrumentIdMap = new HashMap(); - private static HashMap exchangeSideCodeToMemberSideCodeMap = new HashMap(); - + private static HashMap exchangeSideCodeToMemberSideCodeMap = new HashMap(); private static HashMap exchangeMessageTypeToMemberMessageTypeMap = new HashMap(); - private static HashMap exchangeTimeInForceToMemberTimeInForceMap = new HashMap(); + private static HashMap exchangeExecTypeToExecTypeMap = new HashMap(); + private static HashMap exchangeOrdStatusToMemberOrdStatusMap = new HashMap(); + + + + private static AtomicBoolean initialised = new AtomicBoolean(false); + public final static Short EXCHANGEMESSAGETYPEMAPPEDFROMEXECUTIONREPORT = getExchangeMessageTypeMappedFromMemberMessageType("8"); + public final static Short EXCHANGEMESSAGETYPEMAPPEDFROMNEWORDERSINGLE = getExchangeMessageTypeMappedFromMemberMessageType("D"); + public final static Short EXCHANGEORDSTATUSNEW = memberOrdStatusToExchangeOrdStatusMap.get("0".charAt(0)); + public final static Short EXCHANGEEXECTYPENEW = memberExecTypeToExchangeExecTypeMap.get("0".charAt(0)); + + public final static Short EXCHANGEORDSTATUSFILLED = memberOrdStatusToExchangeOrdStatusMap.get("2".charAt(0)); + public final static Short EXCHANGEEXECTYPETRADE = memberExecTypeToExchangeExecTypeMap.get("F".charAt(0)); + + public final static Short EXCHANGESIDEBUY = memberSideCodeToExchangeSideCodeMap.get(Integer.toString(1).charAt(0)); + public final static Short EXCHANGESIDESELL = memberSideCodeToExchangeSideCodeMap.get(Integer.toString(2).charAt(0)); + + + + - private static AtomicBoolean initialised = new AtomicBoolean(false); public DataMapper(){ initialise(); + + } private static void initialise() { - loadFIXSenderCompIdToExchangeId(); - loadFIXTargetCompIdToExchangeId(); - loadInstrumentIdToExchangeInstrumentId(); - loadMemberSideCodeToExchangeSideCode(); - loadMemberMessageTypeToExchangeMessageType(); - loadmemberTimeInForceToExchangeTimeInForce(); - initialised.set(true); + if(!initialised.get()) { + loadFIXSenderCompIdToExchangeId(); + loadFIXTargetCompIdToExchangeId(); + loadInstrumentIdToExchangeInstrumentId(); + loadMemberSideCodeToExchangeSideCode(); + loadMemberMessageTypeToExchangeMessageType(); + loadmemberTimeInForceToExchangeTimeInForce(); + loadExecTypeToExchangeId(); + loadMemberOrdStatusToExchangeOrdStatus(); + initialised.set(true); + } } - private static void addMemberSideCodeToExchangeSideCode(Long exchangeId , String memberId) { + private static void addMemberSideCodeToExchangeSideCode(Short exchangeId , Character memberId) { memberSideCodeToExchangeSideCodeMap.put(memberId, exchangeId); exchangeSideCodeToMemberSideCodeMap.put(exchangeId, memberId); } @@ -78,6 +101,70 @@ private static void addInstrumentIdToExchangeInstrumentId(Long exchangeId, Strin exchangeInstrumentIdToMemberInstrumentIdMap.put(exchangeId, memberId); } + private static void addmemberExecTypeToExchangeExecTypeMap(Short exchangeId , Character memberId) { + memberExecTypeToExchangeExecTypeMap.put(memberId, exchangeId); + exchangeExecTypeToExecTypeMap.put(exchangeId, memberId); + } + + + private static void loadMemberOrdStatusToExchangeOrdStatus() { + Short id = 0; + + addMemberOrdStatusToExchangeOrdStatusMap(id++,"0".charAt(0));//New + addMemberOrdStatusToExchangeOrdStatusMap(id++,"1".charAt(0));//Partially filled + addMemberOrdStatusToExchangeOrdStatusMap(id++,"2".charAt(0));//Filled + addMemberOrdStatusToExchangeOrdStatusMap(id++,"3".charAt(0));//Done for day + addMemberOrdStatusToExchangeOrdStatusMap(id++,"4".charAt(0));//Canceled + addMemberOrdStatusToExchangeOrdStatusMap(id++,"5".charAt(0));//Replaced (No longer used) + addMemberOrdStatusToExchangeOrdStatusMap(id++,"6".charAt(0));//Pending Cancel (i.e. result of Order Cancel Request) + addMemberOrdStatusToExchangeOrdStatusMap(id++,"7".charAt(0));//Stopped + addMemberOrdStatusToExchangeOrdStatusMap(id++,"8".charAt(0));//Rejected + addMemberOrdStatusToExchangeOrdStatusMap(id++,"9".charAt(0));//Suspended + addMemberOrdStatusToExchangeOrdStatusMap(id++,"A".charAt(0));//Pending New + addMemberOrdStatusToExchangeOrdStatusMap(id++,"B".charAt(0));//Calculated + addMemberOrdStatusToExchangeOrdStatusMap(id++,"C".charAt(0));//Expired + addMemberOrdStatusToExchangeOrdStatusMap(id++,"D".charAt(0));//Accepted for Bidding + addMemberOrdStatusToExchangeOrdStatusMap(id++,"E".charAt(0));//Pending Replace (i.e. result of Order Cancel/Replace Request) + } + + private static void addMemberOrdStatusToExchangeOrdStatusMap(Short exchangeOrdStatus , Character memberOrdStatus ) { + memberOrdStatusToExchangeOrdStatusMap.put(memberOrdStatus, exchangeOrdStatus); + exchangeOrdStatusToMemberOrdStatusMap.put(exchangeOrdStatus, memberOrdStatus); + } + + + + // setField(ordStatus); + private static void loadExecTypeToExchangeId() { + Short id = 0; + addmemberExecTypeToExchangeExecTypeMap(id++,"0".charAt(0));//New + addmemberExecTypeToExchangeExecTypeMap(id++,"3".charAt(0));//Done for day + addmemberExecTypeToExchangeExecTypeMap(id++,"4".charAt(0));//Canceled + addmemberExecTypeToExchangeExecTypeMap(id++,"5".charAt(0));//Replaced + addmemberExecTypeToExchangeExecTypeMap(id++,"6".charAt(0));//Pending Cancel + addmemberExecTypeToExchangeExecTypeMap(id++,"7".charAt(0));//Stopped + addmemberExecTypeToExchangeExecTypeMap(id++,"8".charAt(0));//Rejected + addmemberExecTypeToExchangeExecTypeMap(id++,"9".charAt(0));//Suspended + addmemberExecTypeToExchangeExecTypeMap(id++,"A".charAt(0));//Pending New + addmemberExecTypeToExchangeExecTypeMap(id++,"B".charAt(0));//Calculated + addmemberExecTypeToExchangeExecTypeMap(id++,"C".charAt(0));//Expired + addmemberExecTypeToExchangeExecTypeMap(id++,"D".charAt(0));//Restated + addmemberExecTypeToExchangeExecTypeMap(id++,"E".charAt(0));//Pending Replace (e.g. result of Order Cancel/Replace Request) + addmemberExecTypeToExchangeExecTypeMap(id++,"F".charAt(0));//Trade (partial fill or fill) + addmemberExecTypeToExchangeExecTypeMap(id++,"G".charAt(0));//Trade Correct + addmemberExecTypeToExchangeExecTypeMap(id++,"H".charAt(0));//Trade Cancel + addmemberExecTypeToExchangeExecTypeMap(id++,"I".charAt(0));//Order Status + addmemberExecTypeToExchangeExecTypeMap(id++,"J".charAt(0));//Trade in a Clearing Hold + addmemberExecTypeToExchangeExecTypeMap(id++,"J".charAt(0));//Trade has been released to Clearing + addmemberExecTypeToExchangeExecTypeMap(id++,"L".charAt(0));//Triggered or Activated by System + addmemberExecTypeToExchangeExecTypeMap(id++,"M".charAt(0));//Locked + addmemberExecTypeToExchangeExecTypeMap(id++,"N".charAt(0));//Released + } + + + + + private static void loadFIXSenderCompIdToExchangeId() { final String memberA = "MEMBER_A"; @@ -290,11 +377,13 @@ private static void addMemberMessageTypeToExchangeMessageType(Short exchangeId, } - public static Short getExchangeMessageTypeMappedFromMemberMessageType( String memberId) { + + + public static Short getExchangeMessageTypeMappedFromMemberMessageType( String memberMessageType) { if (!initialised.get()) { initialise(); } - return memberMessageTypeToExchangeMessageTypeMap.get(memberId); + return memberMessageTypeToExchangeMessageTypeMap.get(memberMessageType); }; public static String getMemberMessageTypeMappedFromExchangeMessageType( Short exchangeId) { @@ -316,19 +405,17 @@ private static void loadInstrumentIdToExchangeInstrumentId() { } private static void loadMemberSideCodeToExchangeSideCode() { - Long added = 0L; + Short added = 0; - addMemberSideCodeToExchangeSideCode(added, Integer.toString(1));//Buy + addMemberSideCodeToExchangeSideCode(added, Integer.toString(1).charAt(0));//Buy added++; - addMemberSideCodeToExchangeSideCode(added, Integer.toString(2));//Sell + addMemberSideCodeToExchangeSideCode(added, Integer.toString(2).charAt(0));//Sell added++; //call addMemberSideCodeToExchangeSideCode(added, Integer.toString(1)); //here as required... - // 1 = Buy - // 2 = Sell // 3 = Buy minus // 4 = Sell plus // 5 = Sell short @@ -375,14 +462,14 @@ public static String getMemberFIXSenderCompIdMappedFromExchangeId(Long exchangeI return exchangeIdToMemberFIXSenderCompIdMap.get(exchangeId); } - public static String getMemberSideCodeMappedFromExchangeSideCode(Long exchangeId) { + public static Character getMemberSideCodeMappedFromExchangeSideCode(Short exchangeId) { if (!initialised.get()) { initialise(); } return exchangeSideCodeToMemberSideCodeMap.get(exchangeId); } - public static Long getExchangeSideCodeMappedFromMemberSideCode(String sideCode) { + public static Short getExchangeSideCodeMappedFromMemberSideCode(Character sideCode) { if (!initialised.get()) { initialise(); } @@ -404,11 +491,60 @@ public static String getMemberInstrumentIdMappedFromExchangeInstrumentId(Long ex } public static Short getMemberTimeInForceMappedToExchangeTimeInForce (char memberTimeInForce) { + if (!initialised.get()) { + initialise(); + } return memberTimeInForceToExchangeTimeInForceMap.get(memberTimeInForce); } public static char getExchangeTimeInForceMappedToMemberTimeInForce(Short exchangeTimeInForce) { + if (!initialised.get()) { + initialise(); + } return exchangeTimeInForceToMemberTimeInForceMap.get( exchangeTimeInForce); } + + + public static Short getExchangeExecTypeMappedFromMemberExecType (char memberExecType) { + if (!initialised.get()) { + initialise(); + } + return memberExecTypeToExchangeExecTypeMap.get(memberExecType); + } + + + public static char getMemberExecTypeMappedFromExchangeExecType(Short exchangeExecType) { + if (!initialised.get()) { + initialise(); + } + return exchangeExecTypeToExecTypeMap.get(exchangeExecType); + } + + + + + public static Short getExchangeOrdStatusMappedToMemberOrdStatus (char memberOrdStatus) { + if (!initialised.get()) { + initialise(); + } + + return memberOrdStatusToExchangeOrdStatusMap.get(memberOrdStatus); + + + } + + + public static char getMemberOrdStatusMappedToExchangeOrdStatus(Short exchangeOrdStatus) { + if (!initialised.get()) { + initialise(); + } + return exchangeOrdStatusToMemberOrdStatusMap.get(exchangeOrdStatus); + + } + + + + + } \ No newline at end of file diff --git a/sharedlibrary/src/main/java/com/alignmentsystems/library/LibraryOrders.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/LibraryOrders.java index 3fbad4a..28ba313 100644 --- a/sharedlibrary/src/main/java/com/alignmentsystems/library/LibraryOrders.java +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/LibraryOrders.java @@ -49,45 +49,7 @@ public static OrderBookSide getOrderBookSideFromFIXSide(Side side) { } } - public static ExecutionReport getExecutionReportAcknowledgementForOrder(InterfaceOrder nos) throws FieldNotFound { - OrderID orderId = new OrderID(nos.getOrderId().toString()); - ExecID execID = new ExecID (UUID.randomUUID().toString()); - ExecType execType = new ExecType(ExecType.NEW); - OrdStatus ordStatus = new OrdStatus(OrdStatus.NEW); - Side side = null; - LeavesQty leavesQty = null; - CumQty cumQty = new CumQty(0d); - AvgPx avgPx = new AvgPx(0d); - TimeInForce tif = new TimeInForce(nos.getTimeInForce()); - - try { - side = new Side(nos.getNewOrderSingle().getSide().getValue()); - leavesQty = new LeavesQty(nos.getNewOrderSingle().getOrderQty().getValue()); - - } catch (FieldNotFound e) { - throw e; - } - - - - ExecutionReport er = new ExecutionReport( - orderId - , execID - , execType - , ordStatus - , side - , leavesQty - , cumQty - , avgPx - ); - - er.set(tif); - - - return er; - - } - + diff --git a/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceAddedOrderToOrderBook.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceAddedOrderToOrderBook.java index fb32cfb..cc2345f 100644 --- a/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceAddedOrderToOrderBook.java +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceAddedOrderToOrderBook.java @@ -1,4 +1,7 @@ package com.alignmentsystems.library.interfaces; + +import com.alignmentsystems.library.AlignmentExecutionReport; + /****************************************************************************** * * Author : John Greenan @@ -15,5 +18,5 @@ * */ public interface InterfaceAddedOrderToOrderBook { - public void addedOrderToOrderBook(InterfaceOrder nos); + public void addedOrderToOrderBook(InterfaceExecutionReport er); } diff --git a/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceExecutionReport.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceExecutionReport.java index 9bfd946..db57351 100644 --- a/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceExecutionReport.java +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceExecutionReport.java @@ -11,6 +11,7 @@ *****************************************************************************/ import java.time.OffsetDateTime; +import java.util.UUID; import com.alignmentsystems.fix44.ExecutionReport; @@ -20,8 +21,31 @@ * */ public interface InterfaceExecutionReport { + + + /** + * + * @param execID + * @param clOrdID + * @param orderID + * @param buySenderId + * @param buyTargetId + * @param sellSenderId + * @param sellTargetId + * @param timestamp + * @param executionQuantity + * @param executionPrice + * @param leavesQuantity + * @param cumQuantity + * @param averagePrice + * @param ordStatus + * @param execType + * @param sideCode + */ public void setExecutionReport( - String execID + UUID execID + , UUID clOrdID + , UUID orderID , String buySenderId , String buyTargetId , String sellSenderId @@ -29,9 +53,21 @@ public void setExecutionReport( , OffsetDateTime timestamp , Long executionQuantity , Long executionPrice + , Long leavesQuantity + , Long cumQuantity + , Long averagePrice + , Short ordStatus + , Short execType + , Short sideCode ); - - public String getExecID(); + + /** + * + * @return + */ + public UUID getClOrdID(); + public UUID getOrderID(); + public UUID getExecID(); public String getBuySenderId(); public String getBuyTargetId(); public String getSellSenderId(); @@ -39,4 +75,10 @@ public void setExecutionReport( public OffsetDateTime getTimestamp(); public Long getExecutionQuantity(); public Long getExecutionPrice(); -} + public Long getLeavesQuantity(); + public Long getCumQuantity(); + public Long getAveragePrice(); + public Short getOrdStatus(); + public Short getExecType(); + public Short getSideCode(); +} \ No newline at end of file diff --git a/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceMatch.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceMatch.java index f2e1ffd..097bb44 100644 --- a/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceMatch.java +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceMatch.java @@ -12,6 +12,7 @@ import java.time.OffsetDateTime; import java.util.UUID; +import com.alignmentsystems.library.AlignmentExecutionReport; import com.alignmentsystems.library.enumerations.OrderBookSide; /** * @author John Greenan @@ -38,9 +39,15 @@ public interface InterfaceMatch { public String getSellSenderId(); public String getSellTargetId(); public void setBuyAvgPx(Long avgPx); - + public Short getBuyOrdStatus(); + public Short getBuyExecType(); + public Short getSellOrdStatus(); + public Short getSellExecType(); + public void getSellAvgPx(Long avgPx); public void setMatchId(UUID matchID); public Boolean getIsEligibleForMarketData(); + public AlignmentExecutionReport getBuyReport(); + public AlignmentExecutionReport getSellReport(); } \ No newline at end of file diff --git a/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceOrder.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceOrder.java index cfab936..c3b7ed4 100644 --- a/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceOrder.java +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/interfaces/InterfaceOrder.java @@ -52,6 +52,7 @@ public void setNewOrderSingle( public void setTimeInForce(char timeInForce); public long getCumQty(); public long getAvgPx(); + public Long getLeavesQty(); public void reCreateOrder( String symbol diff --git a/sharedlibrary/src/main/java/com/alignmentsystems/library/sbe/SimpleBinaryEncodingMessage.java b/sharedlibrary/src/main/java/com/alignmentsystems/library/sbe/SimpleBinaryEncodingMessage.java index 29c3ec1..6a1dfc4 100644 --- a/sharedlibrary/src/main/java/com/alignmentsystems/library/sbe/SimpleBinaryEncodingMessage.java +++ b/sharedlibrary/src/main/java/com/alignmentsystems/library/sbe/SimpleBinaryEncodingMessage.java @@ -15,7 +15,7 @@ import java.time.OffsetDateTime; import java.util.UUID; -import com.alignmentsystems.library.Match; +import com.alignmentsystems.library.AlignmentMatch; import com.alignmentsystems.library.annotations.NotYetImplemented; import com.alignmentsystems.library.constants.Constants; import com.alignmentsystems.library.enumerations.Encodings; @@ -103,7 +103,8 @@ public void setMessage(InterfaceMatch match) { @Override @NotYetImplemented public InterfaceMatch getMessage() { - InterfaceMatch match = new Match(marketDataPrice, marketDataPrice, null, timestamp, marketDataId, marketDataId, marketDataId, marketDataId, marketDataPrice, marketDataPrice, marketDataPrice, marketDataPrice, marketDataPrice, marketDataPrice, null, null, null, null, null); + //InterfaceMatch match = new AlignmentMatch(marketDataPrice, marketDataPrice, null, timestamp, marketDataId, marketDataId, marketDataId, marketDataId, marketDataPrice, marketDataPrice, marketDataPrice, marketDataPrice, marketDataPrice, marketDataPrice, null, null, null, null, null); + InterfaceMatch match =null; return match; } diff --git a/sharedlibrary/version.properties b/sharedlibrary/version.properties index fc0faa9..884d706 100644 --- a/sharedlibrary/version.properties +++ b/sharedlibrary/version.properties @@ -1,2 +1,2 @@ -#Mon Sep 18 00:46:07 AEST 2023 -VERSION_BUILD=662 +#Mon Sep 18 18:10:51 AEST 2023 +VERSION_BUILD=701