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()); } }
void executor_OrderUpdatedEvent(IOrderSink executor, AccountInfo account, string[] previousOrdersIds, OrderInfo[] orderInfos, Order.UpdateTypeEnum[] updatesType) { //RaiseSeriesValuesUpdated(true); }
void management_OrdersRemovedEvent(ITradeEntityManagement provider, AccountInfo account, IEnumerable <Order> order) { RaiseSeriesValuesUpdated(true); }
protected override void Orders_OrderUpdatedEvent(ITradeEntityManagement provider, AccountInfo account, Order[] orders, Order.UpdateTypeEnum[] updatesType) { base.Orders_OrderUpdatedEvent(provider, account, orders, updatesType); DoUpdate(); }
void management_OrderUpdatedEvent(ITradeEntityManagement provider, AccountInfo account, Order[] orders, Order.UpdateTypeEnum[] updatesType) { //RaiseSeriesValuesUpdated(true); }
/// <summary> /// /// </summary> public new void AdoptInfo(AccountInfo info) { base.AdoptInfo(info); }
protected override void Orders_OrdersRemovedEvent(ITradeEntityManagement provider, AccountInfo account, IEnumerable <Order> order) { base.Orders_OrdersRemovedEvent(provider, account, order); DoUpdate(); }
/// <summary> /// Constructor. /// </summary> public Account(AccountInfo info) { _accountInfo = info; }
/// <summary> /// Constructor. /// </summary> public BackTestAccount(AccountInfo info) : base(info) { }
protected virtual void Orders_OrderUpdatedEvent(ITradeEntityManagement provider, AccountInfo account, Order[] orders, Order.UpdateTypeEnum[] updatesType) { }
protected virtual void Orders_OrdersAddedEvent(ITradeEntityManagement provider, AccountInfo account, IEnumerable <Order> order) { }
/// <summary> /// /// </summary> public bool CloseOrder(AccountInfo account, Order order, decimal?allowedSlippage, decimal?desiredPrice, out decimal closingPrice, out DateTime closingTime, out string modifiedId, out string operationResultMessage) { closingPrice = decimal.MinValue; closingTime = DateTime.MinValue; modifiedId = order.Id; if (_orders.ContainsValue(order) == false) { operationResultMessage = "Order [" + order.Id + "] not registered in provider."; SystemMonitor.OperationError(operationResultMessage); return(false); } if (_lastDataBar.HasValue == false || _lastDataQuote.HasValue == false) { operationResultMessage = "Data bar/quote information not available."; SystemMonitor.OperationError(operationResultMessage); return(false); } decimal?currentPrice = _lastDataQuote.Value.Bid; if (order.IsBuy == false) {// Sell order. currentPrice = _lastDataQuote.Value.Ask; } if (desiredPrice.HasValue == false) { desiredPrice = currentPrice; } if (UpdatePosition(order.Symbol, -order.Info.DirectionalVolume, out operationResultMessage) == false) { return(false); } //if (dataProvider.DataBars.Current.HasValue && currentPrice.HasValue) {//Check if we have reached the stoploss or takeprofit in last bar //Default case. closingPrice = currentPrice.Value; if (order.StopLoss.HasValue && CheckStopLossInsideBar(order)) {// StopLoss has been triggered inside bar. closingPrice = order.StopLoss.Value; } if (order.TakeProfit.HasValue && CheckTakeProfitInsideBar(order)) {// TakeProfit has been triggered inside bar. closingPrice = order.TakeProfit.Value; } //Check if both : StopLoss and TakeProfit has been triggered inside bar if (CheckForConflictsInsideBar(order)) {//We have a collision here, If SL > lastbar.Low and TP < lastbar.High we do not know what have been triggered first : the SL or the TP //To solve the situation, 4 posiblities are offered for now : best case, worst case, probabilistic case, exact case switch (_resultsApproximationMode) { case ResultsAproximationModeEnum.PesimisticResult: if (order.StopLoss.HasValue) { closingPrice = order.StopLoss.Value; } break; case ResultsAproximationModeEnum.OptimisticResult: if (order.TakeProfit.HasValue) { closingPrice = order.TakeProfit.Value; } break; case ResultsAproximationModeEnum.MostProbableResult: //Probabilistic aproximation : If open is nearest stoploss than takeprofit, stoploss win otherwise takeprofit win if (order.TakeProfit.HasValue && order.StopLoss.HasValue) { decimal diffToStopLoss = Math.Abs(order.StopLoss.Value - _lastDataBar.Value.Open); decimal diffToTakeProfit = Math.Abs(_lastDataBar.Value.Open - order.TakeProfit.Value); if (diffToStopLoss > diffToTakeProfit) { //Most probable that takeprofit was triggered closingPrice = order.TakeProfit.Value; } else { //Most probable that stoploss was triggered closingPrice = order.StopLoss.Value; } } break; //case ResultsAproximationModeEnum.ExactResult: // // Not implemented yet // // To implement this part, we need tick by tick dataDelivery to know exactly what has happened inside bar // closingPrice = currentPrice; // break; } } } //else if (currentPrice.HasValue) //{ // closingPrice = currentPrice.Value; //} //else //{ // operationResultMessage = "Current price has no value."; // return false; //} if (desiredPrice.HasValue && allowedSlippage.HasValue && allowedSlippage > 0 && Math.Abs(currentPrice.Value - desiredPrice.Value) > allowedSlippage) { operationResultMessage = "Slippage criteria not met."; return(false); } closingTime = _lastDataQuote.Value.Time.Value; operationResultMessage = string.Empty; RaiseOrderUpdateEvent(order.Info, Order.UpdateTypeEnum.Closed); return(true); }
public bool IncreaseOrderVolume(AccountInfo account, Order order, decimal volumeIncrease, decimal?allowedSlippage, decimal?desiredPrice, out decimal increasalPrice, out string modifiedId, out string operationResultMessage) { increasalPrice = 0; if (order.State != OrderStateEnum.Submitted) { modifiedId = string.Empty; operationResultMessage = "Only submitted orders can be modified in volume."; return(false); } SystemMonitor.NotImplementedWarning(); modifiedId = order.Info.Id; operationResultMessage = string.Empty; return(true); #region Old Active Orders Implementation // increasalPrice = 0; // modifiedId = order.Id; // lock (this) // { // if (_provider.Account.TradeEntities.GetOrderById(order.Id) == null) // { // operationResultMessage = "Order [" + order.Guid + "] not registered in provider."; // SystemMonitor.OperationError(operationResultMessage); // return false; // } // } // increasalPrice = decimal.MinValue; // ISessionDataProvider dataProvider = SessionDataProvider; // if (dataProvider == null || dataProvider.Quotes == null // || dataProvider.DataBars == null) // { // operationResultMessage = "Data provider not assigned."; // SystemMonitor.OperationError(operationResultMessage); // return false; // } // if (desiredPrice.HasValue == false) // { // desiredPrice = dataProvider.Quotes.Ask; // } // if (volumeIncrease == 0) // { // increasalPrice = desiredPrice.Value; // operationResultMessage = "No change."; // return true; // } // decimal? currentPrice = dataProvider.Quotes.Bid; // if (order.IsBuy == false) // {// Sell order. // currentPrice = dataProvider.Quotes.Ask; // } // if (desiredPrice.HasValue && allowedSlippage.HasValue // && allowedSlippage > 0 && (currentPrice.HasValue && Math.Abs(currentPrice.Value - desiredPrice.Value) > allowedSlippage)) // {// Fail. // operationResultMessage = "Slippage criteria not met."; // return false; // } // if (currentPrice.HasValue == false) // { // operationResultMessage = "Current price not assigned."; // return false; // } // operationResultMessage = string.Empty; // increasalPrice = currentPrice.Value; // RaiseOrderUpdateEvent(order.Info, Order.UpdateTypeEnum.VolumeChanged); // return true; #endregion }
public bool DecreaseOrderVolume(AccountInfo account, Order order, decimal volumeDecreasal, decimal?allowedSlippage, decimal?desiredPrice, out decimal decreasalPrice, out string modifiedId, out string operationResultMessage) { decreasalPrice = 0; if (order.State != OrderStateEnum.Submitted) { modifiedId = string.Empty; operationResultMessage = "Only submitted orders can be modified in volume."; return(false); } SystemMonitor.NotImplementedWarning(); modifiedId = order.Info.Id; operationResultMessage = string.Empty; return(true); #region Old Active Orders Implementation // modifiedId = order.Id; // decreasalPrice = 0; // if (_provider.Account.TradeEntities.ContainsOrder(order) == false) // { // operationResultMessage = "Order [" + order.Guid + "] not registered in provider."; // SystemMonitor.OperationError(operationResultMessage); // return false; // } // decreasalPrice = decimal.MinValue; // ISessionDataProvider dataProvider = SessionDataProvider; // if (dataProvider == null || dataProvider.Quotes == null) // { // operationResultMessage = "Data provider not assigned or initialized properly."; // SystemMonitor.OperationError(operationResultMessage); // return false; // } // decimal? currentPrice = dataProvider.Quotes.Bid; // if (order.IsSell) // {// Sell order. // currentPrice = dataProvider.Quotes.Ask; // } // if (desiredPrice.HasValue && allowedSlippage.HasValue // && allowedSlippage > 0 && // (currentPrice.HasValue && Math.Abs(currentPrice.Value - desiredPrice.Value) > allowedSlippage)) // {// // operationResultMessage = "Slippage criteria not met."; // return false; // } // if (volumeDecreasal == order.CurrentVolume) // {// Closing order. // DateTime closingDateTime; // CloseOrder(_provider.Account.Info, order, allowedSlippage, desiredPrice, out decreasalPrice, out closingDateTime, out modifiedId, out operationResultMessage); // return true; // } // if (currentPrice.HasValue == false) // {// // operationResultMessage = "Can not decrease order since dataDelivery provider has no Ask/Bid values."; // return false; // } // operationResultMessage = string.Empty; // // TODO: implement a proper decreasal model here, just like the cloing one. // // This is a rough estimation. // decreasalPrice = currentPrice.Value; // RaiseOrderUpdateEvent(order.Info, Order.UpdateTypeEnum.VolumeChanged); // return true; #endregion }
/// <summary> /// /// </summary> public bool SynchronousExecute(AccountInfo account, Order order, Symbol symbol, OrderTypeEnum orderType, int volume, decimal?allowedSlippage, decimal?desiredPrice, decimal?takeProfit, decimal?stopLoss, string comment, TimeSpan operationTimeOut, out OrderInfo?info, out string operationResultMessage) { info = null; OrderInfo updatedInfo = order.Info; updatedInfo.OpenPrice = null; updatedInfo.OpenTime = null; updatedInfo.State = OrderStateEnum.Unknown; IQuoteProvider quotes; IDataBarHistoryProvider bars; if (GetProviders(symbol, out quotes, out bars) == false) { operationResultMessage = "Failed to establish corresponding providers."; return(false); } if (quotes.OperationalState != OperationalStateEnum.Operational || quotes.Ask.HasValue == false || quotes.Bid.HasValue == false || quotes.Time.HasValue == false) { operationResultMessage = "Data provider not operational or not providing valid dataDelivery."; return(false); } decimal?currentPrice = quotes.GetOrderOpenQuote(orderType); if (desiredPrice.HasValue && allowedSlippage.HasValue && currentPrice.HasValue && allowedSlippage > 0 && Math.Abs(currentPrice.Value - desiredPrice.Value) > allowedSlippage) {// Slippage requirements failed. operationResultMessage = "Slippage criteria not met."; return(false); } operationResultMessage = string.Empty; updatedInfo.OpenTime = quotes.Time.Value; if (orderType == OrderTypeEnum.BUY_MARKET || orderType == OrderTypeEnum.SELL_MARKET) {// Immediate order. updatedInfo.State = OrderStateEnum.Executed; updatedInfo.OpenPrice = currentPrice; } else {// Delayed pending order. //updatedInfo.State = OrderStateEnum.Submitted; //updatedInfo.OpenPrice = desiredPrice; operationResultMessage = "Order type not currently supported in back testing mode."; return(false); } updatedInfo.StopLoss = stopLoss; updatedInfo.TakeProfit = takeProfit; updatedInfo.Comment = comment; updatedInfo.Type = orderType; updatedInfo.Symbol = symbol; updatedInfo.Volume = volume; updatedInfo.Id = (_pendingOrderId++).ToString(); if (UpdatePosition(symbol, OrderInfo.TypeIsBuy(updatedInfo.Type) ? volume : -volume, out operationResultMessage) == false) { return(false); } info = updatedInfo; lock (this) { _orders.Add(updatedInfo.Id, order); } BeginAccountInfoUpdate(_account.Info); BeginManagedOrdersUpdate(_lastDataQuote); //RaiseOrderUpdateEvent(updatedInfo, Order.UpdateTypeEnum.Executed); return(true); }
public bool GetAvailableAccountInfos(out AccountInfo[] accounts) { accounts = new AccountInfo[] { _account.Info }; return(true); }