Пример #1
0
        /// <summary>
        /// Event handler for streaming events
        /// </summary>
        /// <param name="data">The event object</param>
        private void OnEventReceived(Event data)
        {
            if (data.IsHeartbeat())
            {
                lock (LockerConnectionMonitor)
                {
                    LastHeartbeatUtcTime = DateTime.UtcNow;
                }
                return;
            }

            if (data.transaction != null)
            {
                if (data.transaction.type == "ORDER_FILLED")
                {
                    var qcOrder = OrderProvider.GetOrderByBrokerageId(data.transaction.orderId);
                    qcOrder.PriceCurrency = SecurityProvider.GetSecurity(qcOrder.Symbol).SymbolProperties.QuoteCurrency;

                    const int orderFee = 0;
                    var       fill     = new OrderEvent(qcOrder, DateTime.UtcNow, orderFee, "Oanda Fill Event")
                    {
                        Status       = OrderStatus.Filled,
                        FillPrice    = (decimal)data.transaction.price,
                        FillQuantity = data.transaction.units
                    };

                    // flip the quantity on sell actions
                    if (qcOrder.Direction == OrderDirection.Sell)
                    {
                        fill.FillQuantity *= -1;
                    }
                    OnOrderEvent(fill);
                }
            }
        }
Пример #2
0
        /// <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":
                lock (LockerConnectionMonitor)
                {
                    LastHeartbeatUtcTime = DateTime.UtcNow;
                }
                break;

            case "ORDER_FILL":
                var transaction = obj.ToObject <OrderFillTransaction>();

                var order = OrderProvider.GetOrderByBrokerageId(transaction.OrderID);
                if (order != null)
                {
                    order.PriceCurrency = SecurityProvider.GetSecurity(order.Symbol).SymbolProperties.QuoteCurrency;

                    const int orderFee = 0;
                    OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, orderFee, "Oanda Fill Event")
                    {
                        Status       = OrderStatus.Filled,
                        FillPrice    = transaction.Price.ToDecimal(),
                        FillQuantity = Convert.ToInt32(transaction.Units)
                    });
                }
                break;
            }
        }
Пример #3
0
        /// <summary>
        /// Event handler for streaming events
        /// </summary>
        /// <param name="data">The event object</param>
        private void OnEventReceived(Event data)
        {
            if (data.IsHeartbeat())
            {
                lock (LockerConnectionMonitor)
                {
                    LastHeartbeatUtcTime = 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;

                            const int orderFee = 0;
                            var       fill     = new OrderEvent(order, DateTime.UtcNow, orderFee, "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}");
                    }
                }
            }
        }
Пример #4
0
        /// <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":
                lock (LockerConnectionMonitor)
                {
                    LastHeartbeatUtcTime = 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;

                        const int orderFee = 0;
                        OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, orderFee, "Oanda Fill Event")
                        {
                            Status       = OrderStatus.Filled,
                            FillPrice    = transaction.Price.ToDecimal(),
                            FillQuantity = Convert.ToInt32(transaction.Units)
                        });
                    }
                }
                else
                {
                    Log.Error($"OandaBrokerage.OnTransactionDataReceived(): order id not found: {transaction.OrderID}");
                }
                break;
            }
        }
Пример #5
0
        /// <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))
                    {
                        OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, OrderFee.Zero, "Oanda Fill Event")
                        {
                            Status       = OrderStatus.Filled,
                            FillPrice    = transaction.Price.ToDecimal(),
                            FillQuantity = transaction.Units.ConvertInvariant <decimal>()
                        });
                    }
                }
                else
                {
                    Log.Error($"OandaBrokerage.OnTransactionDataReceived(): order id not found: {transaction.OrderID}");
                }
                break;
            }
        }
Пример #6
0
        /// <summary>
        /// Converts an Oanda order into a LEAN order.
        /// </summary>
        private Order ConvertOrder(JToken order)
        {
            var type = order["type"].ToString();

            Order qcOrder;

            switch (type)
            {
            case "MARKET_IF_TOUCHED":
                var stopOrder = order.ToObject <MarketIfTouchedOrder>();
                qcOrder = new StopMarketOrder
                {
                    StopPrice = stopOrder.Price.ToDecimal()
                };
                break;

            case "LIMIT":
                var limitOrder = order.ToObject <OandaLimitOrder>();
                qcOrder = new LimitOrder
                {
                    LimitPrice = limitOrder.Price.ToDecimal()
                };
                break;

            case "STOP":
                var stopLimitOrder = order.ToObject <StopOrder>();
                qcOrder = new StopLimitOrder
                {
                    Price      = stopLimitOrder.Price.ConvertInvariant <decimal>(),
                    LimitPrice = stopLimitOrder.PriceBound.ConvertInvariant <decimal>()
                };
                break;

            case "MARKET":
                qcOrder = new MarketOrder();
                break;

            default:
                throw new NotSupportedException(
                          "An existing " + type + " working order was found and is currently unsupported. Please manually cancel the order before restarting the algorithm.");
            }

            var instrument = order["instrument"].ToString();
            var id         = order["id"].ToString();
            var units      = order["units"].ConvertInvariant <int>();
            var createTime = order["createTime"].ToString();

            var securityType = SymbolMapper.GetBrokerageSecurityType(instrument);

            qcOrder.Symbol   = SymbolMapper.GetLeanSymbol(instrument, securityType, Market.Oanda);
            qcOrder.Time     = GetTickDateTimeFromString(createTime);
            qcOrder.Quantity = units;
            qcOrder.Status   = OrderStatus.None;
            qcOrder.BrokerId.Add(id);

            var orderByBrokerageId = OrderProvider.GetOrderByBrokerageId(id);

            if (orderByBrokerageId != null)
            {
                qcOrder.Id = orderByBrokerageId.Id;
            }

            var gtdTime = order["gtdTime"];

            if (gtdTime != null)
            {
                var expiry = GetTickDateTimeFromString(gtdTime.ToString());
                qcOrder.Properties.TimeInForce = TimeInForce.GoodTilDate(expiry);
            }

            return(qcOrder);
        }
