/// <summary> /// Helper, remove order from manipulation list. /// </summary> void ReleaseManipulationOrder(ActiveOrder order) { lock (_activeSelectedOrders) { _activeSelectedOrders.Remove(order); } }
/// <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> public OrdersInformationUpdateResponseMessage(AccountInfo accountInfo, OrderInfo[] orderInformations, ActiveOrder.UpdateTypeEnum[] ordersUpdates, bool operationResult) : base(accountInfo, operationResult) { _ordersUpdates = ordersUpdates; _orderInformations = orderInformations; }
/// <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); }
protected override void Orders_OrderUpdatedEvent(ITradeEntityManagement provider, AccountInfo account, Order[] orders, ActiveOrder.UpdateTypeEnum[] updatesType) { base.Orders_OrderUpdatedEvent(provider, account, orders, updatesType); // Run in a separate thread since it takes time to request from server. //GeneralHelper.FireAndForget(new GeneralHelper.GenericReturnDelegate<bool>(Update)); }
/// <summary> /// Open orders in position management /// </summary> public bool CancelPending(string openOrderId, out string operationResultMessage) { ISourceOrderExecution provider = _orderProvider; if (provider == null || provider.DefaultAccount == null) { operationResultMessage = "Position not initialized."; return(false); } Order order = provider.TradeEntities.GetOrderById(openOrderId); if (order.State != OrderStateEnum.Submitted) { operationResultMessage = "Order state not 'submitted', so not able to cancel as a pending order"; return(false); } ActiveOrder activeOrder = order as ActiveOrder; if (null != activeOrder) { return(activeOrder.Cancel(out operationResultMessage)); } PassiveOrder passiveOrder = order as PassiveOrder; if (null != passiveOrder) { return(passiveOrder.CloseOrCancel(null, null, out operationResultMessage)); } operationResultMessage = "Not able to cancel order"; return(false); }
/// <summary> /// Detailed constructor. /// </summary> public ModifyOrderControl(ModeEnum mode, ActiveOrder order) { InitializeComponent(); _provider = order.OrderExecutionProvider; _mode = mode; _order = order; _dataProvider = order.QuoteProvider; _dataProvider.QuoteUpdateEvent += new QuoteProviderUpdateDelegate(_dataProvider_QuoteUpdateEvent); _session = order.SessionInfo.Value; }
public void UnInitialize() { if (_dataProvider != null) { _dataProvider.QuoteUpdateEvent -= new QuoteProviderUpdateDelegate(_dataProvider_QuoteUpdateEvent); _dataProvider = null; } _order = null; }
/// <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 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); }
/// <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); }
void _executor_OrderUpdatedEvent(IOrderSink providerSink, AccountInfo accountInfo, string[] previousOrdersIds, OrderInfo[] ordersInfos, Order.UpdateTypeEnum[] updatesType) { ISourceOrderExecution provider = _provider; if (providerSink != _provider) { SystemMonitor.Warning("Provider mismatch."); return; } List<Order> updatedOrders = new List<Order>(); List<Order.UpdateTypeEnum> updatedOrdersUpdateTypes = new List<Order.UpdateTypeEnum>(); for (int i = 0; i < ordersInfos.Length; i++) { if (string.IsNullOrEmpty(ordersInfos[i].Id)) { SystemMonitor.Warning("Order update of order with no ID."); continue; } if (previousOrdersIds.Length > i && previousOrdersIds[i] != ordersInfos[i].Id && string.IsNullOrEmpty(previousOrdersIds[i]) == false) {// Order Id has changed, remove old order. Order superceededOrder = GetOrderById(previousOrdersIds[i]); RemoveOrder(superceededOrder); } Order order = GetOrderById(ordersInfos[i].Id); if (order == null) {// Create new order based on incoming information. if (provider.SupportsActiveOrderManagement) { order = new ActiveOrder(_manager, provider, _delivery.SourceId, true); } else { order = new PassiveOrder(_manager, _delivery.SourceId, provider.SourceId); } order.AdoptInfo(ordersInfos[i]); if (AddOrder(order) == false) { SystemMonitor.OperationError("Failed to add order to keeper (id [" + order.Id + "] already used for another order).", TracerItem.PriorityEnum.Medium); } } else {// Existing order, to be updated. OrderInfo info = ordersInfos[i]; // First, check for critical modifications (price changes). if (order.Info.IsCriticalUpdate(info)) { SystemMonitor.Report(string.Format("Order has received a critical data modication Id[{0}], Open[{1} / {2}], Close[{3} / {4}].", order.Id, order.OpenPrice.ToString(), info.OpenPrice.ToString(), order.ClosePrice.ToString(), info.ClosePrice.ToString()), TracerItem.PriorityEnum.High); if (OrdersCriticalInformationChangedEvent != null) { OrdersCriticalInformationChangedEvent(this, accountInfo, order, info); } } if (order.UpdateInfo(info) == false) { SystemMonitor.OperationError("Failed to update order [" + order.Id + "]."); continue; } lock (this) { // Remove from any of the sub arrays it may be in. foreach (OrderStateEnum state in Enum.GetValues(typeof(OrderStateEnum))) { if (_ordersByState.ContainsKey(state) && _ordersByState[state].Contains(order)) { _ordersByState[state].Remove(order); } } _ordersByState[info.State].Add(order); } updatedOrders.Add(order); updatedOrdersUpdateTypes.Add(updatesType[i]); } } if (updatedOrders.Count > 0 && OrdersUpdatedEvent != null) { OrdersUpdatedEvent(this, accountInfo, updatedOrders.ToArray(), updatedOrdersUpdateTypes.ToArray() ); } }
///// <summary> ///// Obtain orders Ids from the server. ///// </summary> //public bool GetAllOrdersIds(AccountInfo accountInfo, out string[] activeOrdersIds, out string[] inactiveOrdersIds, // out string operationResultMessage) //{ // TracerHelper.Trace(this.Name); // activeOrdersIds = new string[] { }; // inactiveOrdersIds = new string[] { }; // if (OperationalState != OperationalStateEnum.Operational) // { // operationResultMessage = "Attempted operations on non operational order executioner."; // SystemMonitor.Error(operationResultMessage); // return false; // } // ResponceMessage responceMessage = // this.SendAndReceiveResponding<ResponceMessage>(SourceTransportInfo, new GetAllOrdersIDsMessage(accountInfo)); // if (responceMessage == null) // { // operationResultMessage = "Timeout"; // return false; // } // if (responceMessage.OperationResult == false || responceMessage is GetOrdersIDsResponceMessage == false) // { // operationResultMessage = responceMessage.OperationResultMessage; // return false; // } // GetOrdersIDsResponceMessage castedResponceMessage = (GetOrdersIDsResponceMessage)responceMessage; // activeOrdersIds = new string[castedResponceMessage.OpenTickets.Length]; // for (int i = 0; i < castedResponceMessage.OpenTickets.Length; i++) // { // activeOrdersIds[i] = castedResponceMessage.OpenTickets[i].ToString(); // } // inactiveOrdersIds = new string[castedResponceMessage.HistoricalTickets.Length]; // for (int i = 0; i < castedResponceMessage.HistoricalTickets.Length; i++) // { // inactiveOrdersIds[i] = castedResponceMessage.HistoricalTickets[i].ToString(); // } // operationResultMessage = "Orders obtained properly."; // return true; //} /// <summary> /// Helper. /// </summary> /// <param name="order"></param> /// <param name="updateType"></param> void RaiseOrderUpdateEvent(AccountInfo info, string previousOrderId, OrderInfo order, ActiveOrder.UpdateTypeEnum updateType) { if (OrdersUpdatedEvent != null) { OrdersUpdatedEvent(this, info, new string[] { previousOrderId }, new OrderInfo[] { order }, new ActiveOrder.UpdateTypeEnum[] { updateType }); } }
void _executor_OrderUpdatedEvent(IOrderSink providerSink, AccountInfo accountInfo, string[] previousOrdersIds, OrderInfo[] ordersInfos, Order.UpdateTypeEnum[] updatesType) { ISourceOrderExecution provider = _provider; if (providerSink != _provider) { SystemMonitor.Warning("Provider mismatch."); return; } List <Order> updatedOrders = new List <Order>(); List <Order.UpdateTypeEnum> updatedOrdersUpdateTypes = new List <Order.UpdateTypeEnum>(); for (int i = 0; i < ordersInfos.Length; i++) { if (string.IsNullOrEmpty(ordersInfos[i].Id)) { SystemMonitor.Warning("Order update of order with no ID."); continue; } if (previousOrdersIds.Length > i && previousOrdersIds[i] != ordersInfos[i].Id && string.IsNullOrEmpty(previousOrdersIds[i]) == false) {// Order Id has changed, remove old order. Order superceededOrder = GetOrderById(previousOrdersIds[i]); RemoveOrder(superceededOrder); } Order order = GetOrderById(ordersInfos[i].Id); if (order == null) {// Create new order based on incoming information. if (provider.SupportsActiveOrderManagement) { order = new ActiveOrder(_manager, provider, _delivery.SourceId, true); } else { order = new PassiveOrder(_manager, _delivery.SourceId, provider.SourceId); } order.AdoptInfo(ordersInfos[i]); if (AddOrder(order) == false) { SystemMonitor.OperationError("Failed to add order to keeper (id [" + order.Id + "] already used for another order).", TracerItem.PriorityEnum.Medium); } } else {// Existing order, to be updated. OrderInfo info = ordersInfos[i]; // First, check for critical modifications (price changes). if (order.Info.IsCriticalUpdate(info)) { SystemMonitor.Report(string.Format("Order has received a critical data modication Id[{0}], Open[{1} / {2}], Close[{3} / {4}].", order.Id, order.OpenPrice.ToString(), info.OpenPrice.ToString(), order.ClosePrice.ToString(), info.ClosePrice.ToString()), TracerItem.PriorityEnum.High); if (OrdersCriticalInformationChangedEvent != null) { OrdersCriticalInformationChangedEvent(this, accountInfo, order, info); } } if (order.UpdateInfo(info) == false) { SystemMonitor.OperationError("Failed to update order [" + order.Id + "]."); continue; } lock (this) { // Remove from any of the sub arrays it may be in. foreach (OrderStateEnum state in Enum.GetValues(typeof(OrderStateEnum))) { if (_ordersByState.ContainsKey(state) && _ordersByState[state].Contains(order)) { _ordersByState[state].Remove(order); } } _ordersByState[info.State].Add(order); } updatedOrders.Add(order); updatedOrdersUpdateTypes.Add(updatesType[i]); } } if (updatedOrders.Count > 0 && OrdersUpdatedEvent != null) { OrdersUpdatedEvent(this, accountInfo, updatedOrders.ToArray(), updatedOrdersUpdateTypes.ToArray()); } }
public virtual void OrderExecutionProvider_OrderUpdatedEvent(IOrderSink executor, AccountInfo account, string[] previousOrdersIds, OrderInfo[] providerOrders, ActiveOrder.UpdateTypeEnum[] updatesType) { UpdateOrdersStatistics(); }
/// <summary> /// /// </summary> public override decimal? GetResult(ActiveOrder.ResultModeEnum resultMode) { if (_placedSlaveOrders == null || _placedSlaveOrders.Count == 0) { return null; } decimal result = 0; lock (this) { foreach (ActiveOrder order in _placedSlaveOrders) { decimal? orderResult = order.GetResult(resultMode); if (orderResult.HasValue) { result += orderResult.Value; } } } return result; }