Algorithm Framework

Alpha Creation

Introduction

The Alpha Model is primarily concerned with predicting market trends and signalling to the algorithm the best moments for making an investment. These signals, or Insight objects contain the Direction, Magnitude and Confidence of a market prediction. Insights should be generated on a defined set of assets provided by the Universe Selection Model; and only emitted when they change.

To set an Alpha Model you can use the SetAlpha(alpha)self.SetAlpha(alpha) method. This should be done from your algorithm Initialize()def Initialize() method.

public override void Initialize()
{
      // Initialize Framework with simplest possible alpha model - constant up signal.
      SetAlpha( new ConstantAlphaModel(InsightType.Price, InsightDirection.Up, TimeSpan.FromMinutes(20), 0.025, null) );
}
def Initialize(self):
     # Initialize Framework with simplest possible alpha model - constant up signal.
     self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(minutes = 20), 0.025, None))

Alpha Model Structure

Alpha models are intended to be easy to create and the primary location for iterating your strategy. To create Alpha Models you must implement the IAlphaModel interface as shown in the examples below. This has two methods:

1. Update() - Generate Insight objects.
2. OnSecuritiesChanged() - Receive notifications about security changes.

// Algorithm framework model that produces insights
class MyAlphaModel : IAlphaModel, INotifiedSecurityChanges
{
    // Updates this alpha model with the latest data from the algorithm.
    // This is called each time the algorithm receives data for subscribed securities
    Insight[] Update(QCAlgorithmFramework algorithm, Slice data) {
         // Generate insights on the securities in universe.
    }

    void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes) {
         // Handle security changes in from your universe model.
    }
}
# Algorithm framework model that produces insights
class MyAlphaModel:

    def Update(self, algorithm, slice):
         # Updates this alpha model with the latest data from the algorithm.
         # This is called each time the algorithm receives data for subscribed securities
         # Generate insights on the securities in universe.
         insights = []
         return insights

    def OnSecuritiesChanged(self, algorithm, changes):
         # Handle security changes in from your universe model.

Creating Insights

The Update method returns an array of Insight objects. An Insight is a single prediction for an asset. These can be thought of actionable trading signals; indicating the asset direction, magnitude and confidence in the near future. Insight classes have the following important properties:

class Insight {
    // Symbol of this Insight
    Symbol Symbol;

    // Gets the type of insight, for example, price insight or volatility insight
    InsightType Type;

    // Gets the predicted direction, Down, Flat or Up.
    InsightDirection Direction;

    // Gets the period over which this insight is expected to come to fruition
    TimeSpan Period;

    // Gets the predicted percent change in the insight type (price/volatility) (optional)
    double? Magnitude;

    // Gets the confidence in this insight (optional)
    double? Confidence { get; private set; }
}
class Insight:
    self.Symbol # Symbol of this Insight
    self.Type # Type of insight (price or volatility)
    self.Direction # Insight Direction (down, flat or up)
    self.Period # Insight period (TimeSpan)
    self.Magnitude # Expected percent change (optional, double)
    self.Confidence # Confidence in insight (optional, double)}

An Insight constructor takes the following arguments:

# Insight Constructor Arguments:
# Insight(symbol, timedelta, type, direction, magnitude=None, confidence=None, sourceModel=None)
 Insight("IBM", timedelta(minutes=20), InsightType.Price, InsightDirection.Up, 0.0025, 1.00)
// Insight Constructor Arguments
// new Insight(symbol, period, type, confidence=null, magnitude=null, source=null);
var insight = new Insight("IBM", TimeSpan.FromMinutes(20), InsightType.Price, InsightDirection.Up);

We have provided a helper method to make creating Insights easier. This can be used in your Update method to create insight objects for your Alpha Model of the Price type:

insight = Insight.Price("IBM", timedelta(minutes = 20), InsightDirection.Up)
var insight = Insight.Price("IBM", TimeSpan.FromMinutes(20), InsightDirection.Up);

Grouped Insights

Sometimes an algorithm performance relies on multiple insights being traded together - such as pairs trading and an options straddle. These insights should be grouped together. Insight groups signals to the execution models that the insights need to be acted on as a single unit to maximize the alpha created.

When you return the grouped insights from your Alpha Model; simply use the Insight.Group() helper method to mark the insights as a set.

 // Insight helper for grouping insights together
