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(string baseApiEndpoint, Orders.Order order, Securities.Security security)
199  {
200  return Invariant($@"{order.Type} orders are not supported for this symbol. Please check '{baseApiEndpoint}/exchangeInfo?symbol={security.SymbolProperties.MarketTicker}' to see supported order types.");
201  }
202  }
203 
204  /// <summary>
205  /// Provides user-facing messages for the <see cref="Brokerages.BinanceUSBrokerageModel"/> class and its consumers or related classes
206  /// </summary>
207  public static class BinanceUSBrokerageModel
208  {
209  /// <summary>
210  /// String message saying: The Binance.US brokerage does not currently support Margin trading
211  /// </summary>
212  public static string UnsupportedAccountType = "The Binance.US brokerage does not currently support Margin trading.";
213  }
214 
215  /// <summary>
216  /// Provides user-facing messages for the <see cref="Brokerages.BrokerageMessageEvent"/> class and its consumers or related classes
217  /// </summary>
218  public static class BrokerageMessageEvent
219  {
220  /// <summary>
221  /// String message saying: Disconnect
222  /// </summary>
223  public static string DisconnectCode = "Disconnect";
224 
225  /// <summary>
226  /// String message saying: Reconnect
227  /// </summary>
228  public static string ReconnectCode = "Reconnect";
229 
230  /// <summary>
231  /// Parses a given BrokerageMessageEvent object into a string containing basic information about it
232  /// </summary>
233  [MethodImpl(MethodImplOptions.AggressiveInlining)]
234  public static string ToString(Brokerages.BrokerageMessageEvent messageEvent)
235  {
236  return Invariant($"{messageEvent.Type} - Code: {messageEvent.Code} - {messageEvent.Message}");
237  }
238  }
239 
240  /// <summary>
241  /// Provides user-facing messages for the <see cref="Brokerages.DefaultBrokerageMessageHandler"/> class and its consumers or related classes
242  /// </summary>
243  public static class DefaultBrokerageMessageHandler
244  {
245  /// <summary>
246  /// String message saying: Brokerage Error
247  /// </summary>
248  public static string BrokerageErrorContext = "Brokerage Error";
249 
250  /// <summary>
251  /// String message saying: DefaultBrokerageMessageHandler.Handle(): Disconnected
252  /// </summary>
253  public static string Disconnected = "DefaultBrokerageMessageHandler.Handle(): Disconnected.";
254 
255  /// <summary>
256  /// String message saying: DefaultBrookerageMessageHandler.Handle(): Reconnected
257  /// </summary>
258  public static string Reconnected = "DefaultBrokerageMessageHandler.Handle(): Reconnected.";
259 
260  /// <summary>
261  /// String message saying: DefaultBrokerageMessageHandler.Handle(): Disconnect when exchanges are closed,
262  /// checking back before exchange open
263  /// </summary>
264  public static string DisconnectedWhenExchangesAreClosed =
265  "DefaultBrokerageMessageHandler.Handle(): Disconnect when exchanges are closed, checking back before exchange open.";
266 
267  /// <summary>
268  /// String message saying: DefaultBrokerageMessageHandler.Handle(): Still disconnected, goodbye
269  /// </summary>
270  public static string StillDisconnected = "DefaultBrokerageMessageHandler.Handle(): Still disconnected, goodbye.";
271 
272  /// <summary>
273  /// String message saying: Brokerage Disconnect
274  /// </summary>
275  public static string BrokerageDisconnectedShutDownContext = "Brokerage Disconnect";
276 
277  /// <summary>
278  /// Returns a string message with basic information about the given message event
279  /// </summary>
280  [MethodImpl(MethodImplOptions.AggressiveInlining)]
281  public static string BrokerageInfo(Brokerages.BrokerageMessageEvent messageEvent)
282  {
283  return $"Brokerage Info: {messageEvent.Message}";
284  }
285 
286  /// <summary>
287  /// Returns a string message warning from the given message event
288  /// </summary>
289  [MethodImpl(MethodImplOptions.AggressiveInlining)]
290  public static string BrokerageWarning(Brokerages.BrokerageMessageEvent messageEvent)
291  {
292  return $"Brokerage Warning: {messageEvent.Message}";
293  }
294 
295  /// <summary>
296  /// Returns a string message saying the brokerage is disconnected when exchanges are open and that it's
297  /// trying to reconnect for the given reconnection timeout minutes
298  /// </summary>
299  [MethodImpl(MethodImplOptions.AggressiveInlining)]
300  public static string DisconnectedWhenExchangesAreOpen(TimeSpan reconnectionTimeout)
301  {
302  return Invariant($@"DefaultBrokerageMessageHandler.Handle(): Disconnect when exchanges are open, trying to reconnect for {
303  reconnectionTimeout.TotalMinutes} minutes.");
304  }
305 
306  /// <summary>
307  /// Returns a string message with the time until the next market open
308  /// </summary>
309  [MethodImpl(MethodImplOptions.AggressiveInlining)]
310  public static string TimeUntilNextMarketOpen(TimeSpan timeUntilNextMarketOpen)
311  {
312  return Invariant($"DefaultBrokerageMessageHandler.Handle(): TimeUntilNextMarketOpen: {timeUntilNextMarketOpen}");
313  }
314  }
315 
316  /// <summary>
317  /// Provides user-facing messages for the <see cref="Brokerages.ExanteBrokerageModel"/> class and its consumers or related classes
318  /// </summary>
319  public static class ExanteBrokerageModel
320  {
321  /// <summary>
322  /// String message saying: Order is null
323  /// </summary>
324  public static string NullOrder = "Order is null.";
325 
326  /// <summary>
327  /// String message saying: Price is not set
328  /// </summary>
329  public static string PriceNotSet = "Price is not set.";
330  }
331 
332  /// <summary>
333  /// Provides user-facing messages for the <see cref="Brokerages.FTXBrokerageModel"/> class and its consumers or related classes
334  /// </summary>
335  public static class FTXBrokerageModel
336  {
337  /// <summary>
338  /// String message saying: Trigger price too high, must be below current market price
339  /// </summary>
340  public static string TriggerPriceTooHigh = "Trigger price too high: must be below current market price.";
341 
342  /// <summary>
343  /// String message saying: Trigger price too low, must be above current market price
344  /// </summary>
345  public static string TriggerPriceTooLow = "Trigger price too low: must be above current market price.";
346  }
347 
348  /// <summary>
349  /// Provides user-facing messages for the <see cref="Brokerages.FxcmBrokerageModel"/> class and its consumers or related classes
350  /// </summary>
351  public static class FxcmBrokerageModel
352  {
353  /// <summary>
354  /// String message saying: Limit Buy orders and Stop Sell orders must be below market, Limit Sell orders and Stop Buy orders
355  /// must be above market
356  /// </summary>
357  public static string InvalidOrderPrice =
358  "Limit Buy orders and Stop Sell orders must be below market, Limit Sell orders and Stop Buy orders must be above market.";
359 
360  /// <summary>
361  /// Returns a string message saying the order quantity must be a multiple of LotSize. It also contains the security's Lot
362  /// Size
363  /// </summary>
364  [MethodImpl(MethodImplOptions.AggressiveInlining)]
365  public static string InvalidOrderQuantityForLotSize(Securities.Security security)
366  {
367  return Invariant($"The order quantity must be a multiple of LotSize: [{security.SymbolProperties.LotSize}].");
368  }
369 
370  /// <summary>
371  /// Returns a string message saying the order price is too far from the current market price
372  /// </summary>
373  [MethodImpl(MethodImplOptions.AggressiveInlining)]
374  public static string PriceOutOfRange(OrderType orderType, OrderDirection orderDirection, decimal orderPrice, decimal currentPrice)
375  {
376  return Invariant($@"The {orderType} {orderDirection} order price ({
377  orderPrice}) is too far from the current market price ({currentPrice}).");
378  }
379  }
380 
381  /// <summary>
382  /// Provides user-facing messages for the <see cref="Brokerages.CoinbaseBrokerageModel"/> class and its consumers or related classes
383  /// </summary>
384  public static class CoinbaseBrokerageModel
385  {
386  /// <summary>
387  /// String message saying: The Coinbase brokerage does not currently support Margin trading
388  /// </summary>
389  public static string UnsupportedAccountType = "The Coinbase brokerage does not currently support Margin trading.";
390 
391  /// <summary>
392  /// Returns a string message saying the Stop Market orders are no longer supported since the given end date
393  /// </summary>
394  [MethodImpl(MethodImplOptions.AggressiveInlining)]
395  public static string StopMarketOrdersNoLongerSupported(DateTime stopMarketOrderSupportEndDate)
396  {
397  return Invariant($"Stop Market orders are no longer supported since {stopMarketOrderSupportEndDate}.");
398  }
399  }
400 
401  /// <summary>
402  /// Provides user-facing messages for the <see cref="Brokerages.InteractiveBrokersBrokerageModel"/> class and its consumers or related classes
403  /// </summary>
405  {
406  /// <summary>
407  /// Returns a string message saying the given brokerage model does not support order exercises
408  /// for index and cash-settled options
409  /// </summary>
410  [MethodImpl(MethodImplOptions.AggressiveInlining)]
411  public static string UnsupportedExerciseForIndexAndCashSettledOptions(Brokerages.InteractiveBrokersBrokerageModel brokerageModel,
412  Orders.Order order)
413  {
414  return Invariant($@"The {brokerageModel.GetType().Name} does not support {
415  order.Type} exercises for index and cash-settled options.");
416  }
417 
418  /// <summary>
419  /// Returns a string message containing the minimum and maximum limits for the allowable order size as well as the currency
420  /// </summary>
421  [MethodImpl(MethodImplOptions.AggressiveInlining)]
422  public static string InvalidForexOrderSize(decimal min, decimal max, string currency)
423  {
424  return Invariant($"The minimum and maximum limits for the allowable order size are ({min}, {max}){currency}.");
425  }
426  }
427 
428  /// <summary>
429  /// Provides user-facing messages for the <see cref="Brokerages.TradierBrokerageModel"/> class and its consumers or related classes
430  /// </summary>
431  public static class TradierBrokerageModel
432  {
433  /// <summary>
434  /// Unsupported Security Type string message
435  /// </summary>
436  public static string UnsupportedSecurityType = "This model only supports equities and options.";
437 
438  /// <summary>
439  /// Unsupported Time In Force Type string message
440  /// </summary>
441  public static string UnsupportedTimeInForceType = $"This model only supports orders with the following time in force types: {typeof(DayTimeInForce)} and {typeof(GoodTilCanceledTimeInForce)}";
442 
443  /// <summary>
444  /// Extended Market Hours Trading Not Supported string message
445  /// </summary>
447  "Tradier does not support extended market hours trading. Your order will be processed at market open.";
448 
449  /// <summary>
450  /// Order Quantity Update Not Supported string message
451  /// </summary>
452  public static string OrderQuantityUpdateNotSupported = "Tradier does not support updating order quantities.";
453 
454  /// <summary>
455  /// Open Orders Cancel On Reverse Split Symbols string message
456  /// </summary>
457  public static string OpenOrdersCancelOnReverseSplitSymbols = "Tradier Brokerage cancels open orders on reverse split symbols";
458 
459  /// <summary>
460  /// Short Order Is GTC string message
461  /// </summary>
462  public static string ShortOrderIsGtc = "You cannot place short stock orders with GTC, only day orders are allowed";
463 
464  /// <summary>
465  /// Sell Short Order Last Price Below 5 string message
466  /// </summary>
467  public static string SellShortOrderLastPriceBelow5 = "Sell Short order cannot be placed for stock priced below $5";
468 
469  /// <summary>
470  /// Incorrect Order Quantity string message
471  /// </summary>
472  public static string IncorrectOrderQuantity = "Quantity should be between 1 and 10,000,000";
473  }
474 
475  /// <summary>
476  /// Provides user-facing messages for the <see cref="Brokerages.TradingTechnologiesBrokerageModel"/> class and its consumers or related classes
477  /// </summary>
479  {
480  /// <summary>
481  /// Invalid Stop Market Order Price string message
482  /// </summary>
483  public static string InvalidStopMarketOrderPrice =
484  "StopMarket Sell orders must be below market, StopMarket Buy orders must be above market.";
485 
486  /// <summary>
487  /// Invalid Stop Limit Order Price string message
488  /// </summary>
489  public static string InvalidStopLimitOrderPrice =
490  "StopLimit Sell orders must be below market, StopLimit Buy orders must be above market.";
491 
492  /// <summary>
493  /// Invalid Stop Limit Order Limit Price string message
494  /// </summary>
495  public static string InvalidStopLimitOrderLimitPrice =
496  "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.";
497  }
498 
499  /// <summary>
500  /// Provides user-facing messages for the <see cref="Brokerages.WolverineBrokerageModel"/> class and its consumers or related classes
501  /// </summary>
502  public static class WolverineBrokerageModel
503  {
504  /// <summary>
505  /// Returns a message for an unsupported order type in Wolverine Brokerage Model
506  /// </summary>
507  [MethodImpl(MethodImplOptions.AggressiveInlining)]
508  public static string UnsupportedOrderType(Orders.Order order)
509  {
510  return Invariant($"{order.Type} order is not supported by Wolverine. Currently, only Market Order is supported.");
511  }
512  }
513 
514  /// <summary>
515  /// Provides user-facing messages for the <see cref="Brokerages.RBIBrokerageModel"/> class and its consumers or related classes
516  /// </summary>
517  public static class RBIBrokerageModel
518  {
519  /// <summary>
520  /// Returns a message for an unsupported order type in RBI Brokerage Model
521  /// </summary>
522  /// <param name="order"></param>
523  /// <returns></returns>
524  [MethodImpl(MethodImplOptions.AggressiveInlining)]
525  public static string UnsupportedOrderType(Orders.Order order)
526  {
527  return Invariant($"{order.Type} order is not supported by RBI. Currently, only Market Order, Limit Order, StopMarket Order and StopLimit Order are supported.");
528  }
529  }
530  }
531 }