Skip to content
Closed
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

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adds INamedModel and a default name because this model does not inherit from PortfolioConstructionModel.

Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@ namespace QuantConnect.Algorithm.Framework.Portfolio
/// <summary>
/// Base alpha streams portfolio construction model
/// </summary>
public class AlphaStreamsPortfolioConstructionModel : IPortfolioConstructionModel
public class AlphaStreamsPortfolioConstructionModel : IPortfolioConstructionModel, INamedModel
{
/// <summary>
/// Defines a name for the framework model
/// </summary>
public virtual string Name { get; set; } = nameof(AlphaStreamsPortfolioConstructionModel);

/// <summary>
/// Get's the weight for an alpha
/// </summary>
Expand Down

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adds a stable name containing its weight bounds and risk-free rate so configured instances are identifiable.

Comment thread
jrile018 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
using Accord.Math;
using Accord.Math.Optimization;
using Accord.Statistics;
using QuantConnect.Algorithm.Framework.Alphas;
using static System.FormattableString;

namespace QuantConnect.Algorithm.Framework.Portfolio
{
Expand All @@ -26,12 +28,17 @@ namespace QuantConnect.Algorithm.Framework.Portfolio
/// The interval of weights in optimization method can be changed based on the long-short algorithm.
/// The default model uses flat risk free rate and weight for an individual security range from -1 to 1.
/// </summary>
public class MaximumSharpeRatioPortfolioOptimizer : IPortfolioOptimizer
public class MaximumSharpeRatioPortfolioOptimizer : IPortfolioOptimizer, INamedModel
{
private double _lower;
private double _upper;
private double _riskFreeRate;

/// <summary>
/// Defines a name for the portfolio optimizer
/// </summary>
public string Name { get; }

/// <summary>
/// Initialize a new instance of <see cref="MaximumSharpeRatioPortfolioOptimizer"/>
/// </summary>
Expand All @@ -43,6 +50,7 @@ public MaximumSharpeRatioPortfolioOptimizer(double lower = -1, double upper = 1,
_lower = lower;
_upper = upper;
_riskFreeRate = riskFreeRate;
Name = Invariant($"{nameof(MaximumSharpeRatioPortfolioOptimizer)}({lower},{upper},{riskFreeRate})");
}

/// <summary>
Expand Down Expand Up @@ -137,4 +145,4 @@ public double[] Optimize(double[,] historicalReturns, double[] expectedReturns =
return sum > 0 ? y.Divide(sum) : equalWeights;
}
}
}
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adds a name containing its bounds and target return.

Comment thread
jrile018 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
using Accord.Math;
using Accord.Math.Optimization;
using Accord.Statistics;
using QuantConnect.Algorithm.Framework.Alphas;
using static System.FormattableString;

namespace QuantConnect.Algorithm.Framework.Portfolio
{
Expand All @@ -26,12 +28,17 @@ namespace QuantConnect.Algorithm.Framework.Portfolio
/// with the weight range from -1 to 1 and minimize the portfolio variance with a target return of 2%
/// </summary>
/// <remarks>The budged constrain is scaled down/up to ensure that the sum of the absolute value of the weights is 1.</remarks>
public class MinimumVariancePortfolioOptimizer : IPortfolioOptimizer
public class MinimumVariancePortfolioOptimizer : IPortfolioOptimizer, INamedModel
{
private double _lower;
private double _upper;
private double _targetReturn;

/// <summary>
/// Defines a name for the portfolio optimizer
/// </summary>
public string Name { get; }

/// <summary>
/// Initialize a new instance of <see cref="MinimumVariancePortfolioOptimizer"/>
/// </summary>
Expand All @@ -43,6 +50,7 @@ public MinimumVariancePortfolioOptimizer(double lower = -1, double upper = 1, do
_lower = lower;
_upper = upper;
_targetReturn = targetReturn;
Name = Invariant($"{nameof(MinimumVariancePortfolioOptimizer)}({lower},{upper},{targetReturn})");
}

/// <summary>
Expand Down
22 changes: 21 additions & 1 deletion Algorithm.Framework/Portfolio/PortfolioOptimizerPythonWrapper.cs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Uses a custom Python Name when provided, otherwise falls back to the Python class name.

Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,35 @@
*/

using Python.Runtime;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Python;

namespace QuantConnect.Algorithm.Framework.Portfolio
{
/// <summary>
/// Python wrapper for custom portfolio optimizer
/// </summary>
public class PortfolioOptimizerPythonWrapper : BasePythonWrapper<IPortfolioOptimizer>, IPortfolioOptimizer
public class PortfolioOptimizerPythonWrapper : BasePythonWrapper<IPortfolioOptimizer>, IPortfolioOptimizer, INamedModel
{
/// <summary>
/// Defines a name for the portfolio optimizer
/// </summary>
public string Name
{
get
{
using (Py.GIL())
{
if (HasAttr(nameof(Name)))
{
return GetProperty<string>(nameof(Name));
}

return GetProperty("__class__").GetAttr("__name__").GetAndDispose<string>();
}
}
}

/// <summary>
/// Creates a new instance
/// </summary>
Expand Down
10 changes: 9 additions & 1 deletion Algorithm.Framework/Portfolio/RiskParityPortfolioOptimizer.cs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adds a name containing its resolved lower and upper bounds.

Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,25 @@
using System.Linq;
using Accord.Math;
using Accord.Statistics;
using QuantConnect.Algorithm.Framework.Alphas;
using static System.FormattableString;

namespace QuantConnect.Algorithm.Framework.Portfolio
{
/// <summary>
/// Provides an implementation of a risk parity portfolio optimizer that calculate the optimal weights
/// with the weight range from 0 to 1 and equalize the risk carried by each asset
/// </summary>
public class RiskParityPortfolioOptimizer : IPortfolioOptimizer
public class RiskParityPortfolioOptimizer : IPortfolioOptimizer, INamedModel
{
private double _lower = 1e-05;
private double _upper = Double.MaxValue;

/// <summary>
/// Defines a name for the portfolio optimizer
/// </summary>
public string Name { get; }

/// <summary>
/// Initialize a new instance of <see cref="RiskParityPortfolioOptimizer"/>
/// </summary>
Expand All @@ -38,6 +45,7 @@ public RiskParityPortfolioOptimizer(double? lower = null, double? upper = null)
{
_lower = lower ?? _lower; // has to be greater than or equal to 0
_upper = upper ?? _upper;
Name = Invariant($"{nameof(RiskParityPortfolioOptimizer)}({_lower},{_upper})");
}

/// <summary>
Expand Down

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adds a simple class-based name because it has no configuration parameters.

Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,20 @@

using Accord.Math;
using Accord.Statistics;
using QuantConnect.Algorithm.Framework.Alphas;

namespace QuantConnect.Algorithm.Framework.Portfolio
{
/// <summary>
/// Provides an implementation of a portfolio optimizer with unconstrained mean variance.
/// </summary>
public class UnconstrainedMeanVariancePortfolioOptimizer : IPortfolioOptimizer
public class UnconstrainedMeanVariancePortfolioOptimizer : IPortfolioOptimizer, INamedModel
{
/// <summary>
/// Defines a name for the portfolio optimizer
/// </summary>
public string Name { get; } = nameof(UnconstrainedMeanVariancePortfolioOptimizer);

/// <summary>
/// Perform portfolio optimization for a provided matrix of historical returns and an array of expected returns
/// </summary>
Expand All @@ -37,4 +43,4 @@ public double[] Optimize(double[,] historicalReturns, double[] expectedReturns =
return Π.Dot(Σ.Inverse());
}
}
}
}
9 changes: 8 additions & 1 deletion Algorithm/Execution/ExecutionModel.cs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adds INamedModel and defaults Name to the concrete execution-model type.

Comment thread
jrile018 marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Orders;
using QuantConnect.Python;
Expand All @@ -23,8 +24,13 @@ namespace QuantConnect.Algorithm.Framework.Execution
/// <summary>
/// Provides a base class for execution models
/// </summary>
public class ExecutionModel : BasePythonWrapper<ExecutionModel>, IExecutionModel
public class ExecutionModel : BasePythonWrapper<ExecutionModel>, IExecutionModel, INamedModel
{
/// <summary>
/// Defines a name for the framework model
/// </summary>
public virtual string Name { get; set; }

/// <summary>
/// If true, orders should be submitted asynchronously.
/// </summary>
Expand All @@ -36,6 +42,7 @@ public class ExecutionModel : BasePythonWrapper<ExecutionModel>, IExecutionModel
/// <param name="asynchronous">If true, orders should be submitted asynchronously</param>
public ExecutionModel(bool asynchronous = true)
{
Name = GetType().Name;
Asynchronous = asynchronous;
}

Expand Down
19 changes: 19 additions & 0 deletions Algorithm/Execution/ExecutionModelPythonWrapper.cs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Exposes the Python model’s custom name or Python class name.

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@ public class ExecutionModelPythonWrapper : ExecutionModel
{
private readonly bool _onOrderEventsDefined;

/// <summary>
/// Defines a name for the framework model
/// </summary>
public override string Name
{
get
{
using (Py.GIL())
{
if (HasAttr(nameof(Name)))
{
return GetProperty<string>(nameof(Name));
}

return GetProperty("__class__").GetAttr("__name__").GetAndDispose<string>();
}
}
}

/// <summary>
/// Constructor for initialising the <see cref="IExecutionModel"/> class with wrapped <see cref="PyObject"/> object
/// </summary>
Expand Down
8 changes: 7 additions & 1 deletion Algorithm/Portfolio/PortfolioConstructionModel.cs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Preserves custom names from Python portfolio-construction models, with a class-name fallback.

Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,17 @@ namespace QuantConnect.Algorithm.Framework.Portfolio
/// <summary>
/// Provides a base class for portfolio construction models
/// </summary>
public class PortfolioConstructionModel : IPortfolioConstructionModel
public class PortfolioConstructionModel : IPortfolioConstructionModel, INamedModel
{
private Func<DateTime, DateTime?> _rebalancingFunc;
private DateTime? _rebalancingTime;
private bool _securityChanges;

/// <summary>
/// Defines a name for the framework model
/// </summary>
public virtual string Name { get; set; }

/// <summary>
/// True if should rebalance portfolio on security changes. True by default
/// </summary>
Expand Down Expand Up @@ -63,6 +68,7 @@ public class PortfolioConstructionModel : IPortfolioConstructionModel
/// will trigger rebalance. If null will be ignored</param>
public PortfolioConstructionModel(Func<DateTime, DateTime?> rebalancingFunc)
{
Name = GetType().Name;
_rebalancingFunc = rebalancingFunc;
}

Expand Down
19 changes: 19 additions & 0 deletions Algorithm/Portfolio/PortfolioConstructionModelPythonWrapper.cs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Preserves custom names from Python portfolio-construction models, with a class-name fallback.

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,25 @@ public class PortfolioConstructionModelPythonWrapper : PortfolioConstructionMode
private readonly BasePythonWrapper<PortfolioConstructionModel> _model;
private readonly bool _implementsDetermineTargetPercent;

/// <summary>
/// Defines a name for the framework model
/// </summary>
public override string Name
{
get
{
using (Py.GIL())
{
if (_model.HasAttr(nameof(Name)))
{
return _model.GetProperty<string>(nameof(Name));
}

return _model.GetProperty("__class__").GetAttr("__name__").GetAndDispose<string>();
}
}
}

/// <summary>
/// True if should rebalance portfolio on security changes. True by default
/// </summary>
Expand Down
18 changes: 16 additions & 2 deletions Algorithm/Risk/RiskManagementModel.cs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Adds INamedModel and defaults Name to the concrete risk-model type.

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
*/

using System.Collections.Generic;
using QuantConnect.Algorithm.Framework.Alphas;
using QuantConnect.Algorithm.Framework.Portfolio;
using QuantConnect.Data.UniverseSelection;

Expand All @@ -22,8 +23,21 @@ namespace QuantConnect.Algorithm.Framework.Risk
/// <summary>
/// Provides a base class for risk management models
/// </summary>
public class RiskManagementModel : IRiskManagementModel
public class RiskManagementModel : IRiskManagementModel, INamedModel
{
/// <summary>
/// Defines a name for the framework model
/// </summary>
public virtual string Name { get; set; }

/// <summary>
/// Initializes a new instance of the <see cref="RiskManagementModel"/> class
/// </summary>
public RiskManagementModel()
{
Name = GetType().Name;
}

/// <summary>
/// Manages the algorithm's risk at each time step
/// </summary>
Expand All @@ -43,4 +57,4 @@ public virtual void OnSecuritiesChanged(QCAlgorithm algorithm, SecurityChanges c
{
}
}
}
}
19 changes: 19 additions & 0 deletions Algorithm/Risk/RiskManagementModelPythonWrapper.cs

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Preserves custom Python risk-model names, with a class-name fallback.

Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,25 @@ public class RiskManagementModelPythonWrapper : RiskManagementModel
{
private readonly BasePythonWrapper<IRiskManagementModel> _model;

/// <summary>
/// Defines a name for the framework model
/// </summary>
public override string Name
{
get
{
using (Py.GIL())
{
if (_model.HasAttr(nameof(Name)))
{
return _model.GetProperty<string>(nameof(Name));
}

return _model.GetProperty("__class__").GetAttr("__name__").GetAndDispose<string>();
}
}
}

/// <summary>
/// Constructor for initialising the <see cref="IRiskManagementModel"/> class with wrapped <see cref="PyObject"/> object
/// </summary>
Expand Down
Loading