Lean  $LEAN_TAG$
OrderEvent.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
17 using System.ComponentModel;
18 using Newtonsoft.Json;
19 using ProtoBuf;
23 
24 namespace QuantConnect.Orders
25 {
26  /// <summary>
27  /// Order Event - Messaging class signifying a change in an order state and record the change in the user's algorithm portfolio
28  /// </summary>
29  [ProtoContract(SkipConstructor = true)]
30  public class OrderEvent
31  {
32  private decimal _fillPrice;
33  private decimal _fillQuantity;
34  private decimal _quantity;
35  private decimal? _limitPrice;
36  private decimal? _triggerPrice;
37  private decimal? _stopPrice;
38  private decimal? _trailingAmount;
39  private bool? _trailingAsPercentage;
40 
41  /// <summary>
42  /// Id of the order this event comes from.
43  /// </summary>
44  [ProtoMember(1)]
45  public int OrderId { get; set; }
46 
47  /// <summary>
48  /// The unique order event id for each order
49  /// </summary>
50  [ProtoMember(2)]
51  public int Id { get; set; }
52 
53  /// <summary>
54  /// Easy access to the order symbol associated with this event.
55  /// </summary>
56  [ProtoMember(3)]
57  public Symbol Symbol { get; set; }
58 
59  /// <summary>
60  /// The date and time of this event (UTC).
61  /// </summary>
62  [ProtoMember(4)]
63  public DateTime UtcTime { get; set; }
64 
65  /// <summary>
66  /// Status message of the order.
67  /// </summary>
68  [ProtoMember(5)]
69  public OrderStatus Status { get; set; }
70 
71  /// <summary>
72  /// The fee associated with the order
73  /// </summary>
74  [ProtoMember(6)]
75  public OrderFee OrderFee { get; set; }
76 
77  /// <summary>
78  /// Fill price information about the order
79  /// </summary>
80  [ProtoMember(7)]
81  public decimal FillPrice
82  {
83  get { return _fillPrice; }
84  set { _fillPrice = value.Normalize(); }
85  }
86 
87  /// <summary>
88  /// Currency for the fill price
89  /// </summary>
90  [ProtoMember(8)]
91  public string FillPriceCurrency { get; set; }
92 
93  /// <summary>
94  /// Number of shares of the order that was filled in this event.
95  /// </summary>
96  [ProtoMember(9)]
97  public decimal FillQuantity
98  {
99  get { return _fillQuantity; }
100  set { _fillQuantity = value.Normalize(); }
101  }
102 
103  /// <summary>
104  /// Public Property Absolute Getter of Quantity -Filled
105  /// </summary>
106  [JsonIgnore]
107  public decimal AbsoluteFillQuantity => Math.Abs(FillQuantity);
108 
109  /// <summary>
110  /// Order direction.
111  /// </summary>
112  [ProtoMember(10)]
113  public OrderDirection Direction { get; set; }
114 
115  /// <summary>
116  /// Any message from the exchange.
117  /// </summary>
118  [DefaultValue(""), JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
119  [ProtoMember(11)]
120  public string Message { get; set; }
121 
122  /// <summary>
123  /// True if the order event is an assignment
124  /// </summary>
125  [ProtoMember(12)]
126  public bool IsAssignment { get; set; }
127 
128  /// <summary>
129  /// The current stop price
130  /// </summary>
131  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
132  [ProtoMember(13)]
133  public decimal? StopPrice
134  {
135  get { return _stopPrice; }
136  set
137  {
138  if (value.HasValue)
139  {
140  _stopPrice = value.Value.Normalize();
141  }
142  }
143  }
144 
145  /// <summary>
146  /// The current trigger price
147  /// </summary>
148  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
149  [ProtoMember(14)]
150  public decimal? TriggerPrice
151  {
152  get { return _triggerPrice; }
153  set
154  {
155  if (value.HasValue)
156  {
157  _triggerPrice = value.Value.Normalize();
158  }
159  }
160  }
161 
162  /// <summary>
163  /// The current limit price
164  /// </summary>
165  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
166  [ProtoMember(15)]
167  public decimal? LimitPrice
168  {
169  get { return _limitPrice; }
170  set
171  {
172  if (value.HasValue)
173  {
174  _limitPrice = value.Value.Normalize();
175  }
176  }
177  }
178 
179  /// <summary>
180  /// The current order quantity
181  /// </summary>
182  [ProtoMember(16)]
183  public decimal Quantity
184  {
185  get { return _quantity; }
186  set { _quantity = value.Normalize(); }
187  }
188 
189  /// <summary>
190  /// True if the order event's option is In-The-Money (ITM)
191  /// </summary>
192  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
193  [ProtoMember(17)]
194  public bool IsInTheMoney { get; set; }
195 
196  /// <summary>
197  /// The trailing stop amount
198  /// </summary>
199  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
200  [ProtoMember(18)]
201  public decimal? TrailingAmount
202  {
203  get { return _trailingAmount; }
204  set
205  {
206  if (value.HasValue)
207  {
208  _trailingAmount = value.Value.Normalize();
209  }
210  }
211  }
212 
213  /// <summary>
214  /// Whether the <see cref="TrailingAmount"/> is a percentage or an absolute currency value
215  /// </summary>
216  [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore)]
217  [ProtoMember(19)]
218  public bool? TrailingAsPercentage
219  {
220  get { return _trailingAsPercentage; }
221  set
222  {
223  if (value.HasValue)
224  {
225  _trailingAsPercentage = value.Value;
226  }
227  }
228  }
229 
230  /// <summary>
231  /// The order ticket associated to the order
232  /// </summary>
233  [JsonIgnore]
234  public OrderTicket Ticket { get; set; }
235 
236  /// <summary>
237  /// Order Event empty constructor required for json converter
238  /// </summary>
239  public OrderEvent()
240  {
241  }
242 
243  /// <summary>
244  /// Order Event Constructor.
245  /// </summary>
246  /// <param name="orderId">Id of the parent order</param>
247  /// <param name="symbol">Asset Symbol</param>
248  /// <param name="utcTime">Date/time of this event</param>
249  /// <param name="status">Status of the order</param>
250  /// <param name="direction">The direction of the order this event belongs to</param>
251  /// <param name="fillPrice">Fill price information if applicable.</param>
252  /// <param name="fillQuantity">Fill quantity</param>
253  /// <param name="orderFee">The order fee</param>
254  /// <param name="message">Message from the exchange</param>
255  public OrderEvent(int orderId,
256  Symbol symbol,
257  DateTime utcTime,
258  OrderStatus status,
259  OrderDirection direction,
260  decimal fillPrice,
261  decimal fillQuantity,
262  OrderFee orderFee,
263  string message = ""
264  )
265  {
266  OrderId = orderId;
267  Symbol = symbol;
268  UtcTime = utcTime;
269  Status = status;
270  Direction = direction;
271  FillPrice = fillPrice;
272  FillPriceCurrency = string.Empty;
273  FillQuantity = fillQuantity;
274  OrderFee = orderFee;
275  Message = message;
276  IsAssignment = false;
277  }
278 
279  /// <summary>
280  /// Helper Constructor using Order to Initialize.
281  /// </summary>
282  /// <param name="order">Order for this order status</param>
283  /// <param name="utcTime">Date/time of this event</param>
284  /// <param name="orderFee">The order fee</param>
285  /// <param name="message">Message from exchange or QC.</param>
286  public OrderEvent(Order order, DateTime utcTime, OrderFee orderFee, string message = "")
287  {
288  OrderId = order.Id;
289  Symbol = order.Symbol;
290  Status = order.Status;
291  Direction = order.Direction;
292 
293  //Initialize to zero, manually set fill quantity
294  FillQuantity = 0;
295  FillPrice = 0;
297 
298  UtcTime = utcTime;
299  OrderFee = orderFee;
300  Message = message;
301  IsAssignment = false;
302  }
303 
304  /// <summary>
305  /// Returns a string that represents the current object.
306  /// </summary>
307  /// <returns>
308  /// A string that represents the current object.
309  /// </returns>
310  /// <filterpriority>2</filterpriority>
311  public override string ToString()
312  {
313  return Messages.OrderEvent.ToString(this);
314  }
315 
316  /// <summary>
317  /// Returns a short string that represents the current object.
318  /// </summary>
319  public string ShortToString()
320  {
321  return Messages.OrderEvent.ShortToString(this);
322  }
323 
324  /// <summary>
325  /// Returns a clone of the current object.
326  /// </summary>
327  /// <returns>The new clone object</returns>
328  public OrderEvent Clone()
329  {
330  return (OrderEvent) MemberwiseClone();
331  }
332 
333  /// <summary>
334  /// Creates a new instance based on the provided serialized order event
335  /// </summary>
336  public static OrderEvent FromSerialized(SerializedOrderEvent serializedOrderEvent)
337  {
338  var sid = SecurityIdentifier.Parse(serializedOrderEvent.Symbol);
339  var symbol = new Symbol(sid, sid.Symbol);
340 
341  var orderFee = OrderFee.Zero;
342  if (serializedOrderEvent.OrderFeeAmount.HasValue)
343  {
344  orderFee = new OrderFee(new CashAmount(serializedOrderEvent.OrderFeeAmount.Value,
345  serializedOrderEvent.OrderFeeCurrency));
346  }
347 
348  var orderEvent = new OrderEvent(serializedOrderEvent.OrderId,
349  symbol,
350  DateTime.SpecifyKind(Time.UnixTimeStampToDateTime(serializedOrderEvent.Time), DateTimeKind.Utc),
351  serializedOrderEvent.Status,
352  serializedOrderEvent.Direction,
353  serializedOrderEvent.FillPrice,
354  serializedOrderEvent.FillQuantity,
355  orderFee,
356  serializedOrderEvent.Message)
357  {
358  IsAssignment = serializedOrderEvent.IsAssignment,
359  IsInTheMoney = serializedOrderEvent.IsInTheMoney,
360  LimitPrice = serializedOrderEvent.LimitPrice,
361  StopPrice = serializedOrderEvent.StopPrice,
362  FillPriceCurrency = serializedOrderEvent.FillPriceCurrency,
363  Id = serializedOrderEvent.OrderEventId,
364  Quantity = serializedOrderEvent.Quantity
365  };
366 
367  return orderEvent;
368  }
369  }
370 }