| Overall Statistics |
|
Total Trades 375 Average Win 0.06% Average Loss -0.03% Compounding Annual Return 26.361% Drawdown 8.800% Expectancy 1.375 Net Profit 12.666% Sharpe Ratio 1.131 Probabilistic Sharpe Ratio 54.083% Loss Rate 18% Win Rate 82% Profit-Loss Ratio 1.90 Alpha 0.234 Beta -0.172 Annual Standard Deviation 0.181 Annual Variance 0.033 Information Ratio 0.146 Tracking Error 0.222 Treynor Ratio -1.187 Total Fees $375.59 |
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
class VentralModulatedThrustAssembly(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2019, 7, 9) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.SetUniverseSelection(SelectionModel())
self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1), 0.025, None))
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
class SelectionModel(FundamentalUniverseSelectionModel):
def __init__(self,
filterFineData = True,
universeSettings = None,
securityInitializer = None):
super().__init__(filterFineData, universeSettings, securityInitializer)
self.periodCheck = -1
self.coarse = dict()
def SelectCoarse(self, algorithm, coarse):
if algorithm.Time.year == self.periodCheck:
return Universe.Unchanged
self.coarse = {x.Symbol: x
for x in coarse if x.HasFundamentalData and x.Volume > 0 and x.Price > 0}
return [symbol for symbol,_ in self.coarse.items()]
def SelectFine(self, algorithm, fine):
DERatio = lambda x: x.OperationRatios.LongTermDebtEquityRatio.ThreeMonths
fine = [x for x in fine if DERatio(x)
and x.CompanyReference.CountryId == "USA"
and (x.CompanyReference.PrimaryExchangeID in ["NYS", "NAS"])
and (algorithm.Time - x.SecurityReference.IPODate).days > 180
and x.EarningReports.BasicAverageShares.ThreeMonths *
x.EarningReports.BasicEPS.TwelveMonths *
x.ValuationRatios.PERatio > 1.52e8]
if len(fine) == 0:
return Universe.Unchanged
self.periodCheck = algorithm.Time.year
sortedByDEratio = sorted(fine, key=DERatio, reverse=False)[:50]
symbols = [x.Symbol for x in sortedByDEratio]
averages = dict()
history = algorithm.History(symbols, 200, Resolution.Daily).close.unstack(0)
for symbol in symbols:
# Remove NaN: symbol does not have 200 daily data points
df = history[symbol].dropna()
if df.empty:
continue
mom = Momentum(126)
for time, close in df.iteritems():
mom.Update(time, close)
# Adds Momentum to dict only if it is ready
if mom.IsReady:
averages[symbol] = mom
# Update with current data
for symbol, mom in averages.items():
c = self.coarse.pop(symbol, None)
mom.Update(c.EndTime, c.AdjustedPrice)
sortedbyMomentum = sorted(averages.items(), key=lambda x: x[1], reverse=True)
return [x[0] for x in sortedbyMomentum[:5]]