/*
* 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.");
}
}
}
}