Skip to content

Commit 8dc936b

Browse files
johnjohn
authored andcommitted
Data Cleanup
Added DataMapper, removed Doubles from code and replaced with Long for Price and Quantity (decimal offset to be determined)
1 parent ac784e0 commit 8dc936b

24 files changed

+315
-146
lines changed
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package com.alignmentsystems.matching;
2+
/******************************************************************************
3+
*
4+
* Author : John Greenan
5+
* Contact : sales@alignment-systems.com
6+
* Date : 13th September 2023
7+
* Copyright : Alignment Systems Ltd 2023
8+
* Project : Alignment Matching Toy
9+
* Artefact : DataMapper
10+
* Description :
11+
*****************************************************************************/
12+
import java.util.HashMap;
13+
14+
/**
15+
* @author <a href="mailto:sales@alignment-systems.com">John Greenan</a>
16+
*
17+
*/
18+
public class DataMapper {
19+
private HashMap<String, Long> memberFIXSenderCompIdToExchangeIdMap = new HashMap<String, Long>();
20+
private HashMap<String, Long> memberInstrumentIdToExchangeInstrumentIdMap = new HashMap<String, Long>();
21+
22+
protected HashMap<String, Long> getMemberFIXSenderCompIdToExchangeIdMap() {
23+
return memberFIXSenderCompIdToExchangeIdMap;
24+
}
25+
26+
protected HashMap<String, Long> getMemberInstrumentIdToExchangeInstrumentIdMap() {
27+
return memberInstrumentIdToExchangeInstrumentIdMap;
28+
}
29+
30+
public DataMapper() {
31+
Long added = Long.MIN_VALUE;
32+
memberFIXSenderCompIdToExchangeIdMap.put("MEMBER_A", added);
33+
added++;
34+
memberFIXSenderCompIdToExchangeIdMap.put("MEMBER_B", added);
35+
added++;
36+
memberFIXSenderCompIdToExchangeIdMap.put("EXCHANGE", added);
37+
38+
39+
memberInstrumentIdToExchangeInstrumentIdMap.put("Badger.W", Long.MAX_VALUE);
40+
41+
}
42+
43+
}

