public void RenderOrderAsFix(out QuickFix.Message myNOS, out KaiTrade.Interfaces.Message myMsg, out string myDriverCode, KaiTrade.Interfaces.Order myOrder) { try { lock (this) { // do not actually submit triggered orders // register the order as a publisher KaiTrade.Interfaces.Publisher myPub = null; myPub = AppFactory.Instance().GetPublisherManager().GetPublisher(myOrder.Identity); if (myPub == null) { myPub = myOrder as KaiTrade.Interfaces.Publisher; AppFactory.Instance().GetPublisherManager().Add(myPub); } // Check the limits for the order string myTextErr; if (LimitChecker.Instance().BreaksLimits(out myTextErr, myOrder)) { myOrder.OrdStatus = new QuickFix.OrdStatus(QuickFix.OrdStatus.REJECTED); myOrder.Text = "order failed order qty limit test"; Exception myE = new Exception("process order failed order qty limit test"); throw myE; } // Create the FIX order message myNOS = new QuickFix.Message(); // pending new at this stage myOrder.OrdStatus = new QuickFix.OrdStatus(QuickFix.OrdStatus.PENDING_NEW); myOrder.TransactTime = new QuickFix.TransactTime(DateTime.Now.ToUniversalTime()); myNOS.setField(myOrder.TransactTime); //myOrder.ClOrdID = new QuickFix.ClOrdID(KaiUtil.Identities.Instance.genReqID()); // Associate the CLOrdID with this order AppFactory.Instance().GetOrderManager().AssociateClOrdID(myOrder.ClOrdID.getValue(), myOrder); // Set fix version QuickFix.BeginString myBeginString = new QuickFix.BeginString("FIX.4.4"); myNOS.getHeader().setField(myBeginString); // Set order message type QuickFix.MsgType msgType = new QuickFix.MsgType(); msgType.setValue("D"); myNOS.getHeader().setField(msgType); myNOS.setField(myOrder.ClOrdID); // set up the product details in the message myOrder.Product.Set(myNOS); // Qty myNOS.setField(myOrder.OrderQty); // MaxFloor if (myOrder.MaxFloor != null) { myNOS.setField(myOrder.MaxFloor); } // set the side myNOS.setField(myOrder.Side); // set the order type myNOS.setField(myOrder.OrdType); // Time in force if (myOrder.TimeInForce != null) { myNOS.setField(myOrder.TimeInForce); } else { myOrder.TimeInForce = new QuickFix.TimeInForce(QuickFix.TimeInForce.DAY); myNOS.setField(myOrder.TimeInForce); } // Validation - check they entered a date/time if needed switch (myOrder.TimeInForce.getValue()) { case QuickFix.TimeInForce.GOOD_TILL_DATE: break; default: break; } // do not add the price to the fix message on Market orders if (myOrder.OrdType.getValue() != QuickFix.OrdType.MARKET) { if (myOrder.Price.getValue() > 0) { myNOS.setField(myOrder.Price); } else { throw new Exception("Must specify price > 0 on Limit and other non Market orders"); } } if (myOrder.StopPx != null) { myNOS.setField(myOrder.StopPx); } // default the handlInst to automated if (myOrder.HandlInst != null) { myNOS.setField(myOrder.HandlInst); } else { myOrder.HandlInst = new QuickFix.HandlInst(QuickFix.HandlInst.AUTOEXECPUB); myNOS.setField(myOrder.HandlInst); } // Create the message wrapper used to send the order to the driver myMsg = new KaiTCPComm.KaiMessageWrap(); myMsg.Label = "D"; myDriverCode = ""; // A trade venue must be specified on the order KaiTrade.Interfaces.Venue myVenue = null; if (myOrder.Product.TradeVenue.Length > 0) { // get the driver code and session details from the venue manager myVenue = AppFactory.Instance().GetVenueManager().GetVenue(myOrder.Product.TradeVenue); if (myVenue != null) { myDriverCode = myVenue.DriverCode; if (myVenue.TargetVenue.Length > 0) { myMsg.VenueCode = myVenue.TargetVenue; } if (myVenue.BeginString.Length > 0) { // this is the FIX version the server wants, we convert between // versions in the FIX client myMsg.Format = myVenue.BeginString; } if (myVenue.SID.Length > 0) { QuickFix.SenderCompID mySID = new QuickFix.SenderCompID(myVenue.SID); myNOS.getHeader().setField(mySID); myMsg.ClientID = myVenue.SID; } if (myVenue.TID.Length > 0) { QuickFix.TargetCompID myTID = new QuickFix.TargetCompID(myVenue.TID); myNOS.getHeader().setField(myTID); myMsg.TargetID = myVenue.TID; } } else { string myErr = "Invalid Venue Code:" + myOrder.Product.TradeVenue; m_Log.Error(myErr); Exception myE = new Exception(myErr); throw myE; } } else { string myErr = "No Venue Code specified on product:"; m_Log.Error(myErr); Exception myE = new Exception(myErr); throw myE; } // process any venue field bags - do this prior to the order bags // to allow the order setting to override the venues List<KaiTrade.Interfaces.Field> myFieldBag; KTAFacade.Instance().SetBag(out myFieldBag, myVenue.NOSBag, ","); foreach (KaiTrade.Interfaces.Field myField in myFieldBag) { try { myNOS.setString(int.Parse(myField.ID), myField.Value); } catch (Exception myE) { m_Log.Error("NOS Extra tags from venue error:", myE); } } // process any additional tags for the order foreach (KaiTrade.Interfaces.Field myField in myOrder.NOSBag) { try { myNOS.setString(int.Parse(myField.ID), myField.Value); } catch (Exception myE) { m_Log.Error("NOS Extra tags error:", myE); } } // additional setting placed here will override the // fields in the bags if (myOrder.Account != null) { if (myOrder.Account.getValue().Length > 0) { myNOS.setField(myOrder.Account); } } QuickFix.TargetStrategyParameters targetStrategyParameters = new QuickFix.TargetStrategyParameters(myOrder.StrategyName); myNOS.setField(targetStrategyParameters); // Process any strategy parameters if (myOrder.K2Parameters.Count > 0) { QuickFix.NoStrategyParameters noStratParms = new QuickFix.NoStrategyParameters(myOrder.K2Parameters.Count); myNOS.setField(noStratParms); QuickFix50Sp2.NewOrderSingle.NoStrategyParameters group = new QuickFix50Sp2.NewOrderSingle.NoStrategyParameters(); QuickFix.StrategyParameterName strategyParameterName; QuickFix.StrategyParameterType strategyParameterType; QuickFix.StrategyParameterValue strategyParameterValue; foreach (KaiTrade.Interfaces.K2Parameter param in myOrder.K2Parameters) { strategyParameterName = new QuickFix.StrategyParameterName(param.ParameterName); group.setField(strategyParameterName); strategyParameterType = new QuickFix.StrategyParameterType((int)param.ParameterType); group.setField(strategyParameterType); strategyParameterValue = new QuickFix.StrategyParameterValue(param.ParameterValue); group.setField(strategyParameterValue); myNOS.addGroup(group); } } // Set the FIX string as message data myMsg.Data = myNOS.ToString(); // inform order manager clients that the order has changed AppFactory.Instance().GetOrderManager().SetChanged(myOrder.Identity); } } catch (Exception myE) { m_Log.Error("RenderOrderAsFix:", myE); myOrder.OrdStatus = new QuickFix.OrdStatus(QuickFix.OrdStatus.REJECTED); myOrder.Text = myE.Message; // inform order manager clients that the order has changed AppFactory.Instance().GetOrderManager().SetChanged(myOrder.Identity); throw (myE); } }
/// <summary> /// Edit the order for the ID specified - throws an exception if the order isnt working /// </summary> /// <param name="myID"></param> /// <param name="newQty">new qty if specified</param> /// <param name="newPrice">new price if specified</param> public void ReplaceOrder(string myID, double? newQty, double? newPrice, double? newStopPx) { KaiTrade.Interfaces.Order myOrder = null; try { // Get Order KaiTrade.Interfaces.OrderManager myOM = AppFactory.Instance().GetOrderManager(); myOrder = myOM.GetOrder(myID); if (myOrder == null) { string myError = "Order not found cannot edit:" + myID; Exception myE = new Exception(myError); throw myE; } if (m_ORLog.IsInfoEnabled) { m_ORLog.Info("ReplaceOrder:"+ myOrder.ToString()); } // are these changes? if (!newValueDifferentFromOld(myOrder, newQty, newPrice, newStopPx)) { string myError = "The new fields in the Replace request are the same as the existing fields" + myID; Exception myE = new Exception(myError); throw myE; } // Is this a triggered order if (myOrder.TriggerOrderID.Length > 0) { if (newQty.HasValue) { myOrder.OrderQty = new QuickFix.OrderQty((double)newQty); } if (newPrice.HasValue) { myOrder.Price = new QuickFix.Price((double)newPrice); } if (newStopPx.HasValue) { myOrder.StopPx = new QuickFix.StopPx((double)newStopPx); } return; } // store the clordID's //NOT USED? QuickFix.OrigClOrdID myOrigClOrdID; QuickFix.ClOrdID myClOrdID; // check if we are pending cancel or pending mod if (order.LastOrderCommand == KaiTrade.Interfaces.LastOrderCommand.replace) { // we are currently doing a replace - cannot do another string myError = "Order is already processing a replace cannot modify at this time:" + myID; Exception myE = new Exception(myError); throw myE; } if (order.LastOrderCommand == KaiTrade.Interfaces.LastOrderCommand.cancel) { // we are currently doing a cancel - cannot do a mod string myError = "Order is already processing a cancel cannot modify" + myID; Exception myE = new Exception(myError); throw myE; } // check that the order is working if (!myOrder.IsWorking()) { if ((myOrder.OrdType.getValue() == QuickFix.OrdType.STOP) || (myOrder.OrdType.getValue() == QuickFix.OrdType.STOP_LIMIT)) { // no action } else { string myError = "Order is not in a working state cannot replace:" + myID; Exception myE = new Exception(myError); throw myE; } } // Check the limits for the order string myTextErr; double qty; if (newQty.HasValue) { qty = newQty.Value; } else { qty = myOrder.OrderQty.getValue(); } double px; if (newPrice.HasValue) { px = newPrice.Value; } else { px = myOrder.Price.getValue(); } if (LimitChecker.Instance().BreaksLimits(out myTextErr, myOrder, qty, px)) { myOrder.OrdStatus = new QuickFix.OrdStatus(QuickFix.OrdStatus.REJECTED); myOrder.Text = "You have exceeded the order qty limit - please re-enter"; Exception myE = new Exception("You have exceeded the order qty limit - please re-enter"); throw myE; } // Create a FIX cancel replace messsage QuickFix.Message myFixMsg = new QuickFix.Message(); QuickFix.MsgType msgType = new QuickFix.MsgType("G"); myFixMsg.getHeader().setField(msgType); QuickFix.BeginString myBeginString = new QuickFix.BeginString("FIX.4.4"); myFixMsg.getHeader().setField(myBeginString); // OrderID if (myOrder.OrderID == null) { myOrder.Text = "No order ID found cannot modify order"; Exception myE = new Exception("No order ID found cannot modify order"); throw myE; } // set the original to the existing clordid myOrder.OrigClOrdID = new QuickFix.OrigClOrdID(myOrder.ClOrdID.getValue()); myFixMsg.setField(myOrder.OrigClOrdID); myFixMsg.setField(myOrder.OrderID); ////Side myFixMsg.setField(myOrder.Side); // set up the product details in the message myOrder.Product.Set(myFixMsg); //// Transact Time myOrder.TransactTime = new QuickFix.TransactTime(DateTime.Now.ToUniversalTime()); myFixMsg.setField(myOrder.TransactTime); myFixMsg.setField(myOrder.OrdType); // Create the message wrapper used to send the order cancel to the driver KaiTrade.Interfaces.Message myMsg = new KaiTCPComm.KaiMessageWrap(); myMsg.Label = "G"; string myDriverCode = ""; // A trade venue must be specified on the order KaiTrade.Interfaces.Venue myVenue = null; if (myOrder.Product.TradeVenue.Length > 0) { // get the driver code and session details from the venue manager myVenue = AppFactory.Instance().GetVenueManager().GetVenue(myOrder.Product.TradeVenue); if (myVenue != null) { myDriverCode = myVenue.DriverCode; if (myVenue.TargetVenue.Length > 0) { myMsg.VenueCode = myVenue.TargetVenue; } if (myVenue.BeginString.Length > 0) { // this is the FIX version the server wants, we convert between // versions in the FIX client myMsg.Format = myVenue.BeginString; } if (myVenue.SID.Length > 0) { QuickFix.SenderCompID mySID = new QuickFix.SenderCompID(myVenue.SID); myFixMsg.getHeader().setField(mySID); myMsg.ClientID = myVenue.SID; } if (myVenue.TID.Length > 0) { QuickFix.TargetCompID myTID = new QuickFix.TargetCompID(myVenue.TID); myFixMsg.getHeader().setField(myTID); myMsg.TargetID = myVenue.TID; } } else { string myErr = "Invalid Venue Code:" + myOrder.Product.TradeVenue; m_Log.Error(myErr); Exception myE = new Exception(myErr); throw myE; } } else { string myErr = "No Venue Code specified on product:"; m_Log.Error(myErr); Exception myE = new Exception(myErr); throw myE; } // process any venue field bags - do this prior to the order bags // to allow the order setting to override the venues List<KaiTrade.Interfaces.Field> myFieldBag; KTAFacade.Instance().SetBag(out myFieldBag, myVenue.ReplaceBag, ","); foreach (KaiTrade.Interfaces.Field myField in myFieldBag) { try { myFixMsg.setString(int.Parse(myField.ID), myField.Value); } catch (Exception myE) { m_Log.Error("replace Extra tags from venue error:", myE); } } // process any additional tags for the order foreach (KaiTrade.Interfaces.Field myField in myOrder.ReplaceBag) { try { myFixMsg.setString(int.Parse(myField.ID), myField.Value); } catch (Exception myE) { m_Log.Error("replace Extra tags error:", myE); } } if (myOrder.Account != null) { if (myOrder.Account.getValue().Length > 0) { myFixMsg.setField(myOrder.Account); } } try { //Send the message KaiTrade.Interfaces.Driver myDrv = AppFactory.Instance().GetDriverManager().GetDriver(myDriverCode); if (myDrv != null) { // save the existing clordid and set the new clordid myClOrdID = myOrder.ClOrdID; myOrder.ClOrdID = new QuickFix.ClOrdID(KaiUtil.Identities.Instance.genReqID()); myFixMsg.setField(myOrder.ClOrdID); // Associate the CLOrdID with this order AppFactory.Instance().GetOrderManager().AssociateClOrdID(myOrder.ClOrdID.getValue(), myOrder); if (newQty.HasValue) { myOrder.OrderQty = new QuickFix.OrderQty((double)newQty); myFixMsg.setField(myOrder.OrderQty); } if (newPrice.HasValue) { myOrder.Price = new QuickFix.Price((double)newPrice); myFixMsg.setField(myOrder.Price); } if (newStopPx.HasValue) { myOrder.StopPx = new QuickFix.StopPx((double)newStopPx); myFixMsg.setField(myOrder.StopPx); } // Set the FIX string as message data myMsg.Data = myFixMsg.ToString(); // inform order manager clients that the order has changed myOM.SetChanged(myOrder.Identity); // send the message for processing //myDrv.Send(myMsg); // send the message for processing order.LastOrderCommand = KaiTrade.Interfaces.LastOrderCommand.replace; //SendDelegate mySend = new SendDelegate(myDrv.Send); //IAsyncResult ar = mySend.BeginInvoke(myMsg, SRCallback, "123456789"); myDrv.Send(myMsg); } else { string myError = "Driver not found for code:" + myDriverCode; m_Log.Error(myError); Exception myE = new Exception(myError); throw myE; } } catch (Exception myE) { m_Log.Error("EditOrder:Sendnessage part" + myOrder.Identity, myE); myOrder.OrdStatus = new QuickFix.OrdStatus(QuickFix.OrdStatus.REJECTED); throw (myE); } } catch (Exception myE) { m_Log.Error("ReplaceOrder:", myE); if (myOrder != null) { myOrder.OrdStatus = new QuickFix.OrdStatus(QuickFix.OrdStatus.REJECTED); myOrder.Text = myE.Message; } throw (myE); } }
/// <summary> /// Cancel the order specified /// </summary> /// <param name="myID">ID of order to cancel</param> public void CancelOrder(string myID) { try { // Get Order KaiTrade.Interfaces.OrderManager myOM = AppFactory.Instance().GetOrderManager(); KaiTrade.Interfaces.Order myOrder = myOM.GetOrder(myID); if (myOrder == null) { string myError = "Order not found cannot cancel:" + myID; Exception myE = new Exception(myError); } if (m_ORLog.IsInfoEnabled) { m_ORLog.Info("CancelOrder:" + myOrder.ToString()); } if (order.LastOrderCommand == KaiTrade.Interfaces.LastOrderCommand.cancel) { string myError = "Order has already had a cancel processed - cannot recancel:" + myID; Exception myE = new Exception(myError); } // Is this a triggered order if (myOrder.TriggerOrderID.Length > 0) { KaiTrade.Interfaces.TriggeredOrder triggeredOrder = KTAFacade.Instance().Factory.GetTriggeredOrderManager().Get(myOrder.TriggerOrderID); triggeredOrder.Cancel(); return; } // store the clordID's //NOT USED? QuickFix.OrigClOrdID myOrigClOrdID; QuickFix.ClOrdID myClOrdID; if ((myOrder.OrdStatus.getValue() == QuickFix.OrdStatus.FILLED) || (myOrder.OrdStatus.getValue() == QuickFix.OrdStatus.CANCELED)) { // cannot cancel the order - so return return; } // Create a FIX cancel messsage QuickFix.Message myFixMsg = new QuickFix.Message(); QuickFix.MsgType msgType = new QuickFix.MsgType("F"); myFixMsg.getHeader().setField(msgType); QuickFix.BeginString myBeginString = new QuickFix.BeginString("FIX.4.4"); myFixMsg.getHeader().setField(myBeginString); // set the original to the existing clordid myOrder.OrigClOrdID = new QuickFix.OrigClOrdID(myOrder.ClOrdID.getValue()); myFixMsg.setField(myOrder.OrigClOrdID); // save the existing clordid and set the new clordid myClOrdID = myOrder.ClOrdID; myOrder.ClOrdID = new QuickFix.ClOrdID(KaiUtil.Identities.Instance.genReqID()); myFixMsg.setField(myOrder.ClOrdID); // Associate the CLOrdID with this order AppFactory.Instance().GetOrderManager().AssociateClOrdID(myOrder.ClOrdID.getValue(), myOrder); // OrderID if (myOrder.OrderID != null) { myFixMsg.setField(myOrder.OrderID); } ////Side myFixMsg.setField(myOrder.Side); // set up the product details in the message myOrder.Product.Set(myFixMsg); //// Transact Time myOrder.TransactTime = new QuickFix.TransactTime(DateTime.Now.ToUniversalTime()); myFixMsg.setField(myOrder.TransactTime); // Create the message wrapper used to send the order cancel to the driver KaiTrade.Interfaces.Message myMsg = new KaiTCPComm.KaiMessageWrap(); myMsg.Label = "F"; string myDriverCode = ""; // A trade venue must be specified on the order KaiTrade.Interfaces.Venue myVenue = null; if (myOrder.Product.TradeVenue.Length > 0) { // get the driver code and session details from the venue manager myVenue = AppFactory.Instance().GetVenueManager().GetVenue(myOrder.Product.TradeVenue); if (myVenue != null) { myDriverCode = myVenue.DriverCode; if (myVenue.TargetVenue.Length > 0) { myMsg.VenueCode = myVenue.TargetVenue; } if (myVenue.BeginString.Length > 0) { // this is the FIX version the server wants, we convert between // versions in the FIX client myMsg.Format = myVenue.BeginString; } if (myVenue.SID.Length > 0) { QuickFix.SenderCompID mySID = new QuickFix.SenderCompID(myVenue.SID); myFixMsg.getHeader().setField(mySID); myMsg.ClientID = myVenue.SID; } if (myVenue.TID.Length > 0) { QuickFix.TargetCompID myTID = new QuickFix.TargetCompID(myVenue.TID); myFixMsg.getHeader().setField(myTID); myMsg.TargetID = myVenue.TID; } } else { string myErr = "Invalid Venue Code:" + myOrder.Product.TradeVenue; m_Log.Error(myErr); Exception myE = new Exception(myErr); throw myE; } } else { string myErr = "No Venue Code specified on product:"; m_Log.Error(myErr); Exception myE = new Exception(myErr); throw myE; } // process any venue field bags - do this prior to the order bags // to allow the order setting to override the venues List<KaiTrade.Interfaces.Field> myFieldBag; KTAFacade.Instance().SetBag(out myFieldBag, myVenue.CancelBag, ","); foreach (KaiTrade.Interfaces.Field myField in myFieldBag) { try { myFixMsg.setString(int.Parse(myField.ID), myField.Value); } catch (Exception myE) { m_Log.Error("cancel Extra tags from venue error:", myE); } } // process any additional tags for the order foreach (KaiTrade.Interfaces.Field myField in myOrder.CancelBag) { try { myFixMsg.setString(int.Parse(myField.ID), myField.Value); } catch (Exception myE) { m_Log.Error("cancel Extra tags error:", myE); } } if (myOrder.Account != null) { if (myOrder.Account.getValue().Length > 0) { myFixMsg.setField(myOrder.Account); } } // Set the FIX string as message data myMsg.Data = myFixMsg.ToString(); // inform order manager clients that the order has changed myOM.SetChanged(myOrder.Identity); try { //Send the message KaiTrade.Interfaces.Driver myDrv = AppFactory.Instance().GetDriverManager().GetDriver(myDriverCode); if (myDrv != null) { // send the message for processing order.LastOrderCommand = KaiTrade.Interfaces.LastOrderCommand.cancel; //SendDelegate mySend = new SendDelegate(myDrv.Send); //IAsyncResult ar = mySend.BeginInvoke(myMsg, SRCallback, "123456789"); // send the message for processing myDrv.Send(myMsg); } else { string myError = "Driver not found for code:" + myDriverCode; m_Log.Error(myError); Exception myE = new Exception(myError); throw myE; } } catch (Exception myE) { m_Log.Error("CanceltOrder:" + myOrder.Identity, myE); myOrder.OrdStatus = new QuickFix.OrdStatus(QuickFix.OrdStatus.REJECTED); order.LastOrderCommand = KaiTrade.Interfaces.LastOrderCommand.none; throw (myE); } } catch (Exception myE) { m_Log.Error("CancelOrder:", myE); throw (myE); } }