/// <summary> /// Event handler for streaming events /// </summary> /// <param name="data">The event object</param> private void OnEventReceived(Event data) { if (data.IsHeartbeat()) { TransactionsConnectionHandler.KeepAlive(DateTime.UtcNow); return; } if (data.transaction != null) { if (data.transaction.type == "ORDER_FILLED") { Order order; lock (Locker) { order = OrderProvider.GetOrderByBrokerageId(data.transaction.orderId); } if (order != null) { OrderStatus status; // Market orders are special: if the order was not in 'PartiallyFilledMarketOrders', means // we already sent the fill event with OrderStatus.Filled, else it means we already informed the user // of a partiall fill, or didn't inform the user, so we need to do it now if (order.Type != OrderType.Market || PendingFilledMarketOrders.TryRemove(order.Id, out status)) { order.PriceCurrency = SecurityProvider.GetSecurity(order.Symbol).SymbolProperties.QuoteCurrency; var fill = new OrderEvent(order, DateTime.UtcNow, OrderFee.Zero, "Oanda Fill Event") { Status = OrderStatus.Filled, FillPrice = (decimal)data.transaction.price, FillQuantity = data.transaction.units }; // flip the quantity on sell actions if (order.Direction == OrderDirection.Sell) { fill.FillQuantity *= -1; } OnOrderEvent(fill); } } else { Log.Error($"OandaBrokerage.OnEventReceived(): order id not found: {data.transaction.orderId}"); } } } }
/// <summary> /// Event handler for streaming events /// </summary> /// <param name="json">The event object</param> private void OnTransactionDataReceived(string json) { var obj = (JObject)JsonConvert.DeserializeObject(json); var type = obj["type"].ToString(); switch (type) { case "HEARTBEAT": TransactionsConnectionHandler.KeepAlive(DateTime.UtcNow); break; case "ORDER_FILL": var transaction = obj.ToObject <OrderFillTransaction>(); Order order; lock (Locker) { order = OrderProvider.GetOrderByBrokerageId(transaction.OrderID); } if (order != null) { OrderStatus status; // Market orders are special: if the order was not in 'PartiallyFilledMarketOrders', means // we already sent the fill event with OrderStatus.Filled, else it means we already informed the user // of a partiall fill, or didn't inform the user, so we need to do it now if (order.Type != OrderType.Market || PendingFilledMarketOrders.TryRemove(order.Id, out status)) { order.PriceCurrency = SecurityProvider.GetSecurity(order.Symbol).SymbolProperties.QuoteCurrency; OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, OrderFee.Zero, "Oanda Fill Event") { Status = OrderStatus.Filled, FillPrice = transaction.Price.ToDecimal(), FillQuantity = transaction.Units.ConvertInvariant <int>() }); } } else { Log.Error($"OandaBrokerage.OnTransactionDataReceived(): order id not found: {transaction.OrderID}"); } break; } }