Beispiel #1
0
        public void SendFill(MessageFIX4_2 packetFIX)
        {
            var clientOrderId = 0L;

            long.TryParse(packetFIX.ClientOrderId, out clientOrderId);
            var originalClientOrderId = 0L;

            long.TryParse(packetFIX.ClientOrderId, out originalClientOrderId);
            if (debug)
            {
                log.Debug("SendFill( " + packetFIX.ClientOrderId + ")");
            }
            var             symbolInfo = Factory.Symbol.LookupSymbol(packetFIX.Symbol);
            var             timeZone   = new SymbolTimeZone(symbolInfo);
            SymbolAlgorithm algorithm;

            if (!TryGetAlgorithm(symbolInfo.BinaryIdentifier, out algorithm))
            {
                log.Info("Fill received but OrderAlgorithm not found for " + symbolInfo + ". Ignoring.");
                return;
            }
            var fillPosition = packetFIX.LastQuantity * SideToSign(packetFIX.Side);

            if (GetSymbolStatus(symbolInfo))
            {
                CreateOrChangeOrder order;
                if (OrderStore.TryGetOrderById(clientOrderId, out order))
                {
                    TimeStamp executionTime;
                    if (UseLocalFillTime)
                    {
                        executionTime = TimeStamp.UtcNow;
                    }
                    else
                    {
                        executionTime = new TimeStamp(packetFIX.TransactionTime);
                    }
                    var configTime = executionTime;
                    configTime.AddSeconds(timeZone.UtcOffset(executionTime));
                    var fill = Factory.Utility.PhysicalFill(fillPosition, packetFIX.LastPrice, configTime, executionTime, order.BrokerOrder, false, packetFIX.OrderQuantity, packetFIX.CumulativeQuantity, packetFIX.LeavesQuantity, IsRecovered, true);
                    if (debug)
                    {
                        log.Debug("Sending physical fill: " + fill);
                    }
                    algorithm.OrderAlgorithm.ProcessFill(fill);
                    algorithm.OrderAlgorithm.ProcessOrders();
                    TrySendStartBroker(symbolInfo, "position sync on fill");
                }
                else
                {
                    algorithm.OrderAlgorithm.IncreaseActualPosition(fillPosition);
                    log.Notice("Fill id " + packetFIX.ClientOrderId + " not found. Must have been a manual trade.");
                    if (SyncTicks.Enabled)
                    {
                        var tickSync = SyncTicks.GetTickSync(symbolInfo.BinaryIdentifier);
                        tickSync.RemovePhysicalFill(packetFIX.ClientOrderId);
                    }
                }
            }
        }
Beispiel #2
0
        private CreateOrChangeOrder ConstructCancelOrder(MessageFIX4_2 packet, string clientOrderId)
        {
            if (string.IsNullOrEmpty(clientOrderId))
            {
                var message = "Client order id was null or empty. FIX Message is: " + packet;
                log.Error(message);
                throw new ApplicationException(message);
            }
            var  symbol    = Factory.Symbol.LookupSymbol(packet.Symbol);
            var  side      = OrderSide.Buy;
            var  type      = OrderType.None;
            var  logicalId = 0;
            long clientId;

            if (!long.TryParse(clientOrderId, out clientId))
            {
                log.Error("original client order id " + clientOrderId +
                          " cannot be converted to long: " + packet);
                clientId = 0;
            }
            var utcCreateTime = new TimeStamp(packet.TimeStamp);
            var physicalOrder = Factory.Utility.PhysicalOrder(
                OrderAction.Cancel, OrderState.Active, symbol, side, type, OrderFlags.None,
                0D, 0, logicalId, 0, clientId, null, utcCreateTime);

            if (debug)
            {
                log.Debug("Received physical Order: " + physicalOrder);
            }
            return(physicalOrder);
        }
Beispiel #3
0
        private void FIXRequestSessionStatus(MessageFIX4_2 packet)
        {
            if (packet.TradingSessionId != "TSSTATE")
            {
                throw new ApplicationException("Expected TSSTATE for trading session id but was: " + packet.TradingSessionId);
            }
            if (!packet.TradingSessionRequestId.Contains(sender) || !packet.TradingSessionRequestId.Contains(packet.Sequence.ToString()))
            {
                throw new ApplicationException("Expected unique trading session request id but was:" + packet.TradingSessionRequestId);
            }

            requestSessionStatus = true;
            if (onlineNextTime)
            {
                ProviderSimulator.SetOrderServerOnline();
                onlineNextTime = false;
            }
            if (ProviderSimulator.IsOrderServerOnline)
            {
                SendSessionStatusOnline();
            }
            else
            {
                SendSessionStatus("3");
            }
            onlineNextTime = true;
        }
