/** * Copyright 2011 Archfirst * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.archfirst.bfoms.infra.fixtrading; import javax.inject.Inject; import org.archfirst.bfoms.domain.account.brokerage.BrokerageAccountService; import org.archfirst.bfoms.domain.exchange.ExchangeMessageProcessor; import org.archfirst.bfoms.infra.fixtrading.converters.AvgPriceConverter; import org.archfirst.bfoms.infra.fixtrading.converters.ClOrdIDConverter; import org.archfirst.bfoms.infra.fixtrading.converters.CumQtyConverter; import org.archfirst.bfoms.infra.fixtrading.converters.ExecutionTypeConverter; import org.archfirst.bfoms.infra.fixtrading.converters.FixFormatter; import org.archfirst.bfoms.infra.fixtrading.converters.FixUtil; import org.archfirst.bfoms.infra.fixtrading.converters.LastPriceConverter; import org.archfirst.bfoms.infra.fixtrading.converters.LastQtyConverter; import org.archfirst.bfoms.infra.fixtrading.converters.LeavesQtyConverter; import org.archfirst.bfoms.infra.fixtrading.converters.OrderSideConverter; import org.archfirst.bfoms.infra.fixtrading.converters.OrderStatusConverter; import org.archfirst.bfoms.infra.fixtrading.converters.OrigClOrdIDConverter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import quickfix.DoNotSend; import quickfix.FieldNotFound; import quickfix.IncorrectDataFormat; import quickfix.IncorrectTagValue; import quickfix.InvalidMessage; import quickfix.Message; import quickfix.MessageCracker; import quickfix.MessageUtils; import quickfix.RejectLogon; import quickfix.SessionID; import quickfix.UnsupportedMessageType; import quickfix.fix44.ExecutionReport; import quickfix.fix44.OrderCancelReject; /** * FixExchangeMessageProcessor * * @author Naresh Bhatia */ public class FixExchangeMessageProcessor extends MessageCracker implements quickfix.Application, ExchangeMessageProcessor { private static final Logger logger = LoggerFactory.getLogger(FixExchangeMessageProcessor.class); @Inject private BrokerageAccountService brokerageAccountService; @Override public void processMessage(String messageText) { quickfix.Message fixMessage; try { fixMessage = MessageUtils.parse( FixUtil.getDefaultMessageFactory(), FixUtil.getDefaultDataDictionary(), messageText); logger.debug("Received message:\n{}", FixFormatter.format(fixMessage)); this.fromApp(fixMessage, null); } catch (InvalidMessage e) { logger.error("Invalid FIX message received: " + messageText, e); } catch (FieldNotFound e) { logger.error("Invalid FIX message received: " + messageText, e); } catch (IncorrectDataFormat e) { logger.error("Invalid FIX message received: " + messageText, e); } catch (IncorrectTagValue e) { logger.error("Invalid FIX message received: " + messageText, e); } catch (UnsupportedMessageType e) { logger.error("Invalid FIX message received: " + messageText, e); } } @Override public void fromAdmin(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, RejectLogon { } @Override public void fromApp(Message message, SessionID sessionId) throws FieldNotFound, IncorrectDataFormat, IncorrectTagValue, UnsupportedMessageType { crack(message, sessionId); } @Override public void onMessage(ExecutionReport message, SessionID sessionID) throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue { // Extract symbol String symbol = message.getInstrument().getSymbol().getValue(); // Extract execution report org.archfirst.bfoms.domain.account.brokerage.order.ExecutionReport executionReport = new org.archfirst.bfoms.domain.account.brokerage.order.ExecutionReport( ExecutionTypeConverter.toDomain(message.getExecType()), message.getOrderID().getValue(), message.getExecID().getValue(), ClOrdIDConverter.toDomain(message.getClOrdID()), OrderStatusConverter.toDomain(message.getOrdStatus()), OrderSideConverter.toDomain(message.getSide()), symbol, LastQtyConverter.toDomain(message.getLastQty()), LeavesQtyConverter.toDomain(message.getLeavesQty()), CumQtyConverter.toDomain(message.getCumQty()), LastPriceConverter.toDomain(message.getLastPx()), AvgPriceConverter.toDomain(message.getAvgPx())); // Send to brokerageAccountService for processing brokerageAccountService.processExecutionReport(executionReport); } @Override public void onMessage(OrderCancelReject message, SessionID sessionID) throws FieldNotFound, UnsupportedMessageType, IncorrectTagValue { brokerageAccountService.processOrderCancelReject( OrigClOrdIDConverter.toDomain(message.getOrigClOrdID()), OrderStatusConverter.toDomain(message.getOrdStatus())); } @Override public void onCreate(SessionID sessionId) { } @Override public void onLogon(SessionID sessionId) { } @Override public void onLogout(SessionID sessionId) { } @Override public void toAdmin(Message message, SessionID sessionId) { } @Override public void toApp(Message message, SessionID sessionId) throws DoNotSend { } }