/// <summary> /// Creates a new order /// </summary> /// <param name="order"></param> /// <returns></returns> public override bool PlaceOrder(Order order) { LockStream(); var req = new RestRequest("/orders", Method.POST); dynamic payload = new ExpandoObject(); payload.size = Math.Abs(order.Quantity); payload.side = order.Direction.ToString().ToLower(); payload.type = ConvertOrderType(order.Type); payload.price = (order as LimitOrder)?.LimitPrice ?? ((order as StopMarketOrder)?.StopPrice ?? 0); payload.product_id = ConvertSymbol(order.Symbol); if (_algorithm.BrokerageModel.AccountType == AccountType.Margin) { payload.overdraft_enabled = true; } var orderProperties = order.Properties as GDAXOrderProperties; if (orderProperties != null) { if (order.Type == OrderType.Limit) { payload.post_only = orderProperties.PostOnly; } } req.AddJsonBody(payload); GetAuthenticationToken(req); var response = ExecuteRestRequest(req, GdaxEndpointType.Private); if (response.StatusCode == HttpStatusCode.OK && response.Content != null) { var raw = JsonConvert.DeserializeObject <Messages.Order>(response.Content); if (raw?.Id == null) { var errorMessage = $"Error parsing response from place order: {response.Content}"; OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "GDAX Order Event") { Status = OrderStatus.Invalid, Message = errorMessage }); OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, (int)response.StatusCode, errorMessage)); UnlockStream(); return(true); } if (raw.Status == "rejected") { var errorMessage = "Reject reason: " + raw.RejectReason; OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "GDAX Order Event") { Status = OrderStatus.Invalid, Message = errorMessage }); OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, (int)response.StatusCode, errorMessage)); UnlockStream(); return(true); } var brokerId = raw.Id; if (CachedOrderIDs.ContainsKey(order.Id)) { CachedOrderIDs[order.Id].BrokerId.Add(brokerId); } else { order.BrokerId.Add(brokerId); CachedOrderIDs.TryAdd(order.Id, order); } // Add fill splits in all cases; we'll need to handle market fills too. FillSplit.TryAdd(order.Id, new GDAXFill(order)); // Generate submitted event OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "GDAX Order Event") { Status = OrderStatus.Submitted }); OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Information, -1, "Order completed successfully orderid:" + order.Id)); UnlockStream(); return(true); } var message = $"Order failed, Order Id: {order.Id} timestamp: {order.Time} quantity: {order.Quantity} content: {response.Content}"; OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "GDAX Order Event") { Status = OrderStatus.Invalid }); OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Warning, -1, message)); UnlockStream(); return(true); }
/// <summary> /// Creates a new order /// </summary> /// <param name="order"></param> /// <returns></returns> public override bool PlaceOrder(Orders.Order order) { LockStream(); var req = new RestRequest("/orders", Method.POST); dynamic payload = new ExpandoObject(); payload.size = Math.Abs(order.Quantity); payload.side = order.Direction.ToString().ToLower(); payload.type = ConvertOrderType(order.Type); payload.price = order is LimitOrder ? ((LimitOrder)order).LimitPrice : order is StopMarketOrder ? ((StopMarketOrder)order).StopPrice : 0; payload.product_id = ConvertSymbol(order.Symbol); if (_algorithm.BrokerageModel.AccountType == AccountType.Margin) { payload.overdraft_enabled = true; } req.AddJsonBody(payload); GetAuthenticationToken(req); var response = RestClient.Execute(req); if (response.StatusCode == System.Net.HttpStatusCode.OK && response.Content != null) { var raw = JsonConvert.DeserializeObject <Messages.Order>(response.Content); if (raw == null || raw.Id == null) { OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, (int)response.StatusCode, "GDAXBrokerage.PlaceOrder: Error parsing response from place order: " + response.Content)); UnlockStream(); return(false); } var brokerId = raw.Id; if (CachedOrderIDs.ContainsKey(order.Id)) { CachedOrderIDs[order.Id].BrokerId.Add(brokerId); } else { order.BrokerId.Add(brokerId); CachedOrderIDs.TryAdd(order.Id, order); } // Add fill splits in all cases; we'll need to handle market fills too. FillSplit.TryAdd(order.Id, new GDAXFill(order)); // Generate submitted event OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "GDAX Order Event") { Status = OrderStatus.Submitted }); OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Information, -1, "GDAXBrokerage.PlaceOrder: Order completed successfully orderid:" + order.Id.ToString())); UnlockStream(); return(true); } OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "GDAX Order Event") { Status = OrderStatus.Invalid }); var message = $"GDAXBrokerage.PlaceOrder: Order failed Order Id: {order.Id} timestamp: {order.Time} quantity: {order.Quantity} content: {response.Content}"; OnMessage(new BrokerageMessageEvent(BrokerageMessageType.Error, -1, message)); UnlockStream(); return(false); }
/// <summary> /// Creates a new order /// </summary> /// <param name="order"></param> /// <returns></returns> public override bool PlaceOrder(Orders.Order order) { var req = new RestRequest("/orders", Method.POST); dynamic payload = new ExpandoObject(); payload.size = Math.Abs(order.Quantity); payload.side = order.Direction.ToString().ToLower(); payload.type = ConvertOrderType(order.Type); payload.price = order is LimitOrder ? ((LimitOrder)order).LimitPrice : order is StopMarketOrder ? ((StopMarketOrder)order).StopPrice : 0; payload.product_id = ConvertSymbol(order.Symbol); if (_algorithm.BrokerageModel.AccountType == AccountType.Margin) { payload.overdraft_enabled = true; } req.AddJsonBody(payload); GetAuthenticationToken(req); var response = RestClient.Execute(req); if (response.StatusCode == System.Net.HttpStatusCode.OK && response.Content != null) { dynamic raw = JsonConvert.DeserializeObject <dynamic>(response.Content); if (raw == null || raw.id == null) { Log.Error("GDAXBrokerage.PlaceOrder: Error parsing response from place order"); return(false); } string brokerId = raw.id; if (CachedOrderIDs.ContainsKey(order.Id)) { CachedOrderIDs[order.Id].BrokerId.Add(brokerId); } else { order.BrokerId.Add(brokerId); CachedOrderIDs.TryAdd(order.Id, order); } if (order.Type != OrderType.Market) { FillSplit.TryAdd(order.Id, new GDAXFill(order)); } OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "GDAX Order Event") { Status = OrderStatus.Submitted }); if (order.Type == OrderType.Market) { OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, (decimal)raw.fill_fees, "GDAX Order Event") { Status = OrderStatus.Filled }); Orders.Order outOrder = null; CachedOrderIDs.TryRemove(order.Id, out outOrder); } Log.Trace("GDAXBrokerage.PlaceOrder: Order completed successfully orderid:" + order.Id.ToString()); return(true); } OnOrderEvent(new OrderEvent(order, DateTime.UtcNow, 0, "GDAX Order Event") { Status = OrderStatus.Invalid }); Log.Trace("GDAXBrokerage.PlaceOrder: Order failed Order Id: " + order.Id + " timestamp:" + order.Time + " quantity: " + order.Quantity.ToString() + " content:" + response.Content); return(false); }