Beispiel #4
0
        private void FIXCreateOrder(MessageFIX4_2 packet)
        {
            if (debug)
            {
                log.Debug("FIXCreateOrder() for " + packet.Symbol + ". Client id: " + packet.ClientOrderId);
            }
            var symbol = Factory.Symbol.LookupSymbol(packet.Symbol);
            var order  = ConstructOrder(packet, packet.ClientOrderId);

            if (!ProviderSimulator.IsOrderServerOnline)
            {
                if (debug)
                {
                    log.Debug(symbol + ": Rejected " + packet.ClientOrderId + ". Order server offline.");
                }
                OnRejectOrder(order, symbol + ": Order Server Offline.");
                return;
            }
            var simulator = simulators[SimulatorType.RejectSymbol];

            if (FixFactory != null && simulator.CheckFrequencyAndSymbol(symbol))
            {
                if (debug)
                {
                    log.Debug("Simulating create order reject of 35=" + packet.MessageType);
                }
                OnRejectOrder(order, "Testing reject of create order");
                return;
            }
            simulator = simulators[SimulatorType.ServerOfflineReject];
            if (FixFactory != null && simulator.CheckFrequency())
            {
                if (debug)
                {
                    log.Debug("Simulating order server offline business reject of 35=" + packet.MessageType);
                }
                OnBusinessRejectOrder(packet.ClientOrderId, "Server offline for create order.");
                ProviderSimulator.SwitchBrokerState("offline", false);
                ProviderSimulator.SetOrderServerOffline();
                return;
            }
            if (packet.Symbol == "TestPending")
            {
                log.Info("Ignoring FIX order since symbol is " + packet.Symbol);
            }
            else
            {
                if (string.IsNullOrEmpty(packet.ClientOrderId))
                {
                    System.Diagnostics.Debugger.Break();
                }
                ProviderSimulator.CreateOrder(order);
                ProcessCreateOrder(order);
                ProviderSimulator.TryProcessAdustments(order);
            }
            return;
        }
Beispiel #5
0
 private void TryHandlePiggyBackFill(MessageFIX4_2 packetFIX)
 {
     if (packetFIX.LastQuantity > 0)
     {
         if (debug)
         {
             log.Debug("TryHandlePiggyBackFill triggering fill because LastQuantity = " + packetFIX.LastQuantity);
         }
         SendFill(packetFIX);
     }
 }
Beispiel #6
0
        private void FIXPositionList(MessageFIX4_2 packet)
        {
            var mbtMsg = (FIXMessage4_4)FixFactory.Create();

            mbtMsg.SetText("DONE");
            mbtMsg.AddHeader("AO");
            if (debug)
            {
                log.Debug("Sending end of position list: " + mbtMsg);
            }
            SendMessage(mbtMsg);
        }
Beispiel #7
0
        private void FIXOrderList(MessageFIX4_2 packet)
        {
            var mbtMsg = (FIXMessage4_4)FixFactory.Create();

            mbtMsg.SetText("END");
            mbtMsg.AddHeader("8");
            if (debug)
            {
                log.Debug("Sending end of order list: " + mbtMsg);
            }
            SendMessage(mbtMsg);
        }
Beispiel #8
0
        private void BusinessReject(MessageFIX4_2 packetFIX)
        {
            var lower     = packetFIX.Text.ToLower();
            var text      = packetFIX.Text;
            var errorOkay = false;

            log.Error(packetFIX.Text + " -- Sending EndBroker event.");
            CancelRecovered();
            TrySendEndBroker();
            TryEndRecovery();
            log.Info(packetFIX.Text + " Sent EndBroker event due to Message:\n" + packetFIX);
            if (!errorOkay)
            {
                string message = "FIX Server reported an error: " + packetFIX.Text + "\n" + packetFIX;
                throw new ApplicationException(message);
            }
        }
