/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System.Collections.Generic; using System.ComponentModel; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using QuantConnect.Orders.TimeInForces; namespace QuantConnect.Orders.Serialization { /// /// Data transfer object used for serializing an that was just generated by an algorithm /// public class SerializedOrder { /// /// The unique order id /// [JsonProperty("id", Required = Required.Default)] public string Id => $"{AlgorithmId}-{OrderId}"; /// /// Algorithm Id, BacktestId or DeployId /// [JsonProperty("algorithm-id")] public string AlgorithmId { get; set; } /// /// Order ID /// [JsonProperty("order-id")] public int OrderId { get; set; } /// /// Order id to process before processing this order. /// [JsonProperty("contingent-id")] public int ContingentId { get; set; } /// /// Brokerage Id for this order for when the brokerage splits orders into multiple pieces /// [JsonProperty("broker-id")] public List BrokerId { get; set; } /// /// Symbol of the Asset /// [JsonProperty("symbol")] public string Symbol { get; set; } /// /// Price of the Order. /// [JsonProperty("price")] public decimal Price { get; set; } /// /// Currency for the order price /// [JsonProperty("price-currency")] public string PriceCurrency { get; set; } /// /// Gets the utc time this order was created. Alias for /// [JsonProperty("created-time")] public double CreatedTime { get; set; } /// /// Gets the utc time the last fill was received, or null if no fills have been received /// [JsonProperty("last-fill-time", NullValueHandling = NullValueHandling.Ignore)] public double? LastFillTime { get; set; } /// /// Gets the utc time this order was last updated, or null if the order has not been updated. /// [JsonProperty("last-update-time", NullValueHandling = NullValueHandling.Ignore)] public double? LastUpdateTime { get; set; } /// /// Gets the utc time this order was canceled, or null if the order was not canceled. /// [JsonProperty("canceled-time", NullValueHandling = NullValueHandling.Ignore)] public double? CanceledTime { get; set; } /// /// Number of shares to execute. /// [JsonProperty("quantity")] public decimal Quantity { get; set; } /// /// Order Type /// [JsonProperty("type"), JsonConverter(typeof(StringEnumConverter), true)] public OrderType Type { get; set; } /// /// Status of the Order /// [JsonProperty("status"), JsonConverter(typeof(StringEnumConverter), true)] public OrderStatus Status { get; set; } /// /// Tag the order with some custom data /// [DefaultValue(""), JsonProperty("tag", DefaultValueHandling = DefaultValueHandling.Ignore)] public string Tag { get; set; } /// /// Order Direction Property based off Quantity. /// [JsonProperty("direction"), JsonConverter(typeof(StringEnumConverter), true)] public OrderDirection Direction { get; set; } /// /// The current price at order submission time /// [JsonProperty("submission-last-price", DefaultValueHandling = DefaultValueHandling.Ignore)] public decimal SubmissionLastPrice { get; set; } /// /// The ask price at order submission time /// [JsonProperty("submission-ask-price", DefaultValueHandling = DefaultValueHandling.Ignore)] public decimal SubmissionAskPrice { get; set; } /// /// The bid price at order submission time /// [JsonProperty("submission-bid-price", DefaultValueHandling = DefaultValueHandling.Ignore)] public decimal SubmissionBidPrice { get; set; } /// /// The current stop price /// [JsonProperty("stop-price", DefaultValueHandling = DefaultValueHandling.Ignore)] public decimal? StopPrice { get; set; } /// /// Signal showing the "StopLimitOrder" has been converted into a Limit Order /// [JsonProperty("stop-triggered", DefaultValueHandling = DefaultValueHandling.Ignore)] public bool? StopTriggered { get; set; } /// /// The current limit price /// [JsonProperty("limit-price", DefaultValueHandling = DefaultValueHandling.Ignore)] public decimal? LimitPrice { get; set; } /// /// The time in force type /// [JsonProperty("time-in-force-type")] public string TimeInForceType { get; set; } /// /// The time in force expiration time if any /// [JsonProperty("time-in-force-expiry", DefaultValueHandling = DefaultValueHandling.Ignore)] public double? TimeInForceExpiry { get; set; } /// /// Empty constructor required for JSON converter. /// private SerializedOrder() { } /// /// Creates a new serialized order instance based on the provided order /// public SerializedOrder(Order order, string algorithmId) { AlgorithmId = algorithmId; OrderId = order.Id; ContingentId = order.ContingentId; BrokerId = order.BrokerId; Symbol = order.Symbol.ID.ToString(); Price = order.Price; PriceCurrency = order.PriceCurrency; Quantity = order.Quantity; Type = order.Type; Status = order.Status; Tag = order.Tag; Direction = order.Direction; CreatedTime = Time.DateTimeToUnixTimeStamp(order.CreatedTime); if (order.LastFillTime.HasValue) { LastFillTime = Time.DateTimeToUnixTimeStamp(order.LastFillTime.Value); } if (order.LastUpdateTime.HasValue) { LastUpdateTime = Time.DateTimeToUnixTimeStamp(order.LastUpdateTime.Value); } if (order.CanceledTime.HasValue) { CanceledTime = Time.DateTimeToUnixTimeStamp(order.CanceledTime.Value); } if (order.OrderSubmissionData != null) { SubmissionAskPrice = order.OrderSubmissionData.AskPrice; SubmissionBidPrice = order.OrderSubmissionData.BidPrice; SubmissionLastPrice = order.OrderSubmissionData.LastPrice; } var timeInForceType = order.Properties.TimeInForce.GetType().Name; // camelcase the type name, lowering the first char TimeInForceType = char.ToLowerInvariant(timeInForceType[0]) + timeInForceType.Substring(1); if (order.Properties.TimeInForce is GoodTilDateTimeInForce) { var expiry = (order.Properties.TimeInForce as GoodTilDateTimeInForce).Expiry; TimeInForceExpiry = Time.DateTimeToUnixTimeStamp(expiry); } if (order.Type == OrderType.Limit) { var limit = order as LimitOrder; LimitPrice = limit.LimitPrice; } else if (order.Type == OrderType.StopLimit) { var stopLimit = order as StopLimitOrder; LimitPrice = stopLimit.LimitPrice; StopPrice = stopLimit.StopPrice; StopTriggered = stopLimit.StopTriggered; } else if (order.Type == OrderType.StopMarket) { var stopMarket = order as StopMarketOrder; StopPrice = stopMarket.StopPrice; } } } }