Skip to content

Commit

Permalink
v1 OrderBook streams + Address PR comments.
Browse files Browse the repository at this point in the history
  • Loading branch information
gmax0 committed Mar 22, 2021
1 parent aadbf99 commit 80a47da
Show file tree
Hide file tree
Showing 14 changed files with 593 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,14 @@ public class CurrencyPair extends Instrument implements Comparable<CurrencyPair>
public static final CurrencyPair LINK_BTC = new CurrencyPair(Currency.LINK, Currency.BTC);
public static final CurrencyPair LINK_ETH = new CurrencyPair(Currency.LINK, Currency.ETH);

//dydx Exchange Spot and Perpetual Pairs
public static final CurrencyPair WETH_USDC = new CurrencyPair(Currency.WETH, Currency.USDC);
public static final CurrencyPair WETH_DAI = new CurrencyPair(Currency.WETH, Currency.DAI);
public static final CurrencyPair DAI_USDC = new CurrencyPair(Currency.DAI, Currency.USDC);
public static final CurrencyPair PBTC_USDC = new CurrencyPair(Currency.PBTC, Currency.USDC);
public static final CurrencyPair WETH_PUSD = new CurrencyPair(Currency.WETH, Currency.PUSD);
public static final CurrencyPair PLINK_USDC = new CurrencyPair(Currency.PLINK, Currency.USDC);

public final Currency base;

public final Currency counter;
Expand Down
2 changes: 1 addition & 1 deletion xchange-dydx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>xchange-parent</artifactId>
<groupId>org.knowm.xchange</groupId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
2 changes: 1 addition & 1 deletion xchange-stream-dydx/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>xchange-parent</artifactId>
<groupId>org.knowm.xchange</groupId>
<version>5.0.6-SNAPSHOT</version>
<version>5.0.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package info.bitrich.xchangestream.dydx.dto.v1;

import com.fasterxml.jackson.annotation.JsonProperty;
import info.bitrich.xchangestream.dydx.dto.dydxWebSocketTransaction;
import lombok.Getter;
import lombok.Setter;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.marketdata.OrderBook;
import org.knowm.xchange.dto.trade.LimitOrder;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;

import static info.bitrich.xchangestream.dydx.dydxStreamingAdapters.dydxOrderBookChanges;

