Пример #1
0
        /// <summary>
        /// Gets all orders not yet closed
        /// </summary>
        /// <returns></returns>
        public override List<Order> GetOpenOrders()
        {
            var list = new List<Order>();

            var req = new RestRequest("/orders?status=open&status=pending", Method.GET);
            GetAuthenticationToken(req);
            var response = ExecuteRestRequest(req, GdaxEndpointType.Private);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new Exception($"GDAXBrokerage.GetOpenOrders: request failed: [{(int) response.StatusCode}] {response.StatusDescription}, Content: {response.Content}, ErrorMessage: {response.ErrorMessage}");
            }

            var orders = JsonConvert.DeserializeObject<Messages.Order[]>(response.Content);
            foreach (var item in orders)
            {
                Order order;
                if (item.Type == "market")
                {
                    order = new MarketOrder { Price = item.Price };
                }
                else if (item.Type == "limit")
                {
                    order = new LimitOrder { LimitPrice = item.Price };
                }
                else if (item.Type == "stop")
                {
                    order = new StopMarketOrder { StopPrice = item.Price };
                }
                else
                {
                    OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, (int)response.StatusCode,
                        "GDAXBrokerage.GetOpenOrders: Unsupported order type returned from brokerage: " + item.Type));
                    continue;
                }

                order.Quantity = item.Side == "sell" ? -item.Size : item.Size;
                order.BrokerId = new List<string> { item.Id };
                order.Symbol = ConvertProductId(item.ProductId);
                order.Time = DateTime.UtcNow;
                order.Status = ConvertOrderStatus(item);
                order.Price = item.Price;
                list.Add(order);
            }

            foreach (var item in list)
            {
                if (item.Status.IsOpen())
                {
                    var cached = CachedOrderIDs.Where(c => c.Value.BrokerId.Contains(item.BrokerId.First()));
                    if (cached.Any())
                    {
                        CachedOrderIDs[cached.First().Key] = item;
                    }
                }
            }

            return list;
        }
Пример #2
0
        private void OrderMatch(string data)
        {
            var message = JsonConvert.DeserializeObject <Messages.Matched>(data, JsonSettings);
            var cached  = CachedOrderIDs.Where(o => o.Value.BrokerId.Contains(message.MakerOrderId) || o.Value.BrokerId.Contains(message.TakerOrderId));

            var symbol = ConvertProductId(message.ProductId);

            if (!cached.Any())
            {
                return;
            }

            Log.Trace($"GDAXBrokerage.OrderMatch(): Match: {message.ProductId} {data}");
            var orderId  = cached.First().Key;
            var orderObj = cached.First().Value;

            if (!FillSplit.ContainsKey(orderId))
            {
                FillSplit[orderId] = new GDAXFill(orderObj);
            }

            var split = FillSplit[orderId];

            split.Add(message);

            //is this the total order at once? Is this the last split fill?
            var status = Math.Abs(message.Size) == Math.Abs(cached.Single().Value.Quantity) || Math.Abs(split.OrderQuantity) == Math.Abs(split.TotalQuantity())
                ? OrderStatus.Filled : OrderStatus.PartiallyFilled;

            OrderDirection direction;

            // Messages are always from the perspective of the market maker. Flip it in cases of a market order.
            if (orderObj.Type == OrderType.Market)
            {
                direction = message.Side == "sell" ? OrderDirection.Buy : OrderDirection.Sell;
            }
            else
            {
                direction = message.Side == "sell" ? OrderDirection.Sell : OrderDirection.Buy;
            }

            var orderEvent = new OrderEvent
                             (
                cached.First().Key, symbol, message.Time, status,
                direction,
                message.Price, direction == OrderDirection.Sell ? -message.Size : message.Size,
                GetFee(cached.First().Value), $"GDAX Match Event {direction}"
                             );

            //if we're filled we won't wait for done event
            if (orderEvent.Status == OrderStatus.Filled)
            {
                Orders.Order outOrder = null;
                CachedOrderIDs.TryRemove(cached.First().Key, out outOrder);
            }

            OnOrderEvent(orderEvent);
        }
