Overall Statistics |
Total Trades 3558 Average Win 0.33% Average Loss -0.27% Compounding Annual Return -4.852% Drawdown 24.700% Expectancy -0.015 Net Profit -8.339% Sharpe Ratio -0.235 Loss Rate 56% Win Rate 44% Profit-Loss Ratio 1.23 Alpha 0.556 Beta -35.008 Annual Standard Deviation 0.138 Annual Variance 0.019 Information Ratio -0.357 Tracking Error 0.138 Treynor Ratio 0.001 Total Fees $3558.00 |
from clr import AddReference AddReference("System") AddReference("QuantConnect.Common") AddReference("QuantConnect.Indicators") AddReference("QuantConnect.Algorithm.Framework") from QuantConnect.Data.UniverseSelection import * from QuantConnect.Indicators import ExponentialMovingAverage from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel import decimal as d class UniverseSelectionModel(FundamentalUniverseSelectionModel): def __init__(self, universeCount = 20, filterFineData = True, universeSettings = None, securityInitializer = None): super().__init__(filterFineData, universeSettings, securityInitializer) self.universeCount = universeCount # Holds our coarse fundamental indicators by symbol self.calculations = {} def SelectCoarse(self, algorithm, coarse): '''Performs coarse selection based on price and volume''' # We are going to use a dictionary to refer the object that will keep the calculations for cf in coarse: if cf.Symbol not in self.calculations: self.calculations[cf.Symbol] = SymbolData(cf.Symbol) self.calculations[cf.Symbol].update(cf.EndTime, cf.Price, cf.Volume, cf.DollarVolume, cf.HasFundamentalData) # Updates the SymbolData object with price, volume, dollar volume, etc #avg = self.calculations[cf.Symbol] #avg.update(cf.EndTime, cf.Price, cf.Volume, cf.DollarVolume, cf.HasFundamentalData) # Filter the values of the dict based on chosen criteria. filtered_coarse = list(filter(lambda x: (x.is_uptrend and x.fundamentaldata), self.calculations.values())) # Sort the values of the dict: we want those with greater DollarVolume sorted_coarse = sorted(filtered_coarse, key = lambda x: x.dollarvolume, reverse = True) #for x in sorted_values[:self.universeCount]: # algorithm.Log(str(algorithm.Time) + 'symbol: ' + str(x.symbol.Value) # + ' close price: ' + str(x.price) # + ' volume: ' + str(x.volume) # + ' dollar volume: ' + str(x.dollarvolume) # + ' mean price: ' + str(x.priceSMA.Current.Value) # + ' mean vol: ' + str(x.volSMA.Current.Value)) # Select Top Stocks (based on universeCount) return [ x.Symbol for x in sorted_coarse[:self.universeCount] ] def SelectFine(self, algorithm, fine): '''Performs fine selection: The company's headquarter must in the U.S. The stock must be traded on either the NYSE or NASDAQ At least half a year since its initial public offering The stock's market cap must be greater than 500 million''' filtered_fine = list(filter(lambda x: (x.CompanyReference.CountryId == "USA" and (x.CompanyReference.PrimaryExchangeID == "NYS" or x.CompanyReference.PrimaryExchangeID == "NAS") #and (algorithm.Time - x.SecurityReference.IPODate).days > 180 and x.EarningReports.BasicEPS.TwelveMonths > 0 and x.ValuationRatios.PERatio > 0 and x.EarningReports.BasicAverageShares.ThreeMonths > 0), fine)) #and x.EarningReports.BasicAverageShares.ThreeMonths * (x.EarningReports.BasicEPS.TwelveMonths * x.ValuationRatios.PERatio) > 5e8), fine)) # Sort the values of the dict by market cap sorted_fine = sorted(filtered_fine, key = lambda x: x.EarningReports.BasicAverageShares.ThreeMonths * (x.EarningReports.BasicEPS.TwelveMonths * x.ValuationRatios.PERatio), reverse = True) # Select Top Stocks (up to UniverseCount) return [ x.Symbol for x in filtered_fine[:UniverseCount] ] # Class used to improve readability of the coarse selection function class SymbolData: def __init__(self, symbol): self.Symbol = symbol self.priceWin = RollingWindow[float](5) #self.priceSMA10 = SimpleMovingAverage(10) #self.priceSMA50 = SimpleMovingAverage(50) #self.priceSMA200 = SimpleMovingAverage(200) self.volSMA = SimpleMovingAverage(50) self.is_uptrend = False def update(self, time, price, volume, dollarvolume, fundamentaldata): self.price = price self.volume = volume self.dollarvolume = dollarvolume self.fundamentaldata = fundamentaldata self.priceWin.Add(price) #self.priceSMA10.Update(time, price) #self.priceSMA50.Update(time, price) #self.priceSMA200.Update(time, price) self.volSMA.Update(time, volume) #self.priceSMA10.IsReady and self.priceSMA50.IsReady and self.priceSMA200.IsReady and if self.volSMA.IsReady and self.priceWin.IsReady: #SMA10price = self.priceSMA10.Current.Value #SMA50price = self.priceSMA50.Current.Value #SMA200price = self.priceSMA200.Current.Value SMAvol = self.volSMA.Current.Value # (SMA10price > SMA50price and SMA50price > SMA200price # price > SMA10price # Here we can add the criteria for our universe self.is_uptrend = (price > 20 and price > max(self.priceWin) and price > (self.priceWin[1] + float(1)) and SMAvol > 500 and volume > (d.Decimal(1.5) * SMAvol))
from UniverseSelection import UniverseSelectionModel from AlphaCreation import ConstantAlphaModel from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel from Execution.ImmediateExecutionModel import ImmediateExecutionModel from Risk.NullRiskManagementModel import NullRiskManagementModel from RiskManagement import PnLManagementModel class BasicTemplateFrameworkAlgorithm(QCAlgorithmFramework): def Initialize(self): # Set requested data resolution self.UniverseSettings.Resolution = Resolution.Minute self.SetStartDate(2017, 1, 1) # Set Start Date self.SetEndDate(2018, 10, 1) # Set End Date self.SetCash(10000) # Set Strategy Cash # Adding SPY Market to use in Schedule Function #self.AddEquity("SPY") # Scheduled Function to liquidate all positions 15 minutes before market close #self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 15), self.rebalance) self.SetUniverseSelection(UniverseSelectionModel(universeCount = 5, filterFineData = False)) self.SetAlpha(ConstantAlphaModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.SetExecution(ImmediateExecutionModel()) #self.SetRiskManagement(NullRiskManagementModel()) self.SetRiskManagement(PnLManagementModel(maximumDrawdownPercent = 0.02, TakeProfitPercent = 0.1)) #def rebalance(self): #algorithm.Log(str(algorithm.Time) + 'Liquidating End Of Day: ' + str(security)) #self.Liquidate()
from clr import AddReference AddReference("System") AddReference("QuantConnect.Common") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Algorithm.Framework") from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Algorithm.Framework import * from QuantConnect.Algorithm.Framework.Portfolio import PortfolioTarget from QuantConnect.Algorithm.Framework.Risk import RiskManagementModel class PnLManagementModel(RiskManagementModel): '''Provides an implementation of IRiskManagementModel that limits the drawdown per holding to the specified percentage''' def __init__(self, maximumDrawdownPercent = 0.02, TakeProfitPercent = 0.05): '''Initializes a new instance of the PnLManagementModel class Args: maximumDrawdownPercent: The maximum percentage drawdown allowed for any single security holding TakeProfitPercent: The take profit percentage for any single security holding''' self.maximumDrawdownPercent = -abs(maximumDrawdownPercent) self.TakeProfitPercent = abs(TakeProfitPercent) def ManageRisk(self, algorithm, targets): '''Manages the algorithm's risk at each time step Args: algorithm: The algorithm instance''' targets = [] for kvp in algorithm.Securities: security = kvp.Value if not security.Invested: continue pnl = security.Holdings.UnrealizedProfitPercent if pnl <= self.maximumDrawdownPercent: # Liquidate to limit loss algorithm.Log(str(algorithm.Time) + 'Liquidating Due To MaxDrawdown: ' + str(security)) targets.append(PortfolioTarget(security.Symbol, 0)) elif pnl >= self.TakeProfitPercent: # Liquidate to take profit algorithm.Log(str(algorithm.Time) + 'Taking Profit: ' + str(security)) targets.append(PortfolioTarget(security.Symbol, 0)) return targets
from clr import AddReference AddReference("QuantConnect.Common") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Algorithm.Framework") from QuantConnect import * from QuantConnect.Algorithm import * from QuantConnect.Algorithm.Framework import * from datetime import timedelta from QuantConnect.Algorithm.Framework.Alphas import AlphaModel, Insight, InsightType, InsightDirection class ConstantAlphaModel(AlphaModel): def __init__(self): self.period = timedelta(hours=5,minutes=45) self.securities = [] self.insightsTimeBySymbol = {} self.ShouldEmitInsight = True self.Name = 'ConstantAlphaModel' def Update(self, algorithm, data): insights = [] if self.ShouldEmitInsight: for security in self.securities: insights.append(Insight.Price(security.Symbol, self.period, InsightDirection.Up)) self.ShouldEmitInsight = False return insights def OnSecuritiesChanged(self, algorithm, changes): self.removedSecurities = [] for added in changes.AddedSecurities: self.securities.append(added) self.ShouldEmitInsight = True # This will allow the insight to be re-sent when the security re-joins the universe for removed in changes.RemovedSecurities: self.removedSecurities.append(removed) self.ShouldEmitInsight = True if removed in self.securities: self.securities.remove(removed) if removed.Symbol in self.insightsTimeBySymbol: self.insightsTimeBySymbol.pop(removed.Symbol)