| Overall Statistics |
|
Total Orders 343 Average Win 0.34% Average Loss -0.06% Compounding Annual Return 16.912% Drawdown 19.600% Expectancy 4.111 Start Equity 10000000 End Equity 21848313.64 Net Profit 118.483% Sharpe Ratio 0.693 Sortino Ratio 0.837 Probabilistic Sharpe Ratio 41.757% Loss Rate 19% Win Rate 81% Profit-Loss Ratio 5.32 Alpha 0.037 Beta 0.698 Annual Standard Deviation 0.127 Annual Variance 0.016 Information Ratio 0.169 Tracking Error 0.09 Treynor Ratio 0.126 Total Fees $4103.86 Estimated Strategy Capacity $15000000.00 Lowest Capacity Asset NMR SAOX277NPSO5 Portfolio Turnover 0.14% Drawdown Recovery 483 |
#region imports
from AlgorithmImports import *
#endregion
# https://quantpedia.com/Screener/Details/26
class BooktoMarketAnomaly(QCAlgorithm):
def initialize(self):
self.set_start_date(self.end_date - timedelta(5*365))
self.settings.seed_initial_prices = True
self.set_cash(10_000_000)
# Add a universe of US Equities.
date_rule = self.date_rules.year_start("SPY")
self.universe_settings.schedule.on(date_rule)
self.universe_settings.resolution = Resolution.DAILY
self._universe = self.add_universe(self._select_assets)
# Add a Scheduled Event to rebalance the portfolio.
self.schedule.on(date_rule, self.time_rules.midnight, self._rebalance)
# Add a warm-up period so the algorithm doesn't wait until year start
# to trade.
self.set_warm_up(timedelta(365))
def _select_assets(self, fundamentals):
# Filter stocks with positive market cap and PB Ratio
fundamentals = [f for f in fundamentals if f.market_cap and f.valuation_ratios.pb_ratio > 0]
# Select the largest 20% of companies.
top_market_cap = sorted(fundamentals, key=lambda f: f.market_cap, reverse=True)[:int(len(fundamentals)*0.2)]
# Select the 20% of companies with the largest book-to-market ratios.
top_bm = sorted(top_market_cap, key=lambda f: 1 / f.valuation_ratios.pb_ratio, reverse=True)[:int(len(top_market_cap)*0.2)]
return [f.symbol for f in top_bm]
def on_warmup_finished(self):
self._rebalance()
def _rebalance(self):
# Get all the securities in the universe.
equities = []
for symbol in self._universe.selected:
equity = self.securities[symbol]
if equity.price:
equities.append(equity)
# Form a market-cap weighed portfolio.
total_market_cap = sum([equity.fundamentals.market_cap for equity in equities])
targets = [PortfolioTarget(equity, equity.fundamentals.market_cap/total_market_cap) for equity in equities]
self.set_holdings(targets, True)