Beispiel #9
0
        public void RejectOrder(MessageFIX4_2 packetFIX)
        {
            var clientOrderId = 0L;

            long.TryParse(packetFIX.ClientOrderId, out clientOrderId);
            var originalClientOrderId = 0L;

            long.TryParse(packetFIX.ClientOrderId, out originalClientOrderId);
            if (packetFIX.Text.Contains("Order Server Offline") ||
                packetFIX.Text.Contains("Trading temporarily unavailable") ||
                packetFIX.Text.Contains("Order Server Not Available"))
            {
                CancelRecovered();
                TrySendEndBroker();
                TryEndRecovery();
            }

            var             symbol = Factory.Symbol.LookupSymbol(packetFIX.Symbol);
            SymbolAlgorithm algorithm;

            if (TryGetAlgorithm(symbol.BinaryIdentifier, out algorithm))
            {
                if (IsRecovered && algorithm.OrderAlgorithm.RejectRepeatCounter > 0)
                {
                    var message = "Order Rejected: " + packetFIX.Text + "\n" + packetFIX;
                    log.Warn(message);
                }

                var retryImmediately = algorithm.OrderAlgorithm.RejectRepeatCounter < 1;
                algorithm.OrderAlgorithm.RejectOrder(clientOrderId, IsRecovered, retryImmediately);
                if (!retryImmediately)
                {
                    TrySendEndBroker(symbol);
                }
            }
            else
            {
                log.Info("RejectOrder but OrderAlgorithm not found for " + symbol + ". Ignoring.");
            }
        }
Beispiel #10
0
        private void CancelRejected(MessageFIX4_2 packetFIX)
        {
            var clientOrderId = 0L;

            long.TryParse(packetFIX.ClientOrderId, out clientOrderId);
            var originalClientOrderId = 0L;

            long.TryParse(packetFIX.ClientOrderId, out originalClientOrderId);
            if (debug && (LogRecovery || !IsRecovery))
            {
                log.Debug("CancelRejected: " + packetFIX);
            }
            string orderStatus = packetFIX.OrderStatus;

            switch (orderStatus)
            {
            case "2":      //Filled
                var rejectReason = false;

                if (packetFIX.Text.Contains("Unknown order") || packetFIX.Text.Contains("Order is completed"))
                {
                    rejectReason = true;
                    log.Warn("RemoveOriginal=FALSE for: " + packetFIX.Text);
                    //removeOriginal = true;
                }
                else
                {
                    log.Error("Unknown text meesage in CancelReject: " + packetFIX.Text);
                }


                CreateOrChangeOrder order;
                if (OrderStore.TryGetOrderById(clientOrderId, out order))
                {
                    var             symbol = order.Symbol;
                    SymbolAlgorithm algorithm;
                    if (!TryGetAlgorithm(symbol.BinaryIdentifier, out algorithm))
                    {
                        log.Info("Cancel rejected but OrderAlgorithm not found for " + symbol + ". Ignoring.");
                        break;
                    }
                    var retryImmediately = true;
                    algorithm.OrderAlgorithm.RejectOrder(clientOrderId, IsRecovered, retryImmediately);
                }
                else
                {
                    if (debug)
                    {
                        log.Debug("Order not found for " + clientOrderId + ". Probably allready filled or canceled.");
                    }
                }

                if (!rejectReason && IsRecovered)
                {
                    var message  = "Order Rejected: " + packetFIX.Text + "\n" + packetFIX;
                    var stopping = "The cancel reject error message '" + packetFIX.Text + "' was unrecognized. ";
                    log.Warn(message);
                    log.Error(stopping);
                }
                else
                {
                    if (LogRecovery || !IsRecovery)
                    {
                        log.Info("CancelReject(" + packetFIX.Text + ") Removed cancel order: " + packetFIX.ClientOrderId);
                    }
                }
                break;

            default:
                throw new ApplicationException("Unknown cancel rejected order status: '" + orderStatus + "'");
            }
        }
