| 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)