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  });
54 
55  /// <summary>
56  /// Constructor for TradeStation brokerage model
57  /// </summary>
58  /// <param name="accountType">Cash or Margin</param>
59  public TradeStationBrokerageModel(AccountType accountType = AccountType.Margin)
60  : base(accountType)
61  {
62  }
63 
64  /// <summary>
65  /// Provides TradeStation fee model
66  /// </summary>
67  /// <param name="security">Security</param>
68  /// <returns>TradeStation fee model</returns>
69  public override IFeeModel GetFeeModel(Security security)
70  {
71  return new TradeStationFeeModel();
72  }
73 
74  /// <summary>
75  /// Returns true if the brokerage could accept this order. This takes into account
76  /// order type, security type, and order size limits.
77  /// </summary>
78  /// <remarks>
79  /// For example, a brokerage may have no connectivity at certain times, or an order rate/size limit
80  /// </remarks>
81  /// <param name="security">The security of the order</param>
82  /// <param name="order">The order to be processed</param>
83  /// <param name="message">If this function returns false, a brokerage message detailing why the order may not be submitted</param>
84  /// <returns>True if the brokerage could process the order, false otherwise</returns>
85  public override bool CanSubmitOrder(Security security, Order order, out BrokerageMessageEvent message)
86  {
87  message = default;
88 
89  if (!_supportSecurityTypes.Contains(security.Type))
90  {
91  message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported",
93 
94  return false;
95  }
96 
97  if (!_supportOrderTypes.Contains(order.Type))
98  {
99  message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "NotSupported", Messages.DefaultBrokerageModel.UnsupportedOrderType(this, order, _supportOrderTypes));
100  return false;
101  }
102 
103  if (BrokerageExtensions.OrderCrossesZero(security.Holdings.Quantity, order.Quantity) && IsComboOrderType(order.Type))
104  {
106  return false;
107  }
108 
109  return base.CanSubmitOrder(security, order, out message);
110  }
111 
112  /// <summary>
113  /// TradeStation support Update Order
114  /// </summary>
115  /// <param name="security">Security</param>
116  /// <param name="order">Order that should be updated</param>
117  /// <param name="request">Update request</param>
118  /// <param name="message">Outgoing message</param>
119  /// <returns>True if the brokerage would allow updating the order, false otherwise</returns>
120  public override bool CanUpdateOrder(Security security, Order order, UpdateOrderRequest request, out BrokerageMessageEvent message)
121  {
122  message = null;
123 
125  && request.Quantity != null && request.Quantity != order.Quantity)
126  {
127  message = new BrokerageMessageEvent(BrokerageMessageType.Warning, "UpdateRejected",
129  return false;
130  }
131 
132  if (IsComboOrderType(order.Type) && request.Quantity != null && request.Quantity != order.Quantity)
133  {
135  return false;
136  }
137 
138  return true;
139  }
140 
141  /// <summary>
142  /// Determines if the provided order type is a combo order.
143  /// </summary>
144  /// <param name="orderType">The order type to check.</param>
145  /// <returns>True if the order type is a combo order; otherwise, false.</returns>
146  private static bool IsComboOrderType(OrderType orderType)
147  {
148  return orderType == OrderType.ComboMarket || orderType == OrderType.ComboLimit;
149  }
150  }
151 }