public static async Task <Order> Run([ActivityTrigger] OrderStateChange orderStateChange, [Table(SourceNames.OrdersTable, Connection = "StorageAccount")] CloudTable orderTable, ILogger log) { log.LogInformation($"[START ACTIVITY] --> {FunctionNames.FinalizeOrderFunction} for OrderUd={orderStateChange.OrderId}"); bool retVal = true; Order order = null; (order, retVal) = await GetOrderFromTableAsync(orderStateChange, orderTable, log); if (retVal) { if (order != null) { order.State = orderStateChange.NewOrderState; if (!await orderTable.InsertOrReplaceAsync(order)) { log.LogError($"Error during Updating Order {orderStateChange.OrderId}"); } } else { log.LogWarning($"The Order {orderStateChange.OrderId} doesn't exist in the storage"); order = null; } } return(order); }
/// <summary> /// Submits the order. /// </summary> /// <param name="pendingorder">The order.</param> /// <returns></returns> public bool SubmitOrder(PendingOrder pendingorder) { //get the underlying order var order = pendingorder.Order; //Check current order state if (order.State == OrderState.New) { //Set order lock (_locker) { _activeOrders[pendingorder.OrderId] = pendingorder; } //Check order id if (order.BrokerId.Contains(order.InternalId.ToString())) { order.BrokerId.Add(order.InternalId.ToString()); } //Order event OrderStateChange?.Invoke(this, OrderTicketEvent.Submitted(order.InternalId)); return(true); } return(false); }
/// <summary> /// Cancels the order. /// </summary> /// <param name="order">The order.</param> /// <returns></returns> public bool CancelOrder(PendingOrder order) { //Check if we can remove this order if (!_activeOrders.TryRemove(order.OrderId, out PendingOrder active)) { return(false); //Cannot find order } //Send cancelled order notification OrderStateChange?.Invoke(this, OrderTicketEvent.Cancelled(order.OrderId, "Order was cancelled")); return(true); }
/// <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); }
private static async Task <(Order order, bool result)> GetOrderFromTableAsync(OrderStateChange orderStateChange, CloudTable orderTable, ILogger log) { var result = true; Order order = null; try { order = await orderTable.GetOrderByIdAsync(orderStateChange.OrderId); } catch (Exception ex) { log.LogError(ex, $"Error during retriving Order {orderStateChange.OrderId}"); result = false; } return(order, result); }
/// <summary> /// Processes the market data. /// </summary> /// <param name="dataupdates">The data updates.</param> public void ProcessMarketData(DataUpdates dataupdates) { //Only accept market data if (_activeOrders.Count == 0) { return; } //Check if we have any data if (!dataupdates.HasUpdates) { return; } lock (_locker) { foreach (var pkv in _activeOrders.OrderBy(x => x.Key)) { //get the order var pendingorder = pkv.Value; var order = pendingorder.Order; //Get datapoint if (!dataupdates[order.Security].HasUpdates) { continue; } var datapoint = dataupdates[order.Security].Ticks.Count > 0 ? dataupdates[order.Security].Ticks.First().Value.First() as DataPoint : dataupdates[order.Security].QuoteBars.Count > 0 ? dataupdates[order.Security].QuoteBars.First().Value as DataPoint : dataupdates[order.Security].TradeBars.Count > 0 ? dataupdates[order.Security].TradeBars.First().Value as DataPoint : null; if (datapoint == null) { continue; } //Check if order is already done if (order.State.IsDone()) { _activeOrders.TryRemove(pkv.Key, out pendingorder); continue; } //Check if we have enough buying power if (!_portfolio.OrderTicketHandler.GetSufficientCapitalForOrder(pendingorder)) { //Remove order from active orders, as it is cancelled by the broker instance _activeOrders.TryRemove(pkv.Key, out pendingorder); _portfolio.Log(LogLevel.Error, $"Insufficient funds to process order by sim broker"); OrderStateChange?.Invoke(this, OrderTicketEvent.Cancelled(pendingorder.OrderId, "Insufficient funds to process order by sim broker")); } //Check if we need to fill this order var fillmodel = BrokerModel.GetFillModel(order); Fill filledresult = Fill.NoFill(); try { filledresult = fillmodel.FillOrder(BrokerModel, datapoint, pendingorder, _usehighlyliquidfills); } catch (Exception exc) { _log.Error(exc); _portfolio.Log(LogLevel.Error, string.Format("Order Error: id: {0}, Transaction model failed to fill for order type: {1} with error: {2}", order.InternalId, order.Type, exc.Message)); OrderStateChange?.Invoke(this, OrderTicketEvent.Cancelled(pendingorder.OrderId, "Exception during processing fill for this order, please check logs")); } //Check for any full or partial fills if (filledresult.FillQuantity > 0) { if (filledresult.Status == OrderState.Filled) { OrderStateChange?.Invoke(this, OrderTicketEvent.Filled(order.InternalId, filledresult)); } else if (filledresult.Status == OrderState.PartialFilled) { OrderStateChange?.Invoke(this, OrderTicketEvent.PartiallyFilled(order.InternalId, filledresult)); } } //Check if order is done if (filledresult.Status.IsDone()) { _activeOrders.TryRemove(pkv.Key, out pendingorder); } } } }