/// <summary> /// Updates the order. /// </summary> /// <param name="pendingorder">The order.</param> /// <returns></returns> public bool UpdateOrder(PendingOrder pendingorder) { //Check if we can find this order if (!_activeOrders.TryGetValue(pendingorder.OrderId, out PendingOrder active)) { return(false); //Cannot find order } lock (_locker) { //Update order instance pendingorder.UpdateOrder(active.Order); } //Send updated order notification OrderStateChange?.Invoke(this, OrderTicketEvent.Updated(active.OrderId, "Order was updated")); return(true); }
/// <summary> /// Process submit order /// </summary> /// <param name="ticket"></param> protected virtual OrderTicketResponse SubmitOrder(SubmitOrderTicket ticket) { //Get order from factory PendingOrder pendingorder = OrderFactory.CreateOrder(ticket); OrderImpl order = pendingorder.Order as OrderImpl; //Round off order quantity for correct amounts RoundLotSize(order); //try and get the order from the order tracker if (!OrderTracker.TryAddOrder(pendingorder)) { _log.Error($"Unable to add new order, order with id {pendingorder.OrderId} was already submitted"); return(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.OrderAlreadyExists, $"Current order with id {pendingorder.OrderId} was already submitted")); } if (!OrderTracker.TryGetOrder(pendingorder.OrderId, out pendingorder)) { _log.Error($"Unable to retrieve newly added order, order with id {pendingorder.OrderId} was cannot be processed properly"); return(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.UnableToFindOrder, $"Current order with id {pendingorder.OrderId} cannot be found")); } //Round of prices RoundOrderPrices(order); //Set our new order pendingorder.UpdateOrder(order); //Check for correct size if (order.Quantity == 0) { order.State = OrderState.Invalid; var ticketresponse = OrderTicketResponse.Error(order.InternalId, OrderTicketResponseErrorCode.OrderQuantityZero); Portfolio.Log(LogLevel.Error, ticketresponse.ErrorMessage); return(ticketresponse); } //Check if we have enough capital for an order bool sufficientcapital = GetSufficientCapitalForOrder(pendingorder); if (!sufficientcapital) { //Not enough capital to execute this order order.State = OrderState.Invalid; var response = OrderTicketResponse.Error(order.InternalId, OrderTicketResponseErrorCode.InsufficientBuyingPower, $"Cannot execute order with id {order.InternalId}, insufficient funds to execute order."); Portfolio.Log(LogLevel.Error, response.ErrorMessage); HandleOrderTicketEvent(OrderTicketEvent.Error(order.InternalId, $"Insufficent capital to execute order")); return(response); } //Check if broker accepts order at this moment try { if (!Portfolio.BrokerModel.CanSubmitOrder(order, out var message)) { //Broker model did not accept this order order.State = OrderState.Invalid; var response = OrderTicketResponse.Error(order.InternalId, OrderTicketResponseErrorCode.BrokerageModelRefusedToSubmitOrder, $"Order with id {order.InternalId}: {message}"); Portfolio.Log(LogLevel.Error, ""); HandleOrderTicketEvent(OrderTicketEvent.Error(order.InternalId, $"Broker model of type {Portfolio.BrokerModel.BrokerType} declared order cannot be submitted, message: {message}")); return(response); } } catch (Exception exc) { _log.Error(exc, $"Could not run CanSubmitOrder on order with id {order.InternalId}, please check the implemented logic"); order.State = OrderState.Invalid; return(OrderTicketResponse.Error(pendingorder.OrderId, OrderTicketResponseErrorCode.ProcessingError, $"Current order with id {pendingorder.OrderId} cannot be processed due to error")); } //Try to execute this order to the broker connection attached bool ordersuccess = false; try { ordersuccess = BrokerConnection.SubmitOrder(pendingorder); } catch (Exception exc) { _log.Error(exc); } //Check if placing the order was a success if (!ordersuccess) { order.State = OrderState.Invalid; var submitmessage = "BrokerConnection failed to place order"; var response = OrderTicketResponse.Error(order.InternalId, OrderTicketResponseErrorCode.BrokerageFailedToSubmitOrder, submitmessage); Portfolio.Log(LogLevel.Error, submitmessage); HandleOrderTicketEvent(OrderTicketEvent.Error(order.InternalId, submitmessage)); return(response); } order.State = OrderState.Submitted; return(OrderTicketResponse.Processed(order.InternalId)); }