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)