/// <summary> /// Statis helper, allows the calculation of order results. /// </summary> public static Decimal?GetRawResult(decimal?open, decimal volume, OrderStateEnum state, OrderTypeEnum type, decimal?ask, decimal?bid, decimal?close, bool considerVolume) { if (state != OrderStateEnum.Closed && state != OrderStateEnum.Executed) { if (state == OrderStateEnum.Failed || state == OrderStateEnum.Initialized || state == OrderStateEnum.UnInitialized || state == OrderStateEnum.Unknown) { return(null); } // Canceled, Submitted return(0); } if (open.HasValue == false || (state == OrderStateEnum.Executed && (ask.HasValue == false || bid.HasValue == false)) || (state == OrderStateEnum.Closed && close.HasValue == false)) { return(null); } decimal currentValue = 0; if (state == OrderStateEnum.Executed) { currentValue = OrderInfo.TypeIsBuy(type) ? bid.Value : ask.Value; } else if (state == OrderStateEnum.Closed) { currentValue = close.Value; } else { return(null); } Decimal difference = 0; if (OrderInfo.TypeIsBuy(type)) { difference = currentValue - open.Value; } else { difference = open.Value - currentValue; } if (considerVolume) { return(volume * difference); } else { return(difference); } }
/// <summary> /// /// </summary> decimal?ProcessPrice(IQuoteProvider quoteProvider, OrderTypeEnum orderType, decimal?price) { if (price.HasValue == false && quoteProvider.Ask.HasValue && quoteProvider.Bid.HasValue) { if (OrderInfo.TypeIsBuy(orderType)) { return(quoteProvider.Ask); } else { return(quoteProvider.Bid); } } return(price); }
/// <summary> /// Common helper method, establish current placement price for order type. /// </summary> public decimal?GetOrderOpenQuote(OrderTypeEnum orderType) { if (this.OperationalState != OperationalStateEnum.Operational || this.Ask.HasValue == false || this.Bid.HasValue == false) { return(null); } if (OrderInfo.TypeIsBuy(orderType)) { return(this.Ask); } else { return(this.Bid); } }
/// <summary> /// This allows more specific control over the operation. /// </summary> public bool Submit(OrderTypeEnum orderType, int volume, decimal?allowedSlippage, decimal?desiredPrice, decimal?takeProfit, decimal?stopLoss, string comment, out string operationResultMessage) { SystemMonitor.CheckThrow(volume > 0, "Misuse of the Order class."); if (State != OrderStateEnum.Initialized) { operationResultMessage = "Misuse of the Order class [Order not initialized; or Must not place trade, that has already been placed]."; SystemMonitor.Warning(operationResultMessage); return(false); } ISourceOrderExecution executionProvider = _executionProvider; operationResultMessage = "Session not assigned."; if (desiredPrice.HasValue == false) { desiredPrice = OrderInfo.TypeIsBuy(orderType) ? QuoteProvider.Bid : QuoteProvider.Ask; } if (executionProvider == null) {// Placement of order failed. State = OrderStateEnum.Failed; SystemMonitor.Report("Order was not executed [" + operationResultMessage + "]."); return(false); } string id = OrderExecutionProvider.SubmitOrder(Account.Info, this, Symbol, orderType, volume, allowedSlippage, desiredPrice, takeProfit, stopLoss, comment, out operationResultMessage); if (string.IsNullOrEmpty(id)) { State = OrderStateEnum.Failed; SystemMonitor.OperationError("Order was not executed [" + operationResultMessage + "]."); return(false); } lock (this) { _info.Type = orderType; _initialVolume = volume; _info.Id = id; _info.Volume = volume; _info.StopLoss = stopLoss; _info.TakeProfit = takeProfit; State = OrderStateEnum.Submitted; _localOpenTime = DateTime.Now; } Account.TradeEntities.AddOrder(this); if (State == OrderStateEnum.Executed) { RaiseOrderUpdatedEvent(UpdateTypeEnum.Executed); } else { RaiseOrderUpdatedEvent(UpdateTypeEnum.Submitted); } return(true); }
/// <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); }