Пример #3
0
        private void OrderDone(string data)
        {
            Log.Trace($"GDAXBrokerage.Messaging.OrderDone(): Order completed with data {data}");
            var message = JsonConvert.DeserializeObject <Messages.Done>(data, JsonSettings);

            //if we don't exit now, will result in fill message
            if (message.Reason == "canceled" || message.RemainingSize > 0)
            {
                Log.Trace($"GDAXBrokerage.Messaging.OrderDone(): Order cancelled. Remaining {message.RemainingSize}");
                return;
            }

            //is this our order?
            var cached = CachedOrderIDs.Where(o => o.Value.BrokerId.Contains(message.OrderId)).ToList();

            if (cached.Count == 0 || cached[0].Value.Status == OrderStatus.Filled)
            {
                Log.Trace($"GDAXBrokerage.Messaging.OrderDone(): Order could not locate order in cache with order id {message.OrderId}");
                return;
            }

            var orderId = cached[0].Key;

            OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Information, -1,
                                                $"GDAXWebsocketsBrokerage.OrderDone: Encountered done message prior to match filling order brokerId: {message.OrderId} orderId: {orderId}"));

            var split = FillSplit[orderId];

            var symbol       = ConvertProductId(message.ProductId);
            var fillPrice    = message.Price;
            var fillQuantity = message.Side == "sell" ? -split.TotalQuantity() : split.TotalQuantity();
            var orderFee     = GetFillFee(symbol, fillPrice, fillQuantity, true);

            //should have already been filled but match message may have been missed. Let's say we've filled now
            var orderEvent = new OrderEvent
                             (
                orderId, symbol, message.Time, OrderStatus.Filled,
                message.Side == "sell" ? OrderDirection.Sell : OrderDirection.Buy,
                fillPrice, fillQuantity,
                orderFee, "GDAX Fill Event"
                             );

            Order outOrder;

            CachedOrderIDs.TryRemove(orderId, out outOrder);

            OnOrderEvent(orderEvent);
        }
Пример #4
0
        private void OrderDone(string data)
        {
            var message = JsonConvert.DeserializeObject <Messages.Done>(data, JsonSettings);

            //if we don't exit now, will result in fill message
            if (message.Reason == "canceled" || message.RemainingSize > 0)
            {
                return;
            }

            //is this our order?
            var cached = CachedOrderIDs.Where(o => o.Value.BrokerId.Contains(message.OrderId));

            if (!cached.Any() || cached.Single().Value.Status == OrderStatus.Filled)
            {
                return;
            }

            OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Information, -1,
                                                $"GDAXWebsocketsBrokerage.OrderDone: Encountered done message prior to match filling order brokerId: {message.OrderId} orderId: {cached.FirstOrDefault().Key}"));

            var split = this.FillSplit[cached.First().Key];

            //should have already been filled but match message may have been missed. Let's say we've filled now
            var orderEvent = new OrderEvent
                             (
                cached.First().Key, ConvertProductId(message.ProductId), message.Time, OrderStatus.Filled,
                message.Side == "sell" ? OrderDirection.Sell : OrderDirection.Buy,
                message.Price, message.Side == "sell" ? -split.TotalQuantity() : split.TotalQuantity(),
                GetFee(cached.First().Value), "GDAX Fill Event"
                             );

            Orders.Order outOrder = null;
            CachedOrderIDs.TryRemove(cached.First().Key, out outOrder);

            OnOrderEvent(orderEvent);
        }
