public final class FXOrderClassic {
private final int units;
private final CurrencyPair pair;
private final Side side;
private final double price;
private final LocalDateTime sentAt;
private final int ttl;
public FXOrderClassic(int units,
CurrencyPair pair,
Side side,
double price,
LocalDateTime sentAt,
int ttl) {
this.units = units;
this.pair = pair; // CurrencyPair is a simple enum
this.side = side; // Side is a simple enum
this.price = price;
this.sentAt = sentAt;
this.ttl = ttl;
}
public int getUnits() {
return units;
}
public CurrencyPair getPair() {
return pair;
}
public Side getSide() {
return side;
}
public double getPrice() {
return price;
}
public LocalDateTime getSentAt() {
return sentAt;
}
public int getTtl() {
return ttl;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass())
return false;
FXOrderClassic that = (FXOrderClassic) o;
if (units != that.units) return false;
if (Double.compare(that.price, price) != 0)
return false;
if (ttl != that.ttl) return false;
if (pair != that.pair) return false;
if (side != that.side) return false;
return sentAt != null ?
sentAt.equals(that.sentAt) : that.sentAt == null;
}
@Override
public int hashCode() {
int result;
long temp;
result = units;
result = 31 * result +
(pair != null ? pair.hashCode() : 0);
result = 31 * result +
(side != null ? side.hashCode() : 0);
temp = Double.doubleToLongBits(price);
result = 31 * result +
(int) (temp ^ (temp >>> 32));
result = 31 * result +
(sentAt != null ? sentAt.hashCode() : 0);
result = 31 * result + ttl;
return result;
}
@Override
public String toString() {
return "FXOrderClassic{" +
"units=" + units +
", pair=" + pair +
", side=" + side +
", price=" + price +
", sentAt=" + sentAt +
", ttl=" + ttl +
'}';
}
}
var order = new FXOrderClassic(1,
CurrencyPair.GBPUSD,
Side.Bid, 1.25,
LocalDateTime.now(), 1000);
public record FXOrder(int units,
CurrencyPair pair,
Side side,
double price,
LocalDateTime sentAt,
int ttl) {}
javac --enable-preview -source 14 FXOrder.java
$ javap FXOrder.class
Compiled from "FXOrder.java"
public final class FXOrder extends java.lang.Record {
public FXOrder(int, CurrencyPair, Side, double,
java.time.LocalDateTime, int);
public java.lang.String toString();
public final int hashCode();
public final boolean equals(java.lang.Object);
public int units();
public CurrencyPair pair();
public Side side();
public double price();
public java.time.LocalDateTime sentAt();
public int ttl();
}
public final class FXOrderClassic extends Record {
private final int units;
private final CurrencyPair pair;
private final Side side;
private final double price;
private final LocalDateTime sentAt;
private final int ttl;
// ... rest of class elided
}
R copy = new R(r.c1(), r.c2(), ..., r.cn());
jshell> var o = new Object() {
...> public void bar() { System.out.println("bar!"); }
...> }
o ==> $0@37f8bb67
jshell> var o2 = new Object() {
...> public void bar() { System.out.println("bar!"); }
...> }
o2 ==> $1@31cefde0
jshell> o = o2;
| Error:
| incompatible types: $1 cannot be converted to $0
| o = o2;
| ^^
record OrderPartition(CurrencyPair pair, Side side) {}
public record FXOrder(int units,
CurrencyPair pair,
Side side,
double price,
LocalDateTime sentAt,
int ttl) {
public FXOrder {
if (units < 1) {
throw new IllegalArgumentException(
"FXOrder units must be positive");
}
if (ttl < 0) {
throw new IllegalArgumentException(
"FXOrder TTL must be positive, or 0 for market orders");
}
if (price <= 0.0) {
throw new IllegalArgumentException(
"FXOrder price must be positive");
}
}
}
public static FXOrder of(CurrencyPair pair, Side side, double price) {
return new FXOrder(1, pair, side, price,
LocalDateTime.now(), 1000);
}
record OrderPartition(CurrencyPair pair, Side side) {
public OrderPartition(FXOrder order) {
this(order.pair(), order.side());
}
}
public final class MatchingEngine {
private final Map<OrderPartition, RankedOrderBook>
orderBooks = new TreeMap<>();
public void addOrder(final FXOrder o) {
orderBooks.get(new OrderPartition(o)).addAndRank(o);
checkForCrosses(o.pair());
}
public void checkForCrosses(final CurrencyPair pair) {
// Do any buy orders match with sells now?
}
// ...
}