View Javadoc
1   package org.oxerr.okcoin.examples.fix;
2   
3   import java.io.IOException;
4   import java.io.InputStream;
5   import java.util.List;
6   import java.util.UUID;
7   import java.util.concurrent.TimeUnit;
8   
9   import org.knowm.xchange.currency.CurrencyPair;
10  import org.knowm.xchange.dto.account.AccountInfo;
11  import org.knowm.xchange.dto.marketdata.OrderBook;
12  import org.knowm.xchange.dto.marketdata.Trade;
13  import org.knowm.xchange.dto.trade.LimitOrder;
14  import org.oxerr.okcoin.fix.fix44.ExceptionResponseMessage;
15  import org.oxerr.okcoin.fix.fix44.OKCoinMessageFactory;
16  import org.oxerr.okcoin.xchange.service.fix.OKCoinXChangeApplication;
17  import org.slf4j.Logger;
18  import org.slf4j.LoggerFactory;
19  
20  import quickfix.ConfigError;
21  import quickfix.FieldNotFound;
22  import quickfix.FileLogFactory;
23  import quickfix.FileStoreFactory;
24  import quickfix.IncorrectTagValue;
25  import quickfix.Initiator;
26  import quickfix.LogFactory;
27  import quickfix.MessageFactory;
28  import quickfix.MessageStoreFactory;
29  import quickfix.SessionID;
30  import quickfix.SessionSettings;
31  import quickfix.SocketInitiator;
32  import quickfix.UnsupportedMessageType;
33  import quickfix.field.MassStatusReqType;
34  import quickfix.fix44.ExecutionReport;
35  
36  /**
37   * Demonstration of FIX API.
38   */
39  public class Client {
40  
41  	private static final Logger log = LoggerFactory.getLogger(Client.class);
42  
43  	private final OKCoinXChangeApplication app;
44  	private final SessionID sessionId;
45  	private final Initiator initiator;
46  
47  	public Client(String apiKey, String secretKey) throws IOException,
48  			ConfigError, InterruptedException {
49  		app = new OKCoinXChangeApplication(apiKey, secretKey) {
50  
51  			@Override
52  			public void onLogon(SessionID sessionId) {
53  				super.onLogon(sessionId);
54  
55  				String massStatusReqId = UUID.randomUUID().toString();
56  				this.requestOrderMassStatus(massStatusReqId, MassStatusReqType.STATUS_FOR_ALL_ORDERS, sessionId);
57  			}
58  
59  			@Override
60  			public void onOrderBook(OrderBook orderBook, SessionID sessionId) {
61  				log.info("asks: {}, bids: {}", orderBook.getAsks().size(), orderBook.getBids().size());
62  
63  				// bids should be sorted by limit price descending
64  				LimitOrder preOrder = null;
65  				for (LimitOrder order : orderBook.getBids()) {
66  					log.info("Bid: {}, {}", order.getLimitPrice(), order.getTradableAmount());
67  
68  					if (preOrder != null && preOrder.compareTo(order) >= 0) {
69  						log.error("bids should be sorted by limit price descending");
70  					}
71  					preOrder = order;
72  				}
73  
74  				// asks should be sorted by limit price ascending
75  				preOrder = null;
76  				for (LimitOrder order : orderBook.getAsks()) {
77  					log.info("Ask: {}, {}", order.getLimitPrice(), order.getTradableAmount());
78  
79  					if (preOrder != null && preOrder.compareTo(order) >= 0) {
80  						log.error("asks should be sorted by limit price ascending");
81  					}
82  					preOrder = order;
83  				}
84  
85  				LimitOrder ask = orderBook.getAsks().get(0);
86  				LimitOrder bid = orderBook.getBids().get(0);
87  				log.info("lowest  ask: {}, {}", ask.getLimitPrice(), ask.getTradableAmount());
88  				log.info("highest bid: {}, {}", bid.getLimitPrice(), bid.getTradableAmount());
89  
90  				if (ask.getLimitPrice().compareTo(bid.getLimitPrice()) <= 0) {
91  					throw new IllegalStateException(String.format("Lowest ask %s is not higher than the highest bid %s.",
92  							ask.getLimitPrice(), bid.getLimitPrice()));
93  				}
94  			}
95  
96  			@Override
97  			public void onTrades(List<Trade> trades, SessionID sessionId) {
98  				for (Trade trade : trades) {
99  					log.info("{}", trade);
100 				}
101 			}
102 
103 			@Override
104 			public void onAccountInfo(AccountInfo accountInfo,
105 					SessionID sessionId) {
106 				log.info("AccountInfo: {}", accountInfo);
107 			}
108 
109 			@Override
110 			public void onMessage(ExecutionReport message, SessionID sessionId)
111 					throws FieldNotFound, UnsupportedMessageType,
112 					IncorrectTagValue {
113 				log.info(message.toXML(getDataDictionary()));
114 			}
115 
116 			@Override
117 			public void onMessage(ExceptionResponseMessage message,
118 					SessionID sessionId) throws FieldNotFound,
119 							UnsupportedMessageType, IncorrectTagValue {
120 				log.error(message.toXML(getDataDictionary()));
121 			}
122 
123 		};
124 
125 		SessionSettings settings;
126 		try (InputStream inputStream = getClass().getResourceAsStream("client.cfg")) {
127 			settings = new SessionSettings(inputStream);
128 		}
129 
130 		MessageStoreFactory storeFactory = new FileStoreFactory(settings);
131 		LogFactory logFactory = new FileLogFactory(settings);
132 		MessageFactory messageFactory = new OKCoinMessageFactory();
133 		initiator = new SocketInitiator(app, storeFactory, settings,
134 				logFactory, messageFactory);
135 		initiator.start();
136 
137 		while (!initiator.isLoggedOn()) {
138 			log.info("Waiting for logged on...");
139 			TimeUnit.SECONDS.sleep(1);
140 		}
141 
142 		sessionId = initiator.getSessions().get(0);
143 	}
144 
145 	public void demo() {
146 		String mdReqId = UUID.randomUUID().toString();
147 		String symbol = "BTC/CNY";
148 		app.subscribeOrderBook(CurrencyPair.BTC_CNY, sessionId);
149 
150 		mdReqId = UUID.randomUUID().toString();
151 		app.requestLiveTrades(mdReqId, symbol, sessionId);
152 
153 		mdReqId = UUID.randomUUID().toString();
154 		app.request24HTicker(mdReqId, symbol, sessionId);
155 
156 		String accReqId = UUID.randomUUID().toString();
157 		app.requestAccountInfo(accReqId, sessionId);
158 
159 		String tradeRequestId = UUID.randomUUID().toString();
160 		long orderId = 1;
161 		char ordStatus = '0';
162 		app.requestOrdersInfoAfterSomeID(tradeRequestId, symbol, orderId, ordStatus, sessionId);
163 
164 		// to check order id > Integer.MAX_VALUE
165 		app.requestOrderMassStatus("2147488076",
166 				MassStatusReqType.STATUS_FOR_ORDERS_FOR_A_SECURITY, sessionId);
167 
168 	}
169 
170 	public static void main(String[] args) throws IOException, ConfigError,
171 			InterruptedException {
172 		String apiKey = args[0], secretKey = args[1];
173 		Client client = new Client(apiKey, secretKey);
174 		client.demo();
175 
176 		log.info("Waiting a moment and exiting.");
177 		TimeUnit.SECONDS.sleep(30);
178 		client.initiator.stop();
179 	}
180 
181 }