exchange/src/main/java/com/alignmentsystems/matching/FIXEngineExchange.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,7 @@ public void onMessage(com.alignmentsystems.fix44.NewOrderSingle message, Session
238238

239239
AlignmentOrder ao = new AlignmentOrder();
240240

241-
ao.setNewOrderSingle(message, sessionID, MessageDirection.RECEIVED, UUID.randomUUID().toString(),
242-
orderBookSide);
241+
ao.setNewOrderSingle(message, sessionID, UUID.randomUUID(), orderBookSide);
243242

244243
StringBuilder sb = new StringBuilder().append(" OrderID=(").append(ao.getOrderId()).append(" ClOrdID=(")
245244
.append(ao.getClOrdID()).append(" Side=(").append(ao.getOrderBookSide().sideValue)

exchange/src/main/java/com/alignmentsystems/matching/FIXToBinaryProcessor.java

Lines changed: 70 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
*****************************************************************************/
1515

1616
import java.nio.ByteBuffer;
17+
import java.util.HashMap;
1718
import java.util.Properties;
1819
import java.util.concurrent.ConcurrentLinkedQueue;
1920
import java.util.concurrent.atomic.AtomicBoolean;
@@ -24,6 +25,7 @@
2425
import com.alignmentsystems.library.LibraryFunctions;
2526
import com.alignmentsystems.library.LogEncapsulation;
2627
import com.alignmentsystems.library.constants.Constants;
28+
import com.alignmentsystems.library.enumerations.Encodings;
2729
import com.alignmentsystems.library.enumerations.InstanceType;
2830
import com.alignmentsystems.library.interfaces.InterfaceFIXToBinaryProcessor;
2931
import com.alignmentsystems.library.interfaces.InterfaceOrder;
@@ -35,7 +37,13 @@ public class FIXToBinaryProcessor implements Runnable, InterfaceFIXToBinaryProce
3537
private KafkaProducer<String, byte[]> kafkaProducerB = null;
3638
private AtomicBoolean running = new AtomicBoolean(false);
3739
private final static int MILLISLEEP = 200;
40+
private DataMapper dataMapper = null;
41+
private HashMap<String, Long> memberFIXSenderCompIdToExchangeIdMap;
42+
private HashMap<String, Long> memberInstrumentIdToExchangeInstrumentIdMap;
3843

44+
45+
46+
3947
public FIXToBinaryProcessor() {
4048
// TODO Auto-generated constructor stub
4149
}
@@ -45,12 +53,19 @@ public boolean initialise(ConcurrentLinkedQueue<InterfaceOrder> inQueue, LogEnca
4553
this.inQueue = inQueue;
4654
this.log = log;
4755

56+
dataMapper = new DataMapper();
57+
58+
memberFIXSenderCompIdToExchangeIdMap = dataMapper.getMemberFIXSenderCompIdToExchangeIdMap();
59+
memberInstrumentIdToExchangeInstrumentIdMap = dataMapper.getMemberInstrumentIdToExchangeInstrumentIdMap();
60+
61+
62+
4863
if (this.kafkaProducerB == null) {
4964
Properties props;
5065
try {
5166
props = LibraryFunctions.getProperties(FIXToBinaryProcessor.class.getClassLoader(), InstanceType.KAFKA.getProperties());
5267
} catch (FileNotFoundException | NullPointerException e) {
53-
log.error(e.getMessage() , e);
68+
this.log.error(e.getMessage() , e);
5469
throw e;
5570
}
5671
this.kafkaProducerB = new KafkaProducer<>(props);
@@ -60,21 +75,68 @@ public boolean initialise(ConcurrentLinkedQueue<InterfaceOrder> inQueue, LogEnca
6075

6176
}
6277

78+
private Sender getBufferFromOrder(InterfaceOrder inSeq) {
79+
80+
String symbol = inSeq.getSymbol();
81+
String orderId = inSeq.getOrderId().toString();
82+
83+
Long exchangeIdMappedFromSenderCompID = memberFIXSenderCompIdToExchangeIdMap.get(inSeq.getSender());
84+
Long exchangeIdMappedFromTargetCompID = memberFIXSenderCompIdToExchangeIdMap.get(inSeq.getTarget());
85+
Long exchangeInstrumentIdMappedFromSymbol = memberInstrumentIdToExchangeInstrumentIdMap.get(inSeq.getSymbol());
86+
87+
88+
final Encodings encoding = Encodings.FIXSBELITTLEENDIAN;
89+
// TODO Auto-generated method stub
90+
int bufferLength =
91+
Long.BYTES * 2 //ClOrdId
92+
+
93+
Long.BYTES * 2 //OrderId
94+
+
95+
Long.BYTES //exchangeIdMappedFromSenderCompID.BYTES
96+
+
97+
Long.BYTES //exchangeIdMappedFromTargetCompID.BYTES
98+
+
99+
Long.BYTES //this.orderQty
100+
+
101+
Long.BYTES //this.limitPrice
102+
+
103+
Long.BYTES //exchangeInstrumentIdMappedFromSymbol.BYTES
104+
+
105+
Double.BYTES //this.ts
106+
;
107+
108+
ByteBuffer buf = ByteBuffer.allocate(bufferLength).order(encoding.getByteOrder());
109+
buf.putLong(inSeq.getClOrdID().getLeastSignificantBits());
110+
buf.putLong(inSeq.getClOrdID().getMostSignificantBits());
111+
buf.putLong(inSeq.getOrderId().getLeastSignificantBits());
112+
buf.putLong(inSeq.getOrderId().getMostSignificantBits());
113+
buf.putLong(exchangeIdMappedFromSenderCompID);
114+
buf.putLong(exchangeIdMappedFromTargetCompID);
115+
buf.putLong(inSeq.getOrderQty());
116+
buf.putLong(inSeq.getLimitPrice());
117+
buf.putLong(exchangeInstrumentIdMappedFromSymbol);
118+
buf.putLong(Double.doubleToLongBits(inSeq.getTimestamp().toInstant().toEpochMilli()));
119+
120+
Sender sender = new Sender(buf, symbol, orderId);
121+
122+
123+
return sender;
124+
}
125+
126+
127+
128+
63129
@Override
64130
public void run() {
65131
running.set(true);
66-
ByteBuffer bb = null;
67-
String symbol = null;
68-
String orderId = null;
132+
69133
while (running.get()) {
70134

71135
InterfaceOrder inSeq = inQueue.poll();
72136

73137
if (inSeq != null) {
74-
bb = inSeq.getBinaryOrderData();
75-
symbol = inSeq.getSymbol();
76-
orderId = inSeq.getOrderId();
77-
this.send(symbol, orderId, bb);
138+
Sender sender = getBufferFromOrder(inSeq);
139+
this.send(sender.getSymbol(), sender.getOrderId(), sender.getBb());
78140
}
79141
try {
80142
Thread.currentThread();

exchange/src/main/java/com/alignmentsystems/matching/InstanceWrapper.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ public boolean initialise(InstanceType instanceType) {
4747
sb.append(CLASSNAME).append(" Started instance=").append(this.instanceType.type).append(" Started version=")
4848
.append(LibraryFunctions.getVersion(this.getClass()));
4949

50+
51+
Boolean returnValue = Boolean.FALSE;
5052
log.info(sb.toString());
5153

5254
// What do we do here?
@@ -58,12 +60,22 @@ public boolean initialise(InstanceType instanceType) {
5860
switch (instanceType) {
5961

6062
case FIXMESSAGINGINFRA:
61-
return initialiseFIXMessagingInfrastructure(instanceType);
63+
returnValue = initialiseFIXMessagingInfrastructure(instanceType);
6264
case ORDERBOOK:
63-
return initialiseOrderBook(instanceType) ;
65+
returnValue = initialiseOrderBook(instanceType) ;
6466
default:
65-
return false;
67+
returnValue = false;
6668
}
69+
while (returnValue) {
70+
try {
71+
this.wait(2000);
72+
} catch (InterruptedException e) {
73+
log.error(e.getMessage() , e );
74+
}
75+
}
76+
return returnValue;
77+
78+
6779
}
6880

6981
private Boolean initialiseOrderBook(InstanceType instanceType) {

exchange/src/main/java/com/alignmentsystems/matching/KafkaAbstractSimple.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
*****************************************************************************/
1212

1313
/**
14-
* The type Abstract class SimpleKafka
14+
* @author <a href="mailto:sales@alignment-systems.com">John Greenan</a>
15+
*
1516
*/
1617
public abstract class KafkaAbstractSimple {
1718
/**

exchange/src/main/java/com/alignmentsystems/matching/KafkaLibrary.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@
1818
import com.alignmentsystems.library.enumerations.ConfigurationProperties;
1919
import com.alignmentsystems.library.enumerations.InstanceType;
2020

21+
22+
/**
23+
* @author <a href="mailto:sales@alignment-systems.com">John Greenan</a>
24+
*
25+
*/
2126
public class KafkaLibrary {
2227

2328
public static JsonObject getMessageLogEntryJSON(String source, String topic, String key, String message)

exchange/src/main/java/com/alignmentsystems/matching/KafkaMessageHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.apache.kafka.clients.consumer.ConsumerRecord;
1515

1616
/**
17+
* @author <a href="mailto:sales@alignment-systems.com">John Greenan</a>
1718
* The interface KafkaMessageHandler.
1819
*
1920
* This interface is the template callback functions that can be passed to an

exchange/src/main/java/com/alignmentsystems/matching/OrderBook.java

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import java.util.ArrayList;
1616
import java.util.List;
1717
import java.util.PriorityQueue;
18+
import java.util.UUID;
1819
import java.util.concurrent.atomic.AtomicBoolean;
1920

2021
import org.apache.kafka.clients.consumer.ConsumerRecord;
@@ -147,10 +148,10 @@ private void runMatch() {
147148
return;
148149
}
149150

150-
final Double topOfBuyBookPrice = topOfBuyBook.getLimitPrice().getValue();
151-
final Double topOfSellBookPrice = topOfSellBook.getLimitPrice().getValue();
152-
Double tradedQuantity = 0d;
153-
Double tradedPrice = 0d;
151+
final Long topOfBuyBookPrice = topOfBuyBook.getLimitPrice();
152+
final Long topOfSellBookPrice = topOfSellBook.getLimitPrice();
153+
Long tradedQuantity = null;
154+
Long tradedPrice = null;
154155
// If buy top of book price is greater than or equal to the sell top of book
155156
// then we have got a buyer
156157
// who has crossed the spread. So we have a trade, yay!
@@ -178,25 +179,25 @@ private void runMatch() {
178179
aggressor = new Side(Side.BUY);
179180
}
180181

181-
Double topOfBuyBookQty = topOfBuyBook.getOrderQty().getValue();
182-
Double topOfSellBookQty = topOfBuyBook.getOrderQty().getValue();
182+
Long topOfBuyBookQty = topOfBuyBook.getOrderQty();
183+
Long topOfSellBookQty = topOfBuyBook.getOrderQty();
183184

184185
tradedQuantity = Math.min(topOfBuyBookQty, topOfSellBookQty);
185186

186187
switch (aggressor.getValue()) {
187188
case Side.SELL:
188-
tradedPrice = Math.max(topOfBuyBookPrice, topOfSellBookPrice);
189+
tradedPrice = Math. max(topOfBuyBookPrice, topOfSellBookPrice);
189190
break;
190191
case Side.BUY:
191192
tradedPrice = Math.min(topOfBuyBookPrice, topOfSellBookPrice);
192193
break;
193194
}
194195
OffsetDateTime executionTimestamp = OffsetDateTime.now(Constants.HERE);
195196

196-
String buyClOrdID = topOfBuyBook.getClOrdID();
197-
String sellClOrdID = topOfSellBook.getClOrdID();
198-
String buyOrderID = topOfBuyBook.getOrderId();
199-
String sellOrderID = topOfSellBook.getOrderId();
197+
UUID buyClOrdID = topOfBuyBook.getClOrdID();
198+
UUID sellClOrdID = topOfSellBook.getClOrdID();
199+
UUID buyOrderID = topOfBuyBook.getOrderId();
200+
UUID sellOrderID = topOfSellBook.getOrderId();
200201
final boolean isEligibleForMarketData = true;
201202

202203
Match match = new Match(tradedQuantity, tradedPrice, topOfBuyBook, topOfSellBook, aggressor,

exchange/src/main/java/com/alignmentsystems/matching/OrderBookWrapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ private void sendExecutionReportAcknowledgementForReceivedOrder(InterfaceOrder n
133133
}
134134

135135
private static ExecutionReport getExecutionReportAcknowledgementForOrder(InterfaceOrder nos) throws FieldNotFound {
136-
OrderID orderId = new OrderID(nos.getOrderId());
136+
OrderID orderId = new OrderID(nos.getOrderId().toString());
137137
ExecID execID = new ExecID(UUID.randomUUID().toString());
138138
ExecType execType = new ExecType(ExecType.NEW);
139139
OrdStatus ordStatus = new OrdStatus(OrdStatus.NEW);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.alignmentsystems.matching;
2+
/******************************************************************************
3+
*
4+
* Author : John Greenan
5+
* Contact : sales@alignment-systems.com
6+
* Date : 13th September 2023
7+
* Copyright : Alignment Systems Ltd 2023
8+
* Project : Alignment Matching Toy
9+
* Artefact : Sender
10+
* Description :
11+
*****************************************************************************/
12+
import java.nio.ByteBuffer;
13+
14+
/**
15+
* @author <a href="mailto:sales@alignment-systems.com">John Greenan</a>
16+
*
17+
*/
18+
public class Sender {
19+
public Sender(ByteBuffer bb, String symbol, String orderId) {
20+
super();
21+
this.bb = bb;
22+
this.symbol = symbol;
23+
this.orderId = orderId;
24+
}
25+
ByteBuffer bb = null;
26+
String symbol = null;
27+
String orderId = null;
28+
29+
public ByteBuffer getBb() {
30+
return bb;
31+
}
32+
public String getSymbol() {
33+
return symbol;
34+
}
35+
public String getOrderId() {
36+
return orderId;
37+
}
38+
}

0 commit comments

Comments
 (0)