public bool IsValid(out string message) { message = string.Empty; StringBuilder output = new StringBuilder(255); bool valid = true; // validate duration for asset type switch (AssetType) { case AssetType.OP: if (Duration.Code != DurationCode.DAY && Duration.Code != DurationCode.GTC && Duration.Code != DurationCode.GTD && Duration.Code != DurationCode.IOC && Duration.Code != DurationCode.FOK && Duration.Code != DurationCode.OPG) { output.Append(string.Format("Invalid Duration for AssetType {0}: {1}.{2}", AssetType.ToString(), Duration, Environment.NewLine)); valid = false; } break; case AssetType.FX: if (Duration.Code != DurationCode.DAY && Duration.Code != DurationCode.GTC && Duration.Code != DurationCode.GTD && Duration.Code != DurationCode.IOC && Duration.Code != DurationCode.FOK && Duration.Code != DurationCode.OneMinute && Duration.Code != DurationCode.ThreeMinute && Duration.Code != DurationCode.FiveMinute) { output.Append(string.Format("Invalid Duration for AssetType {0}: {1}.{2}", AssetType.ToString(), Duration, Environment.NewLine)); valid = false; } break; case AssetType.FU: if (Duration.Code != DurationCode.DAY && Duration.Code != DurationCode.GTC && Duration.Code != DurationCode.GTD && Duration.Code != DurationCode.IOC && Duration.Code != DurationCode.FOK) { output.Append(string.Format("Invalid Duration for AssetType {0}: {1}.{2}", AssetType.ToString(), Duration, Environment.NewLine)); valid = false; } break; } // validate date if (GTDDate > DateTime.MinValue) { if (GTDDate < DateTime.Now) { output.Append("GTDDate must be in the future" + Environment.NewLine); valid = false; } } else if (Duration.Code == DurationCode.GTD) { output.Append("GTDDate required for GTD orders." + Environment.NewLine); valid = false; } // valididate limit price: required for limit and stop limit orders if ((OrderType == OrderType.Limit || OrderType == OrderType.StopLimit) && LimitPrice <= 0) { output.Append("Limit price must be greater than 0." + Environment.NewLine); valid = false; } // validate quantity if (Quantity <= 0) { output.AppendFormat("Invalid Quantity of {0}.{1}", Quantity, Environment.NewLine); valid = false; } // TODO: could validate route but bypassing for now since this is not required // validate stop price: must be included for stop orders. if ((OrderType == OrderType.StopLimit || OrderType == OrderType.StopMarket) && StopPrice <= 0) { output.Append("StopPrice is required for Stop orders." + Environment.NewLine); valid = false; } // verify valid trade action for asset class string errorMessage = string.Format("{0} is an invalid TradeAction for AssetType {1}.{2}", TradeAction.ToString(), AssetType, Environment.NewLine); switch (TradeAction) { case TradeAction.Buy: case TradeAction.Sell: if (AssetType == AssetType.OP) { output.Append(errorMessage); valid = false; } break; case TradeAction.BuyToCover: case TradeAction.SellShort: if (AssetType != AssetType.EQ) { output.Append(errorMessage); valid = false; } break; case TradeAction.BuyToOpen: case TradeAction.BuyToClose: case TradeAction.SellToOpen: case TradeAction.SellToClose: if (AssetType != AssetType.OP) { output.Append(errorMessage); valid = false; } break; } if (!valid) { message = output.ToString(); } return(valid); }