Beispiel #11
0
        private void ExecutionReport(MessageFIX4_2 packetFIX)
        {
            var clientOrderId = 0L;

            long.TryParse(packetFIX.ClientOrderId, out clientOrderId);
            var originalClientOrderId = 0L;

            long.TryParse(packetFIX.ClientOrderId, out originalClientOrderId);
            if (packetFIX.Text == "END")
            {
                throw new ApplicationException("Unexpected END in FIX Text field. Never sent a 35=AF message.");
            }
            SymbolAlgorithm algorithm  = null;
            SymbolInfo      symbolInfo = packetFIX.Symbol != null?Factory.Symbol.LookupSymbol(packetFIX.Symbol) : null;

            if (symbolInfo != null)
            {
                TryGetAlgorithm(symbolInfo.BinaryIdentifier, out algorithm);
            }

            string orderStatus = packetFIX.OrderStatus;

            switch (orderStatus)
            {
            case "0":     // New
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport New: " + packetFIX);
                }
                if (algorithm == null)
                {
                    log.Info("New order but OrderAlgorithm not found for " + symbolInfo + ". Ignoring.");
                    break;
                }
                CreateOrChangeOrder order = null;
                OrderStore.TryGetOrderById(clientOrderId, out order);
                if (order != null && symbolInfo.FixSimulationType == FIXSimulationType.BrokerHeldStopOrder)     // Stop Order
                {
                    if (order.Type == OrderType.BuyStop || order.Type == OrderType.SellStop)
                    {
                        if (debug)
                        {
                            log.Debug("New order message for Forex Stop: " + packetFIX);
                        }
                        break;
                    }
                }
                algorithm.OrderAlgorithm.ConfirmCreate(clientOrderId, IsRecovered);
                TrySendStartBroker(symbolInfo, "sync on confirm cancel");
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                break;

            case "1":     // Partial
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Partial: " + packetFIX);
                }
                //UpdateOrder(packetFIX, OrderState.Active, null);
                SendFill(packetFIX);
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                break;

            case "2":      // Filled
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Filled: " + packetFIX);
                }
                if (packetFIX.CumulativeQuantity < packetFIX.LastQuantity)
                {
                    log.Warn("Ignoring message due to CumQty " + packetFIX.CumulativeQuantity + " less than " + packetFIX.LastQuantity + ". This is a workaround for a MBT FIX server which sends an extra invalid fill message on occasion.");
                    break;
                }
                SendFill(packetFIX);
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                break;

            case "5":     // Replaced
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Replaced: " + packetFIX);
                }
                if (algorithm == null)
                {
                    log.Info("ConfirmChange but OrderAlgorithm not found for " + symbolInfo + ". Ignoring.");
                    break;
                }
                algorithm.OrderAlgorithm.ConfirmChange(clientOrderId, IsRecovered);
                TrySendStartBroker(symbolInfo, "sync on confirm change");
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                break;

            case "4":     // Canceled
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Canceled: " + packetFIX);
                }
                if (algorithm == null)
                {
                    log.Info("Order Canceled but OrderAlgorithm not found for " + symbolInfo + ". Ignoring.");
                    break;
                }
                if (clientOrderId != 0)
                {
                    algorithm.OrderAlgorithm.ConfirmCancel(clientOrderId, IsRecovered);
                    TrySendStartBroker(symbolInfo, "sync on confirm cancel");
                }
                else if (originalClientOrderId != 0)
                {
                    algorithm.OrderAlgorithm.ConfirmCancel(originalClientOrderId, IsRecovered);
                    TrySendStartBroker(symbolInfo, "sync on confirm cancel orig order");
                }
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                break;

            case "6":     // Pending Cancel
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Pending Cancel: " + packetFIX);
                }
                if (!string.IsNullOrEmpty(packetFIX.Text) && packetFIX.Text.Contains("multifunction order"))
                {
                    if (debug && (LogRecovery || IsRecovered))
                    {
                        log.Debug("Pending cancel of multifunction order, so removing " + packetFIX.ClientOrderId + " and " + packetFIX.OriginalClientOrderId);
                    }
                    if (clientOrderId != 0L)
                    {
                        OrderStore.RemoveOrder(clientOrderId);
                    }
                    if (originalClientOrderId != 0L)
                    {
                        OrderStore.RemoveOrder(originalClientOrderId);
                    }
                    break;
                }
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                TryHandlePiggyBackFill(packetFIX);
                break;

            case "8":     // Rejected
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Reject: " + packetFIX);
                }
                RejectOrder(packetFIX);
                break;

            case "9":     // Suspended
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Suspended: " + packetFIX);
                }
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                break;

            case "A":     // PendingNew
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Pending New: " + packetFIX);
                }
                if (algorithm == null)
                {
                    log.Info("PendingNew but OrderAlgorithm not found for " + symbolInfo + ". Ignoring.");
                    break;
                }

                OrderStore.TryGetOrderById(clientOrderId, out order);
                if (order != null && symbolInfo.FixSimulationType == FIXSimulationType.BrokerHeldStopOrder &&
                    (order.Type == OrderType.BuyStop || order.Type == OrderType.SellStop))
                {
                    if (packetFIX.ExecutionType == "D")      // Restated
                    {
                        if (debug)
                        {
                            log.Debug("Ignoring restated message 150=D for Forex stop execution report 39=A.");
                        }
                    }
                    else
                    {
                        algorithm.OrderAlgorithm.ConfirmCreate(originalClientOrderId, IsRecovered);
                    }
                }
                else
                {
                    algorithm.OrderAlgorithm.ConfirmActive(originalClientOrderId, IsRecovered);
                }
                TrySendStartBroker(symbolInfo, "sync on confirm cancel orig order");
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                break;

            case "E":     // Pending Replace
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Pending Replace: " + packetFIX);
                }
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                TryHandlePiggyBackFill(packetFIX);
                break;

            case "R":     // Resumed.
                if (debug && (LogRecovery || !IsRecovery))
                {
                    log.Debug("ExecutionReport Resumed: " + packetFIX);
                }
                OrderStore.SetSequences(RemoteSequence, FixFactory.LastSequence);
                //UpdateOrder(packetFIX, OrderState.Active, null);
                // Ignore
                break;

            default:
                throw new ApplicationException("Unknown order status: '" + orderStatus + "'");
            }
        }
