package org.marketcetera.orderloader.system;
import org.marketcetera.util.misc.ClassVersion;
import org.marketcetera.util.log.I18NBoundMessage;
import org.marketcetera.util.log.I18NBoundMessage2P;
import org.marketcetera.util.log.I18NBoundMessage1P;
import org.marketcetera.trade.*;
import org.marketcetera.orderloader.OrderParsingException;
import org.marketcetera.orderloader.Messages;
import org.marketcetera.module.ExpectedFailure;
import org.marketcetera.core.LoggerConfiguration;
import org.junit.Test;
import org.junit.BeforeClass;
import static org.junit.Assert.*;
import java.util.*;
import java.math.BigDecimal;
/* $License$ */
/**
* Verifies various {@link FieldProcessor} subclasses.
*
* @author anshul@marketcetera.com
* @version $Id: FieldProcessorTest.java 16154 2012-07-14 16:34:05Z colin $
* @since 1.0.0
*/
@ClassVersion("$Id: FieldProcessorTest.java 16154 2012-07-14 16:34:05Z colin $")
public class FieldProcessorTest {
@BeforeClass
public static void logSetup() {
LoggerConfiguration.logSetup();
}
@Test
public void account() throws Exception {
AccountProcessor proc = new AccountProcessor(1);
assertEquals("dfd", apply(proc, "acc", "dfd", "").getAccount());
proc = new AccountProcessor(0);
assertEquals("acc", apply(proc, "acc", "dfd", "").getAccount());
assertEquals("", apply(proc, "", "dfd", "").getAccount());
assertEquals(null, apply(proc, null, "dfd", "").getAccount());
}
@Test
public void custom() throws Exception {
CustomFieldProcessor custom = new CustomFieldProcessor();
assertTrue(custom.isEmpty());
custom.addField(0, "3001");
custom.addField(3, "3009");
assertFalse(custom.isEmpty());
Map<String, String> fields = new HashMap<String, String>();
fields.put("3001", "one");
fields.put("3009", "four");
assertEquals(fields, apply(custom, "one", "two", "three", "four", "five").getCustomFields());
fields.clear();
fields.put("3001", "");
fields.put("3009", null);
assertEquals(fields, apply(custom, "", "two", "three", null, "five").getCustomFields());
}
@Test
public void orderCapacity() throws Exception {
final OrderCapacityProcessor proc = new OrderCapacityProcessor(2);
assertEquals(null, apply(proc, "blue", "green", "", "red").getOrderCapacity());
assertEquals(OrderCapacity.Principal, apply(proc, "blue", "green",
OrderCapacity.Principal.toString(), "red").getOrderCapacity());
//Valid Values
Set<OrderCapacity> validValues = EnumSet.allOf(OrderCapacity.class);
validValues.remove(OrderCapacity.Unknown);
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_ORDER_CAPACITY, "blues", validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", "blues", "clues");
}
};
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_ORDER_CAPACITY,
OrderCapacity.Unknown.toString(), validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", OrderCapacity.Unknown.toString(),
"clues");
}
};
}
@Test
public void orderType() throws Exception {
final OrderTypeProcessor proc = new OrderTypeProcessor(2);
assertEquals(null, apply(proc, "blue", "green", "", "red").getOrderType());
assertEquals(OrderType.Limit, apply(proc, "blue", "green",
OrderType.Limit.toString(), "red").getOrderType());
//Valid Values
Set<OrderType> validValues = EnumSet.allOf(OrderType.class);
validValues.remove(OrderType.Unknown);
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_ORDER_TYPE, "blues", validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", "blues", "clues");
}
};
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_ORDER_TYPE,
OrderType.Unknown.toString(), validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", OrderType.Unknown.toString(),
"clues");
}
};
}
@Test
public void positionEffect() throws Exception {
final PositionEffectProcessor proc = new PositionEffectProcessor(2);
assertEquals(null, apply(proc, "blue", "green", "", "red").getPositionEffect());
assertEquals(PositionEffect.Close, apply(proc, "blue", "green",
PositionEffect.Close.toString(), "red").getPositionEffect());
//Valid Values
Set<PositionEffect> validValues = EnumSet.allOf(PositionEffect.class);
validValues.remove(PositionEffect.Unknown);
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_POSITION_EFFECT, "blues", validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", "blues", "clues");
}
};
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_POSITION_EFFECT,
PositionEffect.Unknown.toString(), validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", PositionEffect.Unknown.toString(),
"clues");
}
};
}
@Test
public void price() throws Exception {
final PriceProcessor proc = new PriceProcessor(1);
assertEquals(null, apply(proc, "go", "", "step").getPrice());
assertEquals(null, apply(proc, "go", null, "step").getPrice());
assertEquals(BigDecimal.ONE, apply(proc, "go", "1", "step").getPrice());
assertEquals(new BigDecimal("10.345"), apply(proc, "go",
"10.345", "yards").getPrice());
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_PRICE_VALUE, "to"){
protected void run() throws Exception {
apply(proc, "go", "to", "hell");
}
};
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_PRICE_VALUE, " "){
protected void run() throws Exception {
apply(proc, "go", " ", "west");
}
};
}
@Test
public void quantity() throws Exception {
final QuantityProcessor proc = new QuantityProcessor(1);
assertEquals(null, apply(proc, "go", "", "step").getQuantity());
assertEquals(null, apply(proc, "go", null, "step").getQuantity());
assertEquals(BigDecimal.ONE, apply(proc, "go", "1", "step").getQuantity());
assertEquals(new BigDecimal("10.345"), apply(proc, "go",
"10.345", "yards").getQuantity());
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_QUANTITY_VALUE, "to"){
protected void run() throws Exception {
apply(proc, "go", "to", "hell");
}
};
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_QUANTITY_VALUE, " "){
protected void run() throws Exception {
apply(proc, "go", " ", "west");
}
};
}
@Test
public void side() throws Exception {
final SideProcessor proc = new SideProcessor(2);
assertEquals(null, apply(proc, "blue", "green", "", "red").getSide());
assertEquals(Side.Buy, apply(proc, "blue", "green",
Side.Buy.toString(), "red").getSide());
//Valid Values
Set<Side> validValues = EnumSet.allOf(Side.class);
validValues.remove(Side.Unknown);
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_SIDE, "blues", validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", "blues", "clues");
}
};
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_SIDE,
Side.Unknown.toString(), validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", Side.Unknown.toString(),
"clues");
}
};
}
@Test
public void equityNoSecurityType() throws Exception {
final InstrumentProcessor proc = new InstrumentProcessor();
assertTrue(proc.canProcess(InstrumentFromRow.FIELD_SYMBOL, 1));
assertEquals(null, apply(proc, "java", null, "mava").getInstrument());
assertEquals(null, apply(proc, "java", "", "mava").getInstrument());
assertEquals(null, apply(proc, "java", " ", "mava").getInstrument());
assertEquals(new Equity("kava"), apply(proc, "java", "kava", "mava").getInstrument());
}
@Test
public void equityWithSecurityType() throws Exception {
final InstrumentProcessor proc = new InstrumentProcessor();
assertTrue(proc.canProcess(InstrumentFromRow.FIELD_SYMBOL, 0));
assertTrue(proc.canProcess(InstrumentFromRow.FIELD_SECURITY_TYPE, 1));
assertEquals(null, apply(proc, null, null, "mava").getInstrument());
assertEquals(null, apply(proc, "", null, "mava").getInstrument());
assertEquals(null, apply(proc, null, SecurityType.CommonStock.toString(), "mava").getInstrument());
assertEquals(null, apply(proc, "", SecurityType.CommonStock.toString(), "mava").getInstrument());
assertEquals(new Equity("java"), apply(proc, "java", null, "mava").getInstrument());
assertEquals(new Equity("java"), apply(proc, "java", "", "mava").getInstrument());
assertEquals(new Equity("java"), apply(proc, " java ", "", "mava").getInstrument());
assertEquals(new Equity("java"), apply(proc, "java", SecurityType.CommonStock.toString(), "mava").getInstrument());
Set<SecurityType> validValues = EnumSet.allOf(SecurityType.class);
validValues.remove(SecurityType.Unknown);
for (String invalidSecType:
Arrays.asList("InvalidSecurityType", SecurityType.Unknown.toString())) {
verifyParseFailure(proc,
new I18NBoundMessage2P(Messages.INVALID_SECURITY_TYPE,
invalidSecType, validValues.toString()),
"java", invalidSecType, "whatever");
}
}
@Test
public void optionInstrument() throws Exception {
InstrumentProcessor proc = new InstrumentProcessor();
assertTrue(proc.canProcess(InstrumentFromRow.FIELD_SYMBOL, 0));
assertTrue(proc.canProcess(InstrumentFromRow.FIELD_SECURITY_TYPE, 1));
assertTrue(proc.canProcess(OptionFromRow.FIELD_EXPIRY, 2));
assertTrue(proc.canProcess(OptionFromRow.FIELD_OPTION_TYPE, 3));
assertTrue(proc.canProcess(OptionFromRow.FIELD_STRIKE_PRICE, 4));
//verify fields that cannot be processed.
assertFalse(proc.canProcess(SystemProcessor.FIELD_ACCOUNT, 4));
//verify equity works
final String symbol = "java";
assertEquals(new Equity(symbol),
apply(proc, symbol, "", "kava", "lava", "mava").getInstrument());
assertEquals(new Equity(symbol),
apply(proc, symbol, SecurityType.CommonStock.toString(), "kava", "lava", "mava").getInstrument());
//verify option works
final String expiry = "20101010";
final BigDecimal strikePrice = BigDecimal.TEN;
final OptionType type = OptionType.Call;
assertEquals(new Option(symbol, expiry, strikePrice, type),
apply(proc, symbol, SecurityType.Option.toString(), expiry,
type.toString(), strikePrice.toPlainString()).getInstrument());
//verify option fields are ignored if the security type is set to equity
assertEquals(new Equity(symbol),
apply(proc, symbol, SecurityType.CommonStock.toString(), expiry,
type.toString(), strikePrice.toPlainString()).getInstrument());
//verify failures
//symbol missing
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_SYMBOL,
null, SecurityType.Option.toString(), expiry, type.toString(), strikePrice.toPlainString());
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_SYMBOL,
"", SecurityType.Option.toString(), expiry, type.toString(), strikePrice.toPlainString());
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_SYMBOL,
" ", SecurityType.Option.toString(), expiry, type.toString(), strikePrice.toPlainString());
//expiry missing
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_EXPIRY,
symbol, SecurityType.Option.toString(), null, type.toString(), strikePrice.toPlainString());
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_EXPIRY,
symbol, SecurityType.Option.toString(), "", type.toString(), strikePrice.toPlainString());
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_EXPIRY,
symbol, SecurityType.Option.toString(), " ", type.toString(), strikePrice.toPlainString());
//type missing
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_OPTION_TYPE,
symbol, SecurityType.Option.toString(), expiry, null, strikePrice.toPlainString());
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_OPTION_TYPE,
symbol, SecurityType.Option.toString(), expiry, "", strikePrice.toPlainString());
//strike missing
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_STRIKE_PRICE,
symbol, SecurityType.Option.toString(), expiry, type.toString(), null);
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_STRIKE_PRICE,
symbol, SecurityType.Option.toString(), expiry, type.toString(), "");
//verify invalid option type failure
EnumSet<OptionType> validValues = EnumSet.allOf(OptionType.class);
validValues.remove(OptionType.Unknown);
for (String opType:Arrays.asList("invalid", OptionType.Unknown.toString())) {
verifyParseFailure(proc,
new I18NBoundMessage2P(Messages.INVALID_OPTION_TYPE,
opType, validValues.toString()),
symbol, SecurityType.Option.toString(), expiry,
opType, strikePrice.toPlainString());
}
//verify invalid strike price value failure
String invalidStrike = "not big D";
verifyParseFailure(proc,
new I18NBoundMessage1P(Messages.INVALID_STRIKE_PRICE_VALUE, invalidStrike),
symbol, SecurityType.Option.toString(), expiry, type.toString(), invalidStrike);
//Create a processor without strike,type,expiry headers
proc = new InstrumentProcessor();
assertTrue(proc.canProcess(InstrumentFromRow.FIELD_SYMBOL, 0));
assertTrue(proc.canProcess(InstrumentFromRow.FIELD_SECURITY_TYPE, 1));
//no expiry header
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_EXPIRY,
symbol, SecurityType.Option.toString(), expiry, type.toString(), strikePrice.toPlainString());
assertTrue(proc.canProcess(OptionFromRow.FIELD_EXPIRY, 2));
//no option type
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_OPTION_TYPE,
symbol, SecurityType.Option.toString(), expiry, type.toString(), strikePrice.toPlainString());
assertTrue(proc.canProcess(OptionFromRow.FIELD_OPTION_TYPE, 3));
//no strike header
verifyOptionMissingFieldFailure(proc, OptionFromRow.FIELD_STRIKE_PRICE,
symbol, SecurityType.Option.toString(), expiry, type.toString(), strikePrice.toPlainString());
}
@Test
public void timeInForce() throws Exception {
final TimeInForceProcessor proc = new TimeInForceProcessor(2);
assertEquals(null, apply(proc, "blue", "green", "", "red").getTimeInForce());
assertEquals(TimeInForce.FillOrKill, apply(proc, "blue", "green",
TimeInForce.FillOrKill.toString(), "red").getTimeInForce());
//Valid Values
Set<TimeInForce> validValues = EnumSet.allOf(TimeInForce.class);
validValues.remove(TimeInForce.Unknown);
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_TIME_IN_FORCE, "blues", validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", "blues", "clues");
}
};
new ExpectedFailure<OrderParsingException>(
Messages.INVALID_TIME_IN_FORCE,
TimeInForce.Unknown.toString(), validValues.toString()){
protected void run() throws Exception {
apply(proc, "red", "greed", TimeInForce.Unknown.toString(),
"clues");
}
};
}
private static void verifyOptionMissingFieldFailure(InstrumentProcessor inProc,
String inFieldName,
String... inRow) throws Exception {
verifyParseFailure(inProc,
new I18NBoundMessage1P(Messages.MISSING_OPTION_FIELD, inFieldName),
inRow);
}
private static void verifyParseFailure(
final FieldProcessor inProc,
I18NBoundMessage inMessage,
final String... inRow) throws Exception {
new ExpectedFailure<OrderParsingException>(inMessage){
@Override
protected void run() throws Exception {
apply(inProc, inRow);
}
};
}
private static OrderSingle apply(FieldProcessor inProcessor, String... inRow)
throws OrderParsingException {
OrderSingle inOrder = createOrder();
inProcessor.apply(inRow, inOrder);
return inOrder;
}
private static OrderSingle createOrder() {
return Factory.getInstance().createOrderSingle();
}
}