/* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Runtime.CompilerServices; using QuantConnect.Brokerages; using QuantConnect.Orders; using static QuantConnect.StringExtensions; using System.Collections.Generic; using QuantConnect.Orders.TimeInForces; using System.Globalization; namespace QuantConnect { /// /// Provides user-facing message construction methods and static messages for the namespace /// public static partial class Messages { /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class DefaultBrokerageModel { /// /// String message saying: MarketOnOpen orders are not supported for futures and future options /// public static string UnsupportedMarketOnOpenOrdersForFuturesAndFutureOptions = "MarketOnOpen orders are not supported for futures and future options."; /// /// String message saying: There is no data for this symbol yet /// public static string NoDataForSymbol = "There is no data for this symbol yet, please check the security.HasData flag to ensure there is at least one data point."; /// /// String message saying: Brokerage does not support update. You must cancel and re-create instead /// public static string OrderUpdateNotSupported = "Brokerage does not support update. You must cancel and re-create instead."; /// /// Retunrns a string message saying the type of the given security is not supported by the given brokerage /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedSecurityType(IBrokerageModel brokerageModel, Securities.Security security) { return Invariant($"The {brokerageModel.GetType().Name} does not support {security.Type} security type."); } /// /// Returns a string message saying the given brokerage does not support updating the quantity of Cross Zero orders /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedCrossZeroOrderUpdate(IBrokerageModel brokerageModel) { return Invariant($"Unfortunately, the {brokerageModel.GetType().Name} brokerage model does not support updating the quantity of Cross Zero Orders."); } /// /// Returns a string message saying the type of the given security is invalid for the given brokerage GetFillModel() method /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string InvalidSecurityTypeToGetFillModel(IBrokerageModel brokerageModel, Securities.Security security) { return Invariant($"{brokerageModel.GetType().Name}.GetFillModel: Invalid security type {security.Type}"); } /// /// Returns a string message saying the quantity given was invalid for the given security /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string InvalidOrderQuantity(Securities.Security security, decimal quantity) { return Invariant($@"The minimum order size (in quote currency) for {security.Symbol.Value} is { security.SymbolProperties.MinimumOrderSize}. Order quantity was {quantity}."); } /// /// Returns a string message saying the given order size (quantity * price) was invalid for the given security /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string InvalidOrderSize(Securities.Security security, decimal quantity, decimal price) { return Invariant($@"The minimum order size (in quote currency) for {security.Symbol.Value} is {security.SymbolProperties.MinimumOrderSize}. Order size was {quantity * price}."); } /// /// Returns a string message saying the type of the given order is unsupported by the given brokerage model. It also /// mentions the supported order types /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedOrderType(IBrokerageModel brokerageModel, Orders.Order order, IEnumerable supportedOrderTypes) { return Invariant($"The {brokerageModel.GetType().Name} does not support {order.Type} order type. Only supports [{string.Join(',', supportedOrderTypes)}]"); } /// /// Returns a string message saying the Time In Force of the given order is unsupported by the given brokerage /// model /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedTimeInForce(IBrokerageModel brokerageModel, Orders.Order order) { return Invariant($@"The {brokerageModel.GetType().Name} does not support { order.TimeInForce.GetType().Name} time in force."); } /// /// Returns a string message saying the type of the given security is invalid /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string InvalidSecurityTypeForLeverage(Securities.Security security) { return Invariant($"Invalid security type: {security.Type}"); } /// /// Returns a message indicating that the specified order type is not supported for orders that cross the zero holdings threshold. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedCrossZeroByOrderType(IBrokerageModel brokerageModel, OrderType orderType) { 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."); } /// /// Returns a message indicating that the specified order type cannot be updated quantity using the given brokerage model. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedUpdateQuantityOrder(IBrokerageModel brokerageModel, OrderType orderType) { return Invariant($"Order type '{orderType}' is not supported to update quantity in the {brokerageModel.GetType().Name}."); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class AlpacaBrokerageModel { /// /// Returns a message indicating that the specified order type is not supported for trading outside /// regular hours by the given brokerage model. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string TradingOutsideRegularHoursNotSupported(IBrokerageModel brokerageModel, OrderType orderType, TimeInForce timeInForce) { return Invariant($"The {brokerageModel.GetType().Name} does not support {orderType} orders with {timeInForce} TIF outside regular hours. ") + Invariant($"Only {OrderType.Limit} orders with {TimeInForce.Day} TIF are supported outside regular trading hours."); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class AlphaStreamsBrokerageModel { /// /// String message saying: The Alpha Streams brokerage does not currently support Cash trading /// public static string UnsupportedAccountType = "The Alpha Streams brokerage does not currently support Cash trading."; } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class AxosBrokerageModel { /// /// Returns a string message saying the order quantity must be Integer. It also contains /// the quantity of the given order /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string NonIntegerOrderQuantity(Orders.Order order) { return Invariant($"Order Quantity must be Integer, but provided {order.Quantity}."); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class BinanceBrokerageModel { /// /// Returns a string message saying the type of the given order is unsupported for the symbol of the given /// security /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedOrderTypeForSecurityType(Orders.Order order, Securities.Security security) { return Invariant($"{order.Type} orders are not supported for this symbol ${security.Symbol}"); } /// /// Returns a string message saying the type of the given order is unsupported for the symbol of the given /// security. The message also contains a link to the supported order types in Binance /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedOrderTypeWithLinkToSupportedTypes(string baseApiEndpoint, Orders.Order order, Securities.Security security) { return Invariant($@"{order.Type} orders are not supported for this symbol. Please check '{baseApiEndpoint}/exchangeInfo?symbol={security.SymbolProperties.MarketTicker}' to see supported order types."); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class BinanceUSBrokerageModel { /// /// String message saying: The Binance.US brokerage does not currently support Margin trading /// public static string UnsupportedAccountType = "The Binance.US brokerage does not currently support Margin trading."; } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class BrokerageMessageEvent { /// /// String message saying: Disconnect /// public static string DisconnectCode = "Disconnect"; /// /// String message saying: Reconnect /// public static string ReconnectCode = "Reconnect"; /// /// Parses a given BrokerageMessageEvent object into a string containing basic information about it /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ToString(Brokerages.BrokerageMessageEvent messageEvent) { return Invariant($"{messageEvent.Type} - Code: {messageEvent.Code} - {messageEvent.Message}"); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class DefaultBrokerageMessageHandler { /// /// String message saying: Brokerage Error /// public static string BrokerageErrorContext = "Brokerage Error"; /// /// String message saying: DefaultBrokerageMessageHandler.Handle(): Disconnected /// public static string Disconnected = "DefaultBrokerageMessageHandler.Handle(): Disconnected."; /// /// String message saying: DefaultBrookerageMessageHandler.Handle(): Reconnected /// public static string Reconnected = "DefaultBrokerageMessageHandler.Handle(): Reconnected."; /// /// String message saying: DefaultBrokerageMessageHandler.Handle(): Disconnect when exchanges are closed, /// checking back before exchange open /// public static string DisconnectedWhenExchangesAreClosed = "DefaultBrokerageMessageHandler.Handle(): Disconnect when exchanges are closed, checking back before exchange open."; /// /// String message saying: DefaultBrokerageMessageHandler.Handle(): Still disconnected, goodbye /// public static string StillDisconnected = "DefaultBrokerageMessageHandler.Handle(): Still disconnected, goodbye."; /// /// String message saying: Brokerage Disconnect /// public static string BrokerageDisconnectedShutDownContext = "Brokerage Disconnect"; /// /// Returns a string message with basic information about the given message event /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string BrokerageInfo(Brokerages.BrokerageMessageEvent messageEvent) { return $"Brokerage Info: {messageEvent.Message}"; } /// /// Returns a string message warning from the given message event /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string BrokerageWarning(Brokerages.BrokerageMessageEvent messageEvent) { return $"Brokerage Warning: {messageEvent.Message}"; } /// /// Returns a string message saying the brokerage is disconnected when exchanges are open and that it's /// trying to reconnect for the given reconnection timeout minutes /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string DisconnectedWhenExchangesAreOpen(TimeSpan reconnectionTimeout) { return Invariant($@"DefaultBrokerageMessageHandler.Handle(): Disconnect when exchanges are open, trying to reconnect for { reconnectionTimeout.TotalMinutes} minutes."); } /// /// Returns a string message with the time until the next market open /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string TimeUntilNextMarketOpen(TimeSpan timeUntilNextMarketOpen) { return Invariant($"DefaultBrokerageMessageHandler.Handle(): TimeUntilNextMarketOpen: {timeUntilNextMarketOpen}"); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class ExanteBrokerageModel { /// /// String message saying: Order is null /// public static string NullOrder = "Order is null."; /// /// String message saying: Price is not set /// public static string PriceNotSet = "Price is not set."; } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class FTXBrokerageModel { /// /// String message saying: Trigger price too high, must be below current market price /// public static string TriggerPriceTooHigh = "Trigger price too high: must be below current market price."; /// /// String message saying: Trigger price too low, must be above current market price /// public static string TriggerPriceTooLow = "Trigger price too low: must be above current market price."; } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class FxcmBrokerageModel { /// /// String message saying: Limit Buy orders and Stop Sell orders must be below market, Limit Sell orders and Stop Buy orders /// must be above market /// public static string InvalidOrderPrice = "Limit Buy orders and Stop Sell orders must be below market, Limit Sell orders and Stop Buy orders must be above market."; /// /// Returns a string message saying the order quantity must be a multiple of LotSize. It also contains the security's Lot /// Size /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string InvalidOrderQuantityForLotSize(Securities.Security security) { return Invariant($"The order quantity must be a multiple of LotSize: [{security.SymbolProperties.LotSize}]."); } /// /// Returns a string message saying the order price is too far from the current market price /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string PriceOutOfRange(OrderType orderType, OrderDirection orderDirection, decimal orderPrice, decimal currentPrice) { return Invariant($@"The {orderType} {orderDirection} order price ({ orderPrice}) is too far from the current market price ({currentPrice})."); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class CoinbaseBrokerageModel { /// /// String message saying: The Coinbase brokerage does not currently support Margin trading /// public static string UnsupportedAccountType = "The Coinbase brokerage does not currently support Margin trading."; /// /// Returns a string message saying the Stop Market orders are no longer supported since the given end date /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string StopMarketOrdersNoLongerSupported(DateTime stopMarketOrderSupportEndDate) { return Invariant($"Stop Market orders are no longer supported since {stopMarketOrderSupportEndDate}."); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class InteractiveBrokersFixModel { /// /// Returns a string message saying the given brokerage model does not support order exercises /// for index and cash-settled options /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedComboOrdersForFutureOptions(Brokerages.InteractiveBrokersFixModel brokerageModel, Orders.Order order) { return Invariant($@"The {brokerageModel.GetType().Name} does not support {order.Type} for future options."); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class InteractiveBrokersBrokerageModel { /// /// Returns a string message saying the given brokerage model does not support order exercises /// for index and cash-settled options /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedExerciseForIndexAndCashSettledOptions(Brokerages.InteractiveBrokersBrokerageModel brokerageModel, Orders.Order order) { return Invariant($@"The {brokerageModel.GetType().Name} does not support { order.Type} exercises for index and cash-settled options."); } /// /// Returns a string message containing the minimum and maximum limits for the allowable order size as well as the currency /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string InvalidForexOrderSize(decimal min, decimal max, string currency) { return Invariant($"The minimum and maximum limits for the allowable order size are ({min}, {max}){currency}."); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class TradierBrokerageModel { /// /// Unsupported Security Type string message /// public static string UnsupportedSecurityType = "This model only supports equities and options."; /// /// Unsupported Time In Force Type string message /// public static string UnsupportedTimeInForceType = $"This model only supports orders with the following time in force types: {typeof(DayTimeInForce)} and {typeof(GoodTilCanceledTimeInForce)}"; /// /// Extended Market Hours Trading Not Supported string message /// public static string ExtendedMarketHoursTradingNotSupported = "Tradier does not support extended market hours trading. Your order will be processed at market open."; /// /// Order Quantity Update Not Supported string message /// public static string OrderQuantityUpdateNotSupported = "Tradier does not support updating order quantities."; /// /// Open Orders Cancel On Reverse Split Symbols string message /// public static string OpenOrdersCancelOnReverseSplitSymbols = "Tradier Brokerage cancels open orders on reverse split symbols"; /// /// Short Order Is GTC string message /// public static string ShortOrderIsGtc = "You cannot place short stock orders with GTC, only day orders are allowed"; /// /// Sell Short Order Last Price Below 5 string message /// public static string SellShortOrderLastPriceBelow5 = "Sell Short order cannot be placed for stock priced below $5"; /// /// Incorrect Order Quantity string message /// public static string IncorrectOrderQuantity = "Quantity should be between 1 and 10,000,000"; /// /// Extended Market Hours Trading Not Supported Outside Extended Session string message /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string ExtendedMarketHoursTradingNotSupportedOutsideExtendedSession(Securities.MarketHoursSegment preMarketSegment, Securities.MarketHoursSegment postMarketSegment) { return "Tradier does not support explicitly placing out-of-regular-hours orders if not currently " + $"during the pre or post market session. {preMarketSegment}. {postMarketSegment}. " + "Only equity limit orders are allowed during extended market hours."; } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class TradingTechnologiesBrokerageModel { /// /// Invalid Stop Market Order Price string message /// public static string InvalidStopMarketOrderPrice = "StopMarket Sell orders must be below market, StopMarket Buy orders must be above market."; /// /// Invalid Stop Limit Order Price string message /// public static string InvalidStopLimitOrderPrice = "StopLimit Sell orders must be below market, StopLimit Buy orders must be above market."; /// /// Invalid Stop Limit Order Limit Price string message /// public static string InvalidStopLimitOrderLimitPrice = "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."; } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class WolverineBrokerageModel { /// /// Returns a message for an unsupported order type in Wolverine Brokerage Model /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedOrderType(Orders.Order order) { return Invariant($"{order.Type} order is not supported by Wolverine. Currently, only Market Order is supported."); } } /// /// Provides user-facing messages for the class and its consumers or related classes /// public static class RBIBrokerageModel { /// /// Returns a message for an unsupported order type in RBI Brokerage Model /// /// /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static string UnsupportedOrderType(Orders.Order order) { return Invariant($"{order.Type} order is not supported by RBI. Currently, only Market Order, Limit Order, StopMarket Order and StopLimit Order are supported."); } } } }