Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Common/Data/Auxiliary/PriceScalingExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;

namespace QuantConnect.Data.Auxiliary
{
Expand Down Expand Up @@ -80,6 +81,7 @@ public static decimal GetPriceScale(
/// Determines the symbol to use to fetch it's factor file
/// </summary>
/// <remarks>This is useful for futures where the symbol to use is the canonical</remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public static Symbol GetFactorFileSymbol(this Symbol symbol)
{
return symbol.SecurityType == SecurityType.Future ? symbol.Canonical : symbol;
Expand All @@ -88,6 +90,7 @@ public static Symbol GetFactorFileSymbol(this Symbol symbol)
/// <summary>
/// Helper method to return an empty factor file
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static IFactorProvider GetEmptyFactorFile(this Symbol symbol)
{
if (symbol.SecurityType == SecurityType.Future)
Expand Down
6 changes: 6 additions & 0 deletions Common/Data/SubscriptionDataConfigExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using QuantConnect.Util;

Expand Down Expand Up @@ -114,6 +115,7 @@ public static void SetDataNormalizationMode(
/// <remarks>One of the objectives of this method is to normalize the 'use mapping'
/// check and void code duplication and related issues</remarks>
/// <returns>True if ticker should be mapped</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool TickerShouldBeMapped(this SubscriptionDataConfig config)
{
// we create an instance of the data type, if it is a custom type
Expand All @@ -129,6 +131,7 @@ public static bool TickerShouldBeMapped(this SubscriptionDataConfig config)
/// check and void code duplication and related issues</remarks>
/// <param name="liveMode">True, is this is a live mode data stream</param>
/// <returns>True if ticker prices should be scaled</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool PricesShouldBeScaled(this SubscriptionDataConfig config, bool liveMode = false)
{
if (config.IsCustomData || config.Symbol.Value.Contains("UNIVERSE"))
Expand All @@ -155,6 +158,7 @@ public static bool PricesShouldBeScaled(this SubscriptionDataConfig config, bool
/// <remarks>Different than <see cref="PricesShouldBeScaled"/> because prices could be scale and no split and dividends
/// really exist, like in the continuous futures case</remarks>
/// <returns>True if this configuration requires split and divided handling</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool EmitSplitsAndDividends(this SubscriptionDataConfig config)
{
return !config.IsCustomData && !config.Symbol.Value.Contains("UNIVERSE") && config.SecurityType == SecurityType.Equity;
Expand All @@ -163,6 +167,7 @@ public static bool EmitSplitsAndDividends(this SubscriptionDataConfig config)
/// <summary>
/// True if this configuration is associated with an asset which can have delisting events
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool CanBeDelisted(this SubscriptionDataConfig config)
{
return config.SecurityType.IsOption() || config.SecurityType == SecurityType.Future || config.SecurityType == SecurityType.Equity;
Expand All @@ -171,6 +176,7 @@ public static bool CanBeDelisted(this SubscriptionDataConfig config)
/// <summary>
/// Initializes a new instance of the <see cref="BaseData"/> type defined in <paramref name="config"/> with the symbol properly set
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static BaseData GetBaseDataInstance(this SubscriptionDataConfig config)
{
var instance = config.Type.GetBaseDataInstance();
Expand Down
10 changes: 10 additions & 0 deletions Common/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
* limitations under the License.
*/

using System.ComponentModel;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: this goes above using System;, while the rest of the block is sorted. Moving it after using System.Collections.Immutable; keeps the order.

using System;
using System.Collections;
using System.Collections.Concurrent;
Expand Down Expand Up @@ -514,6 +515,7 @@ public static void ProtobufSerialize(this IBaseData baseData, Stream stream)
/// Extension method to get security price is 0 messages for users
/// </summary>
/// <remarks>The value of this method is normalization</remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public static string GetZeroPriceMessage(this Symbol symbol)
{
return Messages.Extensions.ZeroPriceForSecurity(symbol);
Expand Down Expand Up @@ -2810,6 +2812,7 @@ public static string ResolutionToLower(this Resolution resolution)
/// <param name="order">The <see cref="Order"/> being converted</param>
/// <param name="transactionManager">The transaction manager, <see cref="SecurityTransactionManager"/></param>
/// <returns></returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static OrderTicket ToOrderTicket(this Order order, SecurityTransactionManager transactionManager)
{
var limitPrice = 0m;
Expand Down Expand Up @@ -3559,6 +3562,7 @@ public static string RemoveFromStart(this string s, string start)
/// Helper method to determine symbol for a live subscription
/// </summary>
/// <remarks>Useful for continuous futures where we subscribe to the underlying</remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool TryGetLiveSubscriptionSymbol(this Symbol symbol, out Symbol mapped)
{
mapped = null;
Expand Down Expand Up @@ -3599,6 +3603,7 @@ public static DateTime GetDelistingDate(this Symbol symbol, MapFile mapFile = nu
/// <summary>
/// Helper method to determine if a given symbol is of custom data
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool IsCustomDataType<T>(this Symbol symbol)
{
return symbol.SecurityType == SecurityType.Base
Expand Down Expand Up @@ -4049,6 +4054,7 @@ public static OrderDirection GetOrderDirection(decimal quantity)
/// <summary>
/// Helper method to process an algorithms security changes, will add and remove securities according to them
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static void ProcessSecurityChanges(this IAlgorithm algorithm, SecurityChanges securityChanges)
{
foreach (var security in securityChanges.AddedSecurities)
Expand Down Expand Up @@ -4082,6 +4088,7 @@ public static void MakeTradable(this Security security)
/// <summary>
/// Helper method to set an algorithm runtime exception in a normalized fashion
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static void SetRuntimeError(this IAlgorithm algorithm, Exception exception, string context)
{
Log.Error(exception, $"Extensions.SetRuntimeError(): {Messages.Extensions.RuntimeError(algorithm, context)}");
Expand Down Expand Up @@ -4216,6 +4223,7 @@ private static IEnumerable<Universe> CreateFutureChain(this IAlgorithm algorithm
/// <param name="security">The found or added security instance</param>
/// <param name="onError">Callback to invoke in case of unsupported security type</param>
/// <returns>True if the security was found or added</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool GetOrAddUnrequestedSecurity(this IAlgorithm algorithm, Symbol symbol, out Security security,
Action<IReadOnlyCollection<SecurityType>> onError = null)
{
Expand Down Expand Up @@ -4340,6 +4348,7 @@ public static SubscriptionDataConfig ToSubscriptionDataConfig(this Data.HistoryR
/// dependency with the FF enumerators requiring that they receive aux data to properly handle delistings.
/// Otherwise we would have issues with delisted symbols continuing to fill forward after expiry/delisting.
/// Reference PR #5485 and related issues for more.</remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool ShouldEmitData(this SubscriptionDataConfig config, BaseData data, bool isUniverse = false)
{
// For now we are only filtering Auxiliary data; so if its another type just return true or if it's a margin interest rate which we want to emit always
Expand Down Expand Up @@ -4494,6 +4503,7 @@ public static int GetListHashCode<T>(this IReadOnlyList<T> list)
/// </summary>
/// <param name="symbol">Type to check</param>
/// <returns>True if it needs to be mapped</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool RequiresMapping(this Symbol symbol)
{
switch (symbol.SecurityType)
Expand Down
7 changes: 7 additions & 0 deletions Common/Orders/ContingentOrderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
using System.Linq;
using QuantConnect.Logging;
using System.Collections.Generic;
using System.ComponentModel;

namespace QuantConnect.Orders
{
Expand Down Expand Up @@ -113,6 +114,7 @@ public static bool IsSameGroupOrder(this Order order, Order other)
/// <param name="orders">List of orders in the set, sorted by id</param>
/// <returns>False if any of the orders in the set is not yet found in the order provider. True otherwise</returns>
/// <remarks>If the target order is not a contingent order, the resulting list will contain that single order alone</remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool TryGetContingentOrders(this Order order, Func<int, Order> orderProvider, out List<Order> orders)
{
var contingency = order.Contingency;
Expand Down Expand Up @@ -166,6 +168,7 @@ public static bool TryGetContingentOrders(this Order order, Func<int, Order> ord
/// <param name="order">Target order, which can be any of the orders in the set</param>
/// <param name="orderProvider">Order provider to use to access the existing orders</param>
/// <returns>The existing orders of the set, including the given one, sorted by id</returns>
[EditorBrowsable(EditorBrowsableState.Never)]
public static List<Order> GetExistingContingentOrders(this Order order, Func<int, Order> orderProvider)
{
var contingency = order.Contingency;
Expand Down Expand Up @@ -196,6 +199,7 @@ public static List<Order> GetExistingContingentOrders(this Order order, Func<int
/// </summary>
/// <param name="order">The parent order</param>
/// <param name="contingentOrders">The orders in the set</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public static IEnumerable<Order> GetContingentChildren(this Order order, IEnumerable<Order> contingentOrders)
{
var parent = order.GetContingencyLink(ContingencyRole.Parent);
Expand All @@ -211,6 +215,7 @@ public static IEnumerable<Order> GetContingentChildren(this Order order, IEnumer
/// </summary>
/// <param name="order">The child order</param>
/// <param name="contingentOrders">The orders in the set</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public static IEnumerable<Order> GetContingentParents(this Order order, IEnumerable<Order> contingentOrders)
{
var child = order.GetContingencyLink(ContingencyRole.Child);
Expand All @@ -227,6 +232,7 @@ public static IEnumerable<Order> GetContingentParents(this Order order, IEnumera
/// </summary>
/// <param name="order">The member order</param>
/// <param name="contingentOrders">The orders in the set</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public static IEnumerable<Order> GetContingentSiblings(this Order order, IEnumerable<Order> contingentOrders)
{
if (order.GetSiblingLink() == null)
Expand All @@ -241,6 +247,7 @@ public static IEnumerable<Order> GetContingentSiblings(this Order order, IEnumer
/// </summary>
/// <param name="order">The parent order</param>
/// <param name="contingentOrders">The orders in the set</param>
[EditorBrowsable(EditorBrowsableState.Never)]
public static List<Order> GetContingentDescendants(this Order order, IReadOnlyCollection<Order> contingentOrders)
{
var result = new List<Order>();
Expand Down
2 changes: 2 additions & 0 deletions Common/Orders/GroupOrderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
using QuantConnect.Logging;
using QuantConnect.Securities;
using System.Collections.Generic;
using System.ComponentModel;

namespace QuantConnect.Orders
{
Expand All @@ -34,6 +35,7 @@ public static class GroupOrderExtensions
/// <param name="orders">List of orders in the combo</param>
/// <returns>False if any of the orders in the combo is not yet found in the order provider. True otherwise</returns>
/// <remarks>If the target order is not a combo order, the resulting list will contain that single order alone</remarks>
[EditorBrowsable(EditorBrowsableState.Never)]
public static bool TryGetGroupOrders(this Order order, Func<int, Order> orderProvider, out List<Order> orders)
{
orders = new List<Order> { order };
Expand Down
1 change: 1 addition & 0 deletions Common/Orders/OrderTicket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -692,6 +692,7 @@ public override string ToString()
/// an error, where it will return the integer value of the <see cref="OrderResponseErrorCode"/> from
/// the most recent response
/// </summary>
[StubsIgnore]
public static implicit operator int(OrderTicket ticket)
{
var response = ticket.GetMostRecentOrderResponse();
Expand Down
37 changes: 37 additions & 0 deletions Tests/Common/Util/ExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,43 @@ public void DeserializeObjectList(string input, int count)
}
}

[Test]
public void EditorBrowsableNeverExtensionMethodsAreNotBoundToPythonInstances()
{
var order = new MarketOrder(Symbols.SPY, 100, DateTime.UtcNow);
var config = new SubscriptionDataConfig(typeof(TradeBar), Symbols.SPY, Resolution.Minute, TimeZones.NewYork,
TimeZones.NewYork, true, true, false);

using (Py.GIL())
{
var module = PyModule.FromString("testModule",
@"
from AlgorithmImports import *

def check(symbol: Symbol, order: Order, config: SubscriptionDataConfig):
hidden = (hasattr(symbol, 'requires_mapping'), hasattr(order, 'try_get_contingent_orders'), hasattr(config, 'ticker_should_be_mapped'))
visible = (hasattr(order, 'is_contingent'), order.is_contingent(), OrderStatus.FILLED.is_open())
static_forms = (Extensions.requires_mapping(symbol), SubscriptionDataConfigExtensions.ticker_should_be_mapped(config))
return hidden, visible, static_forms
");

dynamic check = module.GetAttr("check");
var result = check(Symbols.SPY, order, config);

// hidden extensions are not bound to the instance
Assert.IsFalse((bool)result[0][0]);
Assert.IsFalse((bool)result[0][1]);
Assert.IsFalse((bool)result[0][2]);
// the other extensions are
Assert.IsTrue((bool)result[1][0]);
Assert.IsFalse((bool)result[1][1]);
Assert.IsFalse((bool)result[1][2]);
// the static forms still work
Assert.AreEqual(Symbols.SPY.RequiresMapping(), (bool)result[2][0]);
Assert.AreEqual(config.TickerShouldBeMapped(), (bool)result[2][1]);
}
}

[TestCase(true)]
[TestCase(false)]
public void ConvertPythonSymbolEnumerableSingle(bool useSymbol)
Expand Down
Loading