| Overall Statistics |
|
Total Orders 340 Average Win 0.44% Average Loss -0.44% Compounding Annual Return 7.715% Drawdown 21.800% Expectancy 0.252 Start Equity 100000 End Equity 145021.7 Net Profit 45.022% Sharpe Ratio 0.26 Sortino Ratio 0.291 Probabilistic Sharpe Ratio 19.724% Loss Rate 38% Win Rate 62% Profit-Loss Ratio 1.01 Alpha -0.009 Beta 0.409 Annual Standard Deviation 0.085 Annual Variance 0.007 Information Ratio -0.509 Tracking Error 0.104 Treynor Ratio 0.054 Total Fees $411.76 Estimated Strategy Capacity $240000000.00 Lowest Capacity Asset EEM SNQLASP67O85 Portfolio Turnover 2.07% Drawdown Recovery 1192 |
# region imports
from AlgorithmImports import *
# endregion
# https://quantpedia.com/Screener/Details/15
class CountryEquityIndexesMomentumAlgorithm(QCAlgorithm):
def Initialize(self):
self.set_start_date(self.end_date - timedelta(5*365))
self.set_cash(100_000)
#self.settings.automatic_indicator_warm_up = True
# Add the assets we'll trade and their indicators.
periods = [1, 3, 6, 12]
tickers = [
"SPY", "IWM", "QQQ", "EFA", "EEM", "VNQ",
"LQD", "GLD", "SHY", "IEF", "TLT", "AGG"
]
for ticker in tickers:
equity = self.add_equity(
ticker, Resolution.DAILY,
data_normalization_mode=DataNormalizationMode.TOTAL_RETURN
)
equity.indicators = [self.momp(equity, period*21) for period in periods]
equity.vol = IndicatorExtensions.of(StandardDeviation(3*21), self.logr(equity, 1))
# Add a Scheduled Event to rebalance the portfolio.
self.schedule.on(
self.date_rules.month_end("SPY"),
self.time_rules.after_market_close("SPY", 60),
self._rebalance
)
self.set_warm_up(timedelta(400))
def _rebalance(self):
if self.is_warming_up:
return
# Calculate the combined momentum score all each asset.
factor_by_security = {
security: sum(i.current.value for i in security.indicators)/len(security.indicators)
for security in self.securities.values()
if all([i.is_ready for i in security.indicators]) and security.vol.is_ready
}
if not factor_by_security:
return
# Select the top 5 assets.
selected = sorted(factor_by_security.keys(), key=lambda security: factor_by_security[security])[-5:]
# Form an inverse-volaility portfolio.
vol_sum = sum([1/security.vol.current.value for security in selected])
targets = [PortfolioTarget(security, 1 / security.vol.current.value / vol_sum) for security in selected]
self.set_holdings(targets, True)
def on_warmup_finished(self):
self._rebalance()