Overall Statistics |
Total Trades 1163 Average Win 0.11% Average Loss -0.17% Compounding Annual Return 12.317% Drawdown 23.400% Expectancy 0.122 Net Profit 12.351% Sharpe Ratio 0.603 Probabilistic Sharpe Ratio 31.942% Loss Rate 31% Win Rate 69% Profit-Loss Ratio 0.63 Alpha 0.069 Beta 0.43 Annual Standard Deviation 0.204 Annual Variance 0.041 Information Ratio -0.005 Tracking Error 0.233 Treynor Ratio 0.285 Total Fees $1325.44 |
class TheSlippage(AlphaModel): def __init__(self, period = 30, resolution = Resolution.Daily): self.period = period self.resolution = resolution self.insightPeriod = Time.Multiply(Extensions.ToTimeSpan(self.resolution), self.period) self.symbolDataBySymbol = {} resolutionString = Extensions.GetEnumString(resolution, Resolution) self.Name = '{}({},{})'.format(self.__class__.__name__, period, resolutionString) def OnSecuritiesChanged(self, algorithm, changes): symbols = [x.Symbol for x in changes.RemovedSecurities] if len(symbols) > 0: for subscription in algorithm.SubscriptionManager.Subscriptions: if subscription.Symbol in symbols: self.symbolDataBySymbol.pop(subscription.Symbol, None) subscription.Consolidators.Clear() addedSymbols = [x.Symbol for x in changes.AddedSecurities if x.Symbol not in self.symbolDataBySymbol] if len(addedSymbols) == 0: return history = algorithm.History(addedSymbols, self.period, self.resolution) # initialize data for added securities for symbol in addedSymbols: if not history.empty: ticker = SymbolCache.GetTicker(symbol) if ticker not in history.index.levels[0]: Log.Trace(f'VolAlp.OnSecuritiesChanged: {ticker} not found in history data frame.') continue ''' for tuple in history.loc[ticker].itertuples(): macd.Update(tuple.Index, tuple.close) ''' self.symbolDataBySymbol[symbol] = SymbolData(symbol) algorithm.Securities[symbol].SetSlippageModel(CustomSlippageModel(self)) class SymbolData: '''Contains data specific to a symbol required by this model''' def __init__(self, symbol): self.Symbol = symbol class CustomSlippageModel(): def __init__(self, algorithm): self.algorithm = algorithm def GetSlippageApproximation(self, asset, order): # custom slippage math slippage = asset.Price * d.Decimal(0.0001 * np.log10(2*float(order.AbsoluteQuantity))) self.algorithm.Log("CustomSlippageModel: " + str(slippage)) return slippage
class TrailingStopRiskManagementModel(RiskManagementModel): '''Provides an implementation of IRiskManagementModel that limits the maximum possible loss measured from the highest unrealized profit''' def __init__(self): '''Initializes a new instance of the TrailingStopRiskManagementModel class''' self.liquidated = set() self.lastmonth=-1 def ManageRisk(self, algorithm, targets): '''Manages the algorithm's risk at each time step Args: algorithm: The algorithm instance targets: The current portfolio targets to be assessed for risk''' month= algorithm.Time.month if month!= self.lastmonth: self.liquidated.clear() self.lastmonth= month #if different month clear all liquidations riskAdjustedTargets = list() for kvp in algorithm.Securities: symbol = kvp.Key security = kvp.Value if security.Holdings.UnrealizedProfitPercent > 0.1 or security.Holdings.UnrealizedProfitPercent < -0.1 or security.Symbol in self.liquidated: riskAdjustedTargets.append(PortfolioTarget(symbol, 0)) if algorithm.Securities[security.Symbol].Invested: self.liquidated.add(security.Symbol) return riskAdjustedTargets
from CustomUniverse import FundamentalUniverse from CustomAlpha.Completed import LongHold from CustomRiskManagement import takeprofit from CustomerReconciliation import CurrentSlippageModel from datetime import date, timedelta class test (QCAlgorithm): def Initialize(self): self.SetStartDate(2019,7,25) self.SetEndDate(2020,7, 25) self.SetCash(1000000) # Set Strategy Cash self.SetTimeZone(TimeZones.Chicago) self.AddUniverseSelection(FundamentalUniverse.universe()) self.UniverseSettings.Resolution = Resolution.Minute self.UniverseSettings.DataNormalizationMode=DataNormalizationMode.Raw self.UniverseSettings.FillForward = True #Fill in empty data will next price self.UniverseSettings.ExtendedMarketHours = False #Takes in account after hours data self.UniverseSettings.MinimumTimeInUniverse = 1 # each equity has to spend at least 1 hour in universe selection process self.UniverseSettings.Leverage=1 self.Settings.RebalancePortfolioOnInsightChanges = False; self.Settings.RebalancePortfolioOnSecurityChanges = False; self.SetBenchmark("SPY") self.SetBrokerageModel(BrokerageName.AlphaStreams) self.AddAlpha(LongHold.BuyHold()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetRiskManagement(takeprofit.TrailingStopRiskManagementModel()) self.SetExecution(ImmediateExecutionModel()) '''Slippage model not used'''
from QuantConnect.Algorithm.Framework.Alphas import * class BuyHold(AlphaModel): def __init__(self,period = 30, resolution = Resolution.Daily): self.period = period self.resolution = resolution self.decimal = 2 self.insightPeriod = Time.Multiply(Extensions.ToTimeSpan(self.resolution), self.period) self.symbolDataBySymbol = {} self.month=-1 resolutionString = Extensions.GetEnumString(resolution, Resolution) self.Name = '{}({},{})'.format(self.__class__.__name__, period, resolutionString) def Update(self, algorithm, data): insights = [] if algorithm.Time.month == self.month: return [] self.month = algorithm.Time.month for symbol, SymbolData in self.symbolDataBySymbol.items(): insights.append(Insight.Price(symbol, timedelta(days=26), InsightDirection.Up)) return insights def OnSecuritiesChanged(self, algorithm, changes): addedSymbols = [ x.Symbol for x in changes.AddedSecurities if x not in self.symbolDataBySymbol] for y in changes.RemovedSecurities: for subscription in algorithm.SubscriptionManager.Subscriptions: if subscription in changes.RemovedSecurities: self.symbolDataBySymbol.pop(subscription, None) subscription.Consolidators.Clear() if algorithm.Portfolio[y.Symbol].Invested: algorithm.Liquidate(y.Symbol) self.symbolDataBySymbol.pop(y.Symbol) algorithm.RemoveSecurity(y.Symbol) history = algorithm.History(addedSymbols, self.period, self.resolution) for symbol in addedSymbols: self.symbolDataBySymbol[symbol] = SymbolData(symbol) class SymbolData: '''Contains data specific to a symbol required by this model''' def __init__(self, symbol): self.Symbol = symbol
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel from QuantConnect.Data.Custom.SEC import * from Selection.OptionUniverseSelectionModel import OptionUniverseSelectionModel from datetime import timedelta, datetime from math import ceil from itertools import chain import numpy as np class universe(FundamentalUniverseSelectionModel): def __init__(self, filterFineData = True, universeSettings = None, securityInitializer = None): super().__init__(filterFineData, universeSettings, securityInitializer) self.NumberOfSymbolsCoarse = 2500 self.NumberOfSymbolsFine = 250 self.NumberOfSymbolsInPortfolio = 10 self.lastmonth = -1 self.dollarVolumeBySymbol = {} def SelectCoarse(self, algorithm, coarse): month= algorithm.Time.month if month == self.lastmonth: return Universe.Unchanged self.lastmonth= month top = sorted([x for x in coarse if x.HasFundamentalData], key=lambda x: x.DollarVolume, reverse=True)[:self.NumberOfSymbolsCoarse] self.dollarVolumeBySymbol = { i.Symbol: i.DollarVolume for i in top } return list(self.dollarVolumeBySymbol.keys()) def SelectFine(self, algorithm, fine): self.debttoequityMaxAllowance = 1.2 self.priceAllowance = 180 filteredFine = [x for x in fine if x.CompanyReference.CountryId == "USA" and x.Price > self.priceAllowance and (x.CompanyReference.PrimaryExchangeID == "NYS" or x.CompanyReference.PrimaryExchangeID == "NAS") and (algorithm.Time - x.SecurityReference.IPODate).days > 700 #and x.FinancialStatements.CashFlowStatement.ProvisionandWriteOffofAssets.ThreeMonths != 0 and (x.EarningReports.BasicAverageShares.ThreeMonths * x.EarningReports.BasicEPS.TwelveMonths * x.ValuationRatios.PERatio >= 5e10) #and 0 <= (x.OperationRatios.TotalDebtEquityRatioGrowth.OneYear) <= self.debttoequityMaxAllowance #this value will change in accordance to S&P Momentum #and x.FinancialStatements.BalanceSheet.AllowanceForDoubtfulAccountsReceivable.ThreeMonths <= 2.0 * x.FinancialStatements.CashFlowStatement.ProvisionandWriteOffofAssets.ThreeMonths #and (x.FinancialStatements.IncomeStatement.ProvisionForDoubtfulAccounts.TwoMonths <= 1.0*x.FinancialStatements.CashFlowStatement.ProvisionandWriteOffofAssets.ThreeMonths) ] self.ratingsDict = {} for ticker in filteredFine: rating = 0 '''Financial Strength''' if (ticker.OperationRatios.QuickRatio.ThreeMonths) >= 1.0: rating += 1 if 2.0 >= (ticker.OperationRatios.CurrentRatio.ThreeMonths) >= 1.2: rating += 1 if (ticker.OperationRatios.TotalDebtEquityRatioGrowth.OneYear) <= 1.0: rating += 1 if (ticker.OperationRatios.LongTermDebtEquityRatio.OneYear) < 1.0: rating += 1 if (ticker.OperationRatios.InterestCoverage.ThreeMonths) >= 3.0: rating += 1 '''Suitable Growth''' if (ticker.ValuationRatios.SustainableGrowthRate) >= 0.07: rating += 1 '''Industry Comparison''' '''Management and Equity''' if (ticker.OperationRatios.ROA.ThreeMonths) >= 0.05: rating += 1 if (ticker.ValuationRatios.FCFRatio) >= 1: rating += 1 '''Leverage and Liquidity''' if (ticker.OperationRatios.LongTermDebtTotalCapitalRatio.OneYear) <= 0.4: rating += 1 '''Fundamental Variables''' if (ticker.ValuationRatios.PEGRatio) <= 1.0: rating += 1 if (ticker.OperationRatios.ROE.ThreeMonths) >= 0.15: rating += 1 '''Apply Rating''' self.ratingsDict[ticker.Symbol] = rating count = len(filteredFine) if count == 0: return [] myDict = dict() percent = self.NumberOfSymbolsFine / count value3 = sorted(filteredFine, key = lambda x: self.ratingsDict[x.Symbol], reverse = True) value4 = value3[:ceil(len(value3) * percent)] self.stocks = value4[:self.NumberOfSymbolsInPortfolio] self.newstocks= [x.Symbol for x in self.stocks] return [x for x in self.newstocks]