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