/// <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; }
/// <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); }