Lean  $LEAN_TAG$
LimitIfTouchedOrder.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 Newtonsoft.Json;
20 
21 namespace QuantConnect.Orders
22 {
23  /// <summary>
24  /// In effect, a LimitIfTouchedOrder behaves opposite to the <see cref="StopLimitOrder"/>;
25  /// after a trigger price is touched, a limit order is set for some user-defined value above (below)
26  /// the trigger when selling (buying).
27  /// https://www.interactivebrokers.ca/en/index.php?f=45318
28  /// </summary>
29  public class LimitIfTouchedOrder : Order
30  {
31  /// <summary>
32  /// Order Type
33  /// </summary>
34  public override OrderType Type => OrderType.LimitIfTouched;
35 
36  /// <summary>
37  /// The price which, when touched, will trigger the setting of a limit order at <see cref="LimitPrice"/>.
38  /// </summary>
39  [JsonProperty(PropertyName = "triggerPrice")]
40  public decimal TriggerPrice { get; internal set; }
41 
42  /// <summary>
43  /// The price at which to set the limit order following <see cref="TriggerPrice"/> being touched.
44  /// </summary>
45  [JsonProperty(PropertyName = "limitPrice")]
46  public decimal LimitPrice { get; internal set; }
47 
48  /// <summary>
49  /// Whether or not the <see cref="TriggerPrice"/> has been touched.
50  /// </summary>
51  [JsonProperty(PropertyName = "triggerTouched")]
52  public bool TriggerTouched { get; internal set; }
53 
54  /// <summary>
55  /// New <see cref="LimitIfTouchedOrder"/> constructor.
56  /// </summary>
57  /// <param name="symbol">Symbol asset we're seeking to trade</param>
58  /// <param name="quantity">Quantity of the asset we're seeking to trade</param>
59  /// <param name="limitPrice">Maximum price to fill the order</param>
60  /// <param name="time">Time the order was placed</param>
61  /// <param name="triggerPrice">Price which must be touched in order to then set a limit order</param>
62  /// <param name="tag">User defined data tag for this order</param>
63  /// <param name="properties">The order properties for this order</param>
65  Symbol symbol,
66  decimal quantity,
67  decimal? triggerPrice,
68  decimal limitPrice,
69  DateTime time,
70  string tag = "",
71  IOrderProperties properties = null
72  )
73  : base(symbol, quantity, time, tag, properties)
74  {
75  TriggerPrice = (decimal) triggerPrice;
76  LimitPrice = limitPrice;
77  }
78 
79  /// <summary>
80  /// Default constructor for JSON Deserialization:
81  /// </summary>
83  {
84  }
85 
86  /// <summary>
87  /// Gets the default tag for this order
88  /// </summary>
89  /// <returns>The default tag</returns>
90  public override string GetDefaultTag()
91  {
92  return Messages.LimitIfTouchedOrder.Tag(this);
93  }
94 
95  /// <summary>
96  /// Modifies the state of this order to match the update request
97  /// </summary>
98  /// <param name="request">The request to update this order object</param>
99  public override void ApplyUpdateOrderRequest(UpdateOrderRequest request)
100  {
101  base.ApplyUpdateOrderRequest(request);
102  if (request.TriggerPrice.HasValue)
103  {
104  TriggerPrice = request.TriggerPrice.Value;
105  }
106 
107  if (request.LimitPrice.HasValue)
108  {
109  LimitPrice = request.LimitPrice.Value;
110  }
111  }
112 
113  /// <summary>
114  /// Creates a deep-copy clone of this order
115  /// </summary>
116  /// <returns>A copy of this order</returns>
117  public override Order Clone()
118  {
119  var order = new LimitIfTouchedOrder
121  CopyTo(order);
122  return order;
123  }
124 
125  /// <summary>
126  /// Returns a string that represents the current object.
127  /// </summary>
128  /// <returns>
129  /// A string that represents the current object.
130  /// </returns>
131  /// <filterpriority>2</filterpriority>
132  public override string ToString()
133  {
134  return Messages.LimitIfTouchedOrder.ToString(this);
135  }
136 
137  /// <summary>
138  /// Gets the order value in units of the security's quote currency for a single unit.
139  /// A single unit here is a single share of stock, or a single barrel of oil, or the
140  /// cost of a single share in an option contract.
141  /// </summary>
142  /// <param name="security">The security matching this order's symbol</param>
143  protected override decimal GetValueImpl(Security security)
144  {
145  // selling, so higher price will be used
146  if (Quantity < 0)
147  {
148  return Quantity * Math.Max(LimitPrice, security.Price);
149  }
150 
151  // buying, so lower price will be used
152  if (Quantity > 0)
153  {
154  return Quantity * Math.Min(LimitPrice, security.Price);
155  }
156 
157  return 0m;
158  }
159  }
160 }