/// <summary>
        ///
        /// </summary>
        protected override string OnSubmit(ISourceOrderExecution provider, OrderTypeEnum orderType, int volume, decimal?price,
                                           decimal?slippage, decimal?takeProfit, decimal?stopLoss, out string operationResultMessage)
        {
            SystemMonitor.CheckError(provider.SupportsActiveOrderManagement, "Wrong position type for this provider.");

            IQuoteProvider quotes = _manager.ObtainQuoteProvider(_dataDelivery.SourceId, Symbol);

            ActiveOrder order = new ActiveOrder(_manager, provider, quotes,
                                                _dataDelivery.SourceId, Symbol, true);

            price = ProcessPrice(quotes, orderType, price);

            string id = provider.SubmitOrder(provider.DefaultAccount.Info, order, _info.Symbol,
                                             orderType, volume, slippage, price, takeProfit, stopLoss, string.Empty, out operationResultMessage);

            if (string.IsNullOrEmpty(id))
            {
                return(string.Empty);
            }

            OrderInfo info = new OrderInfo(id, Symbol, orderType, OrderStateEnum.Submitted, volume,
                                           price, null, null, null, null, null, null, null, null, null, null, string.Empty, null);

            order.AdoptInfo(info);
            provider.TradeEntities.AddOrder(order);

            return(id);
        }
        /// <summary>
        /// 
        /// </summary>
        protected override string OnExecuteMarket(ISourceOrderExecution provider, OrderTypeEnum orderType, int volume, 
            decimal? price, decimal? slippage, decimal? takeProfit, decimal? stopLoss, TimeSpan timeOut,
            out PositionExecutionInfo executionInfo, out string operationResultMessage)
        {
            SystemMonitor.CheckError(provider.SupportsActiveOrderManagement, "Wrong position type for this provider.");

            executionInfo = PositionExecutionInfo.Empty;

            IQuoteProvider quoteProvider = _manager.ObtainQuoteProvider(_dataDelivery.SourceId, Symbol);
            if (quoteProvider == null)
            {
                operationResultMessage = "Failed to establish quote provider for [" + _dataDelivery.SourceId.Name + ", " + Symbol.Name + "].";
                SystemMonitor.Error(operationResultMessage);
                return string.Empty;
            }

            price = ProcessPrice(quoteProvider, orderType, price);

            // New order shall be created.
            ActiveOrder order = new ActiveOrder(_manager, provider, quoteProvider, _dataDelivery.SourceId, Symbol, true);

            OrderInfo? infoReference;

            // Using the extended operationTimeOut to 40 seconds.
            bool result = provider.SynchronousExecute(provider.DefaultAccount.Info, order, _info.Symbol,
                orderType, volume, slippage, price, takeProfit, stopLoss, string.Empty, TimeSpan.FromSeconds(40), out infoReference, out operationResultMessage);

            if (result && infoReference.HasValue)
            {
                OrderInfo infoAssign = infoReference.Value;
                if (infoAssign.Type == OrderTypeEnum.UNKNOWN)
                {
                    infoAssign.Type = orderType;
                }

                if (infoAssign.Volume == int.MinValue
                    || infoAssign.Volume == int.MaxValue)
                {// Volume was not retrieved by integration.
                    infoAssign.Volume = volume;
                }

                if (infoAssign.OpenPrice.HasValue)
                {
                    executionInfo = new PositionExecutionInfo(infoReference.Value.Id, _dataDelivery.SourceId, provider.SourceId, Symbol,
                        infoAssign.Type, infoAssign.OpenPrice.Value, volume, volume,
                        infoAssign.OpenTime, PositionExecutionInfo.ExecutionResultEnum.Success);
                }
                else
                {
                    SystemMonitor.Error("Received execution result, but price not assigned.");
                }

                order.AdoptInfo(infoAssign);

                provider.TradeEntities.AddOrder(order);
                return infoReference.Value.Id;
            }

            return string.Empty;
        }
        /// <summary>
        /// 
        /// </summary>
        protected override string OnSubmit(ISourceOrderExecution provider, OrderTypeEnum orderType, int volume, decimal? price,
            decimal? slippage, decimal? takeProfit, decimal? stopLoss, out string operationResultMessage)
        {
            SystemMonitor.CheckError(provider.SupportsActiveOrderManagement, "Wrong position type for this provider.");

            IQuoteProvider quotes = _manager.ObtainQuoteProvider(_dataDelivery.SourceId, Symbol);

            ActiveOrder order = new ActiveOrder(_manager, provider, quotes,
                _dataDelivery.SourceId, Symbol, true);

            price = ProcessPrice(quotes, orderType, price);

            string id = provider.SubmitOrder(provider.DefaultAccount.Info, order, _info.Symbol,
                orderType, volume, slippage, price, takeProfit, stopLoss, string.Empty, out operationResultMessage);

            if (string.IsNullOrEmpty(id))
            {
                return string.Empty;
            }

            OrderInfo info = new OrderInfo(id, Symbol, orderType, OrderStateEnum.Submitted, volume,
                price, null, null, null, null, null, null, null, null, null, null, string.Empty, null);

            order.AdoptInfo(info);
            provider.TradeEntities.AddOrder(order);

            return id;
        }
        /// <summary>
        /// This allows a part of the order to be closed, or all.
        /// </summary>
        public override 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, _dataSourceId, 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;
        }
