1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package net.sf.emarket.trade.service;
21
22 import java.util.ArrayList;
23 import java.util.List;
24
25 import net.sf.emarket.account.service.NotEnoughCashException;
26 import net.sf.emarket.account.service.NotEnoughPositionsException;
27 import net.sf.emarket.account.service.NotValidAccountException;
28 import net.sf.emarket.order.domain.Order;
29 import net.sf.emarket.order.service.IOrderManagerService;
30 import net.sf.emarket.order.service.OrderCannotBeFilledException;
31 import net.sf.emarket.order.service.OrderFillQuantityMismatchException;
32 import net.sf.emarket.quote.service.IQuoteManagerService;
33 import net.sf.emarket.trade.domain.MarketDepth;
34 import net.sf.emarket.trade.domain.OrderBook;
35 import net.sf.emarket.trade.domain.OrderBookLock;
36 import net.sf.emarket.trade.domain.OrderFill;
37 import net.sf.emarket.trade.domain.OrderMatch;
38 import net.sf.emarket.trade.domain.ReceivedOrder;
39 import net.sf.emarket.trade.repository.IOrderBookDao;
40 import net.sf.emarket.trade.repository.IOrderBookLockDao;
41 import net.sf.emarket.trade.repository.IOrderMatchDao;
42 import net.sf.emarket.trade.repository.IReceivedOrdersDao;
43
44 import org.springframework.beans.factory.annotation.Autowired;
45 import org.springframework.dao.EmptyResultDataAccessException;
46 import org.springframework.transaction.annotation.Propagation;
47 import org.springframework.transaction.annotation.Transactional;
48
49 class TradingServiceImpl implements ITradingService {
50
51 private static final long serialVersionUID = 499772084600054782L;
52
53 IReceivedOrdersDao receivedOrderDao = null;
54 IOrderBookDao orderBookDao = null;
55 IOrderBookLockDao orderBookLockDao = null;
56 IOrderMatchDao orderMatchDao = null;
57
58 IQuoteManagerService quoteSvc = null;
59 IOrderManagerService orderSvc = null;
60
61 @Autowired
62 public void setReceivedOrderDao( IReceivedOrdersDao dao){
63 receivedOrderDao = dao;
64 }
65
66 @Autowired
67 public void setOrderBookDao( IOrderBookDao dao){
68 orderBookDao = dao;
69 }
70
71 @Autowired
72 public void setOrderBookLockDao( IOrderBookLockDao dao){
73 orderBookLockDao = dao;
74 }
75
76 @Autowired
77 public void setOrderMatchDao( IOrderMatchDao dao){
78 orderMatchDao = dao;
79 }
80
81 @Autowired
82 public void setQuoteManagerService( IQuoteManagerService svc ){
83 quoteSvc = svc;
84 }
85
86 @Autowired
87 public void setOrderManagerService( IOrderManagerService svc ){
88 orderSvc = svc;
89 }
90
91 public ReceivedOrder getReceivedOrderById( String orderId ){
92
93 ReceivedOrder receivedOrder=null;
94
95 try{
96 receivedOrder = receivedOrderDao.getReceivedOrder(orderId);
97 }catch(EmptyResultDataAccessException dae ){
98 receivedOrder = new ReceivedOrder();
99 receivedOrder.setProcessingStatus(ReceivedOrder.PROCESSING_STATUS_NOT_RECEIVED);
100 }
101
102 return receivedOrder;
103 }
104
105 public void addReceivedOrder( ReceivedOrder order){
106 receivedOrderDao.addOrder(order);
107 }
108
109 public OrderBookLock getOrderBookLockStatus(String symbol){
110
111 OrderBookLock lock = null;
112
113 try{
114 lock = orderBookLockDao.getLock(symbol);
115 }catch( EmptyResultDataAccessException dae ){
116 lock = new OrderBookLock();
117 lock.setSymbol(symbol);
118 lock.setStatus( OrderBookLock.UN_LOCKED);
119 }
120
121 return lock;
122 }
123
124 public OrderBookLock lockOrderBook( String symbol){
125 OrderBookLock lock = null;
126
127 try{
128
129 lock = orderBookLockDao.getLock(symbol);
130
131 }catch(EmptyResultDataAccessException dae ){
132 lock = new OrderBookLock();
133 lock.setSymbol(symbol);
134 lock.setStatus( OrderBookLock.LOCKED);
135 orderBookLockDao.addLock(lock);
136 }
137
138 if( lock.getSymbol().equals(symbol) &&
139 lock.getStatus().equals( OrderBookLock.UN_LOCKED)){
140
141 lock.setStatus(OrderBookLock.LOCKED);
142 orderBookLockDao.updateLock(lock);
143 }else if( lock.getSymbol().equals(symbol) &&
144 lock.getStatus().equals( OrderBookLock.UN_LOCKED)){
145
146 }
147
148 return lock;
149 }
150
151
152 public void releaseOrderBook(String symbol){
153
154 OrderBookLock lock = null;
155
156 try{
157
158 lock = orderBookLockDao.getLock(symbol);
159 lock.setStatus(OrderBookLock.UN_LOCKED);
160
161 orderBookLockDao.updateLock(lock);
162
163 }catch( EmptyResultDataAccessException dae ){
164 lock = new OrderBookLock();
165 lock.setSymbol(symbol);
166 lock.setStatus( OrderBookLock.UN_LOCKED);
167 orderBookLockDao.addLock(lock);
168 }
169 }
170
171 public OrderBook getOrderBook(String symbol){
172 OrderBook book = new OrderBook(symbol);
173
174 List<ReceivedOrder> orders = getOrdersFromBook(symbol);
175 book.loadOrders(orders);
176
177 return book;
178 }
179
180
181 public List<ReceivedOrder> getOrdersFromBook( String symbol ){
182 return orderBookDao.getOrdersBySymbol(symbol);
183 }
184
185 public void updateOrderBook( ReceivedOrder order ){
186
187 try{
188
189 ReceivedOrder o = orderBookDao.getOrderById(order.getId());
190
191 if( o.getId().equalsIgnoreCase(order.getId())){
192
193 }
194
195 }catch( EmptyResultDataAccessException dae ){
196
197 orderBookDao.addOrder(order);
198 }
199
200
201
202
203
204
205
206
207
208 }
209
210 @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
211 public void updateOrderBook( ReceivedOrder receivedOrder, List<OrderMatch> matches, int matchedQuantity ){
212
213
214 int remainingQuantity = receivedOrder.getQuantity() - matchedQuantity;
215 if( remainingQuantity >0 ){
216 receivedOrder.setQuantity(remainingQuantity);
217 orderBookDao.updateOrder(receivedOrder);
218 }else if( remainingQuantity == 0 ){
219 orderBookDao.deleteOrder(receivedOrder);
220 }
221
222 for( OrderMatch match : matches ){
223
224 ReceivedOrder order =null;
225
226 if( receivedOrder.isBuy() ){
227
228
229 order = orderBookDao.getOrderById(match.getSellOrderId());
230 if(match.getSellMatchType().equals(OrderMatch.TYPE_FULL)){
231 orderBookDao.deleteOrder(order);
232 }else if( match.getSellMatchType().equals(OrderMatch.TYPE_PARTIAL) ){
233
234 int remaining = order.getQuantity() - match.getMatchedQuantity();
235 order.setQuantity(remaining);
236 orderBookDao.updateOrder(order);
237 }
238
239 }else if( receivedOrder.isSell()){
240
241
242 order = orderBookDao.getOrderById( match.getBuyOrderId());
243 if( match.getBuyMatchType().equals(OrderMatch.TYPE_FULL) ){
244 orderBookDao.deleteOrder(order);
245 }else if( match.getBuyMatchType().equals(OrderMatch.TYPE_PARTIAL) ){
246
247 int remaining = order.getQuantity() - match.getMatchedQuantity();
248 order.setQuantity(remaining);
249 orderBookDao.updateOrder(order);
250 }
251 }
252 }
253 }
254
255 /***
256 * store the order matches
257 * @param matches
258 */
259 public List<OrderFill> createOrderFills( List<OrderMatch> matches){
260
261 List<OrderFill> fills = new ArrayList<OrderFill>();
262
263 for( OrderMatch match : matches ){
264
265 long orderMatchId = orderMatchDao.generateOrderMatchId();
266 match.setId(orderMatchId);
267 orderMatchDao.addOrderMatch(match);
268
269
270
271 OrderFill buyFill = new OrderFill();
272
273 buyFill.setId(match.getBuyFillId());
274 buyFill.setOrderId(match.getBuyOrderId());
275 buyFill.setMatchId(match.getId());
276 buyFill.setSymbol(match.getSymbol());
277 buyFill.setMatchPrice(match.getMatchPrice());
278 buyFill.setMatchedQuantity(match.getMatchedQuantity());
279 buyFill.setMatchType(match.getBuyMatchType());
280 buyFill.setOrderType(Order.TYPE_BUY);
281
282 buyFill.setMatchTime(match.getMatchTime());
283
284 OrderFill sellFill = new OrderFill();
285
286 sellFill.setId( match.getSellFillId());
287 sellFill.setOrderId(match.getSellOrderId());
288 sellFill.setMatchId(match.getId());
289 sellFill.setSymbol(match.getSymbol());
290 sellFill.setMatchPrice(match.getMatchPrice());
291 sellFill.setMatchedQuantity(match.getMatchedQuantity());
292 sellFill.setMatchType(match.getSellMatchType());
293 sellFill.setMatchTime(match.getMatchTime());
294 sellFill.setOrderType(Order.TYPE_SELL);
295
296 fills.add(buyFill);
297 fills.add(sellFill);
298 }
299
300 return fills;
301 }
302
303 @Transactional(propagation = Propagation.REQUIRED, readOnly = false)
304 public void addMatchedOrders( List<OrderMatch> matches ){
305
306 for( OrderMatch match : matches ){
307 long id = orderMatchDao.generateOrderMatchId();
308 long buyFillId = orderMatchDao.generateOrderFillId();
309 long sellFillId = orderMatchDao.generateOrderFillId();
310 match.setId(id);
311 match.setBuyFillId(buyFillId);
312 match.setSellFillId(sellFillId);
313 orderMatchDao.addOrderMatch(match);
314 }
315
316 }
317
318 public List<OrderMatch> getMatchedOrders( ReceivedOrder order ){
319
320 List<OrderMatch> matchedOrders=null;
321 if( order.isBuy()){
322 matchedOrders = orderMatchDao.getOrderMatchesForBuyOrder(order.getId());
323 }else if( order.isSell() ){
324 matchedOrders = orderMatchDao.getOrderMatchesForSellOrder(order.getId());
325 }
326
327 return matchedOrders;
328 }
329
330 public void matchOrder(Order order) {
331 }
332
333 public void sendOrderFills(List<OrderFill> fills) throws OrderCannotBeFilledException, OrderFillQuantityMismatchException {
334 orderSvc.fillOrders(fills);
335 }
336
337 public void sendOrderMatches(List<OrderMatch> matches) throws OrderCannotBeFilledException,
338 NotEnoughCashException, NotValidAccountException, NotEnoughPositionsException {
339 orderSvc.executeMatches(matches);
340 }
341
342 public MarketDepth getMarketDepth(String symbol) {
343
344 int level =5;
345 OrderBook book = getOrderBook(symbol);
346
347
348 MarketDepth depth = new MarketDepth();
349 depth.setSymbol(symbol);
350 depth.setLevels(level);
351
352
353 depth.setBuys( book.getBuyPriceDepths(level));
354 depth.setSells( book.getSellPriceDepths(level));
355
356 return depth;
357 }
358 }