Overall Statistics |
Total Trades 12498 Average Win 0.00% Average Loss 0.00% Compounding Annual Return 31.232% Drawdown 1.000% Expectancy 0.109 Net Profit 1.879% Sharpe Ratio 6.637 Probabilistic Sharpe Ratio 91.156% Loss Rate 60% Win Rate 40% Profit-Loss Ratio 1.74 Alpha 0.044 Beta 0.754 Annual Standard Deviation 0.036 Annual Variance 0.001 Information Ratio -0.724 Tracking Error 0.026 Treynor Ratio 0.313 Total Fees $14197.95 Estimated Strategy Capacity $1100000.00 Lowest Capacity Asset PUK RVX7NPOIEE05 |
from datetime import timedelta from QuantConnect.Data.UniverseSelection import * from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel BONDS = ['TLH', 'IEF'] class SectorBalancedPortfolioConstruction(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 9, 19) self.SetEndDate(2017, 10, 15) self.SetCash(10000000) bondSymbol = [self.AddEquity(bond, Resolution.Hour).Symbol for bond in BONDS] self.UniverseSettings.Resolution = Resolution.Hour self.SetUniverseSelection(MyUniverseSelectionModel()) self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1), 0.025, None)) self.SetPortfolioConstruction(MySectorWeightingPortfolioConstructionModel(bondSymbol)) self.SetExecution(ImmediateExecutionModel()) class MyUniverseSelectionModel(FundamentalUniverseSelectionModel): def __init__(self): super().__init__(True, None) def SelectCoarse(self, algorithm, coarse): filtered = [x for x in coarse if x.HasFundamentalData and x.Price > 10] sortedByDollarVolume = sorted(filtered, key=lambda x: x.DollarVolume, reverse=True) return [x.Symbol for x in sortedByDollarVolume][:1000] def SelectFine(self, algorithm, fine): for f in fine: try: f.AssetClassification except: algorithm.Quit(f"Error with {f.Symbol}") return [] filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology] self.technology = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:50] filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.FinancialServices] self.financialServices = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:50] filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerDefensive] self.consumerDefensive = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:50] return [x.Symbol for x in self.technology + self.financialServices + self.consumerDefensive] #filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Industrials] #self.industrial = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5] #filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Energy] #self.energy = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5] #filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.BasicMaterials] #self.basicmaterial = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5] #filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.CommunicationServices] #self.communication = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5] #filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Utilities] #self.utility = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5] #filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Healthcare] #self.health = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5] #filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.ConsumerCyclical] #self.consumerCyclical = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5] #filtered = [f for f in fine if f.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.RealEstate] #self.realestate = sorted(filtered, key=lambda f: f.MarketCap, reverse=True)[:5] class MySectorWeightingPortfolioConstructionModel(EqualWeightingPortfolioConstructionModel): def __init__(self, bondSymbol, rebalance = Resolution.Daily): super().__init__() self.bondSymbol = bondSymbol self.symbolBySectorCode = {"Bonds":self.bondSymbol} self.result = dict() def DetermineTargetPercent(self, activeInsights): #1. Set the self.sectorBuyingPower before by dividing one by the length of self.symbolBySectorCode self.sectorBuyingPower = 1/len(self.symbolBySectorCode) for sector, symbols in self.symbolBySectorCode.items(): #2. Search for the active insights in this sector. Save the variable self.insightsInSector self.insightsInSector = [insight for insight in activeInsights if insight.Symbol in symbols] #3. Divide the self.sectorBuyingPower by the length of self.insightsInSector to calculate the variable percent # The percent is the weight we'll assign the direction of the insight self.percent = self.sectorBuyingPower / len(self.insightsInSector) #4. For each insight in self.insightsInSector, assign each insight an allocation. # The allocation is calculated by multiplying the insight direction by the self.percent for insight in self.insightsInSector: self.result[insight] = insight.Direction * self.percent return self.result def OnSecuritiesChanged(self, algorithm, changes): for security in changes.AddedSecurities: if security.Symbol in self.bondSymbol: continue sectorCode = security.Fundamentals.AssetClassification.MorningstarSectorCode if sectorCode not in self.symbolBySectorCode: self.symbolBySectorCode[sectorCode] = list() self.symbolBySectorCode[sectorCode].append(security.Symbol) for security in changes.RemovedSecurities: symbol = security.Symbol for sectorCode in self.symbolBySectorCode.keys(): if symbol in self.symbolBySectorCode[sectorCode]: self.symbolBySectorCode[sectorCode].remove(symbol) super().OnSecuritiesChanged(algorithm, changes)