Overall Statistics
Total Trades
5581
Average Win
0.08%
Average Loss
-0.06%
Compounding Annual Return
-6.231%
Drawdown
12.000%
Expectancy
-0.041
Net Profit
-6.231%
Sharpe Ratio
-0.631
Probabilistic Sharpe Ratio
2.654%
Loss Rate
61%
Win Rate
39%
Profit-Loss Ratio
1.43
Alpha
-0.027
Beta
-0.069
Annual Standard Deviation
0.066
Annual Variance
0.004
Information Ratio
-1.973
Tracking Error
0.129
Treynor Ratio
0.6
Total Fees
$6010.78
Estimated Strategy Capacity
$12000000.00
Lowest Capacity Asset
AVGO UEW4IOBWVPT1
# region imports
from AlgorithmImports import *
# endregion

class ExtractAlphaCrossAssetModelAlgorithm(QCAlgorithm):

    def Initialize(self) -> None:
        self.SetStartDate(2019, 1, 1)
        self.SetEndDate(2019, 12, 31)
        self.SetCash(100000)
        
        self.time = datetime.min
        
        self.AddUniverse(self.MyCoarseFilterFunction)

        self.dataset_symbol_by_symbol = {}
        self.points = {}
        
    def MyCoarseFilterFunction(self, coarse: List[CoarseFundamental]) -> List[Symbol]:
        sorted_by_dollar_volume = sorted([x for x in coarse if x.HasFundamentalData and x.Price > 4], 
                                key=lambda x: x.DollarVolume, reverse=True)
        selected = [x.Symbol for x in sorted_by_dollar_volume[:100]]
        return selected

    def OnData(self, slice: Slice) -> None:
        if self.time > self.Time: return
    
        # Accessing Data
        points = slice.Get(ExtractAlphaCrossAssetModel)
        if points:
            self.points = points

        if slice.Time.time() < time(10): return

        sorted_by_score = sorted([x for x in self.points.items() if x[1].Score != None], 
            key=lambda x: x[1].Score, reverse=True)
        long_symbols = [x[0].Underlying for x in sorted_by_score[:10]]
        short_symbols = [x[0].Underlying for x in sorted_by_score[-10:]]

        portfolio_targets = []
        for symbol, security_holding in self.Portfolio.items():
            weight = 0
            if symbol in long_symbols:
                weight = 0.05
            elif symbol in short_symbols:
                weight = -0.05
            elif not security_holding.Invested:
                continue
            portfolio_targets.append(PortfolioTarget(symbol, weight))
        self.SetHoldings(portfolio_targets)
        
        self.time = Expiry.EndOfDay(self.Time)
        
    def OnSecuritiesChanged(self, changes: SecurityChanges) -> None:
        for security in changes.AddedSecurities:
            self.dataset_symbol_by_symbol[security.Symbol] = self.AddData(ExtractAlphaCrossAssetModel, security.Symbol).Symbol

        for security in changes.RemovedSecurities:
            dataset_symbol = self.dataset_symbol_by_symbol.pop(security.Symbol, None)
            if dataset_symbol:
                self.RemoveSecurity(dataset_symbol)