Beispiel #12
0
        private CreateOrChangeOrder ConstructOrder(MessageFIX4_2 packet, string clientOrderId)
        {
            if (string.IsNullOrEmpty(clientOrderId))
            {
                var message = "Client order id was null or empty. FIX Message is: " + packet;
                log.Error(message);
                throw new ApplicationException(message);
            }
            var symbol = Factory.Symbol.LookupSymbol(packet.Symbol);
            var side   = OrderSide.Buy;

            switch (packet.Side)
            {
            case "1":
                side = OrderSide.Buy;
                break;

            case "2":
                side = OrderSide.Sell;
                break;

            case "5":
            case "9":
                side = OrderSide.SellShort;
                break;
            }
            var type = OrderType.BuyLimit;

            switch (packet.OrderType)
            {
            case "1":
                if (side == OrderSide.Buy)
                {
                    type = OrderType.BuyMarket;
                }
                else
                {
                    type = OrderType.SellMarket;
                }
                break;

            case "2":
                if (side == OrderSide.Buy)
                {
                    type = OrderType.BuyLimit;
                }
                else
                {
                    type = OrderType.SellLimit;
                }
                break;

            default:
                //throw new LimeException("Unsupported Order Type");
                log.Error("Unsupported order type");
                return(null);
            }

            long clientId;
            var  logicalId = 0;

            if (!long.TryParse(clientOrderId, out clientId))
            {
                log.Error("original client order id " + clientOrderId +
                          " cannot be converted to long: " + packet);
                clientId = 0;
            }
            //var utcCreateTime = new TimeStamp(packet.TransactionTime);
            var utcCreateTime = new TimeStamp(packet.TimeStamp);
            var physicalOrder = Factory.Utility.PhysicalOrder(
                OrderAction.Create, OrderState.Active, symbol, side, type, OrderFlags.None,
                packet.Price, packet.OrderQuantity, logicalId, 0, clientId, null, utcCreateTime);

            if (debug)
            {
                log.Debug("Received physical Order: " + physicalOrder);
            }
            return(physicalOrder);
        }
Beispiel #13
0
        private void FIXCancelOrder(MessageFIX4_2 packet)
        {
            var symbol = Factory.Symbol.LookupSymbol(packet.Symbol);

            if (!ProviderSimulator.IsOrderServerOnline)
            {
                throw new LimeException("Order server offline testing for Lime not yet implemeneted");
                if (debug)
                {
                    log.Debug(symbol + ": Cannot cancel order by client id: " + packet.OriginalClientOrderId + ". Order Server Offline.");
                }
                OnRejectCancel(packet.Symbol, packet.ClientOrderId, packet.OriginalClientOrderId, symbol + ": Order Server Offline");
                return;
            }
            var simulator = simulators[SimulatorType.RejectSymbol];

            if (FixFactory != null && simulator.CheckFrequencyAndSymbol(symbol))
            {
                if (debug)
                {
                    log.Debug("Simulating cancel order reject of 35=" + packet.MessageType);
                }
                OnRejectCancel(packet.Symbol, packet.ClientOrderId, packet.OriginalClientOrderId, "Testing reject of cancel order.");
                return;
            }
            simulator = simulators[SimulatorType.ServerOfflineReject];
            if (FixFactory != null && simulator.CheckFrequency())
            {
                throw new LimeException("Order server offline testing for Lime not yet implemeneted");
                if (debug)
                {
                    log.Debug("Simulating order server offline business reject of 35=" + packet.MessageType);
                }
                OnBusinessRejectOrder(packet.ClientOrderId, "Server offline for cancel order.");
                ProviderSimulator.SwitchBrokerState("offline", false);
                ProviderSimulator.SetOrderServerOffline();
                return;
            }
            if (debug)
            {
                log.Debug("FIXCancelOrder() for " + packet.Symbol + ". Original client id: " + packet.OriginalClientOrderId);
            }
            CreateOrChangeOrder origOrder = null;

            try
            {
                long origClientId;
                if (!long.TryParse(packet.OriginalClientOrderId, out origClientId))
                {
                    log.Error("original client order id " + packet.OriginalClientOrderId +
                              " cannot be converted to long: " + packet);
                    origClientId = 0;
                }
                origOrder = ProviderSimulator.GetOrderById(symbol, origClientId);
            }
            catch (ApplicationException)
            {
                if (debug)
                {
                    log.Debug(symbol + ": Cannot cancel order by client id: " + packet.OriginalClientOrderId + ". Probably already filled or canceled.");
                }
                OnRejectCancel(packet.Symbol, packet.ClientOrderId, packet.OriginalClientOrderId, "No such order");
                return;
            }
            var cancelOrder = ConstructCancelOrder(packet, packet.ClientOrderId);

            cancelOrder.OriginalOrder = origOrder;
            ProviderSimulator.CancelOrder(cancelOrder);
            ProcessCancelOrder(cancelOrder);
            ProviderSimulator.TryProcessAdustments(cancelOrder);
            return;
        }
