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