return Insight.Group(insight1, insight2, insight3);
# Insight helper for grouping insights together
return Insight.Group( [ insight1, insight2, insight3 ] )

Multi-Alpha Algorithms

The algorithm framework can take multiple Alpha models and generate insights on all of them. The combined stream of Insights is them passed to the Portfolio Construction model. The CompositeAlphaModel was created to facilitate this functionality. Below is an example of combining two Alpha Models to be used in one algorithm:

// Define alpha model as a composite of the rsi and ema cross models
SetAlpha(new CompositeAlphaModel(
        new RsiAlphaModel(),
        new EmaCrossAlphaModel()
));
# Define alpha model as a composite of the rsi and ema cross models
self.SetAlpha(CompositeAlphaModel([RsiAlphaModel(), EmaCrossAlphaModel()]))

As many Alpha Models as required can be added to the Composite Alpha Model input. Each Alpha Model has a unique name and the Insights generated are automatically named according to the source Alpha Model which created it.

Good Design Patterns

To make Alpha Models as useful and pluggable as possible we recommend you follow the following design suggestions. These will ensure you can quickly migrate the Alpha from one algorithm to another if ever needed.

1. Use Assets Defined By Universe Selection Model

The Universe Selection Model is in charge of selecting assets; so you should not assume any fixed set of assets. When assets are added to your universe they will trigger an OnSecuritiesChanged() event. From there you can initialize any state or history required for your Alpha Model.

 // Event fired each time the we add/remove securities from the data feed
public void OnSecuritiesChanged(QCAlgorithmFramework algorithm, SecurityChanges changes)
{
    foreach (var added in changes.AddedSecurities)
    {
        SymbolData symbolData;
        if (!_symbolDataBySymbol.TryGetValue(added.Symbol, out symbolData))
        {
            // create fast/slow EMAs
            var fast = algorithm.EMA(added.Symbol, _fastPeriod);
            var slow = algorithm.EMA(added.Symbol, _slowPeriod);
            _symbolDataBySymbol[added.Symbol] = new SymbolData
            {
                Security = added,
                Fast = fast,
                Slow = slow
            };
        }
        else
        {
            // a security that was already initialized was re-added, reset the indicators
            symbolData.Fast.Reset();
            symbolData.Slow.Reset();
        }
    }
}

// Contains data specific to a symbol required by this model
private class SymbolData
{
    public Security Security { get; set; }
    public Symbol Symbol => Security.Symbol;
    public ExponentialMovingAverage Fast { get; set; }
    public ExponentialMovingAverage Slow { get; set; }
    public bool FastIsOverSlow { get; set; }
    public bool SlowIsOverFast => !FastIsOverSlow;
}
    def OnSecuritiesChanged(self, algorithm, changes):
        '''Event fired each time the we add/remove securities from the data feed
        Args:
            algorithm: The algorithm instance that experienced the change in securities
            changes: The security additions and removals from the algorithm'''
        for added in changes.AddedSecurities:
            symbolData = self.symbolDataBySymbol.get(added.Symbol)
            if symbolData is None:
                # create fast/slow EMAs
                symbolData = SymbolData(added)
                symbolData.Fast = algorithm.EMA(added.Symbol, self.fastPeriod)
                symbolData.Slow = algorithm.EMA(added.Symbol, self.slowPeriod)
                self.symbolDataBySymbol[added.Symbol] = symbolData
            else:
                # a security that was already initialized was re-added, reset the indicators
                symbolData.Fast.Reset()
                symbolData.Slow.Reset()

class SymbolData:
    '''Contains data specific to a symbol required by this model'''
    def __init__(self, security):
        self.Security = security
        self.Symbol = security.Symbol
        self.Fast = None
        self.Slow = None
        self.FastIsOverSlow = False

    @property
    def SlowIsOverFast(self):
        return not self.FastIsOverSlow

2. Give Alpha Models A Unique Name

To ensure your Alpha Model can be used by all Portfolio Construction Models you should assign a unique name to your Alpha Model. Some Portfolio Construction Models can combine multiple Alpha Models together and it can be important to distinguish between them. By default we use the class-type name as the Alpha Model name.

public class RsiAlphaModel : AlphaModel
{
     // Give your alpha a name (perhaps based on its constructor args?)
     public override string Name { get; }
}

You can also see our Tutorials and Videos. You can also get in touch with us via Chat.

Did you find this page Helpful ?