Overall Statistics
Total Trades
25470
Average Win
0.05%
Average Loss
-0.05%
Compounding Annual Return
2.022%
Drawdown
62.700%
Expectancy
0.032
Net Profit
23.865%
Sharpe Ratio
0.191
Probabilistic Sharpe Ratio
0.179%
Loss Rate
53%
Win Rate
47%
Profit-Loss Ratio
1.18
Alpha
0.056
Beta
-0.111
Annual Standard Deviation
0.226
Annual Variance
0.051
Information Ratio
-0.268
Tracking Error
0.285
Treynor Ratio
-0.388
Total Fees
$28740.18
import numpy as np
from QuantConnect.Data.UniverseSelection import *
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel

class DebtPaydownUniverseSelection(FundamentalUniverseSelectionModel):

    def __init__(self, filterFineData = True, universeSettings = None, securityInitializer = None):
        super().__init__(filterFineData, universeSettings, securityInitializer)
        self.month = -1
        
        
    def SelectCoarse(self, algorithm, coarse):
        if algorithm.Time.month == self.month:
            return Universe.Unchanged
        self.month = algorithm.Time.month
        
        toReturn = [x.Symbol for x in coarse if x.HasFundamentalData and x.Price > 5 and x.DollarVolume > 1E6]
        return toReturn
        
    def SelectFine(self, algorithm, fine):
        fine = [x for x in fine if x.CompanyProfile.EnterpriseValue > 0]
        x = 1
        meanLeverage = np.mean([x.FinancialStatements.BalanceSheet.LongTermDebt.TwelveMonths/x.CompanyProfile.EnterpriseValue for x in fine if x.FinancialStatements.BalanceSheet.LongTermDebt.TwelveMonths/x.CompanyProfile.EnterpriseValue < 1])
        x = 1
        marketCaps = [x.MarketCap for x in fine]
        x = 1
        x = [x.ValuationRatios.EVToEBITDA for x in fine]
        topQuartileValue = np.percentile(x, .75)
        x = 1
        topQuartile = np.percentile(marketCaps, 75)
        x = 1
        bottomQuartile = np.percentile(marketCaps, 25)
        
        toReturn = [x for x in fine if bottomQuartile <= x.MarketCap <= topQuartile]
        x = 1
        toReturn = [x for x in toReturn if x.FinancialStatements.BalanceSheet.LongTermDebt.TwelveMonths/x.CompanyProfile.EnterpriseValue > meanLeverage]
        x = 1
        toReturn = [x for x in toReturn if x.ValuationRatios.EVToEBITDA >= topQuartileValue]
        x = 1
        toReturn = sorted(toReturn, key = lambda x: x.FinancialStatements.BalanceSheet.LongTermDebt.TwelveMonths/x.CompanyProfile.EnterpriseValue, reverse = True)
        return [x.Symbol for x in toReturn][:10]
from ExecutionModel import PercentVolumeExecutionModel
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
import numpy as np
from DebtPaydownUniverseSelection import DebtPaydownUniverseSelection

class DebtPaydown(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2010, 1, 2)  # Set Start Date
        self.SetCash(100000)  # Set Strategy Cash
        # self.AddEquity("SPY", Resolution.Minute)
        
        self.AddAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(30)))

        self.SetExecution(ImmediateExecutionModel())

        self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())

       # self.SetRiskManagement(TrailingStopRiskManagementModel(0.03))

        self.SetUniverseSelection(DebtPaydownUniverseSelection())
        
        self.UniverseSettings.Resolution = Resolution.Daily
        
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage)
class PercentVolumeExecutionModel(ExecutionModel):
    '''Execution model that submits orders while the current market price is more favorable that the current volume weighted average price.'''

    def __init__(self, percentVolume = .01):
        self.targetsCollection = PortfolioTargetCollection()
        
        # Gets or sets the maximum order quantity as a percentage of the current bar's volume.
        # This defaults to 0.01m = 1%. For example, if the current bar's volume is 100,
        # then the maximum order size would equal 1 share.
        self.MaximumOrderQuantityPercentVolume = percentVolume


    def Execute(self, algorithm, targets):
        '''Executes market orders such that each order is less than a certain percent of the securities volume.
       Args:
           algorithm: The algorithm instance
           targets: The portfolio targets'''

        # update the complete set of portfolio targets with the new targets
        self.targetsCollection.AddRange(targets)

        # for performance we check count value, OrderByMarginImpact and ClearFulfilled are expensive to call
        if self.targetsCollection.Count > 0:
            for target in self.targetsCollection.OrderByMarginImpact(algorithm):
                symbol = target.Symbol

                # calculate remaining quantity to be ordered
                unorderedQuantity = OrderSizing.GetUnorderedQuantity(algorithm, target)

                # fetch our symbol data containing our VWAP indicator
                data = self.symbolData.get(symbol, None)
                if data is None: return

                # check order entry conditions
                if self.PriceIsFavorable(data, unorderedQuantity):
                    # adjust order size to respect maximum order size based on a percentage of current volume
                    orderSize = OrderSizing.GetOrderSizeForPercentVolume(data.Security, self.MaximumOrderQuantityPercentVolume, unorderedQuantity)

                    if orderSize != 0:
                        algorithm.MarketOrder(symbol, orderSize)

            self.targetsCollection.ClearFulfilled(algorithm)