Overall Statistics |
Total Trades 56294 Average Win 0.03% Average Loss -0.02% Compounding Annual Return 2.197% Drawdown 58.200% Expectancy 0.039 Net Profit 26.180% Sharpe Ratio 0.199 Probabilistic Sharpe Ratio 0.197% Loss Rate 54% Win Rate 46% Profit-Loss Ratio 1.28 Alpha 0.06 Beta -0.12 Annual Standard Deviation 0.231 Annual Variance 0.053 Information Ratio -0.255 Tracking Error 0.29 Treynor Ratio -0.383 Total Fees $58175.33 |
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] 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]) marketCaps = [x.MarketCap for x in fine] x = [x.ValuationRatios.EVToEBITDA for x in fine] topQuartileValue = np.percentile(x, .75) topQuartile = np.percentile(marketCaps, 75) bottomQuartile = np.percentile(marketCaps, 25) toReturn = [x for x in fine if bottomQuartile <= x.MarketCap <= topQuartile] 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][:25]
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)