-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTradeProcessor.java
More file actions
102 lines (88 loc) · 3.18 KB
/
TradeProcessor.java
File metadata and controls
102 lines (88 loc) · 3.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package com.fintech.trading;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* Legacy Java 8 trade processor — intentionally contains patterns
* that the java-modernization-review skill is designed to detect.
*/
public class TradeProcessor {
private HashMap<String, Double> positionMap = new HashMap<>();
private ExecutorService executor = Executors.newFixedThreadPool(10);
// NPE risk: unguarded chained access
public BigDecimal getCounterpartyBalance(Order order) {
return order.getCounterparty().getAccount().getBalance();
}
// for-loop that should be a stream
public List<Trade> getPendingHighValueTrades(List<Trade> trades) {
List<Trade> results = new ArrayList<>();
for (Trade t : trades) {
if (t.getAmount().doubleValue() > 1000 && t.getStatus().equals("PENDING")) {
results.add(t);
}
}
return results;
}
// double arithmetic for money — precision loss
public double calculateNetExposure(List<Trade> trades) {
double total = 0.0;
for (Trade t : trades) {
if (t.getCurrency().equals("USD")) {
total += t.getAmount().doubleValue() * t.getFxRate().doubleValue();
}
}
return total;
}
// Manual grouping — should use Collectors.groupingBy
public Map<String, List<Trade>> groupByCounterparty(List<Trade> trades) {
Map<String, List<Trade>> grouped = new HashMap<String, List<Trade>>();
for (Trade t : trades) {
String cp = t.getCounterparty();
if (grouped.get(cp) == null) {
grouped.put(cp, new ArrayList<Trade>());
}
grouped.get(cp).add(t);
}
return grouped;
}
// Synchronized block — candidate for ConcurrentHashMap
public synchronized void updatePosition(String counterparty, double delta) {
Double current = positionMap.get(counterparty);
if (current == null) {
positionMap.put(counterparty, delta);
} else {
positionMap.put(counterparty, current + delta);
}
}
// Generic Exception catch, empty handler
public void settleTrade(Trade trade) {
try {
executor.submit(() -> processSettlement(trade));
} catch (Exception e) {
// TODO: handle later
}
}
// Legacy thread-based message listener placeholder
// @Queue(name = "TRADE_QUEUE")
// @Solace(threadPoolSize = 10)
public void onTradeMessage(Trade trade) {
settleTrade(trade);
}
private void processSettlement(Trade trade) {
// settlement logic
}
// Rigid DTO — candidate for Record
static class TradePosition {
String counterparty;
double usdAmount;
double eurAmount;
double jpyAmount;
TradePosition(String counterparty, double usdAmount, double eurAmount, double jpyAmount) {
this.counterparty = counterparty;
this.usdAmount = usdAmount;
this.eurAmount = eurAmount;
this.jpyAmount = jpyAmount;
}
}
}