Пример #1
0
        /// <summary>
        /// Updates the order.
        /// </summary>
        /// <param name="pendingorder">The order.</param>
        /// <returns></returns>
        public bool UpdateOrder(PendingOrder pendingorder)
        {
            //Check if we can find this order
            if (!_activeOrders.TryGetValue(pendingorder.OrderId, out PendingOrder active))
            {
                return(false); //Cannot find order
            }
            lock (_locker)
            {
                //Update order instance
                pendingorder.UpdateOrder(active.Order);
            }

            //Send updated order notification
            OrderStateChange?.Invoke(this, OrderTicketEvent.Updated(active.OrderId, "Order was updated"));
            return(true);
        }
Пример #2
0
        /// <summary>
        /// Process submit order
        /// </summary>
        /// <param name="ticket"></param>
        protected virtual OrderTicketResponse SubmitOrder(SubmitOrderTicket ticket)
        {
            //Get order from factory
            PendingOrder pendingorder = OrderFactory.CreateOrder(ticket);
            OrderImpl    order        = pendingorder.Order as OrderImpl;

            //Round off order quantity for correct amounts
            RoundLotSize(order);

            //try and get the order from the order tracker
            if (!OrderTracker.TryAddOrder(pendingorder))
            {
                _log.Error($"Unable to add new order, order with id {pendingorder.OrderId} was already submitted");
                return(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.OrderAlreadyExists, $"Current order with id {pendingorder.OrderId} was already submitted"));
            }
            if (!OrderTracker.TryGetOrder(pendingorder.OrderId, out pendingorder))
            {
                _log.Error($"Unable to retrieve newly added order, order with id {pendingorder.OrderId} was cannot be processed properly");
                return(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.UnableToFindOrder, $"Current order with id {pendingorder.OrderId} cannot be found"));
            }

            //Round of prices
            RoundOrderPrices(order);

            //Set our new order
            pendingorder.UpdateOrder(order);

            //Check for correct size
            if (order.Quantity == 0)
            {
                order.State = OrderState.Invalid;
                var ticketresponse = OrderTicketResponse.Error(order.InternalId, OrderTicketResponseErrorCode.OrderQuantityZero);
                Portfolio.Log(LogLevel.Error, ticketresponse.ErrorMessage);
                return(ticketresponse);
            }

            //Check if we have enough capital for an order
            bool sufficientcapital = GetSufficientCapitalForOrder(pendingorder);

            if (!sufficientcapital)
            {
                //Not enough capital to execute this order
                order.State = OrderState.Invalid;
                var response = OrderTicketResponse.Error(order.InternalId,
                                                         OrderTicketResponseErrorCode.InsufficientBuyingPower, $"Cannot execute order with id {order.InternalId}, insufficient funds to execute order.");
                Portfolio.Log(LogLevel.Error, response.ErrorMessage);
                HandleOrderTicketEvent(OrderTicketEvent.Error(order.InternalId, $"Insufficent capital to execute order"));
                return(response);
            }

            //Check if broker accepts order at this moment
            try
            {
                if (!Portfolio.BrokerModel.CanSubmitOrder(order, out var message))
                {
                    //Broker model did not accept this order
                    order.State = OrderState.Invalid;
                    var response = OrderTicketResponse.Error(order.InternalId,
                                                             OrderTicketResponseErrorCode.BrokerageModelRefusedToSubmitOrder, $"Order with id {order.InternalId}: {message}");
                    Portfolio.Log(LogLevel.Error, "");
                    HandleOrderTicketEvent(OrderTicketEvent.Error(order.InternalId, $"Broker model of type {Portfolio.BrokerModel.BrokerType} declared order cannot be submitted, message: {message}"));
                    return(response);
                }
            }
            catch (Exception exc)
            {
                _log.Error(exc, $"Could not run CanSubmitOrder on order with id {order.InternalId}, please check the implemented logic");
                order.State = OrderState.Invalid;
                return(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.ProcessingError, $"Current order with id {pendingorder.OrderId} cannot be processed due to error"));
            }

            //Try to execute this order to the broker connection attached
            bool ordersuccess = false;

            try
            {
                ordersuccess = BrokerConnection.SubmitOrder(pendingorder);
            }
            catch (Exception exc)
            {
                _log.Error(exc);
            }

            //Check if placing the order was a success
            if (!ordersuccess)
            {
                order.State = OrderState.Invalid;
                var submitmessage = "BrokerConnection failed to place order";
                var response      = OrderTicketResponse.Error(order.InternalId,
                                                              OrderTicketResponseErrorCode.BrokerageFailedToSubmitOrder, submitmessage);
                Portfolio.Log(LogLevel.Error, submitmessage);
                HandleOrderTicketEvent(OrderTicketEvent.Error(order.InternalId, submitmessage));
                return(response);
            }

            order.State = OrderState.Submitted;
            return(OrderTicketResponse.Processed(order.InternalId));
        }