Esempio n. 5
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);
        }
        /// <summary>
        ///
        /// </summary>
        protected override string OnExecuteMarket(ISourceOrderExecution provider, OrderTypeEnum orderType, int volume,
                                                  decimal?price, decimal?slippage, decimal?takeProfit, decimal?stopLoss, TimeSpan timeOut,
                                                  out PositionExecutionInfo executionInfo, out string operationResultMessage)
        {
            SystemMonitor.CheckError(provider.SupportsActiveOrderManagement, "Wrong position type for this provider.");

            executionInfo = PositionExecutionInfo.Empty;

            IQuoteProvider quoteProvider = _manager.ObtainQuoteProvider(_dataDelivery.SourceId, Symbol);

            if (quoteProvider == null)
            {
                operationResultMessage = "Failed to establish quote provider for [" + _dataDelivery.SourceId.Name + ", " + Symbol.Name + "].";
                SystemMonitor.Error(operationResultMessage);
                return(string.Empty);
            }

            price = ProcessPrice(quoteProvider, orderType, price);

            // New order shall be created.
            ActiveOrder order = new ActiveOrder(_manager, provider, quoteProvider, _dataDelivery.SourceId, Symbol, true);

            OrderInfo?infoReference;

            // Using the extended operationTimeOut to 40 seconds.
            bool result = provider.SynchronousExecute(provider.DefaultAccount.Info, order, _info.Symbol,
                                                      orderType, volume, slippage, price, takeProfit, stopLoss, string.Empty, TimeSpan.FromSeconds(40), out infoReference, out operationResultMessage);

            if (result && infoReference.HasValue)
            {
                OrderInfo infoAssign = infoReference.Value;
                if (infoAssign.Type == OrderTypeEnum.UNKNOWN)
                {
                    infoAssign.Type = orderType;
                }

                if (infoAssign.Volume == int.MinValue ||
                    infoAssign.Volume == int.MaxValue)
                {// Volume was not retrieved by integration.
                    infoAssign.Volume = volume;
                }

                if (infoAssign.OpenPrice.HasValue)
                {
                    executionInfo = new PositionExecutionInfo(infoReference.Value.Id, _dataDelivery.SourceId, provider.SourceId, Symbol,
                                                              infoAssign.Type, infoAssign.OpenPrice.Value, volume, volume,
                                                              infoAssign.OpenTime, PositionExecutionInfo.ExecutionResultEnum.Success);
                }
                else
                {
                    SystemMonitor.Error("Received execution result, but price not assigned.");
                }

                order.AdoptInfo(infoAssign);

                provider.TradeEntities.AddOrder(order);
                return(infoReference.Value.Id);
            }

            return(string.Empty);
        }