6
6
import info .bitrich .xchangestream .bitfinex .dto .BitfinexWebSocketAuthOrder ;
7
7
import info .bitrich .xchangestream .bitfinex .dto .BitfinexWebSocketAuthPreTrade ;
8
8
import info .bitrich .xchangestream .bitfinex .dto .BitfinexWebSocketAuthTrade ;
9
- import info .bitrich .xchangestream .core .OrderStatusChange ;
10
- import info .bitrich .xchangestream .core .OrderStatusChangeType ;
11
-
12
- import io .reactivex .annotations .Nullable ;
13
9
14
10
import io .reactivex .annotations .Nullable ;
15
11
12
+ import org .knowm .xchange .bitfinex .v1 .BitfinexAdapters ;
13
+ import org .knowm .xchange .bitfinex .v1 .BitfinexOrderType ;
14
+ import org .knowm .xchange .bitfinex .v1 .dto .trade .BitfinexOrderStatusResponse ;
15
+ import org .knowm .xchange .currency .Currency ;
16
+ import org .knowm .xchange .dto .Order ;
17
+ import org .knowm .xchange .dto .Order .OrderType ;
18
+ import org .knowm .xchange .dto .trade .OpenOrders ;
19
+ import org .knowm .xchange .dto .trade .UserTrade ;
20
+ import org .knowm .xchange .utils .DateUtils ;
16
21
import org .slf4j .Logger ;
17
22
import org .slf4j .LoggerFactory ;
18
23
19
24
import java .math .BigDecimal ;
20
- import java .util .Date ;
21
25
import java .util .stream .Stream ;
22
26
23
27
import static java .util .stream .StreamSupport .stream ;
@@ -26,6 +30,9 @@ class BitfinexStreamingAdapters {
26
30
27
31
private static final Logger LOG = LoggerFactory .getLogger (BitfinexStreamingAdapters .class );
28
32
33
+ private static final BigDecimal THOUSAND = new BigDecimal (1000 );
34
+
35
+
29
36
@ Nullable
30
37
static BitfinexWebSocketAuthPreTrade adaptPreTrade (JsonNode preTrade ) {
31
38
if (preTrade .size () < 12 ) {
@@ -155,25 +162,77 @@ static private BitfinexWebSocketAuthOrder createOrderObject(JsonNode order) {
155
162
);
156
163
}
157
164
158
- @ Nullable
159
- static OrderStatusChange adaptOrderStatus (BitfinexWebSocketAuthOrder authOrder ) {
160
- OrderStatusChangeType status = adaptOrderStatusType (authOrder .getOrderStatus ());
161
- if (status == null )
162
- return OrderStatusChange .create ().build ();
163
- return OrderStatusChange .create ()
164
- .type (status )
165
- .timestamp (new Date ())
166
- .orderId (Long .toString (authOrder .getId ()))
167
- .build ();
165
+ private static BitfinexOrderType adaptV2OrderTypeToV1 (String orderType ) {
166
+ switch (orderType ) {
167
+ case "LIMIT" : return BitfinexOrderType .MARGIN_LIMIT ;
168
+ case "MARKET" : return BitfinexOrderType .MARGIN_MARKET ;
169
+ case "STOP" : return BitfinexOrderType .MARGIN_STOP ;
170
+ case "TRAILING STOP" : return BitfinexOrderType .MARGIN_TRAILING_STOP ;
171
+ case "EXCHANGE MARKET" : return BitfinexOrderType .MARKET ;
172
+ case "EXCHANGE LIMIT" : return BitfinexOrderType .LIMIT ;
173
+ case "EXCHANGE STOP" : return BitfinexOrderType .STOP ;
174
+ case "EXCHANGE TRAILING STOP" : return BitfinexOrderType .TRAILING_STOP ;
175
+ case "FOK" : return BitfinexOrderType .MARGIN_FILL_OR_KILL ;
176
+ case "EXCHANGE FOK" : return BitfinexOrderType .FILL_OR_KILL ;
177
+ default : return BitfinexOrderType .LIMIT ; // Safe fallback
178
+ }
168
179
}
169
180
170
- @ Nullable
171
- private static OrderStatusChangeType adaptOrderStatusType (String orderStatus ) {
172
- switch (orderStatus ) {
173
- case "ACTIVE" : return OrderStatusChangeType .OPENED ;
174
- case "EXECUTED" : return OrderStatusChangeType .CLOSED ;
175
- case "CANCELED" : return OrderStatusChangeType .CLOSED ;
176
- default : return null ;
181
+ private static String adaptV2SymbolToV1 (String symbol ) {
182
+ return symbol .substring (1 );
183
+ }
184
+
185
+ /**
186
+ * We adapt the websocket message to what we expect from the V1 REST API, so that
187
+ * we don't re-implement the complex logic which works out whether we need
188
+ * limit orders, stop orders, market orders etc.
189
+ */
190
+ private static BitfinexOrderStatusResponse adaptOrderToRestResponse (BitfinexWebSocketAuthOrder authOrder ) {
191
+ int signum = authOrder .getAmountOrig ().signum ();
192
+ return new BitfinexOrderStatusResponse (
193
+ authOrder .getId (),
194
+ adaptV2SymbolToV1 (authOrder .getSymbol ()),
195
+ authOrder .getPrice (),
196
+ authOrder .getPriceAvg (),
197
+ signum > 0 ? "buy" : "sell" ,
198
+ adaptV2OrderTypeToV1 (authOrder .getType ()).getValue (),
199
+ new BigDecimal (authOrder .getMtsCreate ()).divide (THOUSAND ),
200
+ "ACTIVE" .equals (authOrder .getOrderStatus ()),
201
+ "CANCELED" .equals (authOrder .getOrderStatus ()),
202
+ false , //wasForced,
203
+ signum >= 0 ? authOrder .getAmountOrig () : authOrder .getAmountOrig ().negate (),
204
+ signum >= 0 ? authOrder .getAmount () : authOrder .getAmount ().negate (),
205
+ signum >= 0
206
+ ? authOrder .getAmountOrig ().subtract (authOrder .getAmount ())
207
+ : authOrder .getAmountOrig ().subtract (authOrder .getAmount ()).negate ()
208
+ );
209
+ }
210
+
211
+ static Order adaptOrder (BitfinexWebSocketAuthOrder authOrder ) {
212
+ BitfinexOrderStatusResponse [] orderStatus = { adaptOrderToRestResponse (authOrder )};
213
+ OpenOrders orders = BitfinexAdapters .adaptOrders (orderStatus );
214
+ if (orders .getOpenOrders ().isEmpty ()) {
215
+ if (orders .getHiddenOrders ().isEmpty ()) {
216
+ throw new IllegalStateException ("No order in message" );
217
+ }
218
+ return orders .getHiddenOrders ().get (0 );
177
219
}
220
+ return orders .getOpenOrders ().get (0 );
221
+ }
222
+
223
+ static UserTrade adaptUserTrade (BitfinexWebSocketAuthTrade authTrade ) {
224
+ return new UserTrade .Builder ()
225
+ .currencyPair (BitfinexAdapters .adaptCurrencyPair (adaptV2SymbolToV1 (authTrade .getPair ())))
226
+ .feeAmount (authTrade .getFee ())
227
+ .feeCurrency (Currency .getInstance (authTrade .getFeeCurrency ()))
228
+ .id (Long .toString (authTrade .getId ()))
229
+ .orderId (Long .toString (authTrade .getOrderId ()))
230
+ .originalAmount (authTrade .getExecAmount ())
231
+ .price (authTrade .getExecPrice ())
232
+ .timestamp (DateUtils .fromMillisUtc (authTrade .getMtsCreate ()))
233
+ .type (authTrade .getOrderType ().equalsIgnoreCase ("buy" )
234
+ ? OrderType .BID
235
+ : OrderType .ASK )
236
+ .build ();
178
237
}
179
238
}
0 commit comments