| Overall Statistics |
|
Total Trades 490 Average Win 0.82% Average Loss -0.67% Compounding Annual Return 18.445% Drawdown 32.700% Expectancy 0.283 Net Profit 66.244% Sharpe Ratio 0.707 Probabilistic Sharpe Ratio 24.026% Loss Rate 42% Win Rate 58% Profit-Loss Ratio 1.22 Alpha 0.044 Beta 1.227 Annual Standard Deviation 0.212 Annual Variance 0.045 Information Ratio 0.61 Tracking Error 0.104 Treynor Ratio 0.122 Total Fees $907.10 Estimated Strategy Capacity $110000.00 Lowest Capacity Asset CVCO SPYCIDBUES85 |
MAX_POSITIONS = 20
REBALANCE_PERIOD = 20
class DataTesting(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2010, 1, 1)
self.SetEndDate(2012, 12, 31)
self.SetCash(100000)
self.UniverseSettings.Resolution = Resolution.Minute
self.AddUniverse(self.CoarseFilter, self.FineFilter)
self.rebalance = 0
self.buy = []
self.sell = []
def CoarseFilter(self, coarse):
if self.rebalance and self.rebalance <= REBALANCE_PERIOD:
self.rebalance += 1
return Universe.Unchanged
self.rebalance = 1
filtered = [x for x in coarse if x.HasFundamentalData]
filtered = [x for x in filtered if float(x.AdjustedPrice) > 5]
filtered = [x.Symbol for x in filtered]
return filtered
def FineFilter(self, fine):
filtered = list(filter(self.FineFundamentalFilter, fine))
return self.FineSort(filtered)[:MAX_POSITIONS]
def FineFundamentalFilter(self, security):
eps3m = security.EarningRatios.DilutedEPSGrowth.ThreeMonths > 0
eps1y = security.EarningRatios.DilutedEPSGrowth.OneYear > 0
fcf3m = security.FinancialStatements.CashFlowStatement.FreeCashFlow.ThreeMonths > 0
fcf1y = security.FinancialStatements.CashFlowStatement.FreeCashFlow.TwelveMonths > 0
roe3m = security.OperationRatios.ROE.ThreeMonths > 0
roe1y = security.OperationRatios.ROE.OneYear > 0
return eps3m and eps1y and fcf3m and fcf1y and roe3m and roe1y
def FineSort(self, fine):
ranked = {}
ranks = {
'earnings_growth': [x.Symbol for x in sorted(fine, key=lambda x:
(x.EarningRatios.DilutedEPSGrowth.ThreeMonths +
x.EarningRatios.DilutedEPSGrowth.OneYear +
x.EarningRatios.DilutedEPSGrowth.ThreeYears) / 3
)],
'revenue_growth': [x.Symbol for x in sorted(fine, key=lambda x:
(x.OperationRatios.RevenueGrowth.ThreeMonths +
x.OperationRatios.RevenueGrowth.OneYear +
x.OperationRatios.RevenueGrowth.ThreeYears) / 3
)],
'book_growth': [x.Symbol for x in sorted(fine, key=lambda x:
(x.EarningRatios.BookValuePerShareGrowth.ThreeMonths +
x.EarningRatios.BookValuePerShareGrowth.OneYear +
x.EarningRatios.BookValuePerShareGrowth.ThreeYears) / 3
)],
'fcf_growth': [x.Symbol for x in sorted(fine, key=lambda x:
(x.EarningRatios.FCFPerShareGrowth.ThreeMonths +
x.EarningRatios.FCFPerShareGrowth.OneYear +
x.EarningRatios.FCFPerShareGrowth.ThreeYears) / 3
)],
}
for security in fine:
symbol = security.Symbol
ranked[symbol] = 0
for key, sort in ranks.items():
ranked[symbol] += (sort.index(symbol) + 1)
ranked = dict(sorted(ranked.items(), key=lambda x: x[1], reverse=True))
ranked = [symbol for symbol in ranked]
return ranked
def OnSecuritiesChanged(self, changes):
for added in changes.AddedSecurities:
self.buy.append(added.Symbol)
for removed in changes.RemovedSecurities:
self.sell.append(removed.Symbol)
def OnData(self, data):
sell = self.sell[:]
buy = self.buy[:]
if len(sell) > 0:
for symbol in sell:
if data.ContainsKey(symbol):
self.sell.remove(symbol)
self.Liquidate(symbol)
if len(buy) > 0:
for symbol in buy:
if data.ContainsKey(symbol):
self.buy.remove(symbol)
self.SetHoldings(symbol, 1 / MAX_POSITIONS)