Lean  $LEAN_TAG$
Messages.Brokerages.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.Runtime.CompilerServices;
18 
21 using QuantConnect.Orders;
22 
23 using static QuantConnect.StringExtensions;
24 using System.Collections.Generic;
26 
27 namespace QuantConnect
28 {
29  /// <summary>
30  /// Provides user-facing message construction methods and static messages for the <see cref="Brokerages"/> namespace
31  /// </summary>
32  public static partial class Messages
33  {
34  /// <summary>
35  /// Provides user-facing messages for the <see cref="Brokerages.DefaultBrokerageModel"/> class and its consumers or related classes
36  /// </summary>
37  public static class DefaultBrokerageModel
38  {
39  /// <summary>
40  /// String message saying: MarketOnOpen orders are not supported for futures and future options
41  /// </summary>
43  "MarketOnOpen orders are not supported for futures and future options.";
44 
45  /// <summary>
46  /// String message saying: There is no data for this symbol yet
47  /// </summary>
48  public static string NoDataForSymbol =
49  "There is no data for this symbol yet, please check the security.HasData flag to ensure there is at least one data point.";
50 
51  /// <summary>
52  /// String message saying: Brokerage does not support update. You must cancel and re-create instead
53  /// </summary>
54  public static string OrderUpdateNotSupported = "Brokerage does not support update. You must cancel and re-create instead.";
55 
56  /// <summary>
57  /// Retunrns a string message saying the type of the given security is not supported by the given brokerage
58  /// </summary>
59  [MethodImpl(MethodImplOptions.AggressiveInlining)]
60  public static string UnsupportedSecurityType(IBrokerageModel brokerageModel, Securities.Security security)
61  {
62  return Invariant($"The {brokerageModel.GetType().Name} does not support {security.Type} security type.");
63  }
64 
65  /// <summary>
66  /// Returns a string message saying the given brokerage does not support updating the quantity of Cross Zero orders
67  /// </summary>
68  [MethodImpl(MethodImplOptions.AggressiveInlining)]
69  public static string UnsupportedCrossZeroOrderUpdate(IBrokerageModel brokerageModel)
70  {
71  return Invariant($"Unfortunately, the {brokerageModel.GetType().Name} brokerage model does not support updating the quantity of Cross Zero Orders.");
72  }
73 
74  /// <summary>
75  /// Returns a string message saying the type of the given security is invalid for the given brokerage GetFillModel() method
76  /// </summary>
77  [MethodImpl(MethodImplOptions.AggressiveInlining)]
78  public static string InvalidSecurityTypeToGetFillModel(IBrokerageModel brokerageModel, Securities.Security security)
79  {
80  return Invariant($"{brokerageModel.GetType().Name}.GetFillModel: Invalid security type {security.Type}");
81  }
82 
83  /// <summary>
84  /// Returns a string message saying the quantity given was invalid for the given security
85  /// </summary>
86  [MethodImpl(MethodImplOptions.AggressiveInlining)]
87  public static string InvalidOrderQuantity(Securities.Security security, decimal quantity)
88  {
89  return Invariant($@"The minimum order size (in quote currency) for {security.Symbol.Value} is {
90  security.SymbolProperties.MinimumOrderSize}. Order quantity was {quantity}.");
91  }
92 
93  /// <summary>
94  /// Returns a string message saying the given order size (quantity * price) was invalid for the given security
95  /// </summary>
96  [MethodImpl(MethodImplOptions.AggressiveInlining)]
97  public static string InvalidOrderSize(Securities.Security security, decimal quantity, decimal price)
98  {
99  return Invariant($@"The minimum order size (in quote currency) for {security.Symbol.Value} is {security.SymbolProperties.MinimumOrderSize}. Order size was {quantity * price}.");
100  }
101 
102  /// <summary>
103  /// Returns a string message saying the type of the given order is unsupported by the given brokerage model. It also
104  /// mentions the supported order types
105  /// </summary>
106  [MethodImpl(MethodImplOptions.AggressiveInlining)]
107  public static string UnsupportedOrderType(IBrokerageModel brokerageModel, Orders.Order order, IEnumerable<OrderType> supportedOrderTypes)
108  {
109  return Invariant($"The {brokerageModel.GetType().Name} does not support {order.Type} order type. Only supports [{string.Join(',', supportedOrderTypes)}]");
110  }
111 
112  /// <summary>
113  /// Returns a string message saying the Time In Force of the given order is unsupported by the given brokerage
114  /// model
115  /// </summary>
116  [MethodImpl(MethodImplOptions.AggressiveInlining)]
117  public static string UnsupportedTimeInForce(IBrokerageModel brokerageModel, Orders.Order order)
118  {
119  return Invariant($@"The {brokerageModel.GetType().Name} does not support {
120  order.TimeInForce.GetType().Name} time in force.");
121  }
122 
123  /// <summary>
124  /// Returns a string message saying the type of the given security is invalid
125  /// </summary>
126  [MethodImpl(MethodImplOptions.AggressiveInlining)]
127  public static string InvalidSecurityTypeForLeverage(Securities.Security security)
128  {
129  return Invariant($"Invalid security type: {security.Type}");
130  }
131 
132  /// <summary>
133  /// Returns a message indicating that the specified order type is not supported for orders that cross the zero holdings threshold.
134  /// </summary>
135  [MethodImpl(MethodImplOptions.AggressiveInlining)]
136  public static string UnsupportedCrossZeroByOrderType(IBrokerageModel brokerageModel, OrderType orderType)
137  {
138  return Invariant($"Order type '{orderType}' is not supported for orders that cross the zero holdings threshold in the {brokerageModel.GetType().Name}. This means you cannot change a position from positive to negative or vice versa using this order type. Please close the existing position first.");
139  }
140 
141  /// <summary>
142  /// Returns a message indicating that the specified order type cannot be updated quantity using the given brokerage model.
143  /// </summary>
144  [MethodImpl(MethodImplOptions.AggressiveInlining)]
145  public static string UnsupportedUpdateQuantityOrder(IBrokerageModel brokerageModel, OrderType orderType)
146  {
147  return Invariant($"Order type '{orderType}' is not supported to update quantity in the {brokerageModel.GetType().Name}.");
148  }
149  }
150 
151  /// <summary>
152  /// Provides user-facing messages for the <see cref="Brokerages.AlphaStreamsBrokerageModel"/> class and its consumers or related classes
153  /// </summary>
154  public static class AlphaStreamsBrokerageModel
155  {
156  /// <summary>
157  /// String message saying: The Alpha Streams brokerage does not currently support Cash trading
158  /// </summary>
159  public static string UnsupportedAccountType = "The Alpha Streams brokerage does not currently support Cash trading.";
160  }
161 
162  /// <summary>
163  /// Provides user-facing messages for the <see cref="Brokerages.AxosClearingBrokerageModel"/> class and its consumers or related classes
164  /// </summary>
165  public static class AxosBrokerageModel
166  {
167  /// <summary>
168  /// Returns a string message saying the order quantity must be Integer. It also contains
169  /// the quantity of the given order
170  /// </summary>
171  [MethodImpl(MethodImplOptions.AggressiveInlining)]
172  public static string NonIntegerOrderQuantity(Orders.Order order)
173  {
174  return Invariant($"Order Quantity must be Integer, but provided {order.Quantity}.");
175  }
176  }
177 
178  /// <summary>
179  /// Provides user-facing messages for the <see cref="Brokerages.BinanceBrokerageModel"/> class and its consumers or related classes
180  /// </summary>
181  public static class BinanceBrokerageModel
182  {
183  /// <summary>
184  /// Returns a string message saying the type of the given order is unsupported for the symbol of the given
185  /// security
186  /// </summary>
187  [MethodImpl(MethodImplOptions.AggressiveInlining)]
188  public static string UnsupportedOrderTypeForSecurityType(Orders.Order order, Securities.Security security)
189  {
190  return Invariant($"{order.Type} orders are not supported for this symbol ${security.Symbol}");
191  }
192 
193  /// <summary>
194  /// Returns a string message saying the type of the given order is unsupported for the symbol of the given
195  /// security. The message also contains a link to the supported order types in Binance
196  /// </summary>
197  [MethodImpl(MethodImplOptions.AggressiveInlining)]
198  public static string UnsupportedOrderTypeWithLinkToSupportedTypes(Orders.Order order, Securities.Security security)
199  {
200  return Invariant($@"{order.Type} orders are not supported for this symbol. Please check 'https://api.binance.com/api/v3/exchangeInfo?symbol={
201  security.SymbolProperties.MarketTicker}' to see supported order types.");
202  }
203  }
204 
205  /// <summary>
206  /// Provides user-facing messages for the <see cref="Brokerages.BinanceUSBrokerageModel"/> class and its consumers or related classes
207  /// </summary>
208  public static class BinanceUSBrokerageModel
209  {
210  /// <summary>
211  /// String message saying: The Binance.US brokerage does not currently support Margin trading
212  /// </summary>
213  public static string UnsupportedAccountType = "The Binance.US brokerage does not currently support Margin trading.";
214  }
215 
216  /// <summary>
217  /// Provides user-facing messages for the <see cref="Brokerages.BrokerageMessageEvent"/> class and its consumers or related classes
218  /// </summary>
219  public static class BrokerageMessageEvent
220  {
221  /// <summary>
222  /// String message saying: Disconnect
223  /// </summary>
224  public static string DisconnectCode = "Disconnect";
225 
226  /// <summary>
227  /// String message saying: Reconnect
228  /// </summary>
229  public static string ReconnectCode = "Reconnect";
230 
231  /// <summary>
232  /// Parses a given BrokerageMessageEvent object into a string containing basic information about it
233  /// </summary>
234  [MethodImpl(MethodImplOptions.AggressiveInlining)]
235  public static string ToString(Brokerages.BrokerageMessageEvent messageEvent)
236  {
237  return Invariant($"{messageEvent.Type} - Code: {messageEvent.Code} - {messageEvent.Message}");
238  }
239  }
240 
241  /// <summary>
242  /// Provides user-facing messages for the <see cref="Brokerages.DefaultBrokerageMessageHandler"/> class and its consumers or related classes
243  /// </summary>
244  public static class DefaultBrokerageMessageHandler
245  {
246  /// <summary>
247  /// String message saying: Brokerage Error
248  /// </summary>
249  public static string BrokerageErrorContext = "Brokerage Error";
250 
251  /// <summary>
252  /// String message saying: DefaultBrokerageMessageHandler.Handle(): Disconnected
253  /// </summary>
254  public static string Disconnected = "DefaultBrokerageMessageHandler.Handle(): Disconnected.";
255 
256  /// <summary>
257  /// String message saying: DefaultBrookerageMessageHandler.Handle(): Reconnected
258  /// </summary>
259  public static string Reconnected = "DefaultBrokerageMessageHandler.Handle(): Reconnected.";
260 
261  /// <summary>
262  /// String message saying: DefaultBrokerageMessageHandler.Handle(): Disconnect when exchanges are closed,
263  /// checking back before exchange open
264  /// </summary>
265  public static string DisconnectedWhenExchangesAreClosed =
266  "DefaultBrokerageMessageHandler.Handle(): Disconnect when exchanges are closed, checking back before exchange open.";
267 
268  /// <summary>
269  /// String message saying: DefaultBrokerageMessageHandler.Handle(): Still disconnected, goodbye
270  /// </summary>
271  public static string StillDisconnected = "DefaultBrokerageMessageHandler.Handle(): Still disconnected, goodbye.";
272 
273  /// <summary>
274  /// String message saying: Brokerage Disconnect
275  /// </summary>
276  public static string BrokerageDisconnectedShutDownContext = "Brokerage Disconnect";
277 
278  /// <summary>
279  /// Returns a string message with basic information about the given message event
280  /// </summary>
281  [MethodImpl(MethodImplOptions.AggressiveInlining)]
282  public static string BrokerageInfo(Brokerages.BrokerageMessageEvent messageEvent)
283  {
284  return $"Brokerage Info: {messageEvent.Message}";
285  }
286 
287  /// <summary>
288  /// Returns a string message warning from the given message event
289  /// </summary>
290  [MethodImpl(MethodImplOptions.AggressiveInlining)]
291  public static string BrokerageWarning(Brokerages.BrokerageMessageEvent messageEvent)
292  {
293  return $"Brokerage Warning: {messageEvent.Message}";
294  }
295 
296  /// <summary>
297  /// Returns a string message saying the brokerage is disconnected when exchanges are open and that it's
298  /// trying to reconnect for the given reconnection timeout minutes
299  /// </summary>
300  [MethodImpl(MethodImplOptions.AggressiveInlining)]
301  public static string DisconnectedWhenExchangesAreOpen(TimeSpan reconnectionTimeout)
302  {
303  return Invariant($@"DefaultBrokerageMessageHandler.Handle(): Disconnect when exchanges are open, trying to reconnect for {
304  reconnectionTimeout.TotalMinutes} minutes.");
305  }
306 
307  /// <summary>
308  /// Returns a string message with the time until the next market open
309  /// </summary>
310  [MethodImpl(MethodImplOptions.AggressiveInlining)]
311  public static string TimeUntilNextMarketOpen(TimeSpan timeUntilNextMarketOpen)
312  {
313  return Invariant($"DefaultBrokerageMessageHandler.Handle(): TimeUntilNextMarketOpen: {timeUntilNextMarketOpen}");
314  }
315  }
316 
317  /// <summary>
318  /// Provides user-facing messages for the <see cref="Brokerages.ExanteBrokerageModel"/> class and its consumers or related classes
319  /// </summary>
320  public static class ExanteBrokerageModel
321  {
322  /// <summary>
323  /// String message saying: Order is null
324  /// </summary>
325  public static string NullOrder = "Order is null.";
326 
327  /// <summary>
328  /// String message saying: Price is not set
329  /// </summary>
330  public static string PriceNotSet = "Price is not set.";
331  }
332 
333  /// <summary>
334  /// Provides user-facing messages for the <see cref="Brokerages.FTXBrokerageModel"/> class and its consumers or related classes
335  /// </summary>
336  public static class FTXBrokerageModel
337  {
338  /// <summary>
339  /// String message saying: Trigger price too high, must be below current market price
340  /// </summary>
341  public static string TriggerPriceTooHigh = "Trigger price too high: must be below current market price.";
342 
343  /// <summary>
344  /// String message saying: Trigger price too low, must be above current market price
345  /// </summary>
346  public static string TriggerPriceTooLow = "Trigger price too low: must be above current market price.";
347  }
348 
349  /// <summary>
350  /// Provides user-facing messages for the <see cref="Brokerages.FxcmBrokerageModel"/> class and its consumers or related classes
351  /// </summary>
352  public static class FxcmBrokerageModel
353  {
354  /// <summary>
355  /// String message saying: Limit Buy orders and Stop Sell orders must be below market, Limit Sell orders and Stop Buy orders
356  /// must be above market
357  /// </summary>
358  public static string InvalidOrderPrice =
359  "Limit Buy orders and Stop Sell orders must be below market, Limit Sell orders and Stop Buy orders must be above market.";
360 
361  /// <summary>
362  /// Returns a string message saying the order quantity must be a multiple of LotSize. It also contains the security's Lot
363  /// Size
364  /// </summary>
365  [MethodImpl(MethodImplOptions.AggressiveInlining)]
366  public static string InvalidOrderQuantityForLotSize(Securities.Security security)
367  {
368  return Invariant($"The order quantity must be a multiple of LotSize: [{security.SymbolProperties.LotSize}].");
369  }
370 
371  /// <summary>
372  /// Returns a string message saying the order price is too far from the current market price
373  /// </summary>
374  [MethodImpl(MethodImplOptions.AggressiveInlining)]
375  public static string PriceOutOfRange(OrderType orderType, OrderDirection orderDirection, decimal orderPrice, decimal currentPrice)
376  {
377  return Invariant($@"The {orderType} {orderDirection} order price ({
378  orderPrice}) is too far from the current market price ({currentPrice}).");
379  }
380  }
381 
382  /// <summary>
383  /// Provides user-facing messages for the <see cref="Brokerages.CoinbaseBrokerageModel"/> class and its consumers or related classes
384  /// </summary>
385  public static class CoinbaseBrokerageModel
386  {
387  /// <summary>
388  /// String message saying: The Coinbase brokerage does not currently support Margin trading
389  /// </summary>
390  public static string UnsupportedAccountType = "The Coinbase brokerage does not currently support Margin trading.";
391 
392  /// <summary>
393  /// Returns a string message saying the Stop Market orders are no longer supported since the given end date
394  /// </summary>
395  [MethodImpl(MethodImplOptions.AggressiveInlining)]
396  public static string StopMarketOrdersNoLongerSupported(DateTime stopMarketOrderSupportEndDate)
397  {
398  return Invariant($"Stop Market orders are no longer supported since {stopMarketOrderSupportEndDate}.");
399  }
400  }
401 
402  /// <summary>
403  /// Provides user-facing messages for the <see cref="Brokerages.InteractiveBrokersBrokerageModel"/> class and its consumers or related classes
404  /// </summary>
406  {
407  /// <summary>
408  /// Returns a string message saying the given brokerage model does not support order exercises
409  /// for index and cash-settled options
410  /// </summary>
411  [MethodImpl(MethodImplOptions.AggressiveInlining)]
412  public static string UnsupportedExerciseForIndexAndCashSettledOptions(Brokerages.InteractiveBrokersBrokerageModel brokerageModel,
413  Orders.Order order)
414  {
415  return Invariant($@"The {brokerageModel.GetType().Name} does not support {
416  order.Type} exercises for index and cash-settled options.");
417  }
418 
419  /// <summary>
420  /// Returns a string message containing the minimum and maximum limits for the allowable order size as well as the currency
421  /// </summary>
422  [MethodImpl(MethodImplOptions.AggressiveInlining)]
423  public static string InvalidForexOrderSize(decimal min, decimal max, string currency)
424  {
425  return Invariant($"The minimum and maximum limits for the allowable order size are ({min}, {max}){currency}.");
426  }
427  }
428 
429  /// <summary>
430  /// Provides user-facing messages for the <see cref="Brokerages.TradierBrokerageModel"/> class and its consumers or related classes
431  /// </summary>
432  public static class TradierBrokerageModel
433  {
434  /// <summary>
435  /// Unsupported Security Type string message
436  /// </summary>
437  public static string UnsupportedSecurityType = "This model only supports equities and options.";
438 
439  /// <summary>
440  /// Unsupported Time In Force Type string message
441  /// </summary>
442  public static string UnsupportedTimeInForceType = $"This model only supports orders with the following time in force types: {typeof(DayTimeInForce)} and {typeof(GoodTilCanceledTimeInForce)}";
443 
444  /// <summary>
445  /// Extended Market Hours Trading Not Supported string message
446  /// </summary>
448  "Tradier does not support extended market hours trading. Your order will be processed at market open.";
449 
450  /// <summary>
451  /// Order Quantity Update Not Supported string message
452  /// </summary>
453  public static string OrderQuantityUpdateNotSupported = "Tradier does not support updating order quantities.";
454 
455  /// <summary>
456  /// Open Orders Cancel On Reverse Split Symbols string message
457  /// </summary>
458  public static string OpenOrdersCancelOnReverseSplitSymbols = "Tradier Brokerage cancels open orders on reverse split symbols";
459 
460  /// <summary>
461  /// Short Order Is GTC string message
462  /// </summary>
463  public static string ShortOrderIsGtc = "You cannot place short stock orders with GTC, only day orders are allowed";
464 
465  /// <summary>
466  /// Sell Short Order Last Price Below 5 string message
467  /// </summary>
468  public static string SellShortOrderLastPriceBelow5 = "Sell Short order cannot be placed for stock priced below $5";
469 
470  /// <summary>
471  /// Incorrect Order Quantity string message
472  /// </summary>
473  public static string IncorrectOrderQuantity = "Quantity should be between 1 and 10,000,000";
474  }
475 
476  /// <summary>
477  /// Provides user-facing messages for the <see cref="Brokerages.TradingTechnologiesBrokerageModel"/> class and its consumers or related classes
478  /// </summary>
480  {
481  /// <summary>
482  /// Invalid Stop Market Order Price string message
483  /// </summary>
484  public static string InvalidStopMarketOrderPrice =
485  "StopMarket Sell orders must be below market, StopMarket Buy orders must be above market.";
486 
487  /// <summary>
488  /// Invalid Stop Limit Order Price string message
489  /// </summary>
490  public static string InvalidStopLimitOrderPrice =
491  "StopLimit Sell orders must be below market, StopLimit Buy orders must be above market.";
492 
493  /// <summary>
494  /// Invalid Stop Limit Order Limit Price string message
495  /// </summary>
496  public static string InvalidStopLimitOrderLimitPrice =
497  "StopLimit Buy limit price must be greater than or equal to stop price, StopLimit Sell limit price must be smaller than or equal to stop price.";
498  }
499 
500  /// <summary>
501  /// Provides user-facing messages for the <see cref="Brokerages.WolverineBrokerageModel"/> class and its consumers or related classes
502  /// </summary>
503  public static class WolverineBrokerageModel
504  {
505  /// <summary>
506  /// Returns a message for an unsupported order type in Wolverine Brokerage Model
507  /// </summary>
508  [MethodImpl(MethodImplOptions.AggressiveInlining)]
509  public static string UnsupportedOrderType(Orders.Order order)
510  {
511  return Invariant($"{order.Type} order is not supported by Wolverine. Currently, only Market Order is supported.");
512  }
513  }
514 
515  /// <summary>
516  /// Provides user-facing messages for the <see cref="Brokerages.RBIBrokerageModel"/> class and its consumers or related classes
517  /// </summary>
518  public static class RBIBrokerageModel
519  {
520  /// <summary>
521  /// Returns a message for an unsupported order type in RBI Brokerage Model
522  /// </summary>
523  /// <param name="order"></param>
524  /// <returns></returns>
525  [MethodImpl(MethodImplOptions.AggressiveInlining)]
526  public static string UnsupportedOrderType(Orders.Order order)
527  {
528  return Invariant($"{order.Type} order is not supported by RBI. Currently, only Market Order, Limit Order, StopMarket Order and StopLimit Order are supported.");
529  }
530  }
531  }
532 }