/** Author: Max Gao ([email protected]) Created: 08-03-2021 */
public class dydxInitialOrderBookMessage extends dydxWebSocketTransaction {
@JsonProperty("contents")
private Contents contents;

@Getter
@Setter
public static class Contents {
@JsonProperty("offset")
private String offset;

@JsonProperty("bids")
private Order bids[];

@JsonProperty("asks")
private Order asks[];
}

@Getter
@Setter
public static class Order {
@JsonProperty("id")
private String id;

@JsonProperty("uuid")
private String uuid;

@JsonProperty("price")
private String price;

@JsonProperty("amount")
private String amount;
}

public OrderBook toOrderBook(
SortedMap<BigDecimal, BigDecimal> bids,
SortedMap<BigDecimal, BigDecimal> asks,
Map<String, String> bidIds,
Map<String, String> askIds,
int maxDepth,
CurrencyPair currencyPair) {
String[][] bidsData = null;
String[][] asksData = null;

if (this.contents.getBids() != null) {
bidsData =
Arrays.stream(this.contents.getBids())
.map(
b -> {
bidIds.put(b.id, b.price);
return new String[] {b.price, b.amount};
})
.toArray(String[][]::new);
}
if (this.contents.getAsks() != null) {
asksData =
Arrays.stream(this.contents.getAsks())
.map(
a -> {
askIds.put(a.id, a.price);
return new String[] {a.price, a.amount};
})
.toArray(String[][]::new);
}

List<LimitOrder> dydxBids =
dydxOrderBookChanges(
org.knowm.xchange.dto.Order.OrderType.BID,
currencyPair,
bidsData,
bids,
maxDepth,
true);

List<LimitOrder> dydxAsks =
dydxOrderBookChanges(
org.knowm.xchange.dto.Order.OrderType.ASK,
currencyPair,
asksData,
asks,
maxDepth,
true);

return new OrderBook(null, dydxBids, dydxAsks, false);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package info.bitrich.xchangestream.dydx.dto.v1;

import com.fasterxml.jackson.annotation.JsonProperty;
import info.bitrich.xchangestream.dydx.dto.dydxWebSocketTransaction;
import lombok.Getter;
import lombok.Setter;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.marketdata.OrderBook;
import org.knowm.xchange.dto.trade.LimitOrder;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.SortedMap;

import static info.bitrich.xchangestream.dydx.dydxStreamingAdapters.dydxOrderBookChanges;

/** Author: Max Gao ([email protected]) Created: 08-03-2021 */
public class dydxUpdateOrderBookMessage extends dydxWebSocketTransaction {
@JsonProperty("contents")
private Contents contents;

@Getter
@Setter
public static class Contents {
@JsonProperty("updates")
private Update updates[];
}

@Getter
@Setter
public static class Update {
@JsonProperty("type")
private String type;

@JsonProperty("id")
private String id;

@JsonProperty("side")
private String side;

@JsonProperty("amount")
private String amount;

@JsonProperty("price")
private String price;
}

private String[][] buildChangeData(String side, Map<String, String> idMap) {
return Arrays.stream(this.contents.getUpdates())
.filter(update -> (side).equals(update.side))
.map(
update -> {
switch (update.type) {
case "NEW":
idMap.put(update.id, update.price);
return new String[] {update.price, update.amount};
case "REMOVED":
String removedPriceLevel = idMap.get(update.id);
idMap.remove(update.id);
if (removedPriceLevel != null) {
return new String[] {removedPriceLevel, "0"};
} else {
return null; // Occasionally the websocket will return duplicate removal
// messages.
}
case "UPDATED":
return new String[] {update.price, update.amount};
default:
return null;
}
})
.filter(Objects::nonNull)
.toArray(String[][]::new);
}

public OrderBook toOrderBook(
SortedMap<BigDecimal, BigDecimal> bids,
SortedMap<BigDecimal, BigDecimal> asks,
Map<String, String> bidIds,
Map<String, String> askIds,
int maxDepth,
CurrencyPair currencyPair) {

String[][] bidsData = buildChangeData("BUY", bidIds);
String[][] asksData = buildChangeData("SELL", askIds);

List<LimitOrder> dydxBids =
dydxOrderBookChanges(
org.knowm.xchange.dto.Order.OrderType.BID,
currencyPair,
bidsData,
bids,
maxDepth,
true);

List<LimitOrder> dydxAsks =
dydxOrderBookChanges(
org.knowm.xchange.dto.Order.OrderType.ASK,
currencyPair,
asksData,
asks,
maxDepth,
true);

return new OrderBook(null, dydxAsks, dydxBids, false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,11 @@
import org.knowm.xchange.dto.trade.LimitOrder;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static info.bitrich.xchangestream.dydx.dydxStreamingAdapters.dydxOrderBookChanges;

/** Author: Max Gao ([email protected]) Created: 08-03-2021 */
@NoArgsConstructor
Expand Down Expand Up @@ -48,60 +47,44 @@ public static class Order {
private String size;
}

/** Adapted from coinbaseProOrderBookChanges */
protected List<LimitOrder> dydxOrderBookChanges(
org.knowm.xchange.dto.Order.OrderType orderType,
CurrencyPair currencyPair,
Order[] orders,
SortedMap<BigDecimal, BigDecimal> sideEntries,
int maxDepth) {

if (sideEntries == null) {
return Collections.emptyList();
}

for (Order order : orders) {
BigDecimal price = new BigDecimal(order.price);
BigDecimal volume = new BigDecimal(order.size);
sideEntries.put(price, volume);
}

Stream<Map.Entry<BigDecimal, BigDecimal>> stream =
sideEntries.entrySet().stream()
.filter(level -> level.getValue().compareTo(BigDecimal.ZERO) != 0);

if (maxDepth != 0) {
stream = stream.limit(maxDepth);
}

return stream
.map(
level ->
new LimitOrder(
orderType, level.getValue(), currencyPair, "0", null, level.getKey()))
.collect(Collectors.toList());
}

public OrderBook toOrderBook(
SortedMap<BigDecimal, BigDecimal> bids,
SortedMap<BigDecimal, BigDecimal> asks,
int maxDepth,
CurrencyPair currencyPair) {
String[][] bidsData = null;
String[][] asksData = null;

if (this.contents.getBids() != null) {
bidsData =
Arrays.stream(this.contents.getBids())
.map(b -> new String[] {b.price, b.size})
.toArray(String[][]::new);
}
if (this.contents.getAsks() != null) {
asksData =
Arrays.stream(this.contents.getAsks())
.map(a -> new String[] {a.price, a.size})
.toArray(String[][]::new);
}

List<LimitOrder> dydxBids =
dydxOrderBookChanges(
org.knowm.xchange.dto.Order.OrderType.BID,
currencyPair,
this.contents.getBids() != null ? this.contents.getBids() : null,
bidsData,
bids,
maxDepth);
maxDepth,
false);

List<LimitOrder> dydxAsks =
dydxOrderBookChanges(
org.knowm.xchange.dto.Order.OrderType.ASK,
currencyPair,
this.contents.getAsks() != null ? this.contents.getAsks() : null,
asksData,
asks,
maxDepth);
maxDepth,
false);

return new OrderBook(null, dydxBids, dydxAsks, false);
}
Expand Down
Loading

0 comments on commit 80a47da

Please sign in to comment.