Exemple #1
0
        private SymbolAlgorithm CreateAlgorithm(long symbol)
        {
            SymbolAlgorithm symbolAlgorithm;

            lock ( orderAlgorithmsLocker) {
                if (!orderAlgorithms.TryGetValue(symbol, out symbolAlgorithm))
                {
                    var symbolInfo = Factory.Symbol.LookupSymbol(symbol);
                    var orderCache = Factory.Engine.LogicalOrderCache(symbolInfo, false);
                    var algorithm  = Factory.Utility.OrderAlgorithm("limefix", symbolInfo, this, orderCache, OrderStore);
                    algorithm.EnableSyncTicks = SyncTicks.Enabled;
                    symbolAlgorithm           = new SymbolAlgorithm {
                        OrderAlgorithm = algorithm
                    };
                    orderAlgorithms.Add(symbol, symbolAlgorithm);
                    algorithm.OnProcessFill = ProcessFill;
                }
            }
            return(symbolAlgorithm);
        }
Exemple #2
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 + "'");
            }
        }