View Javadoc
1   package org.oxerr.okcoin.fix;
2   
3   import java.math.BigDecimal;
4   
5   import org.oxerr.okcoin.fix.fix44.AccountInfoRequest;
6   import org.oxerr.okcoin.fix.fix44.AccountInfoResponse;
7   import org.oxerr.okcoin.fix.fix44.ExceptionResponseMessage;
8   import org.oxerr.okcoin.fix.fix44.OrdersInfoAfterSomeIDRequest;
9   import org.slf4j.Logger;
10  import org.slf4j.LoggerFactory;
11  
12  import quickfix.Application;
13  import quickfix.ConfigError;
14  import quickfix.DataDictionary;
15  import quickfix.DoNotSend;
16  import quickfix.FieldNotFound;
17  import quickfix.IncorrectDataFormat;
18  import quickfix.IncorrectTagValue;
19  import quickfix.Message;
20  import quickfix.RejectLogon;
21  import quickfix.Session;
22  import quickfix.SessionID;
23  import quickfix.UnsupportedMessageType;
24  import quickfix.field.MsgType;
25  import quickfix.field.Password;
26  import quickfix.field.Username;
27  import quickfix.fix44.ExecutionReport;
28  import quickfix.fix44.MarketDataRequest;
29  import quickfix.fix44.MessageCracker;
30  import quickfix.fix44.NewOrderSingle;
31  import quickfix.fix44.OrderCancelRequest;
32  import quickfix.fix44.OrderMassStatusRequest;
33  import quickfix.fix44.TradeCaptureReportRequest;
34  
35  /**
36   * {@link Application} implementation.
37   */
38  public class OKCoinApplication extends MessageCracker implements Application {
39  
40  	private final Logger log = LoggerFactory.getLogger(OKCoinApplication.class);
41  	private final DataDictionary dataDictionary;
42  	private final MarketDataRequestCreator marketDataRequestCreator;
43  	private final TradeRequestCreator tradeRequestCreator;
44  	private final String apiKey;
45  	private final String secretKey;
46  
47  	public OKCoinApplication(String apiKey, String secretKey) {
48  		this.apiKey = apiKey;
49  		this.secretKey = secretKey;
50  		this.marketDataRequestCreator = new MarketDataRequestCreator();
51  		this.tradeRequestCreator = new TradeRequestCreator(apiKey, secretKey);
52  
53  		try {
54  			dataDictionary = new DataDictionary("org/oxerr/okcoin/fix/FIX44.xml");
55  		} catch (ConfigError e) {
56  			throw new RuntimeException(e);
57  		}
58  	}
59  
60  	public DataDictionary getDataDictionary() {
61  		return dataDictionary;
62  	}
63  
64  	/**
65  	 * {@inheritDoc}
66  	 */
67  	@Override
68  	public void onCreate(SessionID sessionId) {
69  	}
70  
71  	/**
72  	 * {@inheritDoc}
73  	 */
74  	@Override
75  	public void onLogon(SessionID sessionId) {
76  	}
77  
78  	/**
79  	 * {@inheritDoc}
80  	 */
81  	@Override
82  	public void onLogout(SessionID sessionId) {
83  	}
84  
85  	/**
86  	 * {@inheritDoc}
87  	 */
88  	@Override
89  	public void toAdmin(Message message, SessionID sessionId) {
90  		String msgType;
91  		try {
92  			msgType = message.getHeader().getString(MsgType.FIELD);
93  		} catch (FieldNotFound e) {
94  			throw new RuntimeException(e.getMessage(), e);
95  		}
96  
97  		if (MsgType.LOGON.equals(msgType) || MsgType.HEARTBEAT.equals(msgType)) {
98  			message.setField(new Username(apiKey));
99  			message.setField(new Password(secretKey));
100 		}
101 
102 		if (log.isTraceEnabled()) {
103 			log.trace("toAdmin: {}", message);
104 			log.trace("toAdmin: {}", message.toXML(dataDictionary));
105 		}
106 	}
107 
108 	/**
109 	 * {@inheritDoc}
110 	 */
111 	@Override
112 	public void fromAdmin(Message message, SessionID sessionId)
113 			throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue,
114 			RejectLogon {
115 		if (log.isTraceEnabled()) {
116 			log.trace("fromAdmin: {}", message);
117 			log.trace("fromAdmin: {}", message.toXML(dataDictionary));
118 		}
119 	}
120 
121 	/**
122 	 * {@inheritDoc}
123 	 */
124 	@Override
125 	public void toApp(Message message, SessionID sessionId) throws DoNotSend {
126 		if (log.isTraceEnabled()) {
127 			log.trace("toApp: {}", message);
128 			log.trace("toApp: {}", message.toXML(dataDictionary));
129 		}
130 	}
131 
132 	/**
133 	 * {@inheritDoc}
134 	 */
135 	@Override
136 	public void fromApp(Message message, SessionID sessionId)
137 			throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue,
138 			UnsupportedMessageType {
139 		if (log.isTraceEnabled()) {
140 			log.trace("fromApp: {}", message);
141 			log.trace("fromApp: {}", message.toXML(dataDictionary));
142 		}
143 		crack(message, sessionId);
144 	}
145 
146 	@Override
147 	public void crack(quickfix.Message message, SessionID sessionId)
148 			throws UnsupportedMessageType, FieldNotFound, IncorrectTagValue {
149 		if (message instanceof AccountInfoResponse) {
150 			onMessage((AccountInfoResponse) message, sessionId);
151 		} else if (message instanceof ExceptionResponseMessage) {
152 			onMessage((ExceptionResponseMessage) message, sessionId);
153 		} else {
154 			super.crack(message, sessionId);
155 		}
156 	}
157 
158 	@Override
159 	public void onMessage(ExecutionReport message, SessionID sessionId)
160 			throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
161 	}
162 
163 	public void onMessage(AccountInfoResponse message, SessionID sessionId)
164 			throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
165 	}
166 
167 	public void onMessage(ExceptionResponseMessage message, SessionID sessionId)
168 			throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue {
169 	}
170 
171 	public void sendMessage(final Message message, final SessionID sessionId) {
172 		log.trace("sending message: {}", message);
173 		Session.lookupSession(sessionId).send(message);
174 	}
175 
176 	public void requestMarketData(
177 			String mdReqId,
178 			String symbol,
179 			char subscriptionRequestType,
180 			int marketDepth,
181 			int mdUpdateType,
182 			char[] mdEntryTypes,
183 			SessionID sessionId) {
184 		MarketDataRequest message = marketDataRequestCreator.createMarketDataRequest(
185 				mdReqId, symbol, subscriptionRequestType, marketDepth,
186 				mdUpdateType, mdEntryTypes);
187 		sendMessage(message, sessionId);
188 	}
189 
190 	/**
191 	 *
192 	 * @param mdReqId Unique ID assigned to this request.
193 	 * @param symbol Symbol, BTC/CNY or LTC/CNY.
194 	 * @param subscriptionRequestType 0 = Snapshot, 1 = Snapshot + Subscribe,
195 	 * 2 = Unsubscribe.
196 	 * @param marketDepth Applicable only to order book snapshot requests.
197 	 * Should be ignored otherwise.
198 	 * 0 = Full Book
199 	 * @param mdUpdateType 0 = Full Refresh, 1 = Incremental Refresh.
200 	 * @param sessionId FIX session ID.
201 	 */
202 	public void requestOrderBook(
203 			String mdReqId,
204 			String symbol,
205 			char subscriptionRequestType,
206 			int marketDepth,
207 			int mdUpdateType,
208 			SessionID sessionId) {
209 		MarketDataRequest message = marketDataRequestCreator.createOrderBookRequest(
210 				mdReqId,
211 				symbol,
212 				subscriptionRequestType,
213 				marketDepth,
214 				mdUpdateType);
215 		sendMessage(message, sessionId);
216 	}
217 
218 	public void requestLiveTrades(
219 			String mdReqId,
220 			String symbol,
221 			SessionID sessionId) {
222 		MarketDataRequest message = marketDataRequestCreator.createLiveTradesRequest(
223 				mdReqId,
224 				symbol);
225 		sendMessage(message, sessionId);
226 	}
227 
228 	public void request24HTicker(
229 			String mdReqId,
230 			String symbol,
231 			SessionID sessionId
232 			) {
233 		MarketDataRequest message = marketDataRequestCreator.create24HTickerRequest(
234 				mdReqId, symbol);
235 		sendMessage(message, sessionId);
236 	}
237 
238 	public void placeOrder(
239 			String clOrdId,
240 			char side,
241 			char ordType,
242 			BigDecimal orderQty,
243 			BigDecimal price,
244 			String symbol,
245 			SessionID sessionId) {
246 		NewOrderSingle message = tradeRequestCreator.createNewOrderSingle(
247 				clOrdId, side, ordType, orderQty, price, symbol);
248 		sendMessage(message, sessionId);
249 	}
250 
251 	public void cancelOrder(
252 			String clOrdId,
253 			String origClOrdId,
254 			char side,
255 			String symbol,
256 			SessionID sessionId) {
257 		OrderCancelRequest message = tradeRequestCreator.createOrderCancelRequest(
258 				clOrdId, origClOrdId, side, symbol);
259 		sendMessage(message, sessionId);
260 	}
261 
262 	/**
263 	 * Request order status.
264 	 *
265 	 * @param massStatusReqId Client-assigned unique ID of this request.(or ORDERID)
266 	 * @param massStatusReqType Specifies the scope of the mass status request.
267 	 * 1 = status of a specified order(Tag584 is ORDERID)
268 	 * 7 = Status for all orders
269 	 * @param sessionId the FIX session ID.
270 	 */
271 	public void requestOrderMassStatus(
272 			String massStatusReqId,
273 			int massStatusReqType,
274 			SessionID sessionId) {
275 		OrderMassStatusRequest message = tradeRequestCreator.createOrderMassStatusRequest(
276 				massStatusReqId, massStatusReqType);
277 		sendMessage(message, sessionId);
278 	}
279 
280 	public void requestTradeCaptureReportRequest(
281 			String tradeRequestId,
282 			String symbol,
283 			SessionID sessionId) {
284 		TradeCaptureReportRequest message = tradeRequestCreator
285 				.createTradeCaptureReportRequest(tradeRequestId, symbol);
286 		sendMessage(message, sessionId);
287 	}
288 
289 	public void requestAccountInfo(String accReqId, SessionID sessionId) {
290 		AccountInfoRequest message = tradeRequestCreator.createAccountInfoRequest(
291 				accReqId);
292 		sendMessage(message, sessionId);
293 	}
294 
295 	/**
296 	 * Request history order information which order ID is after the specified
297 	 * {@code orderId}.
298 	 *
299 	 * @param tradeRequestId Client-assigned unique ID of this request.
300 	 * @param symbol Symbol. BTC/CNY or LTC/CNY.
301 	 * @param orderId Order ID. Return 10 records after this id.
302 	 * @param ordStatus Order status. 0 = Not filled 1 = Fully filled.
303 	 * @param sessionId the FIX session ID.
304 	 */
305 	public void requestOrdersInfoAfterSomeID(
306 			String tradeRequestId,
307 			String symbol,
308 			long orderId,
309 			char ordStatus,
310 			SessionID sessionId) {
311 		OrdersInfoAfterSomeIDRequest message = tradeRequestCreator.createOrdersInfoAfterSomeIDRequest(
312 				tradeRequestId, symbol, orderId, ordStatus);
313 		sendMessage(message, sessionId);
314 	}
315 
316 }