| Overall Statistics |
|
Total Orders 5887 Average Win 0.08% Average Loss -0.12% Compounding Annual Return 0.636% Drawdown 24.200% Expectancy 0.017 Start Equity 100000 End Equity 103220.81 Net Profit 3.221% Sharpe Ratio -0.202 Sortino Ratio -0.206 Probabilistic Sharpe Ratio 0.836% Loss Rate 38% Win Rate 62% Profit-Loss Ratio 0.63 Alpha 0.017 Beta -0.604 Annual Standard Deviation 0.123 Annual Variance 0.015 Information Ratio -0.388 Tracking Error 0.243 Treynor Ratio 0.041 Total Fees $6108.13 Estimated Strategy Capacity $110000000.00 Lowest Capacity Asset NOW V7TVHLCHTXLX Portfolio Turnover 9.12% Drawdown Recovery 742 |
# region imports
from AlgorithmImports import *
# endregion
# https://quantpedia.com/Screener/Details/25
class SmallCapInvestmentAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(self.end_date - timedelta(5*365))
self.set_cash(100_000)
# Define some parameters.
self._liquidity_filter_size = 100
self._universe_size = 10
self._ema_period = 200
# Add a universe of US Equities.
self.universe_settings.resolution = Resolution.HOUR
self.universe_settings.schedule.on(self.date_rules.month_start('SPY'))
self._universe = self.add_universe(self._select_assets)
# Add a warm-up period so that algorithm trades right away
# instead of waiting for a new month to start.
self.set_warm_up(timedelta(45))
def _select_assets(self, fundamentals):
# Select the most liquid Equities.
filtered = sorted(fundamentals, key=lambda f: f.dollar_volume)[-self._liquidity_filter_size:]
# Select the subset of Equities that have the highest PE ratios.
filtered = [f for f in filtered if not np.isnan(f.valuation_ratios.pe_ratio)]
filtered = sorted(filtered, key=lambda f: f.valuation_ratios.pe_ratio)[-self._universe_size:]
return [f.symbol for f in filtered]
def on_securities_changed(self, changes):
# As assets enter the universe, add their EMA indicators.
for security in changes.added_securities:
security.ema = self.ema(security, self._ema_period)
for security in changes.removed_securities:
self.deregister_indicator(security.ema)
def on_data(self, data):
if self.is_warming_up:
return
# Rebalance the portfolio to short all Equities in the
# universe that are trading below their EMA.
targets = []
for symbol in self._universe.selected:
security = self.securities[symbol]
if not security.ema.is_ready:
continue
if security.price < security.ema.current.value:
targets.append(PortfolioTarget(security, -1/self._universe_size))
self.set_holdings(targets, True)