Overall Statistics
Total Trades
10232
Average Win
0.36%
Average Loss
-0.28%
Compounding Annual Return
23.334%
Drawdown
36.000%
Expectancy
0.176
Net Profit
1013.191%
Sharpe Ratio
1.053
Probabilistic Sharpe Ratio
43.468%
Loss Rate
49%
Win Rate
51%
Profit-Loss Ratio
1.32
Alpha
0.222
Beta
-0.063
Annual Standard Deviation
0.203
Annual Variance
0.041
Information Ratio
0.31
Tracking Error
0.261
Treynor Ratio
-3.4
Total Fees
$0.00
Estimated Strategy Capacity
$420000.00
Lowest Capacity Asset
AGMH WTSBRPH5YMP1
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
class VentralModulatedCompensator(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2010, 1, 1)  # Set Start Date
        self.SetExecution(ImmediateExecutionModel())
        self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x)))
        self.UniverseSettings.Leverage = 1
        self.UniverseSettings.Resolution = Resolution.Daily
        self.AddUniverseSelection(FineFundamentalUniverseSelectionModel(self.SelectCoarse, self.SelectFine))
        self.SetSecurityInitializer(self.CustomSecurityInitializer)
        self.InitCash = 15000
        self.SetCash(self.InitCash)  
        self.MKT = self.AddEquity("SPY", Resolution.Daily).Symbol
        self.mkt = []
        self.AddRiskManagement(MaximumDrawdownPercentPerSecurity(.20))
        self.AddAlpha(MacdAlphaModel())
        
        
    def CustomSecurityInitializer(self, security):
        security.SetFeeModel(CustomFeeModel())    
    
    def SelectCoarse(self, coarse):
        # sort descending by daily dollar volume
        sortedByDollarVolume = sorted([x for x in coarse if x.HasFundamentalData], key=lambda x: x.DollarVolume, reverse=True)

        return [x.Symbol for x in sortedByDollarVolume[:1500]]


    def SelectFine(self, fine):
    
        sorted_by_ev = sorted(fine, key=lambda x: x.ValuationRatios.PricetoEBITDA, reverse=True)[:100]
        sorted_by_roic = sorted(sorted_by_ev, key=lambda x: x.OperationRatios.ROIC.ThreeMonths, reverse=True)[:50]
        sorted_by_bookvalue = sorted(sorted_by_roic, key=lambda x: x.ValuationRatios.BookValuePerShare, reverse = False)[:15]
        
        return [x.Symbol for x in sorted_by_bookvalue]
        
    def OnSecuritiesChanged(self, changes):
        self.changes = changes
        self.Log(f"OnSecuritiesChanged({self.Time}):: {changes}")
        
        for security in self.changes.RemovedSecurities:
            if security.Invested:
                self.Liquidate(security.Symbol)
        
        for security in self.changes.AddedSecurities:
            self.SetHoldings(security.Symbol, 0.065)
            
    def OnEndOfDay(self):  
    
        mkt_price = self.History(self.MKT, 2, Resolution.Daily)['close'].unstack(level= 0).iloc[-1]
        self.mkt.append(mkt_price)
        mkt_perf = self.InitCash * self.mkt[-1] / self.mkt[0] 
        self.Plot('Strategy Equity', self.MKT, mkt_perf)        
            
class CustomFeeModel:
    def GetOrderFee(self, parameters):
        return OrderFee(CashAmount(0, 'USD'))