예제 #1
0
        /// <summary>
        /// Process submit order
        /// </summary>
        /// <param name="ticket"></param>
        protected virtual OrderTicketResponse CancelOrder(CancelOrderTicket ticket)
        {
            //Check if we can get the order
            if (!OrderTracker.TryGetOrder(ticket.OrderId, out PendingOrder pendingorder))
            {
                _log.Error($"Unable to cancel order with ID {ticket.OrderId}, order id unkown.");
                return(OrderTicketResponse.Error(ticket.OrderId, OrderTicketResponseErrorCode.UnableToFindOrder));
            }

            //Check if order is closed
            if (pendingorder.Order.State.IsDone())
            {
                return(OrderTicketResponse.Error(ticket.OrderId, OrderTicketResponseErrorCode.InvalidOrderStatus));
            }

            //try and cancel the order
            bool ordercancelled = false;

            try
            {
                ordercancelled = BrokerConnection.CancelOrder(pendingorder);
            }
            catch (Exception exc)
            {
                _log.Error(exc, $"Could not cancel order with id {ticket.OrderId} broker connection refused to do so");
            }

            //If not managed to cancel
            if (!ordercancelled)
            {
                var message = $"Brokerconnection failed to cancel order with id {ticket.OrderId}";
                Portfolio.Log(LogLevel.Error, message);
                HandleOrderTicketEvent(OrderTicketEvent.Error(ticket.OrderId));
                return(OrderTicketResponse.Error(ticket.OrderId, OrderTicketResponseErrorCode.BrokerageFailedToCancelOrder));
            }

            //Order was cancelled
            var order = pendingorder.Order as OrderImpl;

            order.State = OrderState.Cancelled;
            pendingorder.UpdateOrder(order);

            //Return result for order ticket
            return(OrderTicketResponse.Processed(ticket.OrderId));
        }
예제 #2
0
        /// <summary>
        /// Processes the market data.
        /// </summary>
        /// <param name="dataupdates">The data updates.</param>
        public void ProcessMarketData(DataUpdates dataupdates)
        {
            //Only accept market data
            if (_activeOrders.Count == 0)
            {
                return;
            }

            //Check if we have any data
            if (!dataupdates.HasUpdates)
            {
                return;
            }

            lock (_locker)
            {
                foreach (var pkv in _activeOrders.OrderBy(x => x.Key))
                {
                    //get the order
                    var pendingorder = pkv.Value;
                    var order        = pendingorder.Order;

                    //Get datapoint
                    if (!dataupdates[order.Security].HasUpdates)
                    {
                        continue;
                    }

                    var datapoint = dataupdates[order.Security].Ticks.Count > 0
                        ? dataupdates[order.Security].Ticks.First().Value.First() as DataPoint
                        : dataupdates[order.Security].QuoteBars.Count > 0
                            ? dataupdates[order.Security].QuoteBars.First().Value as DataPoint
                            : dataupdates[order.Security].TradeBars.Count > 0
                                ? dataupdates[order.Security].TradeBars.First().Value as DataPoint
                                : null;

                    if (datapoint == null)
                    {
                        continue;
                    }

                    //Check if order is already done
                    if (order.State.IsDone())
                    {
                        _activeOrders.TryRemove(pkv.Key, out pendingorder);
                        continue;
                    }

                    //Check if we have enough buying power
                    if (!_portfolio.OrderTicketHandler.GetSufficientCapitalForOrder(pendingorder))
                    {
                        //Remove order from active orders, as it is cancelled by the broker instance
                        _activeOrders.TryRemove(pkv.Key, out pendingorder);
                        _portfolio.Log(LogLevel.Error, $"Insufficient funds to process order by sim broker");
                        OrderStateChange?.Invoke(this, OrderTicketEvent.Cancelled(pendingorder.OrderId, "Insufficient funds to process order by sim broker"));
                    }

                    //Check if we need to fill this order
                    var  fillmodel    = BrokerModel.GetFillModel(order);
                    Fill filledresult = Fill.NoFill();

                    try
                    {
                        filledresult = fillmodel.FillOrder(BrokerModel, datapoint, pendingorder, _usehighlyliquidfills);
                    }
                    catch (Exception exc)
                    {
                        _log.Error(exc);
                        _portfolio.Log(LogLevel.Error, string.Format("Order Error: id: {0}, Transaction model failed to fill for order type: {1} with error: {2}", order.InternalId, order.Type, exc.Message));
                        OrderStateChange?.Invoke(this, OrderTicketEvent.Cancelled(pendingorder.OrderId, "Exception during processing fill for this order, please check logs"));
                    }

                    //Check for any full or partial fills
                    if (filledresult.FillQuantity > 0)
                    {
                        if (filledresult.Status == OrderState.Filled)
                        {
                            OrderStateChange?.Invoke(this, OrderTicketEvent.Filled(order.InternalId, filledresult));
                        }
                        else if (filledresult.Status == OrderState.PartialFilled)
                        {
                            OrderStateChange?.Invoke(this, OrderTicketEvent.PartiallyFilled(order.InternalId, filledresult));
                        }
                    }

                    //Check if order is done
                    if (filledresult.Status.IsDone())
                    {
                        _activeOrders.TryRemove(pkv.Key, out pendingorder);
                    }
                }
            }
        }