Пример #7
0
        /// <summary>
        /// Converts the specified Oanda order into a qc order.
        /// The 'task' will have a value if we needed to issue a rest call for the stop price, otherwise it will be null
        /// </summary>
        private Order ConvertOrder(RestV1.DataType.Order order)
        {
            Order qcOrder;

            switch (order.type)
            {
            case "limit":
                qcOrder = new LimitOrder();
                if (order.side == "buy")
                {
                    ((LimitOrder)qcOrder).LimitPrice = Convert.ToDecimal(order.lowerBound);
                }

                if (order.side == "sell")
                {
                    ((LimitOrder)qcOrder).LimitPrice = Convert.ToDecimal(order.upperBound);
                }
                break;

            case "stop":
                qcOrder = new StopLimitOrder();
                if (order.side == "buy")
                {
                    ((StopLimitOrder)qcOrder).LimitPrice = Convert.ToDecimal(order.lowerBound);
                }

                if (order.side == "sell")
                {
                    ((StopLimitOrder)qcOrder).LimitPrice = Convert.ToDecimal(order.upperBound);
                }
                break;

            case "marketIfTouched":
                //when market reaches the price sell at market.
                qcOrder = new StopMarketOrder {
                    Price = Convert.ToDecimal(order.price), StopPrice = Convert.ToDecimal(order.price)
                };
                break;

            case "market":
                qcOrder = new MarketOrder();
                break;

            default:
                throw new NotSupportedException("The Oanda order type " + order.type + " is not supported.");
            }

            var securityType = SymbolMapper.GetBrokerageSecurityType(order.instrument);

            qcOrder.Symbol   = SymbolMapper.GetLeanSymbol(order.instrument, securityType, Market.Oanda);
            qcOrder.Quantity = ConvertQuantity(order);
            qcOrder.Status   = OrderStatus.None;
            qcOrder.BrokerId.Add(order.id.ToString());

            var orderByBrokerageId = OrderProvider.GetOrderByBrokerageId(order.id);

            if (orderByBrokerageId != null)
            {
                qcOrder.Id = orderByBrokerageId.Id;
            }

            var expiry = XmlConvert.ToDateTime(order.expiry, XmlDateTimeSerializationMode.Utc);

            qcOrder.Properties.TimeInForce = TimeInForce.GoodTilDate(expiry);
            qcOrder.Time = XmlConvert.ToDateTime(order.time, XmlDateTimeSerializationMode.Utc);

            return(qcOrder);
        }
Пример #8
0
        /// <summary>
        /// Converts an Oanda order into a LEAN order.
        /// </summary>
        private Order ConvertOrder(JToken order)
        {
            var type       = order["type"].ToString();
            var instrument = order["instrument"].ToString();
            var id         = order["id"].ToString();
            var units      = Convert.ToInt32(order["units"]);
            var createTime = order["createTime"].ToString();

            Order qcOrder;

            switch (type)
            {
            case "MARKET_IF_TOUCHED":
                var stopOrder = order.ToObject <MarketIfTouchedOrder>();
                qcOrder = new StopMarketOrder
                {
                    StopPrice = stopOrder.Price.ToDecimal()
                };
                break;

            case "LIMIT":
                var limitOrder = order.ToObject <OandaLimitOrder>();
                qcOrder = new LimitOrder
                {
                    LimitPrice = limitOrder.Price.ToDecimal()
                };
                break;

            case "STOP":
                var stopLimitOrder = order.ToObject <StopOrder>();
                qcOrder = new StopLimitOrder
                {
                    Price      = Convert.ToDecimal(stopLimitOrder.Price),
                    LimitPrice = Convert.ToDecimal(stopLimitOrder.PriceBound)
                };
                break;

            case "MARKET":
                qcOrder = new MarketOrder();
                break;

            default:
                throw new NotSupportedException("The Oanda order type " + type + " is not supported.");
            }

            var securityType = SymbolMapper.GetBrokerageSecurityType(instrument);

            qcOrder.Symbol   = SymbolMapper.GetLeanSymbol(instrument, securityType, Market.Oanda);
            qcOrder.Time     = GetTickDateTimeFromString(createTime);
            qcOrder.Quantity = units;
            qcOrder.Status   = OrderStatus.None;
            qcOrder.BrokerId.Add(id);

            var orderByBrokerageId = OrderProvider.GetOrderByBrokerageId(id);

            if (orderByBrokerageId != null)
            {
                qcOrder.Id = orderByBrokerageId.Id;
            }

            var gtdTime = order["gtdTime"];

            if (gtdTime != null)
            {
                qcOrder.Duration      = OrderDuration.Custom;
                qcOrder.DurationValue = GetTickDateTimeFromString(gtdTime.ToString());
            }

            return(qcOrder);
        }