Пример #5
0
        private void OrderMatch(string data)
        {
            var message = JsonConvert.DeserializeObject <Messages.Matched>(data, JsonSettings);
            var cached  = CachedOrderIDs.Where(o => o.Value.BrokerId.Contains(message.MakerOrderId) || o.Value.BrokerId.Contains(message.TakerOrderId));

            var symbol = ConvertProductId(message.ProductId);

            if (!cached.Any())
            {
                return;
            }

            var split = this.FillSplit[cached.First().Key];

            split.Add(message);

            //is this the total order at once? Is this the last split fill?
            var status = Math.Abs(message.Size) == Math.Abs(cached.Single().Value.Quantity) || Math.Abs(split.OrderQuantity) == Math.Abs(split.TotalQuantity())
                ? OrderStatus.Filled : OrderStatus.PartiallyFilled;

            var orderEvent = new OrderEvent
                             (
                cached.First().Key, symbol, message.Time, status,
                message.Side == "sell" ? OrderDirection.Sell : OrderDirection.Buy,
                message.Price, message.Side == "sell" ? -message.Size : message.Size,
                GetFee(cached.First().Value), "GDAX Match Event"
                             );

            //if we're filled we won't wait for done event
            if (orderEvent.Status == OrderStatus.Filled)
            {
                Orders.Order outOrder = null;
                CachedOrderIDs.TryRemove(cached.First().Key, out outOrder);
            }

            OnOrderEvent(orderEvent);
        }
Пример #6
0
        /// <summary>
        /// Gets all orders not yet closed
        /// </summary>
        /// <returns></returns>
        public override List <Order> GetOpenOrders()
        {
            var          orders = _apiClient.GetOpenOrders();
            List <Order> list   = new List <Order>();

            foreach (var item in orders)
            {
                Order order;
                switch (item.Type.LazyToUpper())
                {
                case "MARKET":
                    order = new MarketOrder {
                        Price = item.Price
                    };
                    break;

                case "LIMIT":
                case "LIMIT_MAKER":
                    order = new LimitOrder {
                        LimitPrice = item.Price
                    };
                    break;

                case "STOP_LOSS":
                case "TAKE_PROFIT":
                    order = new StopMarketOrder {
                        StopPrice = item.StopPrice, Price = item.Price
                    };
                    break;

                case "STOP_LOSS_LIMIT":
                case "TAKE_PROFIT_LIMIT":
                    order = new StopLimitOrder {
                        StopPrice = item.StopPrice, LimitPrice = item.Price
                    };
                    break;

                default:
                    OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, -1,
                                                        "BinanceBrokerage.GetOpenOrders: Unsupported order type returned from brokerage: " + item.Type));
                    continue;
                }

                order.Quantity = item.Quantity;
                order.BrokerId = new List <string> {
                    item.Id
                };
                order.Symbol = _symbolMapper.GetLeanSymbol(item.Symbol, SecurityType.Crypto, Market.Binance);
                order.Time   = Time.UnixMillisecondTimeStampToDateTime(item.Time);
                order.Status = ConvertOrderStatus(item.Status);
                order.Price  = item.Price;

                if (order.Status.IsOpen())
                {
                    var cached = CachedOrderIDs.Where(c => c.Value.BrokerId.Contains(order.BrokerId.First())).ToList();
                    if (cached.Any())
                    {
                        CachedOrderIDs[cached.First().Key] = order;
                    }
                }

                list.Add(order);
            }

            return(list);
        }