Beispiel #14
0
        private void FIXChangeOrder(MessageFIX4_2 packet)
        {
            var symbol = Factory.Symbol.LookupSymbol(packet.Symbol);
            var order  = ConstructOrder(packet, packet.ClientOrderId);

            if (!ProviderSimulator.IsOrderServerOnline)
            {
                throw new LimeException("Order server offline testing for Lime not yet implemeneted");
                log.Info(symbol + ": Rejected " + packet.ClientOrderId + ". Order server offline.");
                OnRejectOrder(order, symbol + ": Order Server Offline.");
                return;
            }
            var simulator = simulators[SimulatorType.RejectSymbol];

            if (FixFactory != null && simulator.CheckFrequencyAndSymbol(symbol))
            {
                if (debug)
                {
                    log.Debug("Simulating create order reject of 35=" + packet.MessageType);
                }
                OnRejectOrder(order, "Testing reject of change order.");
                return;
            }
            simulator = simulators[SimulatorType.ServerOfflineReject];
            if (FixFactory != null && simulator.CheckFrequency())
            {
                throw new LimeException("Order server offline testing for Lime not yet implemeneted");
                if (debug)
                {
                    log.Debug("Simulating order server offline business reject of 35=" + packet.MessageType);
                }
                OnBusinessRejectOrder(packet.ClientOrderId, "Server offline for change order.");
                ProviderSimulator.SwitchBrokerState("offline", false);
                ProviderSimulator.SetOrderServerOffline();
                return;
            }
            CreateOrChangeOrder origOrder = null;

            if (debug)
            {
                log.Debug("FIXChangeOrder() for " + packet.Symbol + ". Client id: " + packet.ClientOrderId + ". Original client id: " + packet.OriginalClientOrderId);
            }
            try
            {
                long origClientId;
                if (!long.TryParse(packet.OriginalClientOrderId, out origClientId))
                {
                    log.Error("original client order id " + packet.OriginalClientOrderId + " cannot be converted to long: " + packet);
                    origClientId = 0;
                }
                origOrder = ProviderSimulator.GetOrderById(symbol, origClientId);
            }
            catch (ApplicationException ex)
            {
                if (debug)
                {
                    log.Debug(symbol + ": Rejected " + packet.ClientOrderId + ". Cannot change order: " + packet.OriginalClientOrderId + ". Already filled or canceled.  Message: " + ex.Message);
                }
                OnRejectOrder(order, symbol + ": Cannot change order. Probably already filled or canceled.");
                return;
            }
            order.OriginalOrder = origOrder;
#if VERIFYSIDE
            if (order.Side != origOrder.Side)
            {
                var message = symbol + ": Cannot change " + origOrder.Side + " to " + order.Side;
                log.Error(message);
                OnRejectOrder(order, false, message);
                return;
            }
            if (order.Type != origOrder.Type)
            {
                var message = symbol + ": Cannot change " + origOrder.Type + " to " + order.Type;
                log.Error(message);
                OnRejectOrder(order, false, message);
                return;
            }
#endif
            ProviderSimulator.ChangeOrder(order);
            ProcessChangeOrder(order);
        }