/// <summary> /// /// </summary> protected override bool OnExecuteMarketBalanced(ISourceOrderExecution provider, int volumeModification, decimal?desiredPrice, decimal?slippage, TimeSpan timeOut, out PositionExecutionInfo executionInfo, out string operationResultMessage) { if (_manipulateExistingOrders == false) { return(base.OnExecuteMarketBalanced(provider, volumeModification, desiredPrice, slippage, timeOut, out executionInfo, out operationResultMessage)); } OrderTypeEnum orderType = OrderTypeEnum.BUY_MARKET; if (volumeModification < 0) { orderType = OrderTypeEnum.SELL_MARKET; volumeModification = Math.Abs(volumeModification); } executionInfo = PositionExecutionInfo.Empty; int originalVolumeModification = volumeModification; List <KeyValuePair <double, decimal> > closePrices = new List <KeyValuePair <double, decimal> >(); bool suitableOrdersAvailable; ActiveOrder orderSelected = ObtainManipulationOrder(provider, GetReverseOrderType(orderType), Math.Abs(originalVolumeModification), out suitableOrdersAvailable); if (orderSelected != null && volumeModification > 0) { if (volumeModification >= orderSelected.CurrentVolume) { int orderVolume = orderSelected.CurrentVolume; if (orderSelected.Close(slippage, null)) { volumeModification -= orderVolume; if (orderSelected.ClosePrice.HasValue) { closePrices.Add(new KeyValuePair <double, decimal>(orderVolume, orderSelected.ClosePrice.Value)); } else { SystemMonitor.Error("Order [{" + orderSelected.Id + "}] closed but close price not assigned."); } } else { ReleaseManipulationOrder(orderSelected); operationResultMessage = "Failed to close corresponding reverse active order."; return(false); } } else { if (orderSelected.DecreaseVolume(volumeModification, slippage, null)) { volumeModification = 0; } } ReleaseManipulationOrder(orderSelected); orderSelected = null; } if (suitableOrdersAvailable && volumeModification > 0 && originalVolumeModification == volumeModification) {// Complete failure to close anything, and there are some suitable. executionInfo = PositionExecutionInfo.Empty; operationResultMessage = "Suitable reverse market orders are available, but currently manipulated, so hedging rules forbid reverse orders placement at this moment."; return(false); } if (volumeModification > 0) {// We need to execute one more in the reverse direction. PositionExecutionInfo marketExecutionInfo; string tmp; string executionResult = ExecuteMarket(orderType, volumeModification, null, slippage, null, null, timeOut, out marketExecutionInfo, out tmp); if (string.IsNullOrEmpty(executionResult) == false) {// Success. volumeModification -= (int)marketExecutionInfo.VolumeExecuted; if (marketExecutionInfo.ExecutedPrice.HasValue) { closePrices.Add(new KeyValuePair <double, decimal>(marketExecutionInfo.VolumeExecuted, marketExecutionInfo.ExecutedPrice.Value)); } else { SystemMonitor.Error("MarketExecutionInfo for a valid execution [{" + executionResult + "}] does not have ExecutedPrice assigned."); } } else { operationResultMessage = tmp; return(false); } } // Calculate the close price, combination from the operations. decimal closePrice = 0; double totalVolume = 0; if (FinancialHelper.CalculateAveragePrice(closePrices, out closePrice, out totalVolume) == false) { SystemMonitor.Error("Failed to calculate average price for market balanced execution."); closePrice = 0; } if (volumeModification > 0) { // Failure. if (originalVolumeModification == volumeModification) { // Complete failure. executionInfo = PositionExecutionInfo.Empty; operationResultMessage = "Failed to execute market operation."; return(false); } else {// Partial execution success. executionInfo = new PositionExecutionInfo(Guid.NewGuid().ToString(), _dataDelivery.SourceId, provider.SourceId, Symbol, orderType, closePrice, originalVolumeModification, originalVolumeModification - volumeModification, DateTime.Now, PositionExecutionInfo.ExecutionResultEnum.PartialSuccess); } } else {// Success. executionInfo = new PositionExecutionInfo(Guid.NewGuid().ToString(), _dataDelivery.SourceId, provider.SourceId, Symbol, orderType, closePrice, originalVolumeModification, originalVolumeModification, DateTime.Now, PositionExecutionInfo.ExecutionResultEnum.Success); } operationResultMessage = string.Empty; return(true); }