Пример #7
0
        /// <summary>
        /// Gets all orders not yet closed
        /// </summary>
        /// <returns></returns>
        public override List <Order> GetOpenOrders()
        {
            var list     = new List <Order>();
            var endpoint = GetEndpoint("orders");
            var request  = new RestRequest(endpoint, Method.POST);

            JsonObject payload = new JsonObject();

            payload.Add("request", endpoint);
            payload.Add("nonce", GetNonce().ToStringInvariant());

            request.AddJsonBody(payload.ToString());
            SignRequest(request, payload.ToString());

            var response = ExecuteRestRequest(request);

            if (response.StatusCode != HttpStatusCode.OK)
            {
                throw new Exception($"BitfinexBrokerage.GetOpenOrders: request failed: [{(int)response.StatusCode}] {response.StatusDescription}, Content: {response.Content}, ErrorMessage: {response.ErrorMessage}");
            }

            var orders = JsonConvert.DeserializeObject <Messages.Order[]>(response.Content)
                         .Where(OrderFilter(_algorithm.BrokerageModel.AccountType));

            foreach (var item in orders)
            {
                Order order;
                if (item.Type.Replace("exchange", "").Trim() == "market")
                {
                    order = new MarketOrder {
                        Price = item.Price
                    };
                }
                else if (item.Type.Replace("exchange", "").Trim() == "limit")
                {
                    order = new LimitOrder {
                        LimitPrice = item.Price
                    };
                }
                else if (item.Type.Replace("exchange", "").Trim() == "stop")
                {
                    order = new StopMarketOrder {
                        StopPrice = item.Price
                    };
                }
                else
                {
                    OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, (int)response.StatusCode,
                                                        "BitfinexBrokerage.GetOpenOrders: Unsupported order type returned from brokerage: " + item.Type));
                    continue;
                }

                order.Quantity = item.Side == "sell" ? -item.OriginalAmount : item.OriginalAmount;
                order.BrokerId = new List <string> {
                    item.Id
                };
                order.Symbol = _symbolMapper.GetLeanSymbol(item.Symbol);
                order.Time   = Time.UnixTimeStampToDateTime(item.Timestamp);
                order.Status = ConvertOrderStatus(item);
                order.Price  = item.Price;
                list.Add(order);
            }

            foreach (var item in list)
            {
                if (item.Status.IsOpen())
                {
                    var cached = CachedOrderIDs.Where(c => c.Value.BrokerId.Contains(item.BrokerId.First()));
                    if (cached.Any())
                    {
                        CachedOrderIDs[cached.First().Key] = item;
                    }
                }
            }

            return(list);
        }
Пример #8
0
        private void OrderMatch(string data)
        {
            var message = JsonConvert.DeserializeObject <Messages.Matched>(data, JsonSettings);

            if (_isDataQueueHandler)
            {
                EmitTradeTick(message);
            }

            var cached = CachedOrderIDs
                         .Where(o => o.Value.BrokerId.Contains(message.MakerOrderId) || o.Value.BrokerId.Contains(message.TakerOrderId))
                         .ToList();

            var symbol = ConvertProductId(message.ProductId);

            if (cached.Count == 0)
            {
                return;
            }

            Log.Trace($"GDAXBrokerage.OrderMatch(): Match: {message.ProductId} {data}");
            var orderId = cached[0].Key;
            var order   = cached[0].Value;

            if (!FillSplit.ContainsKey(orderId))
            {
                FillSplit[orderId] = new GDAXFill(order);
            }

            var split = FillSplit[orderId];

            split.Add(message);

            //is this the total order at once? Is this the last split fill?
            var status = Math.Abs(message.Size) == Math.Abs(order.Quantity) || Math.Abs(split.OrderQuantity) == Math.Abs(split.TotalQuantity())
                ? OrderStatus.Filled : OrderStatus.PartiallyFilled;

            OrderDirection direction;

            // Messages are always from the perspective of the market maker. Flip direction if executed as a taker.
            if (order.BrokerId[0] == message.TakerOrderId)
            {
                direction = message.Side == "sell" ? OrderDirection.Buy : OrderDirection.Sell;
            }
            else
            {
                direction = message.Side == "sell" ? OrderDirection.Sell : OrderDirection.Buy;
            }

            decimal totalOrderFee;

            if (!_orderFees.TryGetValue(orderId, out totalOrderFee))
            {
                totalOrderFee       = GetFee(order);
                _orderFees[orderId] = totalOrderFee;
            }

            // apply order fee on a pro rata basis
            var orderFee = totalOrderFee * Math.Abs(message.Size) / Math.Abs(order.Quantity);

            var orderEvent = new OrderEvent
                             (
                orderId, symbol, message.Time, status,
                direction,
                message.Price, direction == OrderDirection.Sell ? -message.Size : message.Size,
                orderFee, $"GDAX Match Event {direction}"
                             );

            //if we're filled we won't wait for done event
            if (orderEvent.Status == OrderStatus.Filled)
            {
                Order outOrder;
                CachedOrderIDs.TryRemove(orderId, out outOrder);

                decimal outOrderFee;
                _orderFees.TryRemove(orderId, out outOrderFee);
            }

            OnOrderEvent(orderEvent);
        }