package org.marketcetera.trade;
import static org.junit.Assert.*;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.junit.BeforeClass;
import org.junit.Test;
import org.marketcetera.event.HasFIXMessage;
import org.marketcetera.module.ExpectedFailure;
import org.marketcetera.quickfix.*;
import org.marketcetera.util.misc.ClassVersion;
import quickfix.FieldNotFound;
import quickfix.Message;
import quickfix.field.*;
import quickfix.field.converter.BooleanConverter;
import quickfix.field.converter.UtcTimestampConverter;
import quickfix.fix44.OrderCancelRequest;
/* $License$ */
/**
* Tests {@link OrderReplace}
*
* @author anshul@marketcetera.com
* @version $Id: OrderCancelTest.java 16154 2012-07-14 16:34:05Z colin $
* @since 1.0.0
*/
@ClassVersion("$Id: OrderCancelTest.java 16154 2012-07-14 16:34:05Z colin $") //$NON-NLS-1$
public class OrderCancelTest extends TypesTestBase {
/**
* Verifies default attributes of objects returned via
* {@link org.marketcetera.trade.Factory#createOrderReplace(org.marketcetera.trade.ExecutionReport)}
*
* @throws Exception if there were errors
*/
@Test
public void pojoDefaults() throws Exception {
//Null report parameter defaults.
OrderCancel order = sFactory.createOrderCancel(null);
assertOrderCancel(order, NOT_NULL, null, null, null,
null, null, null, null, null, null, null);
//Verify toString() doesn't fail
order.toString();
//Test an empty report.
Message report = createEmptyExecReport();
order = sFactory.createOrderCancel(
sFactory.createExecutionReport
(report, null, Originator.Server, null, null));
assertOrderCancel(order, NOT_NULL, null, null, null,
null, null, null, null, null, null, null);
//Verify toString() doesn't fail
order.toString();
//Test a report with all values in it
String orderID = "clorder-2";
String destOrderID = "brokerder-2";
Side side = Side.Buy;
Instrument instrument = new Equity("IBM");
String account = "what?";
String text = "texty";
BigDecimal orderQty = new BigDecimal("34.5");
BrokerID cID = new BrokerID("iam");
//Create an exec report.
report = createExecReport(orderID, side,
instrument, account, text, destOrderID, orderQty);
//Create the order from the report.
order = sFactory.createOrderCancel(
sFactory.createExecutionReport
(report, cID, Originator.Server, null, null));
assertOrderCancel(order, NOT_NULL, new OrderID(orderID), side,
instrument, instrument.getSecurityType(), orderQty,
destOrderID, account, text, cID, null);
//Verify toString() doesn't fail
order.toString();
assertNotSame(order, sFactory.createOrderCancel(
sFactory.createExecutionReport
(report, cID, Originator.Server, null, null)));
//Test a cancel for a partial fill
//Create an exec report.
report = createExecReport(orderID, side,
instrument, account, text, destOrderID, orderQty);
report.setDecimal(AvgPx.FIELD, new BigDecimal("23.2"));
report.setDecimal(CumQty.FIELD, new BigDecimal("10"));
report.setDecimal(LeavesQty.FIELD, new BigDecimal("9"));
report.setField(new OrdStatus(OrdStatus.PARTIALLY_FILLED));
//Create the order from the report.
order = sFactory.createOrderCancel(
sFactory.createExecutionReport
(report, cID, Originator.Server, null, null));
assertOrderCancel(order, NOT_NULL, new OrderID(orderID), side,
instrument, instrument.getSecurityType(), orderQty,
destOrderID, account, text, cID, null);
//Verify toString() doesn't fail
order.toString();
assertNotSame(order, sFactory.createOrderCancel(
sFactory.createExecutionReport
(report, cID, Originator.Server, null, null)));
}
/**
* Verifies setters of objects returned via
* {@link org.marketcetera.trade.Factory#createOrderCancel(org.marketcetera.trade.ExecutionReport)}
*
* @throws Exception if there were errors
*/
@Test
public void pojoSetters()throws Exception {
//Test with non-null exec report
OrderCancel order = sFactory.createOrderCancel(
sFactory.createExecutionReport
(createEmptyExecReport(), null, Originator.Server, null, null));
checkSetters(order);
//Test with null exec report
order = sFactory.createOrderCancel(null);
checkSetters(order);
}
/**
* Verifies conversion of System FIX message to OrderCancel via
* {@link Factory#createOrderCancel(quickfix.Message, BrokerID)}
*
* @throws Exception if there were errors.
*/
@Test
public void systemFIXWrap() throws Exception {
FIXMessageFactory factory = getSystemMessageFactory();
//An order with no fields set
Message msg = factory.getUnderlyingMessageFactory().create(
factory.getBeginString(), MsgType.ORDER_CANCEL_REQUEST);
OrderCancel order = sFactory.createOrderCancel(msg, null);
assertOrderValues(order, null, null);
OrderID expectedOrderID = NOT_NULL;
assertOrderBaseValues(order, expectedOrderID, null, null, null, null, null, null);
assertRelatedOrderValues(order, null, null);
//Verify toString() doesn't fail
order.toString();
checkSetters(order);
//An order with all fields set.
BrokerID brokerID = new BrokerID("meh");
String destOrderID = "bord1";
String origOrderID = "testOrderID";
BigDecimal qty = new BigDecimal("23434.56989");
SecurityType securityType = SecurityType.CommonStock;
Instrument instrument = new Equity("IBM");
String account = "nonplus";
String text = "some text";
Side side = Side.Buy;
msg = factory.newCancel("order",origOrderID,
side.getFIXValue(), qty, instrument, null);
msg.setField(new Account(account));
msg.setField(new Text(text));
msg.setField(new quickfix.field.OrderID(destOrderID));
order = sFactory.createOrderCancel(msg, brokerID);
assertOrderValues(order, brokerID, securityType);
assertOrderBaseValues(order, expectedOrderID, account, text, null,
qty, side, instrument);
OrderID originalOrderID = new OrderID(origOrderID);
assertRelatedOrderValues(order, originalOrderID, destOrderID);
//Verify toString() doesn't fail
order.toString();
checkSetters(order);
//Check custom fields
//Set fields of every type.
Map<String,String> expectedMap = new HashMap<String, String>();
Date date = new Date();
BigDecimal bigDecimal = new BigDecimal("35234.35989");
char charValue = '0';
int intValue = 1;
boolean boolValue = false;
msg.setField(new ExpireTime(date));
expectedMap.put(String.valueOf(ExpireTime.FIELD),
UtcTimestampConverter.convert(date, true));
msg.setField(new AllocQty(bigDecimal));
expectedMap.put(String.valueOf(AllocQty.FIELD), bigDecimal.toString());
msg.setField(new SettlType(String.valueOf(charValue)));
expectedMap.put(String.valueOf(SettlType.FIELD),
String.valueOf(charValue));
msg.setField(new Product(intValue));
expectedMap.put(String.valueOf(Product.FIELD),
String.valueOf(intValue));
msg.setField(new SolicitedFlag(boolValue));
expectedMap.put(String.valueOf(SolicitedFlag.FIELD),
BooleanConverter.convert(boolValue));
order = sFactory.createOrderCancel(msg, brokerID);
assertOrderCancel(order, expectedOrderID, originalOrderID, side,
instrument, securityType, qty, destOrderID, account, text,
brokerID, expectedMap);
assertNotSame(order, sFactory.createOrderCancel(msg, brokerID));
}
/**
* Verifies failures when wrapping a FIX message in an order.
*
* @throws Exception if there were errors.
*/
@Test
public void systemFIXWrapFailures() throws Exception {
final BrokerID brokerID = new BrokerID("meh");
//Null check for message parameter
new ExpectedFailure<NullPointerException>() {
protected void run() throws Exception {
sFactory.createOrderCancel(null, brokerID);
}
};
final Message msg = createEmptyExecReport();
//Non System FIX Versions.
for (String string: new String[]{
FIXDataDictionary.FIX_4_0_BEGIN_STRING,
FIXDataDictionary.FIX_4_1_BEGIN_STRING,
FIXDataDictionary.FIX_4_2_BEGIN_STRING,
FIXDataDictionary.FIX_4_3_BEGIN_STRING,
FIXDataDictionary.FIX_4_4_BEGIN_STRING}) {
msg.getHeader().setField(new BeginString(string));
new ExpectedFailure<MessageCreationException>(
Messages.NON_SYSTEM_FIX_MESSAGE, string){
@Override
protected void run() throws Exception {
sFactory.createOrderCancel(msg,null);
}
};
}
//No version field
msg.getHeader().removeField(BeginString.FIELD);
MessageCreationException exception =
new ExpectedFailure<MessageCreationException>(
Messages.SYSTEM_FIX_MESSAGE_NO_BEGIN_STRING, msg.toString()){
@Override
protected void run() throws Exception {
sFactory.createOrderCancel(msg,null);
}
}.getException();
assertNotNull(exception.getCause());
assertTrue(exception.getCause() instanceof FieldNotFound);
//Has groups
msg.getHeader().setField(new BeginString(FIXDataDictionary.FIX_SYSTEM_BEGIN_STRING));
OrderCancelRequest.NoEvents group = new OrderCancelRequest.NoEvents();
group.set(new EventDate());
msg.addGroup(group);
new ExpectedFailure<MessageCreationException>(
Messages.MESSAGE_HAS_GROUPS, group.getFieldTag(),
msg.toString()){
@Override
protected void run() throws Exception {
sFactory.createOrderCancel(msg,null);
}
};
//Incorrect message type
final Message incorrectType = getSystemMessageFactory().newBasicOrder();
new ExpectedFailure<MessageCreationException>(
Messages.NOT_CANCEL_ORDER, incorrectType.toString()){
@Override
protected void run() throws Exception {
sFactory.createOrderCancel(incorrectType, null);
}
};
}
/** verify custom fields are preserved, and that nothing else is added from the execution report */
@Test
public void testSecurityExchangePreserved() throws Exception {
Message erMsg = FIXVersion.FIX42.getMessageFactory().newExecutionReport("orderID", "clOrderID", "execID",
OrdStatus.NEW, Side.Buy.getFIXValue(), new BigDecimal("10"), new BigDecimal("100.23"),
BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, new Equity("IBM"),
"accountName", "some other text");
erMsg.setString(SecurityExchange.FIELD, "box");
ExecutionReport er = sFactory.createExecutionReport(erMsg, null, Originator.Server, null, null);
OrderCancel cancel = sFactory.createOrderCancel(er);
assertNotNull("didn't get custom fields", cancel.getCustomFields());
// basically, should only have 1 field: SecurityExchange
assertEquals("has extra fields: "+ Arrays.toString(cancel.getCustomFields().keySet().toArray()), 1, cancel.getCustomFields().size());
}
@Test
/** Create ER for previous order that has OrderID of 12345
* Set an OrigClOrdID on it of 12222
* Create a replace form this ER, the OrigClOrdID should be 12345, not the "very original" of 12222
*/
public void testCreateOrderCancel() throws Exception {
Message erMsg = FIXVersion.FIX42.getMessageFactory().newExecutionReport("7600", "12345", "execID", //$NON-NLS-1$
OrdStatus.NEW, Side.Buy.getFIXValue(), new BigDecimal("10"), new BigDecimal("100.23"),
BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, BigDecimal.ZERO, new Equity("IBM"), //$NON-NLS-1$
"accountName", null); //$NON-NLS-1$
erMsg.setString(OrigClOrdID.FIELD, "12222");
erMsg.setInt(HandlInst.FIELD, HandlInst.AUTOMATED_EXECUTION_ORDER_PRIVATE);
ExecutionReport er = Factory.getInstance().createExecutionReport(erMsg, new BrokerID("broker"), Originator.Server, new UserID(7600L), new UserID(7500L));
assertEquals("12222", er.getOriginalOrderID().getValue());
assertEquals("12222", ((HasFIXMessage) er).getMessage().getString(OrigClOrdID.FIELD));
// now create a cancel, shouldn't have the "very original" order id of 12222
OrderCancel cancel = Factory.getInstance().createOrderCancel(er);
assertEquals("12345", cancel.getOriginalOrderID().getValue());
assertNull("shouldn't get any custom fields", cancel.getCustomFields());
}
/**
* Set the current data dictionary so that various FIXMessageFactory
* methods work.
*
* @throws Exception if there were errors.
*/
@BeforeClass
public static void setupCurrentFIXDictionary() throws Exception {
FIXDataDictionaryManager.initialize(FIXVersion.FIX44,
FIXVersion.FIX44.getDataDictionaryURL());
CurrentFIXDataDictionary.setCurrentFIXDataDictionary(
FIXDataDictionaryManager.getFIXDataDictionary(FIXVersion.FIX44));
}
private Message createExecReport(String inOrderID,
Side inSide,
Instrument inInstrument,
String inAccount,
String inText,
String inDestOrderID,
BigDecimal inQty)
throws FieldNotFound {
return getSystemMessageFactory().newExecutionReport(
inDestOrderID, inOrderID,
"exec-2", OrderStatus.New.getFIXValue(),
inSide.getFIXValue(), inQty,
new BigDecimal("45.67"), new BigDecimal("23.53"),
new BigDecimal("983.43"), new BigDecimal("98.34"),
new BigDecimal("34.32"), inInstrument, inAccount, inText);
}
private void checkSetters(OrderCancel inOrder) {
checkOrderSetters(inOrder);
checkOrderBaseSetters(inOrder);
checkRelatedOrderSetters(inOrder);
}
}