Overall Statistics |
Total Trades 3867 Average Win 0.54% Average Loss -0.27% Compounding Annual Return 5.526% Drawdown 63.600% Expectancy 0.264 Net Profit 208.048% Sharpe Ratio 0.293 Probabilistic Sharpe Ratio 0.002% Loss Rate 58% Win Rate 42% Profit-Loss Ratio 1.99 Alpha 0.079 Beta -0.008 Annual Standard Deviation 0.267 Annual Variance 0.071 Information Ratio 0.029 Tracking Error 0.321 Treynor Ratio -10.14 Total Fees $9406.47 |
from Execution.ImmediateExecutionModel import ImmediateExecutionModel from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel class NetNet(QCAlgorithm): def Initialize(self): self.SetStartDate(2000, 1, 1) # Set Start Date # self.SetEndDate(2020, 10, 31) self.SetCash(100000) # Set Strategy Cash self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.CoarseSelectionFunction, self.FineSelectionFunction, None, None)) self.UniverseSettings.Resolution = Resolution.Daily self.SetSecurityInitializer(lambda x: x.SetDataNormalizationMode(DataNormalizationMode.Raw)) self.SetAlpha(NetNetAlpha()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel(lambda time: None)) self.Settings.RebalancePortfolioOnInsightChanges = True self.Settings.RebalancePortfolioOnSecurityChanges = False self.SetExecution(ImmediateExecutionModel()) self.SetBenchmark("SPY") def OnData(self, data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here. Arguments: data: Slice object keyed by symbol containing the stock data ''' # if not self.Portfolio.Invested: # self.SetHoldings("SPY", 1) # on 15 Jan, filter for securities with fundamental data def CoarseSelectionFunction(self, coarse): # if self.Time.month == 10 and self.Time.day == 18 and self.Time.year == 2018: if not self.Portfolio.Invested: filtered = [ x.Symbol for x in coarse if x.HasFundamentalData ] return filtered else: return Universe.Unchanged # on 15 Jan, filter first for securities with shares and then filter a second time for net net stocks def FineSelectionFunction(self, fine): filtered = [ x for x in fine if ((x.FinancialStatements.BalanceSheet.CurrentAssets.ThreeMonths - x.FinancialStatements.BalanceSheet.TotalLiabilitiesAsReported.ThreeMonths - x.FinancialStatements.BalanceSheet.PreferredStock.ThreeMonths) > 0) and (x.FinancialStatements.BalanceSheet.OrdinarySharesNumber.ThreeMonths > 0) ] # filtered = [ x for x in filtered if (x.FinancialStatements.BalanceSheet.OrdinarySharesNumber.ThreeMonths > 0) ] # filtered = [ x for x in filtered if (x.FinancialStatements.BalanceSheet.PreferredStock.ThreeMonths > 0) ] filtered = [ x.Symbol for x in filtered if (x.Price / ((x.FinancialStatements.BalanceSheet.CurrentAssets.ThreeMonths - x.FinancialStatements.BalanceSheet.TotalLiabilitiesAsReported.ThreeMonths - x.FinancialStatements.BalanceSheet.PreferredStock.ThreeMonths) / x.FinancialStatements.BalanceSheet.OrdinarySharesNumber.ThreeMonths)) <= 0.66 ] # for x in filtered: # self.Log("Symbol: " + str(x.Symbol)) # self.Log("Name: " + x.CompanyReference.LegalName) # self.Log(str(self.Time.month) + str(self.Time.day) + str(self.Time.year)) # self.Log("Price: " + str(x.Price)) # self.Log("Current Assets: " + str(x.FinancialStatements.BalanceSheet.CurrentAssets.ThreeMonths)) # self.Log("Total Liabilities: " + str(x.FinancialStatements.BalanceSheet.TotalLiabilitiesAsReported.ThreeMonths)) # self.Log("Preferred Stock: " + str(x.FinancialStatements.BalanceSheet.PreferredStock.ThreeMonths)) # self.Log("Shares: " + str(x.FinancialStatements.BalanceSheet.OrdinarySharesNumber.ThreeMonths)) # filtered = [ x.Symbol for x in filtered ] return filtered class NetNetAlpha(AlphaModel): def __init__(self): pass # self.lastMonth = -1 def OnSecuritiesChanged(self, algorithm, changes): pass def Update(self, algorithm, data): insights = [] # if algorithm.Time.month == 10 and algorithm.Time.day == 18 and algorithm.Time.year == 2018: if not algorithm.Portfolio.Invested: for security in algorithm.ActiveSecurities.Values: # price = security.Price # currentAssets = security.Fundamentals.FinancialStatements.BalanceSheet.CurrentAssets.ThreeMonths # totalLiabilities = security.Fundamentals.FinancialStatements.BalanceSheet.TotalLiabilitiesAsReported.ThreeMonths # shares = security.Fundamentals.FinancialStatements.BalanceSheet.OrdinarySharesNumber.ThreeMonths # if ( price / ( (currentAssets - totalLiabilities) / shares ) <= 0.66 ): # insights.append(Insight.Price(security.Symbol, timedelta(days = 366), InsightDirection.Up)) insights.append(Insight.Price(security.Symbol, timedelta(days=254), InsightDirection.Up)) return insights else: return insights