Algorithm Framework

Hybrid Algorithms

Introduction

Classic style algorithms can also use Algorithm Framework modules. This allows you to get the best of both styles of algorithm design, combining easily pluggable modules with the superior control of classic format.

Examples of popular use-cases of a hybrid approach are:

  • Using framework universe selection models as the assets to select.
  • Using portfolio construction models to decide portfolio allocations.
  • Using a risk control model for free portfolio risk monitoring.
  • Passing data between modules freely without concerns of the module interface.

Universe Selection

You can add one or more Framework Universe Selection Models to your algorithm and it will operate normally. You can also combine it with the AddUniverse method of the classic approach. The following example initializes a classic algorithm with framework universe selection models:

public override void Initialize()
{
    SetUniverseSelection(new ManualUniverseSelectionModel(QuantConnect.Symbol.Create("SPY", SecurityType.Equity, Market.USA)));
    AddUniverseSelection(new ManualUniverseSelectionModel(QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA)));
    AddUniverseSelection(new QC500UniverseSelectionModel());
    AddUniverse(CoarseSelection);
}
def Initialize(self):
    self.SetUniverseSelection(ManualUniverseSelectionModel([ Symbol.Create("SPY", SecurityType.Equity, Market.USA) ]))
    self.AddUniverseSelection(ManualUniverseSelectionModel([ Symbol.Create("AAPL", SecurityType.Equity, Market.USA) ]))
    self.AddUniverseSelection(QC500UniverseSelectionModel())
    self.AddUniverse(self.CoarseSelection)

Alpha

You can add one or multiple Alpha models to your classic algorithm and place the orders using Insight objects without a Portfolio Construction model. To receive the collection of Insight objects in a your classic algorithm, implement the InsightsGenerated event handler:

public override void Initialize()
{
    AddAlpha(new EmaCrossAlphaModel());
    InsightsGenerated += OnInsightsGenerated;
}
private void OnInsightsGenerated(IAlgorithm algorithm, GeneratedInsightsCollection insightsCollection)
{
    var insights = insightsCollection.Insights;
}
def Initialize(self):
    self.AddAlpha(EmaCrossAlphaModel())
    self.InsightsGenerated += self.OnInsightsGenerated

def OnInsightsGenerated(self, algorithm: IAlgorithm, insights_collection: GeneratedInsightsCollection) -> None:
    insights = insights_collection.Insights

Portfolio Construction

You can add a Portfolio Construction model to your classic algorithm and have it place orders without returning Insight objects from an Alpha model. To emit insights without an Alpha model, in the OnData method, call the EmitInsights method.

The following example uses a Portfolio Construction Framework model with EmitInsights method in a classic algorithm:

public override void Initialize()
{
    SetPortfolioConstruction(new EqualWeightingPortfolioConstructionModel());
}

public override void OnData(Slice slice)
{
	EmitInsights(new Insight("GOOG", TimeSpan.FromMinutes(20), InsightType.Price, InsightDirection.Up));
	EmitInsights(new []{
		new Insight("AAPL", TimeSpan.FromMinutes(20), InsightType.Price, InsightDirection.Up),
		new Insight("MSFT", TimeSpan.FromMinutes(20), InsightType.Price, InsightDirection.Up)
	});
}
def Initialize(self):
    self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())

def OnData(self, slice):
	self.EmitInsights(Insight("GOOG", TimeSpan.FromMinutes(20), InsightType.Price, InsightDirection.Up))
	self.EmitInsights([
		Insight("AAPL", TimeSpan.FromMinutes(20), InsightType.Price, InsightDirection.Up),
		Insight("MSFT", TimeSpan.FromMinutes(20), InsightType.Price, InsightDirection.Up)
	])

Risk Management

Some Risk Management Models don't require a Portfolio Construction model to provide PortfolioTarget objects, allowing them to directly monitor the portfolio holdings and liquidate positions when neccessary. To see which pre-built Risk Management models don't need the Portfolio Construction model to provide PortfolioTarget objects, see Supported Models.

You can add one or more Risk Management Models to your algorithm and it will operate normally. The following example initializes a classic algorithm with framework risk management models:

public override void Initialize()
{
    AddRiskManagement(new MaximumDrawdownPercentPerSecurity(0.05m));
    AddRiskManagement(new MaximumUnrealizedProfitPercentPerSecurity(0.1m));
}
def Initialize(self):
    self.AddRiskManagement(MaximumDrawdownPercentPerSecurity(0.05))
    self.AddRiskManagement(MaximumUnrealizedProfitPercentPerSecurity(0.1))

Execution

Execution models can place orders for your strategy instead of placing them manually. To do so, PortfolioTargets are routed to the Execute method of the Execution Model to place orders.

The following example uses a Framework Execution Model in a classic style algorithm:

public override void Initialize()
{
    SetExecution(new ImmediateExecutionModel());
}
def Initialize(self):
    self.SetExecution(ImmediateExecutionModel())

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: