Beispiel #1
0
        /// <summary>
        /// This allows a part of the order to be closed, or all.
        /// </summary>
        public bool DecreaseVolume(int volumeDecrease, decimal?allowedSlippage, decimal?desiredPrice,
                                   out string operationResultMessage)
        {
            if (volumeDecrease == 0)
            {
                operationResultMessage = string.Empty;
                return(true);
            }

            if (this.OpenPrice.HasValue == false)
            {
                operationResultMessage = "Invalid order open price.";
                return(false);
            }

            if (State != OrderStateEnum.Executed && State != OrderStateEnum.Submitted)
            {
                operationResultMessage = "Close/Decrease volume can be done only to open/pending orders.";
                return(false);
            }

            if (volumeDecrease < 0)
            {
                operationResultMessage = "Positive volume decrease required.";
                return(false);
            }

            if (CurrentVolume < volumeDecrease)
            {
                operationResultMessage = "Misuse of the Order class [Can not close more volume than already open].";
                return(false);
            }

            decimal operationPrice;
            bool    operationResult = false;

            ISourceOrderExecution executionProvider = _executionProvider;

            if (executionProvider == null)
            {
                operationResultMessage = "Execution provider not assigned.";
                return(false);
            }

            DateTime closeTime = DateTime.MinValue;

            string modifiedId;

            if (_info.Volume == volumeDecrease)
            {// Close/Cancel order.
                if (State == OrderStateEnum.Executed)
                {
                    operationResult = OrderExecutionProvider.CloseOrder(Account.Info, this, allowedSlippage, desiredPrice, out operationPrice, out closeTime, out modifiedId, out operationResultMessage);
                }
                else
                {
                    operationPrice  = decimal.MinValue;
                    operationResult = OrderExecutionProvider.CancelPendingOrder(Account.Info, this, out modifiedId, out operationResultMessage);
                }
            }
            else
            {// Decrease order closeVolume.
                operationResult = OrderExecutionProvider.DecreaseOrderVolume(Account.Info, this, volumeDecrease, allowedSlippage, desiredPrice, out operationPrice, out modifiedId, out operationResultMessage);
            }

            if (operationResult == false)
            {
                SystemMonitor.Report("Order volume decrease has failed in executioner.");
                return(false);
            }

            if (string.IsNullOrEmpty(modifiedId))
            {// Since the original order has changed its ticket number; and we have failed to establish the new one - we can no longer track it so unregister.
                SystemMonitor.OperationWarning("Failed to establish new modified order ticket; order will be re-aquired.", TracerItem.PriorityEnum.High);
                Account.TradeEntities.RemoveOrder(this);

                return(true);
            }

            if (State == OrderStateEnum.Executed)
            {
                if (modifiedId != this.Id)
                {
                    Account.TradeEntities.RemoveOrder(this);

                    OrderInfo newUpdatedInfo = _info;
                    newUpdatedInfo.Id     = modifiedId;
                    newUpdatedInfo.Volume = _info.Volume - volumeDecrease;

                    ActiveOrder updatedOrder = new ActiveOrder(_manager, _executionProvider, _quoteProvider, _dataSourceId, Symbol, true);
                    updatedOrder.AdoptInfo(newUpdatedInfo);
                    _executionProvider.TradeEntities.AddOrder(updatedOrder);

                    // Request updated order info for this and new one and remove current one.
                    if (_executionProvider != null && _executionProvider.DefaultAccount != null && string.IsNullOrEmpty(modifiedId) == false)
                    {
                        _executionProvider.BeginOrdersInformationUpdate(_executionProvider.DefaultAccount.Info, new string[] { this.Id, modifiedId }, out operationResultMessage);
                    }
                }
                else
                {
                    _info.Volume = _info.Volume - volumeDecrease;

                    if (_info.Volume == 0)
                    {
                        State            = OrderStateEnum.Closed;
                        _info.CloseTime  = closeTime;
                        _info.ClosePrice = operationPrice;
                    }
                }
            }
            else if (State == OrderStateEnum.Submitted)
            {
                lock (this)
                {
                    _initialVolume -= volumeDecrease;
                    _info.Volume    = _initialVolume;

                    if (_info.Volume == 0)
                    {
                        State = OrderStateEnum.Canceled;
                    }
                }
            }

            if (State == OrderStateEnum.Closed)
            {// Closed.
                RaiseOrderUpdatedEvent(UpdateTypeEnum.Closed);
            }
            else
            {// Still open.
                RaiseOrderUpdatedEvent(UpdateTypeEnum.VolumeChanged);
            }

            return(true);
        }