| Overall Statistics |
|
Total Trades 1099 Average Win 0.35% Average Loss -0.13% Compounding Annual Return -4.771% Drawdown 48.200% Expectancy 0.360 Net Profit -12.944% Sharpe Ratio 0.034 Probabilistic Sharpe Ratio 3.392% Loss Rate 63% Win Rate 37% Profit-Loss Ratio 2.72 Alpha 0.013 Beta -0.008 Annual Standard Deviation 0.362 Annual Variance 0.131 Information Ratio -0.211 Tracking Error 0.38 Treynor Ratio -1.457 Total Fees $1316.30 |
from Execution.ImmediateExecutionModel import ImmediateExecutionModel
from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel
class NetNet(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 1, 1) # Set Start Date
self.SetEndDate(2017, 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(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(days=365)))
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel(lambda time: None))
self.Settings.RebalancePortfolioOnInsightChanges = True
self.Settings.RebalancePortfolioOnSecurityChanges = False
self.SetExecution(ImmediateExecutionModel())
self.SetBenchmark("SPY")
self.year = -1
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 self.Time.year == self.year:
return Universe.Unchanged
self.year = self.Time.year
return [ x.Symbol for x in coarse if x.HasFundamentalData ]
# 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