| Overall Statistics |
|
Total Orders 135 Average Win 3.79% Average Loss -5.47% Compounding Annual Return 7.730% Drawdown 50.500% Expectancy 0.016 Start Equity 100000 End Equity 145096.86 Net Profit 45.097% Sharpe Ratio 0.213 Sortino Ratio 0.289 Probabilistic Sharpe Ratio 3.285% Loss Rate 40% Win Rate 60% Profit-Loss Ratio 0.69 Alpha -0.012 Beta 1.13 Annual Standard Deviation 0.305 Annual Variance 0.093 Information Ratio -0.013 Tracking Error 0.261 Treynor Ratio 0.058 Total Fees $484.12 Estimated Strategy Capacity $1900000.00 Lowest Capacity Asset JSPR XS705BNI7QLH Portfolio Turnover 0.58% Drawdown Recovery 812 |
# region imports
from AlgorithmImports import *
# endregion
class SmallCapsLowPERatioUniverseSelectionModel(FundamentalUniverseSelectionModel):
'''
Description:
This Universe model selects Small Cap stocks with low P/E Ratio (in the 1st percentile)
Details:
The important thing to understand here is the internal flow of the Universe module:
1) Select stocks with price above $5.
2) Further filter those stocks by fundamental data. In this case, we use Market Cap and P/E Ratio.
'''
def select(self, algorithm, fundamental):
# Securities must have:
# - Fundamental data (to avoid ETFs)
# - Price > $5
# - $300M < Market cap < $2B (small caps only)
filtered = [
f for f in fundamental
if (f.has_fundamental_data and
f.price > 5 and
3e8 < f.market_cap < 2e9 and
f.valuation_ratios.pe_ratio > 0)
]
# Select the stocks that have a PE Ratio in the 1st percentile.
lowest_pe_ratio_percentile = np.percentile([f.valuation_ratios.pe_ratio for f in filtered], 1)
selected = list(filter(lambda f: f.valuation_ratios.pe_ratio <= lowest_pe_ratio_percentile, filtered))
return [f.symbol for f in selected]# region imports
from AlgorithmImports import *
from SmallCapsLowPERatioUniverseSelection import SmallCapsLowPERatioUniverseSelectionModel
# endregion
### PRODUCT INFORMATION --------------------------------------------------------------------------------
# Copyright InnoQuantivity.com, granted to the public domain.
# Use entirely at your own risk.
# This algorithm contains open source code from other sources and no claim is being made to such code.
# Do not remove this copyright notice.
### ----------------------------------------------------------------------------------------------------
class LongOnlySmallCapsLowPERatioFrameworkAlgorithm(QCAlgorithmFramework):
'''
Trading Logic:
This algorithm buys at the start of every year Small Caps with low P/E Ratio
Universe: Dynamically selects stocks at the start of each year based on:
- Price above $5
- Small Caps (Market Cap between $300 million and $2 billion)
- Then select stocks in the 1st percentile of Price To Earnings Ratio (PE Ratio)
Alpha: Constant creation of Up Insights every trading bar
Portfolio: Equal Weighting (allocate equal amounts of portfolio % to each security)
Execution: Immediate Execution with Market Orders
Risk: Null
'''
def initialize(self):
self.set_start_date(self.end_date - timedelta(5*365))
self.set_cash(100_000)
# Define the universe settings.
self.universe_settings.resolution = Resolution.DAILY
self.universe_settings.fill_forward = False
self.universe_settings.schedule.on(self.date_rules.year_start('SPY'))
# Add the framework modules.
self.set_universe_selection(SmallCapsLowPERatioUniverseSelectionModel())
self.add_alpha(ConstantAlphaModel(InsightType.PRICE, InsightDirection.UP, timedelta(1)))
self.settings.rebalance_portfolio_on_insight_changes = False # Emit new insights when the universe changes
self.set_portfolio_construction(EqualWeightingPortfolioConstructionModel(lambda time: None))
self.set_execution(ImmediateExecutionModel())
self.set_risk_management(NullRiskManagementModel())