Example #1
0
        /// <summary>
        /// Change order execution related parameters.
        /// </summary>
        /// <param name="remoteStopLoss">Applicable to open or pending orders only, pass null to skip, decimal.MinValue (or zero) to signify no value.</param>
        /// <param name="remoteTakeProfit">Applicable to open or pending orders only, pass null to skip, decimal.MinValue (or zero) to signify no value.</param>
        /// <param name="operationResultMessage">Applicable ONLY to pending order. Pass null otherwise or to leave unchanged.</param>
        /// <returns></returns>
        public bool ModifyRemoteParameters(decimal?remoteStopLoss, decimal?remoteTakeProfit, decimal?remoteTargetOpenPrice,
                                           out string operationResultMessage)
        {
            if (this.IsOpenOrPending == false)
            {
                operationResultMessage = "Wrong order state.";
                return(false);
            }

            if (State != OrderStateEnum.Submitted && remoteTargetOpenPrice.HasValue)
            {
                operationResultMessage = "Wrong order state for this operation (operation only applicable to pending orders).";
                return(false);
            }

            if (remoteStopLoss == StopLoss && TakeProfit == remoteTakeProfit)
            {
                // remoteTargetOpenPrice only counts if you do it on a pending order.
                if ((State == OrderStateEnum.Submitted && remoteTargetOpenPrice == OpenPrice) ||
                    (State != OrderStateEnum.Submitted))
                {// No changes needed.
                    operationResultMessage = "No changes needed.";
                    return(true);
                }
            }

            operationResultMessage = "Session not assigned.";
            ISourceOrderExecution executionProvider = _executionProvider;
            string modifiedId;

            if (executionProvider == null || OrderExecutionProvider.ModifyOrder(Account.Info, this, remoteStopLoss, remoteTakeProfit, remoteTargetOpenPrice,
                                                                                out modifiedId, out operationResultMessage) == false)
            {
                return(false);
            }

            //lock (this)
            //{
            //    //_info.Id = modifiedId;
            //    if (remoteStopLoss.HasValue)
            //    {
            //        _info.StopLoss = remoteStopLoss;
            //    }

            //    if (remoteTakeProfit.HasValue)
            //    {
            //        _info.TakeProfit = remoteTakeProfit;
            //    }

            //    if (remoteTargetOpenPrice.HasValue)
            //    {
            //        _info.OpenPrice = remoteTargetOpenPrice.Value;
            //    }
            //}

            //RaiseOrderUpdatedEvent(UpdateTypeEnum.Modified);

            return(true);
        }
Example #2
0
        /// <summary>
        /// Applicable to pending/delayed orders only.
        /// </summary>
        /// <returns></returns>
        public bool Cancel(out string operationResultMessage)
        {
            if (State != OrderStateEnum.Submitted)
            {
                operationResultMessage = "Not pending order can not be canceled.";
                SystemMonitor.OperationError(operationResultMessage);
                return(false);
            }

            string modifiedId;

            if (OrderExecutionProvider.CancelPendingOrder(Account.Info, this, out modifiedId, out operationResultMessage))
            {
                State = OrderStateEnum.Canceled;
                //_info.Id = modifiedId;

                RaiseOrderUpdatedEvent(UpdateTypeEnum.Canceled);

                return(true);
            }

            return(false);
        }
Example #3
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);
        }
Example #4
0
        /// <summary>
        /// This allows more specific control over the operation.
        /// </summary>
        public bool Submit(OrderTypeEnum orderType, int volume, decimal?allowedSlippage,
                           decimal?desiredPrice, decimal?takeProfit, decimal?stopLoss, string comment, out string operationResultMessage)
        {
            SystemMonitor.CheckThrow(volume > 0, "Misuse of the Order class.");

            if (State != OrderStateEnum.Initialized)
            {
                operationResultMessage = "Misuse of the Order class [Order not initialized; or Must not place trade, that has already been placed].";
                SystemMonitor.Warning(operationResultMessage);
                return(false);
            }

            ISourceOrderExecution executionProvider = _executionProvider;

            operationResultMessage = "Session not assigned.";

            if (desiredPrice.HasValue == false)
            {
                desiredPrice = OrderInfo.TypeIsBuy(orderType) ? QuoteProvider.Bid : QuoteProvider.Ask;
            }

            if (executionProvider == null)
            {// Placement of order failed.
                State = OrderStateEnum.Failed;
                SystemMonitor.Report("Order was not executed [" + operationResultMessage + "].");
                return(false);
            }

            string id = OrderExecutionProvider.SubmitOrder(Account.Info, this, Symbol, orderType, volume,
                                                           allowedSlippage, desiredPrice, takeProfit, stopLoss, comment, out operationResultMessage);

            if (string.IsNullOrEmpty(id))
            {
                State = OrderStateEnum.Failed;
                SystemMonitor.OperationError("Order was not executed [" + operationResultMessage + "].");
                return(false);
            }

            lock (this)
            {
                _info.Type     = orderType;
                _initialVolume = volume;
                _info.Id       = id;
                _info.Volume   = volume;

                _info.StopLoss   = stopLoss;
                _info.TakeProfit = takeProfit;

                State          = OrderStateEnum.Submitted;
                _localOpenTime = DateTime.Now;
            }

            Account.TradeEntities.AddOrder(this);

            if (State == OrderStateEnum.Executed)
            {
                RaiseOrderUpdatedEvent(UpdateTypeEnum.Executed);
            }
            else
            {
                RaiseOrderUpdatedEvent(UpdateTypeEnum.Submitted);
            }

            return(true);
        }