| Overall Statistics |
|
Total Trades
1592
Average Win
0.48%
Average Loss
-0.55%
Compounding Annual Return
2.579%
Drawdown
19.000%
Expectancy
0.137
Net Profit
67.443%
Sharpe Ratio
0.318
Probabilistic Sharpe Ratio
0.040%
Loss Rate
39%
Win Rate
61%
Profit-Loss Ratio
0.87
Alpha
0.024
Beta
-0.008
Annual Standard Deviation
0.075
Annual Variance
0.006
Information Ratio
-0.13
Tracking Error
0.192
Treynor Ratio
-3.003
Total Fees
$3059.84
|
# https://quantpedia.com/strategies/multi-asset-market-breadth-momentum/
#
# Investor is invested in stocks during FOMC cycle weeks (going long S&P 500 ETF, fund, future or CFD in weeks 0, 2, 4, 6 only).
# Otherwise he is invested in cash during remaining days. The FOMC cycle starts on the day before a scheduled FOMC announcement day
# and resets at each of the eight times the FOMC meets per year.
from collections import deque
class MultiAssetMarketBreadthMomentum(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2000, 1, 1)
self.SetCash(100000)
self.symbols = ['SPY', 'QQQ', 'IWM', 'VGK', 'EWJ', 'EEM', 'GSG', 'GLD', 'IYR', 'HYG', 'LQD', 'TLT']
self.safe_bond = 'IEF'
self.period = 12 * 21
self.data = {}
self.sma = {}
for symbol in self.symbols:
self.AddEquity(symbol, Resolution.Daily)
self.data[symbol] = deque(maxlen = self.period)
self.sma[symbol] = self.SMA(symbol, self.period, Resolution.Daily)
self.AddEquity(self.safe_bond, Resolution.Daily)
self.Schedule.On(self.DateRules.MonthStart(self.symbols[0]), self.TimeRules.AfterMarketOpen(self.symbols[0]), self.Rebalance)
def Rebalance(self):
mom = {}
for symbol in self.symbols:
# SMA data is ready.
if self.sma[symbol].IsReady:
price = self.Securities[symbol].Price
if price != 0:
mom[symbol] = price / self.sma[symbol].Current.Value - 1
else:
return # Wait for every asset.
if len(mom) != 0:
# Bond fraction calc.
good_assets = sorted([x[0] for x in mom.items() if x[1] > 0], key = lambda x: x[1], reverse = True)[:6]
N = len(self.symbols)
n = len(good_assets)
a = 2
n1 = a*N/4
BF = (N-n)/(N-n1)
bond_share = (1-BF)/BF
# Trade execution.
self.Liquidate()
# Risky part.
# "leverage" ratio in case there's two parts of portfolio - risky as well as safe part.
ratio = 0.5 if bond_share != 0 else 1
for symbol in good_assets:
self.SetHoldings(symbol, ratio * (1/n))
# Bond part.
self.SetHoldings(self.safe_bond, ratio * bond_share)