Overall Statistics
Total Trades
30987
Average Win
0.02%
Average Loss
-0.01%
Compounding Annual Return
10.843%
Drawdown
2.100%
Expectancy
0.696
Net Profit
246.349%
Sharpe Ratio
2.892
Probabilistic Sharpe Ratio
100.000%
Loss Rate
36%
Win Rate
64%
Profit-Loss Ratio
1.67
Alpha
0.096
Beta
0.079
Annual Standard Deviation
0.038
Annual Variance
0.001
Information Ratio
-0.348
Tracking Error
0.172
Treynor Ratio
1.386
Total Fees
$33257.96
##########################################
###Combinatorial Portfolio Optimization###
#Kamer Ali Yuksel, Principal AI Architect#
##########################################

import numpy as np

syms = ['ERIE', 'TTEK', 'CLX', 'TMO', 'MO', 'TYL', 'SAFM', 'LLY', 'EXR', 'CBRL', 'MGPI', 'RNR', 'AGNC', 'CCI', 'EXPO', 'MGEE', 'OVBC', 'TDG', 'AAPL', 'HRL', 'GABC', 
'CSGP', 'DVA', 'CMS', 'MLAB', 'ORLY', 'ISRG', 'AGM', 'NEE', 'TJX', 'WST', 'DPZ', 'JBSS', 'ROST', 'HIFS', 'AVY', 'BRO', 'USLM', 'NWN', 'ETR', 'FE', 'VAR', 'CAH', 'WNEB', 
'ATLO', 'FSP', 'HUBG', 'PAYX', 'ARR', 'J', 'MPB', 'STFC', 'DAKT', 'LMNX', 'SNCR', 'CXW', 'FLIR', 'VSAT', 'OTTR', 'PPL', 'BAX', 'PRGO', 'MKL', 'PICO', 'OFC', 'ARE']

class MultidimensionalModulatedRegulators(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2009, 1, 1)
        self.SetCash(1000000)
        self.SetExecution(VolumeWeightedAveragePriceExecutionModel())
 
        self.symbols = []
        for i in range(len(syms)):
            self.symbols.append(Symbol.Create(syms[i], SecurityType.Equity, Market.USA))
            self.Debug(syms[i])
            
        self.SetUniverseSelection(ManualUniverseSelectionModel(self.symbols) )
        self.UniverseSettings.Resolution = Resolution.Hour
        
        self.AddEquity('SPY', Resolution.Hour)
        self.SetBenchmark('SPY')

        self.SetBrokerageModel(AlphaStreamsBrokerageModel())
        self.constant_weights = np.ones(len(syms))
        self.constant_weights[-28:] = -1.0
        self.constant_weights = self.constant_weights / np.sum(np.abs(self.constant_weights))

    def OnData(self, data):
                
        rebalance = False
        
        if self.Portfolio.TotalHoldingsValue > 0:
            total = 0.0
            for i, sym in enumerate(self.symbols):
                curr = (self.Securities[sym].Holdings.HoldingsValue/self.Portfolio.TotalPortfolioValue)
                diff = self.constant_weights[i] - curr
                total += np.abs(diff)
                
            if total > 0.05: 
                rebalance = True
                
            if rebalance:
                for i, sym in enumerate(self.symbols):
                    curr = (self.Securities[sym].Holdings.HoldingsValue/self.Portfolio.TotalPortfolioValue)
                    if self.constant_weights[i] < curr:
                        self.SetHoldings(sym, self.constant_weights[i])
                for i, sym in enumerate(self.symbols):
                    curr = (self.Securities[sym].Holdings.HoldingsValue/self.Portfolio.TotalPortfolioValue)                       
                    if self.constant_weights[i] > curr:
                        self.SetHoldings(sym, self.constant_weights[i])
        else:
            for i, sym in enumerate(self.symbols):
                    self.SetHoldings(sym, self.constant_weights[i])