Overall Statistics
Total Trades
266
Average Win
0.11%
Average Loss
-0.07%
Compounding Annual Return
-0.656%
Drawdown
1.600%
Expectancy
0.051
Net Profit
-0.108%
Sharpe Ratio
-0.086
Probabilistic Sharpe Ratio
30.031%
Loss Rate
58%
Win Rate
42%
Profit-Loss Ratio
1.53
Alpha
-0.118
Beta
0.177
Annual Standard Deviation
0.043
Annual Variance
0.002
Information Ratio
-6.199
Tracking Error
0.105
Treynor Ratio
-0.021
Total Fees
$276.27
Estimated Strategy Capacity
$5900000.00
Lowest Capacity Asset
ELAN WY0Y276BTKKL
from AlgorithmImports import *

class KavoutCompositeFactorBundleAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019, 1, 1)
        self.SetEndDate(2019, 3, 1)
        self.SetCash(100000)
        
        self.time = datetime.min
        
        self.AddUniverse(self.MyCoarseFilterFunction)
        self.UniverseSettings.Resolution = Resolution.Minute
        
    def MyCoarseFilterFunction(self, coarse):
        sorted_by_dollar_volume = sorted([x for x in coarse if x.HasFundamentalData], 
                                key=lambda x: x.DollarVolume, reverse=True)
        selected = [x.Symbol for x in sorted_by_dollar_volume[:100]]
        return selected

    def OnData(self, data):
        if self.time > self.Time: return
    
        # Accessing Data
        points = data.Get(KavoutCompositeFactorBundle)
        for kvp in points:
            self.Log(f"Symbol: {kvp.Key} - Growth:{kvp.Value.Growth} - Low Volatility: {kvp.Value.LowVolatility} - Momentum: {kvp.Value.Momentum}"
                     f" - Quality: {kvp.Value.Quality} - Value Factor: {kvp.Value.ValueFactor}")
            
        sorted_by_score = sorted(points.items(), key=self.TotalScore)
        long_symbols = [x[0].Underlying for x in sorted_by_score[-10:]]
        short_symbols = [x[0].Underlying for x in sorted_by_score[:10]]
        
        for symbol in [x.Symbol for x in self.Portfolio.Values if x.Invested]:
            if symbol not in long_symbols + short_symbols:
                self.Liquidate(symbol)
        
        long_targets = [PortfolioTarget(symbol, 0.05) for symbol in long_symbols]
        short_targets = [PortfolioTarget(symbol, -0.05) for symbol in short_symbols]
        self.SetHoldings(long_targets + short_targets)
        
        self.time = Expiry.EndOfDay(self.Time)
        
    def OnSecuritiesChanged(self, changes):
        for security in changes.AddedSecurities:
            # Requesting Data
            kavout_composite_factor_bundle_symbol= self.AddData(KavoutCompositeFactorBundle, security.Symbol).Symbol
            
            # Historical Data
            history = self.History(kavout_composite_factor_bundle_symbol, 2, Resolution.Daily)
            self.Debug(f"We got {len(history)} items from our history request")
            
    def TotalScore(self, value):
        '''Return the total score to integrate overall likelihood to outcompete, take equal weighting for each factor'''
        value = value[1]
        return value.Growth + value.LowVolatility + value.Momentum + value.Quality + value.ValueFactor