Lean  $LEAN_TAG$
TradeStationBrokerageModel.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 
17 using System;
18 using QuantConnect.Orders;
21 using System.Collections.Generic;
22 
24 {
25  /// <summary>
26  /// Represents a brokerage model specific to TradeStation.
27  /// </summary>
29  {
30  /// <summary>
31  /// HashSet containing the security types supported by TradeStation.
32  /// </summary>
33  private readonly HashSet<SecurityType> _supportSecurityTypes = new(
34  new[]
35  {
36  SecurityType.Equity,
37  SecurityType.Option,
38  SecurityType.Future
39  });
40 
41  /// <summary>
42  /// HashSet containing the order types supported by the <see cref="CanSubmitOrder"/> operation in TradeStation.
43  /// </summary>
44  private readonly HashSet<OrderType> _supportOrderTypes = new(
45  new[]
46  {
47  OrderType.Market,
48  OrderType.Limit,
49  OrderType.StopMarket,
50  OrderType.StopLimit,
51  OrderType.ComboMarket,
52  OrderType.ComboLimit,
53  OrderType.MarketOnOpen,
54  OrderType.MarketOnClose
55  });
56 
57  /// <summary>
58  /// Constructor for TradeStation brokerage model
59  /// </summary>
60  /// <param name="accountType">Cash or Margin</param>
61  public TradeStationBrokerageModel(AccountType accountType = AccountType.Margin)
62  : base(accountType)
63  {
64  }
65 
66  /// <summary>
67  /// Provides TradeStation fee model
68  /// </summary>
69  /// <param name="security">Security</param>
70  /// <returns>TradeStation fee model</returns>
71  public override IFeeModel GetFeeModel(Security security)
72  {
73  return new TradeStationFeeModel();
74  }
75 
76  /// <summary>
77  /// Returns true if the brokerage could accept this order. This takes into account
78  /// order type, security type, and order size limits.
79  /// </summary>
80  /// <remarks>
81  /// For example, a brokerage may have no connectivity at certain times, or an order rate/size limit
82  /// </remarks>
83  /// <param name="security">The security of the order</param>
84  /// <param name="order">The order to be processed</param>
85  /// <param name="message">If this function returns false, a brokerage message detailing why the order may not be submitted</param>
86  /// <returns>True if the brokerage could process the order, false otherwise</returns>
87  public override bool CanSubmitOrder(Security security, Order order, out BrokerageMessageEvent message)
88  {
89  message = default;
90 
91  if (!_supportSecurityTypes.Contains(security.Type))
92  {
93  message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
95 
96  return false;
97  }
98 
99  if (!_supportOrderTypes.Contains(order.Type))
100  {
101  message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported", Messages.DefaultBrokerageModel.UnsupportedOrderType(this, order, _supportOrderTypes));
102  return false;
103  }
104 
105  if (BrokerageExtensions.OrderCrossesZero(security.Holdings.Quantity, order.Quantity) && IsComboOrderType(order.Type))
106  {
108  return false;
109  }
110 
111  return base.CanSubmitOrder(security, order, out message);
112  }
113 
114  /// <summary>
115  /// TradeStation support Update Order
116  /// </summary>
117  /// <param name="security">Security</param>
118  /// <param name="order">Order that should be updated</param>
119  /// <param name="request">Update request</param>
120  /// <param name="message">Outgoing message</param>
121  /// <returns>True if the brokerage would allow updating the order, false otherwise</returns>
122  public override bool CanUpdateOrder(Security security, Order order, UpdateOrderRequest request, out BrokerageMessageEvent message)
123  {
124  message = null;
125 
127  && request.Quantity != null && request.Quantity != order.Quantity)
128  {
129  message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "UpdateRejected",
131  return false;
132  }
133 
134  if (IsComboOrderType(order.Type) && request.Quantity != null && request.Quantity != order.Quantity)
135  {
137  return false;
138  }
139 
140  return true;
141  }
142 
143  /// <summary>
144  /// Determines if the provided order type is a combo order.
145  /// </summary>
146  /// <param name="orderType">The order type to check.</param>
147  /// <returns>True if the order type is a combo order; otherwise, false.</returns>
148  private static bool IsComboOrderType(OrderType orderType)
149  {
150  return orderType == OrderType.ComboMarket || orderType == OrderType.ComboLimit;
151  }
152  }
153 }