/// <summary> /// Handles a request to update order properties /// </summary> private OrderResponse HandleUpdateOrderRequest(UpdateOrderRequest request) { Order order; OrderTicket ticket; if (!_orders.TryGetValue(request.OrderId, out order) || !_orderTickets.TryGetValue(request.OrderId, out ticket)) { Log.Error("BrokerageTransactionHandler.HandleUpdateOrderRequest(): Unable to update order with ID " + request.OrderId); return(OrderResponse.UnableToFindOrder(request)); } if (!CanUpdateOrder(order)) { return(OrderResponse.InvalidStatus(request, order)); } // verify that our current brokerage can actually update the order BrokerageMessageEvent message; if (!_algorithm.LiveMode && !_algorithm.BrokerageModel.CanUpdateOrder(_algorithm.Securities[order.Symbol], order, request, out message)) { // if we couldn't actually process the order, mark it as invalid and bail order.Status = OrderStatus.Invalid; if (message == null) { message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "InvalidOrder", "BrokerageModel declared unable to update order: " + order.Id); } var response = OrderResponse.Error(request, OrderResponseErrorCode.BrokerageModelRefusedToUpdateOrder, "OrderID: " + order.Id + " " + message); _algorithm.Error(response.ErrorMessage); HandleOrderEvent(new OrderEvent(order, _algorithm.UtcTime, 0m, "BrokerageModel declared unable to update order")); return(response); } // modify the values of the order object order.ApplyUpdateOrderRequest(request); ticket.SetOrder(order); bool orderUpdated; try { orderUpdated = _brokerage.UpdateOrder(order); } catch (Exception err) { Log.Error(err); orderUpdated = false; } if (!orderUpdated) { // we failed to update the order for some reason var errorMessage = "Brokerage failed to update order with id " + request.OrderId; _algorithm.Error(errorMessage); HandleOrderEvent(new OrderEvent(order, _algorithm.UtcTime, 0m, "Brokerage failed to update order")); return(OrderResponse.Error(request, OrderResponseErrorCode.BrokerageFailedToUpdateOrder, errorMessage)); } return(OrderResponse.Success(request)); }
/// <summary> /// Remove this order from outstanding queue: user is requesting a cancel. /// </summary> /// <param name="request">Request containing the specific order id to remove</param> public OrderTicket CancelOrder(CancelOrderRequest request) { OrderTicket ticket; if (!_orderTickets.TryGetValue(request.OrderId, out ticket)) { Log.Error("BrokerageTransactionHandler.CancelOrder(): Unable to locate ticket for order."); return(OrderTicket.InvalidCancelOrderId(_algorithm.Transactions, request)); } try { // if we couldn't set this request as the cancellation then another thread/someone // else is already doing it or it in fact has already been cancelled if (!ticket.TrySetCancelRequest(request)) { // the ticket has already been cancelled request.SetResponse(OrderResponse.Error(request, OrderResponseErrorCode.InvalidRequest, "Cancellation is already in progress.")); return(ticket); } //Error check var order = GetOrderByIdInternal(request.OrderId); if (order != null && request.Tag != null) { order.Tag = request.Tag; } if (order == null) { Log.Error("BrokerageTransactionHandler.CancelOrder(): Cannot find this id."); request.SetResponse(OrderResponse.UnableToFindOrder(request)); } else if (order.Status.IsClosed()) { Log.Error("BrokerageTransactionHandler.CancelOrder(): Order already " + order.Status); request.SetResponse(OrderResponse.InvalidStatus(request, order)); } else if (_algorithm.IsWarmingUp) { request.SetResponse(OrderResponse.WarmingUp(request)); } else { // send the request to be processed request.SetResponse(OrderResponse.Success(request), OrderRequestStatus.Processing); _orderRequestQueue.Add(request); } } catch (Exception err) { Log.Error(err); request.SetResponse(OrderResponse.Error(request, OrderResponseErrorCode.ProcessingError, err.Message)); } return(ticket); }
/// <summary> /// Handles a request to cancel an order /// </summary> private OrderResponse HandleCancelOrderRequest(CancelOrderRequest request) { Order order; OrderTicket ticket; if (!_orders.TryGetValue(request.OrderId, out order) || !_orderTickets.TryGetValue(request.OrderId, out ticket)) { Log.Error("BrokerageTransactionHandler.HandleCancelOrderRequest(): Unable to cancel order with ID " + request.OrderId + "."); return(OrderResponse.UnableToFindOrder(request)); } if (order.Status.IsClosed()) { return(OrderResponse.InvalidStatus(request, order)); } ticket.SetOrder(order); bool orderCanceled; try { orderCanceled = _brokerage.CancelOrder(order); } catch (Exception err) { Log.Error(err); orderCanceled = false; } if (!orderCanceled) { // failed to cancel the order var message = "Brokerage failed to cancel order with id " + order.Id; _algorithm.Error(message); HandleOrderEvent(new OrderEvent(order, _algorithm.UtcTime, 0m, "Brokerage failed to cancel order")); return(OrderResponse.Error(request, OrderResponseErrorCode.BrokerageFailedToCancelOrder, message)); } // we succeeded to cancel the order order.Status = OrderStatus.Canceled; if (request.Tag != null) { // update the tag, useful for 'why' we canceled the order order.Tag = request.Tag; } return(OrderResponse.Success(request)); }
/// <summary> /// Handles a request to cancel an order /// </summary> private OrderResponse HandleCancelOrderRequest(CancelOrderRequest request) { Order order; OrderTicket ticket; if (!_orders.TryGetValue(request.OrderId, out order) || !_orderTickets.TryGetValue(request.OrderId, out ticket)) { Log.Error("BrokerageTransactionHandler.HandleCancelOrderRequest(): Unable to cancel order with ID " + request.OrderId + "."); return(OrderResponse.UnableToFindOrder(request)); } if (order.Status.IsClosed()) { return(OrderResponse.InvalidStatus(request, order)); } ticket.SetOrder(order); bool orderCanceled; try { orderCanceled = _brokerage.CancelOrder(order); } catch (Exception err) { Log.Error(err); orderCanceled = false; } if (!orderCanceled) { // we failed to cancel the order for some reason order.Status = OrderStatus.Invalid; } else { // we succeeded to cancel the order order.Status = OrderStatus.Canceled; } if (request.Tag != null) { // update the tag, useful for 'why' we canceled the order order.Tag = request.Tag; } return(OrderResponse.Success(request)); }
/// <summary> /// Update an order yet to be filled such as stop or limit orders. /// </summary> /// <param name="request">Request detailing how the order should be updated</param> /// <remarks>Does not apply if the order is already fully filled</remarks> public OrderTicket UpdateOrder(UpdateOrderRequest request) { OrderTicket ticket; if (!_orderTickets.TryGetValue(request.OrderId, out ticket)) { return(OrderTicket.InvalidUpdateOrderId(_algorithm.Transactions, request)); } ticket.AddUpdateRequest(request); try { //Update the order from the behaviour var order = GetOrderByIdInternal(request.OrderId); if (order == null) { // can't update an order that doesn't exist! request.SetResponse(OrderResponse.UnableToFindOrder(request)); } else if (order.Status.IsClosed()) { // can't update a completed order request.SetResponse(OrderResponse.InvalidStatus(request, order)); } else if (request.Quantity.HasValue && request.Quantity.Value == 0) { request.SetResponse(OrderResponse.ZeroQuantity(request)); } else if (_algorithm.IsWarmingUp) { request.SetResponse(OrderResponse.WarmingUp(request)); } else { request.SetResponse(OrderResponse.Success(request), OrderRequestStatus.Processing); _orderRequestQueue.Add(request); } } catch (Exception err) { Log.Error(err); request.SetResponse(OrderResponse.Error(request, OrderResponseErrorCode.ProcessingError, err.Message)); } return(ticket); }
/// <summary> /// Handles a request to update order properties /// </summary> private OrderResponse HandleUpdateOrderRequest(UpdateOrderRequest request) { Order order; OrderTicket ticket; if (!_orders.TryGetValue(request.OrderId, out order) || !_orderTickets.TryGetValue(request.OrderId, out ticket)) { Log.Error("BrokerageTransactionHandler.HandleUpdateOrderRequest(): Unable to update order with ID " + request.OrderId); return(OrderResponse.UnableToFindOrder(request)); } if (!CanUpdateOrder(order)) { return(OrderResponse.InvalidStatus(request, order)); } // modify the values of the order object order.ApplyUpdateOrderRequest(request); ticket.SetOrder(order); bool orderUpdated; try { orderUpdated = _brokerage.UpdateOrder(order); } catch (Exception err) { Log.Error(err); orderUpdated = false; } if (!orderUpdated) { // we failed to update the order for some reason order.Status = OrderStatus.Invalid; return(OrderResponse.Error(request, OrderResponseErrorCode.BrokerageFailedToUpdateOrder, "Brokerage failed to update order with id " + request.OrderId)); } return(OrderResponse.Success(request)); }
/// <summary> /// Remove this order from outstanding queue: user is requesting a cancel. /// </summary> /// <param name="request">Request containing the specific order id to remove</param> public OrderTicket CancelOrder(CancelOrderRequest request) { OrderTicket ticket; if (!_orderTickets.TryGetValue(request.OrderId, out ticket)) { Log.Error("BrokerageTransactionHandler.CancelOrder(): Unable to locate ticket for order."); return(OrderTicket.InvalidCancelOrderId(_algorithm.Transactions, request)); } ticket.SetCancelRequest(request); try { //Error check var order = GetOrderById(request.OrderId); if (order == null) { Log.Error("BrokerageTransactionHandler.CancelOrder(): Cannot find this id."); request.SetResponse(OrderResponse.UnableToFindOrder(request)); } else if (order.Status.IsClosed()) { Log.Error("BrokerageTransactionHandler.CancelOrder(): Order already filled"); request.SetResponse(OrderResponse.InvalidStatus(request, order)); } else { // send the request to be processed request.SetResponse(OrderResponse.Success(request), OrderRequestStatus.Processing); _orderRequestQueue.Enqueue(request); } } catch (Exception err) { Log.Error("TransactionManager.RemoveOrder(): " + err.Message); request.SetResponse(OrderResponse.Error(request, OrderResponseErrorCode.ProcessingError, err.Message)); } return(ticket); }
public void TestInvalidSubmitRequest() { var orderRequest = new SubmitOrderRequest(OrderType.Limit, SecurityType.Equity, Symbols.AAPL, 1000, 0, 1.11m, DateTime.Now, "Pepe"); var order = Order.CreateOrder(orderRequest); orderRequest.SetOrderId(orderRequest.OrderId); var orderResponse = OrderResponse.InvalidStatus(orderRequest, order); var ticket = OrderTicket.InvalidSubmitRequest(null, orderRequest, orderResponse); Assert.AreEqual(ticket.OrderId, orderRequest.OrderId); Assert.AreEqual(ticket.Quantity, 1000); Assert.AreEqual(ticket.Tag, "Pepe"); Assert.AreEqual(ticket.Status, OrderStatus.Invalid); Assert.AreEqual(ticket.OrderType, OrderType.Limit); Assert.AreEqual(ticket.SecurityType, SecurityType.Equity); Assert.AreEqual(ticket.Symbol, Symbols.AAPL); Assert.AreEqual(ticket.SubmitRequest, orderRequest); Assert.AreEqual(ticket.SubmitRequest.Status, OrderRequestStatus.Error); Assert.AreEqual(ticket.SubmitRequest.OrderId, orderRequest.OrderId); Assert.AreEqual(ticket.SubmitRequest.Quantity, 1000); Assert.AreEqual(ticket.SubmitRequest.Tag, "Pepe"); }