package org.marketcetera.core.instruments; import org.marketcetera.util.misc.ClassVersion; import org.marketcetera.trade.Instrument; import org.marketcetera.trade.Option; import org.marketcetera.quickfix.FIXVersion; import quickfix.Message; import quickfix.DataDictionary; import quickfix.field.*; import java.util.regex.Pattern; /* $License$ */ /** * Adds the appropriate fields for an option instrument to a FIX Message. * * @author anshul@marketcetera.com * @version $Id: OptionToMessage.java 16154 2012-07-14 16:34:05Z colin $ * @since 2.0.0 */ @ClassVersion("$Id: OptionToMessage.java 16154 2012-07-14 16:34:05Z colin $") public class OptionToMessage extends InstrumentToMessage<Option> { /** * Creates an instance that handles options. */ public OptionToMessage() { super(Option.class); } @Override public void set(Instrument inInstrument, String inBeginString, Message inMessage) { if(FIXVersion.FIX40.equals(FIXVersion.getFIXVersion(inBeginString))) { throw new IllegalArgumentException( Messages.OPTION_NOT_SUPPORTED_FOR_FIX_VERSION.getText(inBeginString)); } inMessage.setField(new Symbol(inInstrument.getSymbol())); Option option = (Option) inInstrument; inMessage.setField(new StrikePrice(option.getStrikePrice())); String expiry = option.getExpiry(); switch(FIXVersion.getFIXVersion(inBeginString)){ case FIX_SYSTEM: //fall through case FIX41: //fall through case FIX42: setSecurityType(inInstrument, inBeginString, inMessage); inMessage.setField(new PutOrCall(option.getType().getFIXValue())); if(expiry.length() > 6) { inMessage.setField(new MaturityDay(expiry.substring(6))); expiry = expiry.substring(0,6); } inMessage.setField(new MaturityMonthYear(expiry)); break; case FIX43: setCFICode(inMessage, option); inMessage.setField(new MaturityDate(expiry)); break; default: setCFICode(inMessage, option); //set maturity month year inMessage.setField(new MaturityMonthYear(expiry)); break; } } @Override public boolean isSupported(DataDictionary inDictionary, String inMsgType) { //if dictionary supports means to specify the 5 attributes of an option return //symbol (inDictionary.isMsgField(inMsgType,Symbol.FIELD)) && //strike (inDictionary.isMsgField(inMsgType,StrikePrice.FIELD)) && //security and option type ((inDictionary.isMsgField(inMsgType,SecurityType.FIELD) && inDictionary.isMsgField(inMsgType,PutOrCall.FIELD)) || inDictionary.isMsgField(inMsgType,CFICode.FIELD)) && //expiry (inDictionary.isMsgField(inMsgType,MaturityDate.FIELD) || inDictionary.isMsgField(inMsgType,MaturityMonthYear.FIELD)); } @Override public void set(Instrument inInstrument, DataDictionary inDictionary, String inMsgType, Message inMessage) { setSecurityType(inInstrument, inDictionary, inMsgType, inMessage); setSymbol(inInstrument, inDictionary, inMsgType, inMessage); Option option = (Option) inInstrument; //set as many fields as are available in the dictionary. if(inDictionary.isMsgField(inMsgType, CFICode.FIELD)) { setCFICode(inMessage, option); } if(inDictionary.isMsgField(inMsgType, PutOrCall.FIELD)) { inMessage.setField(new PutOrCall(option.getType().getFIXValue())); } if(inDictionary.isMsgField(inMsgType, StrikePrice.FIELD)) { inMessage.setField(new StrikePrice(option.getStrikePrice())); } final String expiry = option.getExpiry(); if(inDictionary.isMsgField(inMsgType, MaturityMonthYear.FIELD)) { inMessage.setField(new MaturityMonthYear(expiry)); } if(inDictionary.isMsgField(inMsgType, MaturityDay.FIELD)&& isYYYYMMDD(expiry)) { inMessage.setField(new MaturityDay(expiry.substring(6))); } if(inDictionary.isMsgField(inMsgType, MaturityDate.FIELD) && isYYYYMMDD(expiry)) { inMessage.setField(new MaturityDate(expiry)); } } /** * Sets the CFI code for the option on the message. * * @param inMessage the message * @param inOption the option */ private static void setCFICode(Message inMessage, Option inOption) { String cfiCode = CFICodeUtils.getOptionCFICode(inOption.getType()); if(cfiCode != null) { inMessage.setField(new CFICode(cfiCode)); } } /** * Returns true if the option expiry includes the day. * * @param inExpiry the expiry value to test * * @return true if the expiry includes the day */ private static boolean isYYYYMMDD(String inExpiry) { return YYYYMMDD.matcher(inExpiry).matches(); } /** * Pattern to figure out if the option expiry date includes the day. */ private static final Pattern YYYYMMDD = Pattern.compile("^(\\d{4})((0[1-9])|(1[012]))((0[1-9])|([12]\\d)|(3[01]))$"); //$NON-NLS-1$ }